From 1cadbeed88d2e5f413c8f7e39aaee6efcff89831 Mon Sep 17 00:00:00 2001
From: Fabio Berger <me@fabioberger.com>
Date: Tue, 30 Jan 2018 12:38:44 +0100
Subject: Add shouldAddPersonalMessagePrefix param to signOrderHashAsync
 instead of trying to infer whether to add it or not from the nodeVersion

---
 packages/0x.js/CHANGELOG.md                | 15 +++++++++++++--
 packages/0x.js/src/0x.ts                   | 20 +++++++++++---------
 packages/0x.js/src/utils/utils.ts          |  6 ------
 packages/0x.js/test/0x.js_test.ts          | 20 +++++++++++++++++---
 packages/0x.js/test/utils/order_factory.ts |  4 +++-
 5 files changed, 44 insertions(+), 21 deletions(-)

diff --git a/packages/0x.js/CHANGELOG.md b/packages/0x.js/CHANGELOG.md
index ec44bfc16..1acc202e2 100644
--- a/packages/0x.js/CHANGELOG.md
+++ b/packages/0x.js/CHANGELOG.md
@@ -1,10 +1,21 @@
 # CHANGELOG
 
-## v0.30.1 - _TBD, 2018_
+## v0.31.0 - _January 30, 2018_
+
+    * Add the `shouldAddPersonalMessagePrefix` parameter to `signOrderHashAsync` so that the
+    caller can decide on whether to add the personalMessage prefix before relaying the request
+    to the signer. Parity Signer, Ledger and TestRPC add the prefix themselves, Metamask expects
+    it to have already been added.
+
+## v0.30.2 - _January 29, 2018_
+
+    * Add Rinkeby testnet addresses to artifacts  (#337)
+    * Move @0xproject/types to dependencies from devDependencies fixing missing type errors
+
+## v0.30.1 - _January 24, 2018_
 
     * Fix a bug allowing negative fill values  (#212)
     * Fix a bug that made it impossible to pass a custom ZRX address  (#341)
-    * Add Rinkeby testnet addresses to artifacts  (#337)
 
 ## v0.30.0 - _January 17, 2018_
 
diff --git a/packages/0x.js/src/0x.ts b/packages/0x.js/src/0x.ts
index 503a937c4..f8a484c5d 100644
--- a/packages/0x.js/src/0x.ts
+++ b/packages/0x.js/src/0x.ts
@@ -240,20 +240,22 @@ export class ZeroEx {
      * @param   orderHash       Hex encoded orderHash to sign.
      * @param   signerAddress   The hex encoded Ethereum address you wish to sign it with. This address
      *          must be available via the Web3.Provider supplied to 0x.js.
+     * @param   shouldAddPersonalMessagePrefix  Some signers add the personal message prefix `\x19Ethereum Signed Message`
+     *          themselves (e.g Parity Signer, Ledger, TestRPC) and others expect it to already be done by the client
+     *          (e.g Metamask). Depending on which signer this request is going to, decide on whether to add the prefix
+     *          before sending the request.
      * @return  An object containing the Elliptic curve signature parameters generated by signing the orderHash.
      */
-    public async signOrderHashAsync(orderHash: string, signerAddress: string): Promise<ECSignature> {
+    public async signOrderHashAsync(
+        orderHash: string,
+        signerAddress: string,
+        shouldAddPersonalMessagePrefix: boolean,
+    ): Promise<ECSignature> {
         assert.isHexString('orderHash', orderHash);
         await assert.isSenderAddressAsync('signerAddress', signerAddress, this._web3Wrapper);
 
-        let msgHashHex;
-        const nodeVersion = await this._web3Wrapper.getNodeVersionAsync();
-        const isParityNode = utils.isParityNode(nodeVersion);
-        const isTestRpc = utils.isTestRpc(nodeVersion);
-        if (isParityNode || isTestRpc) {
-            // Parity and TestRpc nodes add the personalMessage prefix itself
-            msgHashHex = orderHash;
-        } else {
+        let msgHashHex = orderHash;
+        if (shouldAddPersonalMessagePrefix) {
             const orderHashBuff = ethUtil.toBuffer(orderHash);
             const msgHashBuff = ethUtil.hashPersonalMessage(orderHashBuff);
             msgHashHex = ethUtil.bufferToHex(msgHashBuff);
diff --git a/packages/0x.js/src/utils/utils.ts b/packages/0x.js/src/utils/utils.ts
index e42a1a853..42cf5d956 100644
--- a/packages/0x.js/src/utils/utils.ts
+++ b/packages/0x.js/src/utils/utils.ts
@@ -20,12 +20,6 @@ export const utils = {
         // tslint:disable-next-line: no-console
         console.log(message);
     },
-    isParityNode(nodeVersion: string): boolean {
-        return _.includes(nodeVersion, 'Parity');
-    },
-    isTestRpc(nodeVersion: string): boolean {
-        return _.includes(nodeVersion, 'TestRPC');
-    },
     spawnSwitchErr(name: string, value: any): Error {
         return new Error(`Unexpected switch value: ${value} encountered for ${name}`);
     },
diff --git a/packages/0x.js/test/0x.js_test.ts b/packages/0x.js/test/0x.js_test.ts
index 5bc2c149c..927fe20be 100644
--- a/packages/0x.js/test/0x.js_test.ts
+++ b/packages/0x.js/test/0x.js_test.ts
@@ -16,6 +16,8 @@ const blockchainLifecycle = new BlockchainLifecycle(constants.RPC_URL);
 chaiSetup.configure();
 const expect = chai.expect;
 
+const SHOULD_ADD_PERSONAL_MESSAGE_PREFIX = false;
+
 describe('ZeroEx library', () => {
     const web3 = web3Factory.create();
     const config = {
@@ -198,7 +200,11 @@ describe('ZeroEx library', () => {
                 r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
                 s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
             };
-            const ecSignature = await zeroEx.signOrderHashAsync(orderHash, makerAddress);
+            const ecSignature = await zeroEx.signOrderHashAsync(
+                orderHash,
+                makerAddress,
+                SHOULD_ADD_PERSONAL_MESSAGE_PREFIX,
+            );
             expect(ecSignature).to.deep.equal(expectedECSignature);
         });
         it('should return the correct ECSignature for signatureHex concatenated as R + S + V', async () => {
@@ -215,7 +221,11 @@ describe('ZeroEx library', () => {
                 Sinon.stub(ZeroEx, 'isValidSignature').returns(true),
             ];
 
-            const ecSignature = await zeroEx.signOrderHashAsync(orderHash, makerAddress);
+            const ecSignature = await zeroEx.signOrderHashAsync(
+                orderHash,
+                makerAddress,
+                SHOULD_ADD_PERSONAL_MESSAGE_PREFIX,
+            );
             expect(ecSignature).to.deep.equal(expectedECSignature);
         });
         it('should return the correct ECSignature for signatureHex concatenated as V + R + S', async () => {
@@ -232,7 +242,11 @@ describe('ZeroEx library', () => {
                 Sinon.stub(ZeroEx, 'isValidSignature').returns(true),
             ];
 
-            const ecSignature = await zeroEx.signOrderHashAsync(orderHash, makerAddress);
+            const ecSignature = await zeroEx.signOrderHashAsync(
+                orderHash,
+                makerAddress,
+                SHOULD_ADD_PERSONAL_MESSAGE_PREFIX,
+            );
             expect(ecSignature).to.deep.equal(expectedECSignature);
         });
     });
diff --git a/packages/0x.js/test/utils/order_factory.ts b/packages/0x.js/test/utils/order_factory.ts
index 60a7c5fb2..08f2081a4 100644
--- a/packages/0x.js/test/utils/order_factory.ts
+++ b/packages/0x.js/test/utils/order_factory.ts
@@ -3,6 +3,8 @@ import * as _ from 'lodash';
 
 import { SignedOrder, ZeroEx } from '../../src';
 
+const SHOULD_ADD_PERSONAL_MESSAGE_PREFIX = false;
+
 export const orderFactory = {
     async createSignedOrderAsync(
         zeroEx: ZeroEx,
@@ -37,7 +39,7 @@ export const orderFactory = {
             expirationUnixTimestampSec,
         };
         const orderHash = ZeroEx.getOrderHashHex(order);
-        const ecSignature = await zeroEx.signOrderHashAsync(orderHash, maker);
+        const ecSignature = await zeroEx.signOrderHashAsync(orderHash, maker, SHOULD_ADD_PERSONAL_MESSAGE_PREFIX);
         const signedOrder: SignedOrder = _.assign(order, { ecSignature });
         return signedOrder;
     },
-- 
cgit v1.2.3


From 4242176d291f54212797de9f5df80b1346724ebb Mon Sep 17 00:00:00 2001
From: Fabio Berger <me@fabioberger.com>
Date: Tue, 30 Jan 2018 13:16:31 +0100
Subject: Fix prettier

---
 packages/website/package.json | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/packages/website/package.json b/packages/website/package.json
index 678893f59..6db74a20e 100644
--- a/packages/website/package.json
+++ b/packages/website/package.json
@@ -8,9 +8,12 @@
         "clean": "shx rm -f public/bundle*",
         "lint": "tslint --project . 'ts/**/*.ts' 'ts/**/*.tsx'",
         "dev": "webpack-dev-server --content-base public --https",
-        "update_contracts": "for i in ${npm_package_config_artifacts}; do copyfiles -u 4 ../contracts/build/contracts/$i.json ../website/contracts; done;",
-        "deploy_staging": "npm run build; aws s3 sync ./public/. s3://staging-0xproject --profile 0xproject --region us-east-1 --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers",
-        "deploy_live": "npm run build; aws s3 sync ./public/. s3://0xproject.com --profile 0xproject --region us-east-1 --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers"
+        "update_contracts":
+            "for i in ${npm_package_config_artifacts}; do copyfiles -u 4 ../contracts/build/contracts/$i.json ../website/contracts; done;",
+        "deploy_staging":
+            "npm run build; aws s3 sync ./public/. s3://staging-0xproject --profile 0xproject --region us-east-1 --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers",
+        "deploy_live":
+            "npm run build; aws s3 sync ./public/. s3://0xproject.com --profile 0xproject --region us-east-1 --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers"
     },
     "config": {
         "artifacts": "Mintable"
-- 
cgit v1.2.3


From 93a5b3f457c1211676296840c285759007a55500 Mon Sep 17 00:00:00 2001
From: Fabio Berger <me@fabioberger.com>
Date: Tue, 30 Jan 2018 13:21:01 +0100
Subject: Fix prettier

---
 lerna.json                                         |   10 +-
 package.json                                       |   48 +-
 packages/0x.js/package.json                        |  187 +-
 packages/0x.js/src/0x.ts                           |  608 ++---
 packages/0x.js/src/artifacts.ts                    |   14 +-
 packages/0x.js/src/artifacts/DummyToken.json       |   40 +-
 packages/0x.js/src/artifacts/EtherToken.json       |  570 ++---
 packages/0x.js/src/artifacts/Exchange.json         | 1216 +++++-----
 packages/0x.js/src/artifacts/Token.json            |  340 +--
 packages/0x.js/src/artifacts/TokenRegistry.json    | 1090 ++++-----
 .../0x.js/src/artifacts/TokenTransferProxy.json    |  370 +--
 packages/0x.js/src/artifacts/ZRX.json              |   36 +-
 .../src/contract_wrappers/contract_wrapper.ts      |  378 +--
 .../src/contract_wrappers/ether_token_wrapper.ts   |  318 +--
 .../src/contract_wrappers/exchange_wrapper.ts      | 1718 +++++++-------
 .../contract_wrappers/token_registry_wrapper.ts    |  224 +-
 .../token_transfer_proxy_wrapper.ts                |  110 +-
 .../0x.js/src/contract_wrappers/token_wrapper.ts   |  720 +++---
 packages/0x.js/src/globals.d.ts                    |   50 +-
 packages/0x.js/src/globalsAugment.d.ts             |   34 +-
 packages/0x.js/src/index.ts                        |   88 +-
 packages/0x.js/src/order_watcher/event_watcher.ts  |  148 +-
 .../0x.js/src/order_watcher/expiration_watcher.ts  |  118 +-
 .../0x.js/src/order_watcher/order_state_watcher.ts |  670 +++---
 .../order_watcher/remaining_fillable_calculator.ts |  180 +-
 .../0x.js/src/schemas/zero_ex_config_schema.ts     |   50 +-
 .../stores/balance_proxy_allowance_lazy_store.ts   |  150 +-
 .../stores/order_filled_cancelled_lazy_store.ts    |  100 +-
 packages/0x.js/src/types.ts                        |  390 ++--
 packages/0x.js/src/utils/abi_decoder.ts            |  118 +-
 packages/0x.js/src/utils/assert.ts                 |   42 +-
 packages/0x.js/src/utils/constants.ts              |   16 +-
 packages/0x.js/src/utils/decorators.ts             |  114 +-
 .../0x.js/src/utils/exchange_transfer_simulator.ts |  182 +-
 packages/0x.js/src/utils/filter_utils.ts           |  150 +-
 packages/0x.js/src/utils/order_state_utils.ts      |  254 +-
 packages/0x.js/src/utils/order_validation_utils.ts |  404 ++--
 packages/0x.js/src/utils/signature_utils.ts        |   80 +-
 packages/0x.js/src/utils/utils.ts                  |  116 +-
 packages/0x.js/test/0x.js_test.ts                  |  538 ++---
 packages/0x.js/test/artifacts_test.ts              |   80 +-
 packages/0x.js/test/assert_test.ts                 |   60 +-
 packages/0x.js/test/ether_token_wrapper_test.ts    |  668 +++---
 packages/0x.js/test/event_watcher_test.ts          |  212 +-
 .../0x.js/test/exchange_transfer_simulator_test.ts |  198 +-
 packages/0x.js/test/exchange_wrapper_test.ts       | 2234 +++++++++---------
 packages/0x.js/test/expiration_watcher_test.ts     |  266 +--
 packages/0x.js/test/order_state_watcher_test.ts    | 1022 ++++----
 packages/0x.js/test/order_validation_test.ts       |  900 +++----
 .../test/remaining_fillable_calculator_test.ts     |  436 ++--
 packages/0x.js/test/subscription_test.ts           |  130 +-
 packages/0x.js/test/token_registry_wrapper_test.ts |  212 +-
 .../test/token_transfer_proxy_wrapper_test.ts      |   46 +-
 packages/0x.js/test/token_wrapper_test.ts          |  994 ++++----
 packages/0x.js/test/utils/chai_setup.ts            |   12 +-
 packages/0x.js/test/utils/constants.ts             |   18 +-
 packages/0x.js/test/utils/fill_scenarios.ts        |  374 +--
 packages/0x.js/test/utils/order_factory.ts         |   74 +-
 .../0x.js/test/utils/report_callback_errors.ts     |  102 +-
 .../utils/subproviders/empty_wallet_subprovider.ts |   34 +-
 .../subproviders/fake_gas_estimate_subprovider.ts  |   42 +-
 packages/0x.js/test/utils/token_utils.ts           |   48 +-
 packages/0x.js/test/utils/web3_factory.ts          |   40 +-
 packages/0x.js/tsconfig.json                       |   28 +-
 packages/0x.js/tslint.json                         |    2 +-
 packages/abi-gen/package.json                      |   92 +-
 packages/abi-gen/src/globals.d.ts                  |    2 +-
 packages/abi-gen/src/index.ts                      |  130 +-
 packages/abi-gen/src/types.ts                      |   20 +-
 packages/abi-gen/src/utils.ts                      |  128 +-
 packages/abi-gen/tsconfig.json                     |   10 +-
 packages/abi-gen/tslint.json                       |    2 +-
 packages/assert/package.json                       |   86 +-
 packages/assert/src/index.ts                       |  166 +-
 packages/assert/test/assert_test.ts                |  478 ++--
 packages/assert/tsconfig.json                      |   10 +-
 packages/assert/tslint.json                        |    2 +-
 .../chai-as-promised-typescript-typings/index.d.ts |  466 ++--
 .../package.json                                   |   40 +-
 .../tslint.json                                    |    2 +-
 packages/chai-typescript-typings/index.d.ts        | 2462 ++++++++++----------
 packages/chai-typescript-typings/package.json      |   28 +-
 packages/chai-typescript-typings/tslint.json       |    2 +-
 packages/connect/package.json                      |  129 +-
 packages/connect/src/globals.d.ts                  |    4 +-
 packages/connect/src/http_client.ts                |  268 +--
 packages/connect/src/index.ts                      |   30 +-
 .../src/schemas/relayer_fees_request_schema.ts     |   12 +-
 .../schemas/relayer_orderbook_request_schema.ts    |   12 +-
 .../src/schemas/relayer_orders_request_schema.ts   |   28 +-
 .../schemas/relayer_token_pairs_request_schema.ts  |   12 +-
 packages/connect/src/schemas/schemas.ts            |    6 +-
 packages/connect/src/types.ts                      |  192 +-
 .../src/utils/orderbook_channel_message_parser.ts  |   54 +-
 .../src/utils/relayer_response_json_parsers.ts     |   54 +-
 packages/connect/src/utils/type_converters.ts      |   50 +-
 packages/connect/src/ws_orderbook_channel.ts       |  238 +-
 .../test/fixtures/standard_relayer_api/fees.json   |    6 +-
 .../test/fixtures/standard_relayer_api/fees.ts     |    6 +-
 ...77fa9ac94a50f016026fd13f42990861238897721f.json |   34 +-
 ...f977fa9ac94a50f016026fd13f42990861238897721f.ts |   34 +-
 .../fixtures/standard_relayer_api/orderbook.json   |   84 +-
 .../fixtures/standard_relayer_api/orderbook.ts     |   84 +-
 .../test/fixtures/standard_relayer_api/orders.json |   38 +-
 .../test/fixtures/standard_relayer_api/orders.ts   |   38 +-
 .../fixtures/standard_relayer_api/token_pairs.json |   28 +-
 .../fixtures/standard_relayer_api/token_pairs.ts   |   28 +-
 packages/connect/test/http_client_test.ts          |  248 +-
 .../test/orderbook_channel_message_parsers_test.ts |   94 +-
 packages/connect/test/ws_orderbook_channel_test.ts |   96 +-
 packages/connect/tsconfig.json                     |   20 +-
 packages/connect/tslint.json                       |    2 +-
 packages/contracts/globals.d.ts                    |   24 +-
 packages/contracts/globalsAugment.d.ts             |   26 +-
 .../contracts/migrations/1_initial_migration.ts    |    2 +-
 .../migrations/2_deploy_independent_contracts.ts   |   60 +-
 packages/contracts/migrations/3_register_tokens.ts |  166 +-
 packages/contracts/migrations/4_configure_proxy.ts |   30 +-
 .../contracts/migrations/5_transfer_ownership.ts   |   26 +-
 .../contracts/migrations/config/multisig_sample.ts |   10 +-
 packages/contracts/migrations/config/token_info.ts |  188 +-
 packages/contracts/package.json                    |  142 +-
 packages/contracts/test/ts/ether_token.ts          |  206 +-
 packages/contracts/test/ts/exchange/core.ts        | 1610 ++++++-------
 packages/contracts/test/ts/exchange/helpers.ts     |  298 +--
 packages/contracts/test/ts/exchange/wrapper.ts     |  656 +++---
 .../contracts/test/ts/multi_sig_with_time_lock.ts  |  178 +-
 ...i_sig_with_time_lock_except_remove_auth_addr.ts |  264 +--
 packages/contracts/test/ts/token_registry.ts       |  432 ++--
 .../contracts/test/ts/token_transfer_proxy/auth.ts |  150 +-
 .../test/ts/token_transfer_proxy/transfer_from.ts  |  102 +-
 .../contracts/test/ts/unlimited_allowance_token.ts |  218 +-
 .../test/ts/unlimited_allowance_token_v2.ts        |  246 +-
 packages/contracts/test/ts/utils/chai_setup.ts     |   12 +-
 packages/contracts/test/ts/zrx_token.ts            |  314 +--
 packages/contracts/tsconfig.json                   |   46 +-
 packages/contracts/tslint.json                     |    2 +-
 packages/contracts/util/artifacts.ts               |   52 +-
 packages/contracts/util/balances.ts                |   40 +-
 packages/contracts/util/constants.ts               |   14 +-
 packages/contracts/util/crypto.ts                  |   46 +-
 packages/contracts/util/exchange_wrapper.ts        |  358 +--
 packages/contracts/util/formatters.ts              |  206 +-
 packages/contracts/util/multi_sig_wrapper.ts       |   60 +-
 packages/contracts/util/order.ts                   |  188 +-
 packages/contracts/util/order_factory.ts           |   40 +-
 packages/contracts/util/token_registry_wrapper.ts  |  104 +-
 packages/contracts/util/types.ts                   |  150 +-
 packages/deployer/package.json                     |   82 +-
 packages/deployer/src/cli.ts                       |  218 +-
 packages/deployer/src/commands.ts                  |   24 +-
 packages/deployer/src/compiler.ts                  |  450 ++--
 packages/deployer/src/deployer.ts                  |  326 +--
 packages/deployer/src/globals.d.ts                 |    6 +-
 .../src/migrations/config/multisig_sample.ts       |   10 +-
 .../deployer/src/migrations/config/token_info.ts   |   70 +-
 packages/deployer/src/migrations/migrate.ts        |  154 +-
 packages/deployer/src/solc/bin_paths.ts            |   20 +-
 packages/deployer/src/types.ts                     |   24 +-
 packages/deployer/src/utils/constants.ts           |    2 +-
 packages/deployer/src/utils/contract.ts            |  144 +-
 packages/deployer/src/utils/encoder.ts             |   24 +-
 packages/deployer/src/utils/fs_wrapper.ts          |   12 +-
 packages/deployer/src/utils/types.ts               |  110 +-
 packages/deployer/src/utils/utils.ts               |   22 +-
 packages/deployer/test/deploy_test.ts              |  122 +-
 packages/deployer/test/fixtures/exchange_bin.ts    |    4 +-
 packages/deployer/test/util/constants.ts           |   14 +-
 packages/deployer/tsconfig.json                    |   28 +-
 packages/dev-utils/package.json                    |   70 +-
 packages/dev-utils/src/blockchain_lifecycle.ts     |   38 +-
 packages/dev-utils/src/rpc.ts                      |  110 +-
 packages/dev-utils/tsconfig.json                   |   18 +-
 packages/dev-utils/tslint.json                     |    2 +-
 packages/json-schemas/package.json                 |   86 +-
 .../json-schemas/schemas/basic_type_schemas.ts     |   12 +-
 .../json-schemas/schemas/block_range_schema.ts     |   30 +-
 .../json-schemas/schemas/ec_signature_schema.ts    |   30 +-
 .../schemas/index_filter_values_schema.ts          |   10 +-
 .../json-schemas/schemas/order_cancel_schema.ts    |   20 +-
 .../schemas/order_fill_or_kill_requests_schema.ts  |   20 +-
 .../schemas/order_fill_requests_schema.ts          |   20 +-
 packages/json-schemas/schemas/order_hash_schema.ts |    6 +-
 packages/json-schemas/schemas/order_schemas.ts     |   76 +-
 .../schemas/relayer_api_error_response_schema.ts   |   38 +-
 .../schemas/relayer_api_fees_payload_schema.ts     |   44 +-
 .../schemas/relayer_api_fees_response_schema.ts    |   16 +-
 ...layer_api_orberbook_channel_subscribe_schema.ts |   36 +-
 ...elayer_api_orderbook_channel_snapshot_schema.ts |   32 +-
 ...api_orderbook_channel_update_response_schema.ts |   18 +-
 .../relayer_api_orderbook_response_schema.ts       |   14 +-
 .../relayer_api_token_pairs_response_schema.ts     |   38 +-
 .../json-schemas/schemas/signed_orders_schema.ts   |    6 +-
 packages/json-schemas/schemas/token_schema.ts      |   18 +-
 packages/json-schemas/schemas/tx_data_schema.ts    |   56 +-
 packages/json-schemas/src/schema_validator.ts      |   44 +-
 packages/json-schemas/src/schemas.ts               |   68 +-
 packages/json-schemas/test/schema_test.ts          | 1798 +++++++-------
 packages/json-schemas/tsconfig.json                |   10 +-
 packages/json-schemas/tslint.json                  |    2 +-
 packages/monorepo-scripts/package.json             |   64 +-
 packages/monorepo-scripts/src/deps_versions.ts     |   54 +-
 packages/monorepo-scripts/tsconfig.json            |   10 +-
 packages/monorepo-scripts/tslint.json              |    2 +-
 packages/subproviders/package.json                 |  106 +-
 packages/subproviders/src/globals.d.ts             |  150 +-
 packages/subproviders/src/index.ts                 |   18 +-
 .../subproviders/src/subproviders/injected_web3.ts |   68 +-
 packages/subproviders/src/subproviders/ledger.ts   |  544 ++---
 .../subproviders/src/subproviders/redundant_rpc.ts |   84 +-
 .../subproviders/src/subproviders/subprovider.ts   |   58 +-
 packages/subproviders/src/types.ts                 |  102 +-
 packages/subproviders/test/chai_setup.ts           |   10 +-
 .../test/integration/ledger_subprovider_test.ts    |  322 +--
 .../test/unit/ledger_subprovider_test.ts           |  452 ++--
 .../test/unit/redundant_rpc_subprovider_test.ts    |   78 +-
 .../test/utils/report_callback_errors.ts           |   20 +-
 packages/subproviders/tsconfig.json                |   26 +-
 packages/subproviders/tslint.json                  |    2 +-
 packages/testnet-faucets/README.md                 |   40 +-
 packages/testnet-faucets/package.json              |   82 +-
 packages/testnet-faucets/src/ts/configs.ts         |   10 +-
 packages/testnet-faucets/src/ts/error_reporter.ts  |   58 +-
 .../testnet-faucets/src/ts/ether_request_queue.ts  |   30 +-
 packages/testnet-faucets/src/ts/global.d.ts        |   28 +-
 packages/testnet-faucets/src/ts/handler.ts         |  166 +-
 packages/testnet-faucets/src/ts/id_management.ts   |   26 +-
 packages/testnet-faucets/src/ts/request_queue.ts   |   80 +-
 packages/testnet-faucets/src/ts/rpc_urls.ts        |    8 +-
 packages/testnet-faucets/src/ts/server.ts          |    8 +-
 packages/testnet-faucets/src/ts/utils.ts           |   10 +-
 .../testnet-faucets/src/ts/zrx_request_queue.ts    |   52 +-
 packages/testnet-faucets/tsconfig.json             |   10 +-
 packages/testnet-faucets/tslint.json               |    2 +-
 packages/tslint-config/README.md                   |    2 +-
 packages/tslint-config/package.json                |   80 +-
 packages/tslint-config/rules/asyncSuffixRule.ts    |    6 +-
 .../tslint-config/rules/underscorePrivatesRule.ts  |   72 +-
 .../tslint-config/rules/walkers/async_suffix.ts    |   40 +-
 packages/tslint-config/tsconfig.json               |   10 +-
 packages/tslint-config/tslint.json                 |  198 +-
 packages/types/package.json                        |   58 +-
 packages/types/src/index.ts                        |   32 +-
 packages/types/tsconfig.json                       |   10 +-
 packages/types/tslint.json                         |    2 +-
 packages/utils/package.json                        |   64 +-
 packages/utils/src/address_utils.ts                |   56 +-
 packages/utils/src/class_utils.ts                  |   28 +-
 packages/utils/src/configured_bignumber.ts         |    2 +-
 packages/utils/src/interval_utils.ts               |   66 +-
 packages/utils/src/promisify.ts                    |   18 +-
 packages/utils/tsconfig.json                       |   10 +-
 packages/utils/tslint.json                         |    2 +-
 packages/web3-typescript-typings/index.d.ts        |  840 +++----
 packages/web3-typescript-typings/package.json      |   58 +-
 packages/web3-typescript-typings/tslint.json       |    2 +-
 packages/web3-wrapper/package.json                 |   68 +-
 packages/web3-wrapper/src/index.ts                 |  326 +--
 packages/web3-wrapper/tsconfig.json                |   10 +-
 packages/web3-wrapper/tslint.json                  |    2 +-
 packages/website/contracts/Mintable.json           |  376 +--
 packages/website/md/docs/0xjs/async.md             |   14 +-
 packages/website/package.json                      |  214 +-
 packages/website/ts/blockchain.ts                  | 1504 ++++++------
 .../components/dialogs/blockchain_err_dialog.tsx   |  282 +--
 .../dialogs/eth_weth_conversion_dialog.tsx         |  290 +--
 .../ts/components/dialogs/ledger_config_dialog.tsx |  460 ++--
 .../dialogs/portal_disclaimer_dialog.tsx           |   52 +-
 .../website/ts/components/dialogs/send_dialog.tsx  |  200 +-
 .../dialogs/track_token_confirmation_dialog.tsx    |  160 +-
 .../dialogs/u2f_not_supported_dialog.tsx           |   70 +-
 .../dialogs/wrapped_eth_section_notice_dialog.tsx  |   46 +-
 .../ts/components/eth_weth_conversion_button.tsx   |  208 +-
 packages/website/ts/components/eth_wrappers.tsx    |  674 +++---
 packages/website/ts/components/fill_order.tsx      | 1270 +++++-----
 packages/website/ts/components/fill_order_json.tsx |  124 +-
 .../website/ts/components/fill_warning_dialog.tsx  |   70 +-
 .../flash_messages/token_send_completed.tsx        |   38 +-
 .../flash_messages/transaction_submitted.tsx       |   30 +-
 packages/website/ts/components/footer.tsx          |  362 +--
 .../ts/components/generate_order/asset_picker.tsx  |  498 ++--
 .../generate_order/generate_order_form.tsx         |  620 ++---
 .../components/generate_order/new_token_form.tsx   |  418 ++--
 .../website/ts/components/inputs/address_input.tsx |  112 +-
 .../ts/components/inputs/allowance_toggle.tsx      |  142 +-
 .../ts/components/inputs/balance_bounded_input.tsx |  264 +--
 .../ts/components/inputs/eth_amount_input.tsx      |   68 +-
 .../ts/components/inputs/expiration_input.tsx      |  168 +-
 .../website/ts/components/inputs/hash_input.tsx    |   86 +-
 .../components/inputs/identicon_address_input.tsx  |   76 +-
 .../ts/components/inputs/token_amount_input.tsx    |  108 +-
 .../website/ts/components/inputs/token_input.tsx   |  164 +-
 packages/website/ts/components/order_json.tsx      |  322 +--
 packages/website/ts/components/portal.tsx          |  630 ++---
 packages/website/ts/components/portal_menu.tsx     |  122 +-
 packages/website/ts/components/send_button.tsx     |  136 +-
 packages/website/ts/components/token_balances.tsx  | 1066 ++++-----
 packages/website/ts/components/top_bar.tsx         |  634 ++---
 .../website/ts/components/top_bar_menu_item.tsx    |   74 +-
 .../ts/components/track_token_confirmation.tsx     |   94 +-
 .../ts/components/trade_history/trade_history.tsx  |  190 +-
 .../trade_history/trade_history_item.tsx           |  282 +--
 packages/website/ts/components/ui/alert.tsx        |   30 +-
 packages/website/ts/components/ui/badge.tsx        |   84 +-
 packages/website/ts/components/ui/copy_icon.tsx    |  126 +-
 .../ts/components/ui/drop_down_menu_item.tsx       |  170 +-
 .../website/ts/components/ui/ethereum_address.tsx  |   38 +-
 .../website/ts/components/ui/etherscan_icon.tsx    |   52 +-
 .../website/ts/components/ui/fake_text_field.tsx   |   44 +-
 .../website/ts/components/ui/flash_message.tsx     |   52 +-
 packages/website/ts/components/ui/help_tooltip.tsx |   28 +-
 packages/website/ts/components/ui/identicon.tsx    |   72 +-
 packages/website/ts/components/ui/input_label.tsx  |   28 +-
 .../ts/components/ui/lifecycle_raised_button.tsx   |  166 +-
 packages/website/ts/components/ui/loading.tsx      |   52 +-
 packages/website/ts/components/ui/menu_item.tsx    |   78 +-
 packages/website/ts/components/ui/party.tsx        |  240 +-
 .../website/ts/components/ui/required_label.tsx    |   14 +-
 .../website/ts/components/ui/simple_loading.tsx    |   18 +-
 packages/website/ts/components/ui/swap_icon.tsx    |   60 +-
 packages/website/ts/components/ui/token_icon.tsx   |   30 +-
 packages/website/ts/components/visual_order.tsx    |  120 +-
 .../ts/containers/connect_documentation.tsx        |  116 +-
 .../website/ts/containers/generate_order_form.tsx  |   64 +-
 packages/website/ts/containers/portal.tsx          |  112 +-
 .../containers/smart_contracts_documentation.tsx   |   58 +-
 .../ts/containers/zero_ex_js_documentation.tsx     |  258 +-
 packages/website/ts/globals.d.ts                   |  170 +-
 packages/website/ts/index.tsx                      |   60 +-
 packages/website/ts/lazy_component.tsx             |   82 +-
 packages/website/ts/local_storage/local_storage.ts |   62 +-
 .../ts/local_storage/tracked_token_storage.ts      |  114 +-
 .../ts/local_storage/trade_history_storage.tsx     |  160 +-
 packages/website/ts/pages/about/about.tsx          |  416 ++--
 packages/website/ts/pages/about/profile.tsx        |  116 +-
 .../website/ts/pages/documentation/comment.tsx     |   16 +-
 .../website/ts/pages/documentation/custom_enum.tsx |   34 +-
 .../website/ts/pages/documentation/docs_info.ts    |  198 +-
 .../ts/pages/documentation/documentation.tsx       |  648 +++---
 packages/website/ts/pages/documentation/enum.tsx   |   26 +-
 .../ts/pages/documentation/event_definition.tsx    |  132 +-
 .../website/ts/pages/documentation/interface.tsx   |   98 +-
 .../ts/pages/documentation/method_block.tsx        |  238 +-
 .../ts/pages/documentation/method_signature.tsx    |  148 +-
 .../website/ts/pages/documentation/source_link.tsx |   38 +-
 packages/website/ts/pages/documentation/type.tsx   |  354 +--
 .../ts/pages/documentation/type_definition.tsx     |  194 +-
 packages/website/ts/pages/faq/faq.tsx              |  846 +++----
 packages/website/ts/pages/faq/question.tsx         |   76 +-
 packages/website/ts/pages/landing/landing.tsx      | 1420 +++++------
 packages/website/ts/pages/not_found.tsx            |   52 +-
 packages/website/ts/pages/shared/anchor_title.tsx  |  142 +-
 .../ts/pages/shared/markdown_code_block.tsx        |   28 +-
 .../website/ts/pages/shared/markdown_section.tsx   |  112 +-
 .../ts/pages/shared/nested_sidebar_menu.tsx        |  268 +--
 .../website/ts/pages/shared/section_header.tsx     |   72 +-
 .../website/ts/pages/shared/version_drop_down.tsx  |   50 +-
 packages/website/ts/pages/wiki/wiki.tsx            |  344 +--
 packages/website/ts/redux/dispatcher.ts            |  452 ++--
 packages/website/ts/redux/reducer.ts               |  738 +++---
 packages/website/ts/schemas/order_schema.ts        |   26 +-
 packages/website/ts/schemas/order_taker_schema.ts  |   18 +-
 .../website/ts/schemas/signature_data_schema.ts    |   18 +-
 packages/website/ts/schemas/token_schema.ts        |   18 +-
 packages/website/ts/schemas/validator.ts           |   22 +-
 packages/website/ts/types.ts                       |  782 +++----
 packages/website/ts/utils/colors.ts                |   78 +-
 packages/website/ts/utils/configs.ts               |  230 +-
 packages/website/ts/utils/constants.ts             |  164 +-
 packages/website/ts/utils/doc_utils.ts             |   84 +-
 packages/website/ts/utils/doxity_utils.ts          |  316 +--
 packages/website/ts/utils/error_reporter.ts        |   74 +-
 packages/website/ts/utils/mui_theme.ts             |   60 +-
 packages/website/ts/utils/typedoc_utils.ts         |  678 +++---
 packages/website/ts/utils/utils.ts                 |  522 ++---
 packages/website/ts/web3_wrapper.ts                |  288 +--
 packages/website/tsconfig.json                     |   30 +-
 packages/website/tslint.json                       |   14 +-
 tsconfig.json                                      |   22 +-
 379 files changed, 34296 insertions(+), 34316 deletions(-)

diff --git a/lerna.json b/lerna.json
index be294216a..8ca0b0883 100644
--- a/lerna.json
+++ b/lerna.json
@@ -1,7 +1,7 @@
 {
-    "lerna": "2.5.1",
-    "packages": ["packages/*"],
-    "version": "independent",
-    "npmClient": "yarn",
-    "useWorkspaces": true
+	"lerna": "2.5.1",
+	"packages": ["packages/*"],
+	"version": "independent",
+	"npmClient": "yarn",
+	"useWorkspaces": true
 }
diff --git a/package.json b/package.json
index dcb48c10d..77dc32828 100644
--- a/package.json
+++ b/package.json
@@ -1,26 +1,26 @@
 {
-    "private": true,
-    "name": "0x.js",
-    "workspaces": ["packages/*"],
-    "scripts": {
-        "testrpc": "testrpc -p 8545 --networkId 50 -m \"${npm_package_config_mnemonic}\"",
-        "prettier": "prettier --write '**/*.{ts,tsx,json,md}'",
-        "prettier:ci": "prettier --list-different '**/*.{ts,tsx,json,md}'",
-        "lerna:run": "lerna run",
-        "lerna:rebuild": "lerna run clean; lerna run build;",
-        "lerna:publish":
-            "yarn install; lerna run clean; lerna run build; lerna publish --registry=https://registry.npmjs.org/"
-    },
-    "config": {
-        "mnemonic": "concert load couple harbor equip island argue ramp clarify fence smart topic"
-    },
-    "devDependencies": {
-        "@0xproject/utils": "^0.2.0",
-        "async-child-process": "^1.1.1",
-        "ethereumjs-testrpc": "^6.0.3",
-        "lerna": "^2.5.1",
-        "prettier": "1.9.2",
-        "publish-release": "0xproject/publish-release",
-        "semver-sort": "^0.0.4"
-    }
+	"private": true,
+	"name": "0x.js",
+	"workspaces": ["packages/*"],
+	"scripts": {
+		"testrpc": "testrpc -p 8545 --networkId 50 -m \"${npm_package_config_mnemonic}\"",
+		"prettier": "prettier --write '**/*.{ts,tsx,json,md}'",
+		"prettier:ci": "prettier --list-different '**/*.{ts,tsx,json,md}'",
+		"lerna:run": "lerna run",
+		"lerna:rebuild": "lerna run clean; lerna run build;",
+		"lerna:publish":
+			"yarn install; lerna run clean; lerna run build; lerna publish --registry=https://registry.npmjs.org/"
+	},
+	"config": {
+		"mnemonic": "concert load couple harbor equip island argue ramp clarify fence smart topic"
+	},
+	"devDependencies": {
+		"@0xproject/utils": "^0.2.0",
+		"async-child-process": "^1.1.1",
+		"ethereumjs-testrpc": "^6.0.3",
+		"lerna": "^2.5.1",
+		"prettier": "1.9.2",
+		"publish-release": "0xproject/publish-release",
+		"semver-sort": "^0.0.4"
+	}
 }
diff --git a/packages/0x.js/package.json b/packages/0x.js/package.json
index 10d923501..67d6452b5 100644
--- a/packages/0x.js/package.json
+++ b/packages/0x.js/package.json
@@ -1,97 +1,94 @@
 {
-    "name": "0x.js",
-    "version": "0.30.2",
-    "description": "A javascript library for interacting with the 0x protocol",
-    "keywords": [
-        "0x.js",
-        "0xproject",
-        "ethereum",
-        "tokens",
-        "exchange"
-    ],
-    "main": "lib/src/index.js",
-    "types": "lib/src/index.d.ts",
-    "scripts": {
-        "prebuild": "run-s clean generate_contract_wrappers",
-        "build": "run-p build:umd:prod build:commonjs; exit 0;",
-        "docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --json $JSON_FILE_PATH $PROJECT_DIR",
-        "upload_docs_json": "aws s3 cp generated_docs/index.json $S3_URL --profile 0xproject --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --content-type application/json",
-        "generate_contract_wrappers": "node ../abi-gen/lib/index.js --abiGlob 'src/artifacts/@(Exchange|Token|TokenTransferProxy|EtherToken|TokenRegistry|DummyToken).json' --templates contract_templates --output src/contract_wrappers/generated",
-        "lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'",
-        "test:circleci": "run-s test:coverage report_test_coverage",
-        "test": "run-s clean test:commonjs",
-        "test:coverage": "nyc npm run test --all",
-        "report_test_coverage": "nyc report --reporter=text-lcov | coveralls",
-        "update_contracts": "for i in ${npm_package_config_artifacts}; do copyfiles -u 4 ../contracts/build/contracts/$i.json ../0x.js/src/artifacts; done;",
-        "clean": "shx rm -rf _bundles lib test_temp",
-        "build:umd:prod": "NODE_ENV=production webpack",
-        "build:commonjs": "tsc && copyfiles -u 2 './src/artifacts/**/*.json' ./lib/src/artifacts;",
-        "test:commonjs": "run-s build:commonjs run_mocha",
-        "run_mocha": "mocha lib/test/**/*_test.js --timeout 10000 --bail --exit"
-    },
-    "config": {
-        "artifacts": "TokenTransferProxy Exchange TokenRegistry Token EtherToken"
-    },
-    "repository": {
-        "type": "git",
-        "url": "https://github.com/0xProject/0x.js"
-    },
-    "license": "Apache-2.0",
-    "engines": {
-        "node": ">=6.0.0"
-    },
-    "devDependencies": {
-        "@0xproject/abi-gen": "^0.1.4",
-        "@0xproject/dev-utils": "^0.0.7",
-        "@0xproject/tslint-config": "^0.4.4",
-        "@types/bintrees": "^1.0.2",
-        "@types/jsonschema": "^1.1.1",
-        "@types/lodash": "^4.14.86",
-        "@types/mocha": "^2.2.42",
-        "@types/node": "^8.0.53",
-        "@types/sinon": "^2.2.2",
-        "@types/uuid": "^3.4.2",
-        "awesome-typescript-loader": "^3.1.3",
-        "chai": "^4.0.1",
-        "chai-as-promised": "^7.1.0",
-        "chai-as-promised-typescript-typings": "^0.0.6",
-        "chai-bignumber": "^2.0.1",
-        "chai-typescript-typings": "^0.0.2",
-        "copyfiles": "^1.2.0",
-        "coveralls": "^3.0.0",
-        "dirty-chai": "^2.0.1",
-        "json-loader": "^0.5.4",
-        "mocha": "^4.0.1",
-        "npm-run-all": "^4.1.2",
-        "nyc": "^11.0.1",
-        "opn-cli": "^3.1.0",
-        "request": "^2.81.0",
-        "request-promise-native": "^1.0.4",
-        "shx": "^0.2.2",
-        "sinon": "^4.0.0",
-        "source-map-support": "^0.5.0",
-        "truffle-hdwallet-provider": "^0.0.3",
-        "tslint": "5.8.0",
-        "typedoc": "~0.8.0",
-        "typescript": "~2.6.1",
-        "web3-provider-engine": "^13.0.1",
-        "web3-typescript-typings": "^0.9.6",
-        "webpack": "^3.1.0"
-    },
-    "dependencies": {
-        "@0xproject/assert": "^0.0.13",
-        "@0xproject/json-schemas": "^0.7.5",
-        "@0xproject/types": "^0.1.6",
-        "@0xproject/utils": "^0.2.2",
-        "@0xproject/web3-wrapper": "^0.1.7",
-        "bintrees": "^1.0.2",
-        "bn.js": "^4.11.8",
-        "ethereumjs-abi": "^0.6.4",
-        "ethereumjs-blockstream": "^2.0.6",
-        "ethereumjs-util": "^5.1.1",
-        "js-sha3": "^0.6.1",
-        "lodash": "^4.17.4",
-        "uuid": "^3.1.0",
-        "web3": "^0.20.0"
-    }
+	"name": "0x.js",
+	"version": "0.30.2",
+	"description": "A javascript library for interacting with the 0x protocol",
+	"keywords": ["0x.js", "0xproject", "ethereum", "tokens", "exchange"],
+	"main": "lib/src/index.js",
+	"types": "lib/src/index.d.ts",
+	"scripts": {
+		"prebuild": "run-s clean generate_contract_wrappers",
+		"build": "run-p build:umd:prod build:commonjs; exit 0;",
+		"docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --json $JSON_FILE_PATH $PROJECT_DIR",
+		"upload_docs_json":
+			"aws s3 cp generated_docs/index.json $S3_URL --profile 0xproject --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --content-type application/json",
+		"generate_contract_wrappers":
+			"node ../abi-gen/lib/index.js --abiGlob 'src/artifacts/@(Exchange|Token|TokenTransferProxy|EtherToken|TokenRegistry|DummyToken).json' --templates contract_templates --output src/contract_wrappers/generated",
+		"lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'",
+		"test:circleci": "run-s test:coverage report_test_coverage",
+		"test": "run-s clean test:commonjs",
+		"test:coverage": "nyc npm run test --all",
+		"report_test_coverage": "nyc report --reporter=text-lcov | coveralls",
+		"update_contracts":
+			"for i in ${npm_package_config_artifacts}; do copyfiles -u 4 ../contracts/build/contracts/$i.json ../0x.js/src/artifacts; done;",
+		"clean": "shx rm -rf _bundles lib test_temp",
+		"build:umd:prod": "NODE_ENV=production webpack",
+		"build:commonjs": "tsc && copyfiles -u 2 './src/artifacts/**/*.json' ./lib/src/artifacts;",
+		"test:commonjs": "run-s build:commonjs run_mocha",
+		"run_mocha": "mocha lib/test/**/*_test.js --timeout 10000 --bail --exit"
+	},
+	"config": {
+		"artifacts": "TokenTransferProxy Exchange TokenRegistry Token EtherToken"
+	},
+	"repository": {
+		"type": "git",
+		"url": "https://github.com/0xProject/0x.js"
+	},
+	"license": "Apache-2.0",
+	"engines": {
+		"node": ">=6.0.0"
+	},
+	"devDependencies": {
+		"@0xproject/abi-gen": "^0.1.4",
+		"@0xproject/dev-utils": "^0.0.7",
+		"@0xproject/tslint-config": "^0.4.4",
+		"@types/bintrees": "^1.0.2",
+		"@types/jsonschema": "^1.1.1",
+		"@types/lodash": "^4.14.86",
+		"@types/mocha": "^2.2.42",
+		"@types/node": "^8.0.53",
+		"@types/sinon": "^2.2.2",
+		"@types/uuid": "^3.4.2",
+		"awesome-typescript-loader": "^3.1.3",
+		"chai": "^4.0.1",
+		"chai-as-promised": "^7.1.0",
+		"chai-as-promised-typescript-typings": "^0.0.6",
+		"chai-bignumber": "^2.0.1",
+		"chai-typescript-typings": "^0.0.2",
+		"copyfiles": "^1.2.0",
+		"coveralls": "^3.0.0",
+		"dirty-chai": "^2.0.1",
+		"json-loader": "^0.5.4",
+		"mocha": "^4.0.1",
+		"npm-run-all": "^4.1.2",
+		"nyc": "^11.0.1",
+		"opn-cli": "^3.1.0",
+		"request": "^2.81.0",
+		"request-promise-native": "^1.0.4",
+		"shx": "^0.2.2",
+		"sinon": "^4.0.0",
+		"source-map-support": "^0.5.0",
+		"truffle-hdwallet-provider": "^0.0.3",
+		"tslint": "5.8.0",
+		"typedoc": "~0.8.0",
+		"typescript": "~2.6.1",
+		"web3-provider-engine": "^13.0.1",
+		"web3-typescript-typings": "^0.9.6",
+		"webpack": "^3.1.0"
+	},
+	"dependencies": {
+		"@0xproject/assert": "^0.0.13",
+		"@0xproject/json-schemas": "^0.7.5",
+		"@0xproject/types": "^0.1.6",
+		"@0xproject/utils": "^0.2.2",
+		"@0xproject/web3-wrapper": "^0.1.7",
+		"bintrees": "^1.0.2",
+		"bn.js": "^4.11.8",
+		"ethereumjs-abi": "^0.6.4",
+		"ethereumjs-blockstream": "^2.0.6",
+		"ethereumjs-util": "^5.1.1",
+		"js-sha3": "^0.6.1",
+		"lodash": "^4.17.4",
+		"uuid": "^3.1.0",
+		"web3": "^0.20.0"
+	}
 }
diff --git a/packages/0x.js/src/0x.ts b/packages/0x.js/src/0x.ts
index f8a484c5d..dec26e3eb 100644
--- a/packages/0x.js/src/0x.ts
+++ b/packages/0x.js/src/0x.ts
@@ -13,13 +13,13 @@ import { TokenWrapper } from './contract_wrappers/token_wrapper';
 import { OrderStateWatcher } from './order_watcher/order_state_watcher';
 import { zeroExConfigSchema } from './schemas/zero_ex_config_schema';
 import {
-    ECSignature,
-    Order,
-    SignedOrder,
-    TransactionReceiptWithDecodedLogs,
-    Web3Provider,
-    ZeroExConfig,
-    ZeroExError,
+	ECSignature,
+	Order,
+	SignedOrder,
+	TransactionReceiptWithDecodedLogs,
+	Web3Provider,
+	ZeroExConfig,
+	ZeroExError,
 } from './types';
 import { AbiDecoder } from './utils/abi_decoder';
 import { assert } from './utils/assert';
@@ -33,318 +33,318 @@ import { utils } from './utils/utils';
  * 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;
+	/**
+	 * 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);
+	/**
+	 * 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.isValidBaseUnitAmount('amount', amount);
-        assert.isNumber('decimals', decimals);
+		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.isValidBaseUnitAmount('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 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);
-        const hasDecimals = baseUnitAmount.decimalPlaces() !== 0;
-        if (hasDecimals) {
-            throw new Error(`Invalid unit amount: ${amount.toString()} - Too many decimal places`);
-        }
-        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.
-     */
-    @decorators.syncZeroExErrorHandler
-    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);
-        assert.doesConformToSchema('config', config, zeroExConfigSchema);
-        const artifactJSONs = _.values(artifacts);
-        const abiArrays = _.map(artifactJSONs, artifact => artifact.abi);
-        this._abiDecoder = new AbiDecoder(abiArrays);
-        const defaults = {
-            gasPrice: config.gasPrice,
-        };
-        this._web3Wrapper = new Web3Wrapper(provider, defaults);
-        this.proxy = new TokenTransferProxyWrapper(
-            this._web3Wrapper,
-            config.networkId,
-            config.tokenTransferProxyContractAddress,
-        );
-        this.token = new TokenWrapper(this._web3Wrapper, config.networkId, this._abiDecoder, this.proxy);
-        this.exchange = new ExchangeWrapper(
-            this._web3Wrapper,
-            config.networkId,
-            this._abiDecoder,
-            this.token,
-            config.exchangeContractAddress,
-            config.zrxContractAddress,
-        );
-        this.tokenRegistry = new TokenRegistryWrapper(
-            this._web3Wrapper,
-            config.networkId,
-            config.tokenRegistryContractAddress,
-        );
-        this.etherToken = new EtherTokenWrapper(this._web3Wrapper, config.networkId, this._abiDecoder, this.token);
-        this.orderStateWatcher = new OrderStateWatcher(
-            this._web3Wrapper,
-            this._abiDecoder,
-            this.token,
-            this.exchange,
-            config.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.
-     * @param   networkId   The id of the network your provider is connected to
-     */
-    public setProvider(provider: Web3Provider, networkId: number): void {
-        this._web3Wrapper.setProvider(provider);
-        (this.exchange as any)._invalidateContractInstances();
-        (this.exchange as any)._setNetworkId(networkId);
-        (this.tokenRegistry as any)._invalidateContractInstance();
-        (this.tokenRegistry as any)._setNetworkId(networkId);
-        (this.token as any)._invalidateContractInstances();
-        (this.token as any)._setNetworkId(networkId);
-        (this.proxy as any)._invalidateContractInstance();
-        (this.proxy as any)._setNetworkId(networkId);
-        (this.etherToken as any)._invalidateContractInstance();
-        (this.etherToken as any)._setNetworkId(networkId);
-    }
-    /**
-     * 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<string[]> {
-        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.
-     * @param   shouldAddPersonalMessagePrefix  Some signers add the personal message prefix `\x19Ethereum Signed Message`
-     *          themselves (e.g Parity Signer, Ledger, TestRPC) and others expect it to already be done by the client
-     *          (e.g Metamask). Depending on which signer this request is going to, decide on whether to add the prefix
-     *          before sending the request.
-     * @return  An object containing the Elliptic curve signature parameters generated by signing the orderHash.
-     */
-    public async signOrderHashAsync(
-        orderHash: string,
-        signerAddress: string,
-        shouldAddPersonalMessagePrefix: boolean,
-    ): Promise<ECSignature> {
-        assert.isHexString('orderHash', orderHash);
-        await assert.isSenderAddressAsync('signerAddress', signerAddress, this._web3Wrapper);
+		const unit = new BigNumber(10).pow(decimals);
+		const baseUnitAmount = amount.times(unit);
+		const hasDecimals = baseUnitAmount.decimalPlaces() !== 0;
+		if (hasDecimals) {
+			throw new Error(`Invalid unit amount: ${amount.toString()} - Too many decimal places`);
+		}
+		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.
+	 */
+	@decorators.syncZeroExErrorHandler
+	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);
+		assert.doesConformToSchema('config', config, zeroExConfigSchema);
+		const artifactJSONs = _.values(artifacts);
+		const abiArrays = _.map(artifactJSONs, artifact => artifact.abi);
+		this._abiDecoder = new AbiDecoder(abiArrays);
+		const defaults = {
+			gasPrice: config.gasPrice,
+		};
+		this._web3Wrapper = new Web3Wrapper(provider, defaults);
+		this.proxy = new TokenTransferProxyWrapper(
+			this._web3Wrapper,
+			config.networkId,
+			config.tokenTransferProxyContractAddress,
+		);
+		this.token = new TokenWrapper(this._web3Wrapper, config.networkId, this._abiDecoder, this.proxy);
+		this.exchange = new ExchangeWrapper(
+			this._web3Wrapper,
+			config.networkId,
+			this._abiDecoder,
+			this.token,
+			config.exchangeContractAddress,
+			config.zrxContractAddress,
+		);
+		this.tokenRegistry = new TokenRegistryWrapper(
+			this._web3Wrapper,
+			config.networkId,
+			config.tokenRegistryContractAddress,
+		);
+		this.etherToken = new EtherTokenWrapper(this._web3Wrapper, config.networkId, this._abiDecoder, this.token);
+		this.orderStateWatcher = new OrderStateWatcher(
+			this._web3Wrapper,
+			this._abiDecoder,
+			this.token,
+			this.exchange,
+			config.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.
+	 * @param   networkId   The id of the network your provider is connected to
+	 */
+	public setProvider(provider: Web3Provider, networkId: number): void {
+		this._web3Wrapper.setProvider(provider);
+		(this.exchange as any)._invalidateContractInstances();
+		(this.exchange as any)._setNetworkId(networkId);
+		(this.tokenRegistry as any)._invalidateContractInstance();
+		(this.tokenRegistry as any)._setNetworkId(networkId);
+		(this.token as any)._invalidateContractInstances();
+		(this.token as any)._setNetworkId(networkId);
+		(this.proxy as any)._invalidateContractInstance();
+		(this.proxy as any)._setNetworkId(networkId);
+		(this.etherToken as any)._invalidateContractInstance();
+		(this.etherToken as any)._setNetworkId(networkId);
+	}
+	/**
+	 * 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<string[]> {
+		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.
+	 * @param   shouldAddPersonalMessagePrefix  Some signers add the personal message prefix `\x19Ethereum Signed Message`
+	 *          themselves (e.g Parity Signer, Ledger, TestRPC) and others expect it to already be done by the client
+	 *          (e.g Metamask). Depending on which signer this request is going to, decide on whether to add the prefix
+	 *          before sending the request.
+	 * @return  An object containing the Elliptic curve signature parameters generated by signing the orderHash.
+	 */
+	public async signOrderHashAsync(
+		orderHash: string,
+		signerAddress: string,
+		shouldAddPersonalMessagePrefix: boolean,
+	): Promise<ECSignature> {
+		assert.isHexString('orderHash', orderHash);
+		await assert.isSenderAddressAsync('signerAddress', signerAddress, this._web3Wrapper);
 
-        let msgHashHex = orderHash;
-        if (shouldAddPersonalMessagePrefix) {
-            const orderHashBuff = ethUtil.toBuffer(orderHash);
-            const msgHashBuff = ethUtil.hashPersonalMessage(orderHashBuff);
-            msgHashHex = ethUtil.bufferToHex(msgHashBuff);
-        }
+		let msgHashHex = orderHash;
+		if (shouldAddPersonalMessagePrefix) {
+			const orderHashBuff = ethUtil.toBuffer(orderHash);
+			const msgHashBuff = ethUtil.hashPersonalMessage(orderHashBuff);
+			msgHashHex = ethUtil.bufferToHex(msgHashBuff);
+		}
 
-        const signature = await this._web3Wrapper.signTransactionAsync(signerAddress, msgHashHex);
+		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;
-            }
-        }
+		// 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;
-            }
-        }
+		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<TransactionReceiptWithDecodedLogs> {
-        let timeoutExceeded = false;
-        if (timeoutMs) {
-            setTimeout(() => (timeoutExceeded = true), timeoutMs);
-        }
+		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<TransactionReceiptWithDecodedLogs> {
+		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 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,
-                    (err: Error) => {
-                        intervalUtils.clearAsyncExcludingInterval(intervalId);
-                        reject(err);
-                    },
-                );
-            },
-        );
+						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,
+					(err: Error) => {
+						intervalUtils.clearAsyncExcludingInterval(intervalId);
+						reject(err);
+					},
+				);
+			},
+		);
 
-        return txReceiptPromise;
-    }
-    /*
+		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<string> {
-        const tokenTransferProxyAddress = await (this.exchange as any)._getTokenTransferProxyAddressAsync();
-        return tokenTransferProxyAddress;
-    }
+	private async _getTokenTransferProxyAddressAsync(): Promise<string> {
+		const tokenTransferProxyAddress = await (this.exchange as any)._getTokenTransferProxyAddressAsync();
+		return tokenTransferProxyAddress;
+	}
 }
diff --git a/packages/0x.js/src/artifacts.ts b/packages/0x.js/src/artifacts.ts
index cbacd7d56..7d4bd6757 100644
--- a/packages/0x.js/src/artifacts.ts
+++ b/packages/0x.js/src/artifacts.ts
@@ -8,11 +8,11 @@ import * as ZRXArtifact from './artifacts/ZRX.json';
 import { Artifact } from './types';
 
 export const artifacts = {
-    ZRXArtifact: (ZRXArtifact as any) as Artifact,
-    DummyTokenArtifact: (DummyTokenArtifact as any) as Artifact,
-    TokenArtifact: (TokenArtifact as any) as Artifact,
-    ExchangeArtifact: (ExchangeArtifact as any) as Artifact,
-    EtherTokenArtifact: (EtherTokenArtifact as any) as Artifact,
-    TokenRegistryArtifact: (TokenRegistryArtifact as any) as Artifact,
-    TokenTransferProxyArtifact: (TokenTransferProxyArtifact as any) as Artifact,
+	ZRXArtifact: (ZRXArtifact as any) as Artifact,
+	DummyTokenArtifact: (DummyTokenArtifact as any) as Artifact,
+	TokenArtifact: (TokenArtifact as any) as Artifact,
+	ExchangeArtifact: (ExchangeArtifact as any) as Artifact,
+	EtherTokenArtifact: (EtherTokenArtifact as any) as Artifact,
+	TokenRegistryArtifact: (TokenRegistryArtifact as any) as Artifact,
+	TokenTransferProxyArtifact: (TokenTransferProxyArtifact as any) as Artifact,
 };
diff --git a/packages/0x.js/src/artifacts/DummyToken.json b/packages/0x.js/src/artifacts/DummyToken.json
index f64a8cd3d..f96d63c21 100644
--- a/packages/0x.js/src/artifacts/DummyToken.json
+++ b/packages/0x.js/src/artifacts/DummyToken.json
@@ -1,22 +1,22 @@
 {
-    "contract_name": "DummyToken",
-    "abi": [
-        {
-            "constant": false,
-            "inputs": [
-                {
-                    "name": "_target",
-                    "type": "address"
-                },
-                {
-                    "name": "_value",
-                    "type": "uint256"
-                }
-            ],
-            "name": "setBalance",
-            "outputs": [],
-            "payable": false,
-            "type": "function"
-        }
-    ]
+	"contract_name": "DummyToken",
+	"abi": [
+		{
+			"constant": false,
+			"inputs": [
+				{
+					"name": "_target",
+					"type": "address"
+				},
+				{
+					"name": "_value",
+					"type": "uint256"
+				}
+			],
+			"name": "setBalance",
+			"outputs": [],
+			"payable": false,
+			"type": "function"
+		}
+	]
 }
diff --git a/packages/0x.js/src/artifacts/EtherToken.json b/packages/0x.js/src/artifacts/EtherToken.json
index 26cca57cd..ca5f9c035 100644
--- a/packages/0x.js/src/artifacts/EtherToken.json
+++ b/packages/0x.js/src/artifacts/EtherToken.json
@@ -1,287 +1,287 @@
 {
-    "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"
-        },
-        {
-            "anonymous": false,
-            "inputs": [
-                {
-                    "indexed": true,
-                    "name": "_owner",
-                    "type": "address"
-                },
-                {
-                    "indexed": false,
-                    "name": "_value",
-                    "type": "uint256"
-                }
-            ],
-            "name": "Deposit",
-            "type": "event"
-        },
-        {
-            "anonymous": false,
-            "inputs": [
-                {
-                    "indexed": true,
-                    "name": "_owner",
-                    "type": "address"
-                },
-                {
-                    "indexed": false,
-                    "name": "_value",
-                    "type": "uint256"
-                }
-            ],
-            "name": "Withdrawal",
-            "type": "event"
-        }
-    ],
-    "networks": {
-        "1": {
-            "address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
-        },
-        "3": {
-            "address": "0xc00fd9820cd2898cc4c054b7bf142de637ad129a"
-        },
-        "4": {
-            "address": "0xc778417e063141139fce010982780140aa0cd5ab"
-        },
-        "42": {
-            "address": "0x653e49e301e508a13237c0ddc98ae7d4cd2667a1"
-        },
-        "50": {
-            "address": "0x871dd7c2b4b25e1aa18728e9d5f2af4c4e431f5c"
-        }
-    }
+	"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"
+		},
+		{
+			"anonymous": false,
+			"inputs": [
+				{
+					"indexed": true,
+					"name": "_owner",
+					"type": "address"
+				},
+				{
+					"indexed": false,
+					"name": "_value",
+					"type": "uint256"
+				}
+			],
+			"name": "Deposit",
+			"type": "event"
+		},
+		{
+			"anonymous": false,
+			"inputs": [
+				{
+					"indexed": true,
+					"name": "_owner",
+					"type": "address"
+				},
+				{
+					"indexed": false,
+					"name": "_value",
+					"type": "uint256"
+				}
+			],
+			"name": "Withdrawal",
+			"type": "event"
+		}
+	],
+	"networks": {
+		"1": {
+			"address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
+		},
+		"3": {
+			"address": "0xc00fd9820cd2898cc4c054b7bf142de637ad129a"
+		},
+		"4": {
+			"address": "0xc778417e063141139fce010982780140aa0cd5ab"
+		},
+		"42": {
+			"address": "0x653e49e301e508a13237c0ddc98ae7d4cd2667a1"
+		},
+		"50": {
+			"address": "0x871dd7c2b4b25e1aa18728e9d5f2af4c4e431f5c"
+		}
+	}
 }
diff --git a/packages/0x.js/src/artifacts/Exchange.json b/packages/0x.js/src/artifacts/Exchange.json
index af8db7360..44bb41d4d 100644
--- a/packages/0x.js/src/artifacts/Exchange.json
+++ b/packages/0x.js/src/artifacts/Exchange.json
@@ -1,610 +1,610 @@
 {
-    "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"
-        }
-    ],
-    "networks": {
-        "1": {
-            "address": "0x12459c951127e0c374ff9105dda097662a027093"
-        },
-        "3": {
-            "address": "0x479cc461fecd078f766ecc58533d6f69580cf3ac"
-        },
-        "4": {
-            "address": "0x1d16ef40fac01cec8adac2ac49427b9384192c05"
-        },
-        "42": {
-            "address": "0x90fe2af704b34e0224bf2299c838e04d4dcf1364"
-        },
-        "50": {
-            "address": "0x48bacb9266a570d521063ef5dd96e61686dbe788"
-        }
-    }
+	"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"
+		}
+	],
+	"networks": {
+		"1": {
+			"address": "0x12459c951127e0c374ff9105dda097662a027093"
+		},
+		"3": {
+			"address": "0x479cc461fecd078f766ecc58533d6f69580cf3ac"
+		},
+		"4": {
+			"address": "0x1d16ef40fac01cec8adac2ac49427b9384192c05"
+		},
+		"42": {
+			"address": "0x90fe2af704b34e0224bf2299c838e04d4dcf1364"
+		},
+		"50": {
+			"address": "0x48bacb9266a570d521063ef5dd96e61686dbe788"
+		}
+	}
 }
diff --git a/packages/0x.js/src/artifacts/Token.json b/packages/0x.js/src/artifacts/Token.json
index 3b5a86ae0..bd4208275 100644
--- a/packages/0x.js/src/artifacts/Token.json
+++ b/packages/0x.js/src/artifacts/Token.json
@@ -1,172 +1,172 @@
 {
-    "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"
-        }
-    ]
+	"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"
+		}
+	]
 }
diff --git a/packages/0x.js/src/artifacts/TokenRegistry.json b/packages/0x.js/src/artifacts/TokenRegistry.json
index 0f583628c..490ea0c34 100644
--- a/packages/0x.js/src/artifacts/TokenRegistry.json
+++ b/packages/0x.js/src/artifacts/TokenRegistry.json
@@ -1,547 +1,547 @@
 {
-    "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"
-        }
-    ],
-    "networks": {
-        "1": {
-            "address": "0x926a74c5c36adf004c87399e65f75628b0f98d2c"
-        },
-        "3": {
-            "address": "0x6b1a50f0bb5a7995444bd3877b22dc89c62843ed"
-        },
-        "4": {
-            "address": "0x4e9aad8184de8833365fea970cd9149372fdf1e6"
-        },
-        "42": {
-            "address": "0xf18e504561f4347bea557f3d4558f559dddbae7f"
-        },
-        "50": {
-            "address": "0x0b1ba0af832d7c05fd64161e0db78e85978e8082"
-        }
-    }
+	"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"
+		}
+	],
+	"networks": {
+		"1": {
+			"address": "0x926a74c5c36adf004c87399e65f75628b0f98d2c"
+		},
+		"3": {
+			"address": "0x6b1a50f0bb5a7995444bd3877b22dc89c62843ed"
+		},
+		"4": {
+			"address": "0x4e9aad8184de8833365fea970cd9149372fdf1e6"
+		},
+		"42": {
+			"address": "0xf18e504561f4347bea557f3d4558f559dddbae7f"
+		},
+		"50": {
+			"address": "0x0b1ba0af832d7c05fd64161e0db78e85978e8082"
+		}
+	}
 }
diff --git a/packages/0x.js/src/artifacts/TokenTransferProxy.json b/packages/0x.js/src/artifacts/TokenTransferProxy.json
index 8cf551ddb..5e45e4903 100644
--- a/packages/0x.js/src/artifacts/TokenTransferProxy.json
+++ b/packages/0x.js/src/artifacts/TokenTransferProxy.json
@@ -1,187 +1,187 @@
 {
-    "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"
-        }
-    ],
-    "networks": {
-        "1": {
-            "address": "0x8da0d80f5007ef1e431dd2127178d224e32c2ef4"
-        },
-        "3": {
-            "address": "0x4e9aad8184de8833365fea970cd9149372fdf1e6"
-        },
-        "4": {
-            "address": "0xa8e9fa8f91e5ae138c74648c9c304f1c75003a8d"
-        },
-        "42": {
-            "address": "0x087eed4bc1ee3de49befbd66c662b434b15d49d4"
-        },
-        "50": {
-            "address": "0x1dc4c1cefef38a777b15aa20260a54e584b16c48"
-        }
-    }
+	"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"
+		}
+	],
+	"networks": {
+		"1": {
+			"address": "0x8da0d80f5007ef1e431dd2127178d224e32c2ef4"
+		},
+		"3": {
+			"address": "0x4e9aad8184de8833365fea970cd9149372fdf1e6"
+		},
+		"4": {
+			"address": "0xa8e9fa8f91e5ae138c74648c9c304f1c75003a8d"
+		},
+		"42": {
+			"address": "0x087eed4bc1ee3de49befbd66c662b434b15d49d4"
+		},
+		"50": {
+			"address": "0x1dc4c1cefef38a777b15aa20260a54e584b16c48"
+		}
+	}
 }
diff --git a/packages/0x.js/src/artifacts/ZRX.json b/packages/0x.js/src/artifacts/ZRX.json
index e40b8f268..44f478ab4 100644
--- a/packages/0x.js/src/artifacts/ZRX.json
+++ b/packages/0x.js/src/artifacts/ZRX.json
@@ -1,20 +1,20 @@
 {
-    "contract_name": "ZRX",
-    "networks": {
-        "1": {
-            "address": "0xe41d2489571d322189246dafa5ebde1f4699f498"
-        },
-        "3": {
-            "address": "0xa8e9fa8f91e5ae138c74648c9c304f1c75003a8d"
-        },
-        "4": {
-            "address": "0x00f58d6d585f84b2d7267940cede30ce2fe6eae8"
-        },
-        "42": {
-            "address": "0x6ff6c0ff1d68b964901f986d4c9fa3ac68346570"
-        },
-        "50": {
-            "address": "0x1d7022f5b17d2f8b695918fb48fa1089c9f85401"
-        }
-    }
+	"contract_name": "ZRX",
+	"networks": {
+		"1": {
+			"address": "0xe41d2489571d322189246dafa5ebde1f4699f498"
+		},
+		"3": {
+			"address": "0xa8e9fa8f91e5ae138c74648c9c304f1c75003a8d"
+		},
+		"4": {
+			"address": "0x00f58d6d585f84b2d7267940cede30ce2fe6eae8"
+		},
+		"42": {
+			"address": "0x6ff6c0ff1d68b964901f986d4c9fa3ac68346570"
+		},
+		"50": {
+			"address": "0x1d7022f5b17d2f8b695918fb48fa1089c9f85401"
+		}
+	}
 }
diff --git a/packages/0x.js/src/contract_wrappers/contract_wrapper.ts b/packages/0x.js/src/contract_wrappers/contract_wrapper.ts
index 27551c01d..d1b753f45 100644
--- a/packages/0x.js/src/contract_wrappers/contract_wrapper.ts
+++ b/packages/0x.js/src/contract_wrappers/contract_wrapper.ts
@@ -5,203 +5,203 @@ import * as _ from 'lodash';
 import * as Web3 from 'web3';
 
 import {
-    Artifact,
-    BlockParamLiteral,
-    BlockRange,
-    ContractEventArgs,
-    ContractEvents,
-    EventCallback,
-    IndexedFilterValues,
-    InternalZeroExError,
-    LogWithDecodedArgs,
-    RawLog,
-    ZeroExError,
+	Artifact,
+	BlockParamLiteral,
+	BlockRange,
+	ContractEventArgs,
+	ContractEvents,
+	EventCallback,
+	IndexedFilterValues,
+	InternalZeroExError,
+	LogWithDecodedArgs,
+	RawLog,
+	ZeroExError,
 } from '../types';
 import { AbiDecoder } from '../utils/abi_decoder';
 import { constants } from '../utils/constants';
 import { filterUtils } from '../utils/filter_utils';
 
 const CONTRACT_NAME_TO_NOT_FOUND_ERROR: {
-    [contractName: string]: ZeroExError;
+	[contractName: string]: ZeroExError;
 } = {
-    ZRX: ZeroExError.ZRXContractDoesNotExist,
-    EtherToken: ZeroExError.EtherTokenContractDoesNotExist,
-    Token: ZeroExError.TokenContractDoesNotExist,
-    TokenRegistry: ZeroExError.TokenRegistryContractDoesNotExist,
-    TokenTransferProxy: ZeroExError.TokenTransferProxyContractDoesNotExist,
-    Exchange: ZeroExError.ExchangeContractDoesNotExist,
+	ZRX: ZeroExError.ZRXContractDoesNotExist,
+	EtherToken: ZeroExError.EtherTokenContractDoesNotExist,
+	Token: ZeroExError.TokenContractDoesNotExist,
+	TokenRegistry: ZeroExError.TokenRegistryContractDoesNotExist,
+	TokenTransferProxy: ZeroExError.TokenTransferProxyContractDoesNotExist,
+	Exchange: ZeroExError.ExchangeContractDoesNotExist,
 };
 
 export class ContractWrapper {
-    protected _web3Wrapper: Web3Wrapper;
-    private _networkId: number;
-    private _abiDecoder?: AbiDecoder;
-    private _blockAndLogStreamerIfExists: BlockAndLogStreamer | undefined;
-    private _blockAndLogStreamInterval: NodeJS.Timer;
-    private _filters: { [filterToken: string]: Web3.FilterObject };
-    private _filterCallbacks: {
-        [filterToken: string]: EventCallback<ContractEventArgs>;
-    };
-    private _onLogAddedSubscriptionToken: string | undefined;
-    private _onLogRemovedSubscriptionToken: string | undefined;
-    constructor(web3Wrapper: Web3Wrapper, networkId: number, abiDecoder?: AbiDecoder) {
-        this._web3Wrapper = web3Wrapper;
-        this._networkId = networkId;
-        this._abiDecoder = abiDecoder;
-        this._filters = {};
-        this._filterCallbacks = {};
-        this._blockAndLogStreamerIfExists = undefined;
-        this._onLogAddedSubscriptionToken = undefined;
-        this._onLogRemovedSubscriptionToken = undefined;
-    }
-    protected 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<ArgsType extends ContractEventArgs>(
-        address: string,
-        eventName: ContractEvents,
-        indexFilterValues: IndexedFilterValues,
-        abi: Web3.ContractAbi,
-        callback: EventCallback<ArgsType>,
-    ): string {
-        const filter = filterUtils.getFilter(address, eventName, indexFilterValues, abi);
-        if (_.isUndefined(this._blockAndLogStreamerIfExists)) {
-            this._startBlockAndLogStream();
-        }
-        const filterToken = filterUtils.generateUUID();
-        this._filters[filterToken] = filter;
-        this._filterCallbacks[filterToken] = callback as EventCallback<ContractEventArgs>;
-        return filterToken;
-    }
-    protected async _getLogsAsync<ArgsType extends ContractEventArgs>(
-        address: string,
-        eventName: ContractEvents,
-        blockRange: BlockRange,
-        indexFilterValues: IndexedFilterValues,
-        abi: Web3.ContractAbi,
-    ): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
-        const filter = filterUtils.getFilter(address, eventName, indexFilterValues, abi, blockRange);
-        const logs = await this._web3Wrapper.getLogsAsync(filter);
-        const logsWithDecodedArguments = _.map(logs, this._tryToDecodeLogOrNoop.bind(this));
-        return logsWithDecodedArguments;
-    }
-    protected _tryToDecodeLogOrNoop<ArgsType extends ContractEventArgs>(
-        log: Web3.LogEntry,
-    ): LogWithDecodedArgs<ArgsType> | 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<Web3.ContractInstance> {
-        let contractAddress: string;
-        if (_.isUndefined(addressIfExists)) {
-            if (_.isUndefined(artifact.networks[this._networkId])) {
-                throw new Error(ZeroExError.ContractNotDeployedOnNetwork);
-            }
-            contractAddress = artifact.networks[this._networkId].address.toLowerCase();
-        } else {
-            contractAddress = addressIfExists;
-        }
-        const doesContractExist = await this._web3Wrapper.doesContractExistAtAddressAsync(contractAddress);
-        if (!doesContractExist) {
-            throw new Error(CONTRACT_NAME_TO_NOT_FOUND_ERROR[artifact.contract_name]);
-        }
-        const contractInstance = this._web3Wrapper.getContractInstance(artifact.abi, contractAddress);
-        return contractInstance;
-    }
-    protected _getContractAddress(artifact: Artifact, addressIfExists?: string): string {
-        if (_.isUndefined(addressIfExists)) {
-            const contractAddress = artifact.networks[this._networkId].address;
-            if (_.isUndefined(contractAddress)) {
-                throw new Error(ZeroExError.ExchangeContractDoesNotExist);
-            }
-            return contractAddress;
-        } else {
-            return addressIfExists;
-        }
-    }
-    private _onLogStateChanged<ArgsType extends ContractEventArgs>(isRemoved: 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<ArgsType>;
-                const logEvent = {
-                    log: decodedLog,
-                    isRemoved,
-                };
-                this._filterCallbacks[filterToken](null, logEvent);
-            }
-        });
-    }
-    private _startBlockAndLogStream(): void {
-        if (!_.isUndefined(this._blockAndLogStreamerIfExists)) {
-            throw new Error(ZeroExError.SubscriptionAlreadyPresent);
-        }
-        this._blockAndLogStreamerIfExists = new BlockAndLogStreamer(
-            this._web3Wrapper.getBlockAsync.bind(this._web3Wrapper),
-            this._web3Wrapper.getLogsAsync.bind(this._web3Wrapper),
-        );
-        const catchAllLogFilter = {};
-        this._blockAndLogStreamerIfExists.addLogFilter(catchAllLogFilter);
-        this._blockAndLogStreamInterval = intervalUtils.setAsyncExcludingInterval(
-            this._reconcileBlockAsync.bind(this),
-            constants.DEFAULT_BLOCK_POLLING_INTERVAL,
-            this._onReconcileBlockError.bind(this),
-        );
-        let isRemoved = false;
-        this._onLogAddedSubscriptionToken = this._blockAndLogStreamerIfExists.subscribeToOnLogAdded(
-            this._onLogStateChanged.bind(this, isRemoved),
-        );
-        isRemoved = true;
-        this._onLogRemovedSubscriptionToken = this._blockAndLogStreamerIfExists.subscribeToOnLogRemoved(
-            this._onLogStateChanged.bind(this, isRemoved),
-        );
-    }
-    private _onReconcileBlockError(err: Error): void {
-        const filterTokens = _.keys(this._filterCallbacks);
-        _.each(filterTokens, filterToken => {
-            this._unsubscribe(filterToken, err);
-        });
-    }
-    private _setNetworkId(networkId: number): void {
-        this._networkId = networkId;
-    }
-    private _stopBlockAndLogStream(): void {
-        if (_.isUndefined(this._blockAndLogStreamerIfExists)) {
-            throw new Error(ZeroExError.SubscriptionNotFound);
-        }
-        this._blockAndLogStreamerIfExists.unsubscribeFromOnLogAdded(this._onLogAddedSubscriptionToken as string);
-        this._blockAndLogStreamerIfExists.unsubscribeFromOnLogRemoved(this._onLogRemovedSubscriptionToken as string);
-        intervalUtils.clearAsyncExcludingInterval(this._blockAndLogStreamInterval);
-        delete this._blockAndLogStreamerIfExists;
-    }
-    private async _reconcileBlockAsync(): Promise<void> {
-        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._blockAndLogStreamerIfExists)) {
-            // If we clear the interval while fetching the block - this._blockAndLogStreamer will be undefined
-            await this._blockAndLogStreamerIfExists.reconcileNewBlock((latestBlock as any) as Block);
-        }
-    }
+	protected _web3Wrapper: Web3Wrapper;
+	private _networkId: number;
+	private _abiDecoder?: AbiDecoder;
+	private _blockAndLogStreamerIfExists: BlockAndLogStreamer | undefined;
+	private _blockAndLogStreamInterval: NodeJS.Timer;
+	private _filters: { [filterToken: string]: Web3.FilterObject };
+	private _filterCallbacks: {
+		[filterToken: string]: EventCallback<ContractEventArgs>;
+	};
+	private _onLogAddedSubscriptionToken: string | undefined;
+	private _onLogRemovedSubscriptionToken: string | undefined;
+	constructor(web3Wrapper: Web3Wrapper, networkId: number, abiDecoder?: AbiDecoder) {
+		this._web3Wrapper = web3Wrapper;
+		this._networkId = networkId;
+		this._abiDecoder = abiDecoder;
+		this._filters = {};
+		this._filterCallbacks = {};
+		this._blockAndLogStreamerIfExists = undefined;
+		this._onLogAddedSubscriptionToken = undefined;
+		this._onLogRemovedSubscriptionToken = undefined;
+	}
+	protected 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<ArgsType extends ContractEventArgs>(
+		address: string,
+		eventName: ContractEvents,
+		indexFilterValues: IndexedFilterValues,
+		abi: Web3.ContractAbi,
+		callback: EventCallback<ArgsType>,
+	): string {
+		const filter = filterUtils.getFilter(address, eventName, indexFilterValues, abi);
+		if (_.isUndefined(this._blockAndLogStreamerIfExists)) {
+			this._startBlockAndLogStream();
+		}
+		const filterToken = filterUtils.generateUUID();
+		this._filters[filterToken] = filter;
+		this._filterCallbacks[filterToken] = callback as EventCallback<ContractEventArgs>;
+		return filterToken;
+	}
+	protected async _getLogsAsync<ArgsType extends ContractEventArgs>(
+		address: string,
+		eventName: ContractEvents,
+		blockRange: BlockRange,
+		indexFilterValues: IndexedFilterValues,
+		abi: Web3.ContractAbi,
+	): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
+		const filter = filterUtils.getFilter(address, eventName, indexFilterValues, abi, blockRange);
+		const logs = await this._web3Wrapper.getLogsAsync(filter);
+		const logsWithDecodedArguments = _.map(logs, this._tryToDecodeLogOrNoop.bind(this));
+		return logsWithDecodedArguments;
+	}
+	protected _tryToDecodeLogOrNoop<ArgsType extends ContractEventArgs>(
+		log: Web3.LogEntry,
+	): LogWithDecodedArgs<ArgsType> | 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<Web3.ContractInstance> {
+		let contractAddress: string;
+		if (_.isUndefined(addressIfExists)) {
+			if (_.isUndefined(artifact.networks[this._networkId])) {
+				throw new Error(ZeroExError.ContractNotDeployedOnNetwork);
+			}
+			contractAddress = artifact.networks[this._networkId].address.toLowerCase();
+		} else {
+			contractAddress = addressIfExists;
+		}
+		const doesContractExist = await this._web3Wrapper.doesContractExistAtAddressAsync(contractAddress);
+		if (!doesContractExist) {
+			throw new Error(CONTRACT_NAME_TO_NOT_FOUND_ERROR[artifact.contract_name]);
+		}
+		const contractInstance = this._web3Wrapper.getContractInstance(artifact.abi, contractAddress);
+		return contractInstance;
+	}
+	protected _getContractAddress(artifact: Artifact, addressIfExists?: string): string {
+		if (_.isUndefined(addressIfExists)) {
+			const contractAddress = artifact.networks[this._networkId].address;
+			if (_.isUndefined(contractAddress)) {
+				throw new Error(ZeroExError.ExchangeContractDoesNotExist);
+			}
+			return contractAddress;
+		} else {
+			return addressIfExists;
+		}
+	}
+	private _onLogStateChanged<ArgsType extends ContractEventArgs>(isRemoved: 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<ArgsType>;
+				const logEvent = {
+					log: decodedLog,
+					isRemoved,
+				};
+				this._filterCallbacks[filterToken](null, logEvent);
+			}
+		});
+	}
+	private _startBlockAndLogStream(): void {
+		if (!_.isUndefined(this._blockAndLogStreamerIfExists)) {
+			throw new Error(ZeroExError.SubscriptionAlreadyPresent);
+		}
+		this._blockAndLogStreamerIfExists = new BlockAndLogStreamer(
+			this._web3Wrapper.getBlockAsync.bind(this._web3Wrapper),
+			this._web3Wrapper.getLogsAsync.bind(this._web3Wrapper),
+		);
+		const catchAllLogFilter = {};
+		this._blockAndLogStreamerIfExists.addLogFilter(catchAllLogFilter);
+		this._blockAndLogStreamInterval = intervalUtils.setAsyncExcludingInterval(
+			this._reconcileBlockAsync.bind(this),
+			constants.DEFAULT_BLOCK_POLLING_INTERVAL,
+			this._onReconcileBlockError.bind(this),
+		);
+		let isRemoved = false;
+		this._onLogAddedSubscriptionToken = this._blockAndLogStreamerIfExists.subscribeToOnLogAdded(
+			this._onLogStateChanged.bind(this, isRemoved),
+		);
+		isRemoved = true;
+		this._onLogRemovedSubscriptionToken = this._blockAndLogStreamerIfExists.subscribeToOnLogRemoved(
+			this._onLogStateChanged.bind(this, isRemoved),
+		);
+	}
+	private _onReconcileBlockError(err: Error): void {
+		const filterTokens = _.keys(this._filterCallbacks);
+		_.each(filterTokens, filterToken => {
+			this._unsubscribe(filterToken, err);
+		});
+	}
+	private _setNetworkId(networkId: number): void {
+		this._networkId = networkId;
+	}
+	private _stopBlockAndLogStream(): void {
+		if (_.isUndefined(this._blockAndLogStreamerIfExists)) {
+			throw new Error(ZeroExError.SubscriptionNotFound);
+		}
+		this._blockAndLogStreamerIfExists.unsubscribeFromOnLogAdded(this._onLogAddedSubscriptionToken as string);
+		this._blockAndLogStreamerIfExists.unsubscribeFromOnLogRemoved(this._onLogRemovedSubscriptionToken as string);
+		intervalUtils.clearAsyncExcludingInterval(this._blockAndLogStreamInterval);
+		delete this._blockAndLogStreamerIfExists;
+	}
+	private async _reconcileBlockAsync(): Promise<void> {
+		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._blockAndLogStreamerIfExists)) {
+			// If we clear the interval while fetching the block - this._blockAndLogStreamer will be undefined
+			await this._blockAndLogStreamerIfExists.reconcileNewBlock((latestBlock as any) as Block);
+		}
+	}
 }
diff --git a/packages/0x.js/src/contract_wrappers/ether_token_wrapper.ts b/packages/0x.js/src/contract_wrappers/ether_token_wrapper.ts
index b03571636..d412971be 100644
--- a/packages/0x.js/src/contract_wrappers/ether_token_wrapper.ts
+++ b/packages/0x.js/src/contract_wrappers/ether_token_wrapper.ts
@@ -5,14 +5,14 @@ import * as _ from 'lodash';
 
 import { artifacts } from '../artifacts';
 import {
-    BlockRange,
-    EtherTokenContractEventArgs,
-    EtherTokenEvents,
-    EventCallback,
-    IndexedFilterValues,
-    LogWithDecodedArgs,
-    TransactionOpts,
-    ZeroExError,
+	BlockRange,
+	EtherTokenContractEventArgs,
+	EtherTokenEvents,
+	EventCallback,
+	IndexedFilterValues,
+	LogWithDecodedArgs,
+	TransactionOpts,
+	ZeroExError,
 } from '../types';
 import { AbiDecoder } from '../utils/abi_decoder';
 import { assert } from '../utils/assert';
@@ -26,159 +26,159 @@ import { TokenWrapper } from './token_wrapper';
  * The caller can convert ETH into the equivalent number of wrapped ETH ERC20 tokens and back.
  */
 export class EtherTokenWrapper extends ContractWrapper {
-    private _etherTokenContractsByAddress: {
-        [address: string]: EtherTokenContract;
-    } = {};
-    private _tokenWrapper: TokenWrapper;
-    constructor(web3Wrapper: Web3Wrapper, networkId: number, abiDecoder: AbiDecoder, tokenWrapper: TokenWrapper) {
-        super(web3Wrapper, networkId, abiDecoder);
-        this._tokenWrapper = tokenWrapper;
-    }
-    /**
-     * 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   etherTokenAddress   EtherToken address you wish to deposit into.
-     * @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.
-     * @param   txOpts              Transaction parameters.
-     * @return Transaction hash.
-     */
-    public async depositAsync(
-        etherTokenAddress: string,
-        amountInWei: BigNumber,
-        depositor: string,
-        txOpts: TransactionOpts = {},
-    ): Promise<string> {
-        assert.isValidBaseUnitAmount('amountInWei', amountInWei);
-        await assert.isSenderAddressAsync('depositor', depositor, this._web3Wrapper);
+	private _etherTokenContractsByAddress: {
+		[address: string]: EtherTokenContract;
+	} = {};
+	private _tokenWrapper: TokenWrapper;
+	constructor(web3Wrapper: Web3Wrapper, networkId: number, abiDecoder: AbiDecoder, tokenWrapper: TokenWrapper) {
+		super(web3Wrapper, networkId, abiDecoder);
+		this._tokenWrapper = tokenWrapper;
+	}
+	/**
+	 * 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   etherTokenAddress   EtherToken address you wish to deposit into.
+	 * @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.
+	 * @param   txOpts              Transaction parameters.
+	 * @return Transaction hash.
+	 */
+	public async depositAsync(
+		etherTokenAddress: string,
+		amountInWei: BigNumber,
+		depositor: string,
+		txOpts: TransactionOpts = {},
+	): Promise<string> {
+		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 ethBalanceInWei = await this._web3Wrapper.getBalanceInWeiAsync(depositor);
+		assert.assert(ethBalanceInWei.gte(amountInWei), ZeroExError.InsufficientEthBalanceForDeposit);
 
-        const wethContract = await this._getEtherTokenContractAsync(etherTokenAddress);
-        const txHash = await wethContract.deposit.sendTransactionAsync({
-            from: depositor,
-            value: amountInWei,
-            gas: txOpts.gasLimit,
-            gasPrice: txOpts.gasPrice,
-        });
-        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   etherTokenAddress   EtherToken address you wish to withdraw from.
-     * @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.
-     * @param   txOpts       Transaction parameters.
-     * @return Transaction hash.
-     */
-    public async withdrawAsync(
-        etherTokenAddress: string,
-        amountInWei: BigNumber,
-        withdrawer: string,
-        txOpts: TransactionOpts = {},
-    ): Promise<string> {
-        assert.isValidBaseUnitAmount('amountInWei', amountInWei);
-        await assert.isSenderAddressAsync('withdrawer', withdrawer, this._web3Wrapper);
+		const wethContract = await this._getEtherTokenContractAsync(etherTokenAddress);
+		const txHash = await wethContract.deposit.sendTransactionAsync({
+			from: depositor,
+			value: amountInWei,
+			gas: txOpts.gasLimit,
+			gasPrice: txOpts.gasPrice,
+		});
+		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   etherTokenAddress   EtherToken address you wish to withdraw from.
+	 * @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.
+	 * @param   txOpts       Transaction parameters.
+	 * @return Transaction hash.
+	 */
+	public async withdrawAsync(
+		etherTokenAddress: string,
+		amountInWei: BigNumber,
+		withdrawer: string,
+		txOpts: TransactionOpts = {},
+	): Promise<string> {
+		assert.isValidBaseUnitAmount('amountInWei', amountInWei);
+		await assert.isSenderAddressAsync('withdrawer', withdrawer, this._web3Wrapper);
 
-        const WETHBalanceInBaseUnits = await this._tokenWrapper.getBalanceAsync(etherTokenAddress, withdrawer);
-        assert.assert(WETHBalanceInBaseUnits.gte(amountInWei), ZeroExError.InsufficientWEthBalanceForWithdrawal);
+		const WETHBalanceInBaseUnits = await this._tokenWrapper.getBalanceAsync(etherTokenAddress, withdrawer);
+		assert.assert(WETHBalanceInBaseUnits.gte(amountInWei), ZeroExError.InsufficientWEthBalanceForWithdrawal);
 
-        const wethContract = await this._getEtherTokenContractAsync(etherTokenAddress);
-        const txHash = await wethContract.withdraw.sendTransactionAsync(amountInWei, {
-            from: withdrawer,
-            gas: txOpts.gasLimit,
-            gasPrice: txOpts.gasPrice,
-        });
-        return txHash;
-    }
-    /**
-     * Gets historical logs without creating a subscription
-     * @param   etherTokenAddress   An address of the ether token that emmited the logs.
-     * @param   eventName           The ether token contract event you would like to subscribe to.
-     * @param   blockRange          Block range to get logs from.
-     * @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 `{_owner: aUserAddressHex}`
-     * @return  Array of logs that match the parameters
-     */
-    public async getLogsAsync<ArgsType extends EtherTokenContractEventArgs>(
-        etherTokenAddress: string,
-        eventName: EtherTokenEvents,
-        blockRange: BlockRange,
-        indexFilterValues: IndexedFilterValues,
-    ): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
-        assert.isETHAddressHex('etherTokenAddress', etherTokenAddress);
-        assert.doesBelongToStringEnum('eventName', eventName, EtherTokenEvents);
-        assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema);
-        assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
-        const logs = await this._getLogsAsync<ArgsType>(
-            etherTokenAddress,
-            eventName,
-            blockRange,
-            indexFilterValues,
-            artifacts.EtherTokenArtifact.abi,
-        );
-        return logs;
-    }
-    /**
-     * Subscribe to an event type emitted by the Token contract.
-     * @param   etherTokenAddress   The hex encoded address where the ether token is deployed.
-     * @param   eventName           The ether 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 `{_owner: aUserAddressHex}`
-     * @param   callback            Callback that gets called when a log is added/removed
-     * @return Subscription token used later to unsubscribe
-     */
-    public subscribe<ArgsType extends EtherTokenContractEventArgs>(
-        etherTokenAddress: string,
-        eventName: EtherTokenEvents,
-        indexFilterValues: IndexedFilterValues,
-        callback: EventCallback<ArgsType>,
-    ): string {
-        assert.isETHAddressHex('etherTokenAddress', etherTokenAddress);
-        assert.doesBelongToStringEnum('eventName', eventName, EtherTokenEvents);
-        assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
-        assert.isFunction('callback', callback);
-        const subscriptionToken = this._subscribe<ArgsType>(
-            etherTokenAddress,
-            eventName,
-            indexFilterValues,
-            artifacts.EtherTokenArtifact.abi,
-            callback,
-        );
-        return subscriptionToken;
-    }
-    /**
-     * Cancel a subscription
-     * @param   subscriptionToken Subscription token returned by `subscribe()`
-     */
-    public unsubscribe(subscriptionToken: string): void {
-        this._unsubscribe(subscriptionToken);
-    }
-    /**
-     * Cancels all existing subscriptions
-     */
-    public unsubscribeAll(): void {
-        super.unsubscribeAll();
-    }
-    private _invalidateContractInstance(): void {
-        this.unsubscribeAll();
-        this._etherTokenContractsByAddress = {};
-    }
-    private async _getEtherTokenContractAsync(etherTokenAddress: string): Promise<EtherTokenContract> {
-        let etherTokenContract = this._etherTokenContractsByAddress[etherTokenAddress];
-        if (!_.isUndefined(etherTokenContract)) {
-            return etherTokenContract;
-        }
-        const web3ContractInstance = await this._instantiateContractIfExistsAsync(
-            artifacts.EtherTokenArtifact,
-            etherTokenAddress,
-        );
-        const contractInstance = new EtherTokenContract(web3ContractInstance, this._web3Wrapper.getContractDefaults());
-        etherTokenContract = contractInstance;
-        this._etherTokenContractsByAddress[etherTokenAddress] = etherTokenContract;
-        return etherTokenContract;
-    }
+		const wethContract = await this._getEtherTokenContractAsync(etherTokenAddress);
+		const txHash = await wethContract.withdraw.sendTransactionAsync(amountInWei, {
+			from: withdrawer,
+			gas: txOpts.gasLimit,
+			gasPrice: txOpts.gasPrice,
+		});
+		return txHash;
+	}
+	/**
+	 * Gets historical logs without creating a subscription
+	 * @param   etherTokenAddress   An address of the ether token that emmited the logs.
+	 * @param   eventName           The ether token contract event you would like to subscribe to.
+	 * @param   blockRange          Block range to get logs from.
+	 * @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 `{_owner: aUserAddressHex}`
+	 * @return  Array of logs that match the parameters
+	 */
+	public async getLogsAsync<ArgsType extends EtherTokenContractEventArgs>(
+		etherTokenAddress: string,
+		eventName: EtherTokenEvents,
+		blockRange: BlockRange,
+		indexFilterValues: IndexedFilterValues,
+	): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
+		assert.isETHAddressHex('etherTokenAddress', etherTokenAddress);
+		assert.doesBelongToStringEnum('eventName', eventName, EtherTokenEvents);
+		assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema);
+		assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
+		const logs = await this._getLogsAsync<ArgsType>(
+			etherTokenAddress,
+			eventName,
+			blockRange,
+			indexFilterValues,
+			artifacts.EtherTokenArtifact.abi,
+		);
+		return logs;
+	}
+	/**
+	 * Subscribe to an event type emitted by the Token contract.
+	 * @param   etherTokenAddress   The hex encoded address where the ether token is deployed.
+	 * @param   eventName           The ether 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 `{_owner: aUserAddressHex}`
+	 * @param   callback            Callback that gets called when a log is added/removed
+	 * @return Subscription token used later to unsubscribe
+	 */
+	public subscribe<ArgsType extends EtherTokenContractEventArgs>(
+		etherTokenAddress: string,
+		eventName: EtherTokenEvents,
+		indexFilterValues: IndexedFilterValues,
+		callback: EventCallback<ArgsType>,
+	): string {
+		assert.isETHAddressHex('etherTokenAddress', etherTokenAddress);
+		assert.doesBelongToStringEnum('eventName', eventName, EtherTokenEvents);
+		assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
+		assert.isFunction('callback', callback);
+		const subscriptionToken = this._subscribe<ArgsType>(
+			etherTokenAddress,
+			eventName,
+			indexFilterValues,
+			artifacts.EtherTokenArtifact.abi,
+			callback,
+		);
+		return subscriptionToken;
+	}
+	/**
+	 * Cancel a subscription
+	 * @param   subscriptionToken Subscription token returned by `subscribe()`
+	 */
+	public unsubscribe(subscriptionToken: string): void {
+		this._unsubscribe(subscriptionToken);
+	}
+	/**
+	 * Cancels all existing subscriptions
+	 */
+	public unsubscribeAll(): void {
+		super.unsubscribeAll();
+	}
+	private _invalidateContractInstance(): void {
+		this.unsubscribeAll();
+		this._etherTokenContractsByAddress = {};
+	}
+	private async _getEtherTokenContractAsync(etherTokenAddress: string): Promise<EtherTokenContract> {
+		let etherTokenContract = this._etherTokenContractsByAddress[etherTokenAddress];
+		if (!_.isUndefined(etherTokenContract)) {
+			return etherTokenContract;
+		}
+		const web3ContractInstance = await this._instantiateContractIfExistsAsync(
+			artifacts.EtherTokenArtifact,
+			etherTokenAddress,
+		);
+		const contractInstance = new EtherTokenContract(web3ContractInstance, this._web3Wrapper.getContractDefaults());
+		etherTokenContract = contractInstance;
+		this._etherTokenContractsByAddress[etherTokenAddress] = etherTokenContract;
+		return etherTokenContract;
+	}
 }
diff --git a/packages/0x.js/src/contract_wrappers/exchange_wrapper.ts b/packages/0x.js/src/contract_wrappers/exchange_wrapper.ts
index 2b6117729..668893d45 100644
--- a/packages/0x.js/src/contract_wrappers/exchange_wrapper.ts
+++ b/packages/0x.js/src/contract_wrappers/exchange_wrapper.ts
@@ -6,27 +6,27 @@ import * as Web3 from 'web3';
 
 import { artifacts } from '../artifacts';
 import {
-    BlockParamLiteral,
-    BlockRange,
-    DecodedLogArgs,
-    ECSignature,
-    EventCallback,
-    ExchangeContractErrCodes,
-    ExchangeContractErrs,
-    ExchangeContractEventArgs,
-    ExchangeEvents,
-    IndexedFilterValues,
-    LogErrorContractEventArgs,
-    LogWithDecodedArgs,
-    MethodOpts,
-    Order,
-    OrderAddresses,
-    OrderCancellationRequest,
-    OrderFillRequest,
-    OrderTransactionOpts,
-    OrderValues,
-    SignedOrder,
-    ValidateOrderFillableOpts,
+	BlockParamLiteral,
+	BlockRange,
+	DecodedLogArgs,
+	ECSignature,
+	EventCallback,
+	ExchangeContractErrCodes,
+	ExchangeContractErrs,
+	ExchangeContractEventArgs,
+	ExchangeEvents,
+	IndexedFilterValues,
+	LogErrorContractEventArgs,
+	LogWithDecodedArgs,
+	MethodOpts,
+	Order,
+	OrderAddresses,
+	OrderCancellationRequest,
+	OrderFillRequest,
+	OrderTransactionOpts,
+	OrderValues,
+	SignedOrder,
+	ValidateOrderFillableOpts,
 } from '../types';
 import { AbiDecoder } from '../utils/abi_decoder';
 import { assert } from '../utils/assert';
@@ -42,7 +42,7 @@ import { TokenWrapper } from './token_wrapper';
 const SHOULD_VALIDATE_BY_DEFAULT = true;
 
 interface ExchangeContractErrCodesToMsgs {
-    [exchangeContractErrCodes: number]: string;
+	[exchangeContractErrCodes: number]: string;
 }
 
 /**
@@ -50,864 +50,864 @@ interface ExchangeContractErrCodesToMsgs {
  * events of the 0x Exchange smart contract.
  */
 export class ExchangeWrapper extends ContractWrapper {
-    private _exchangeContractIfExists?: ExchangeContract;
-    private _orderValidationUtils: OrderValidationUtils;
-    private _tokenWrapper: TokenWrapper;
-    private _exchangeContractErrCodesToMsg: ExchangeContractErrCodesToMsgs = {
-        [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 _zrxContractAddressIfExists?: 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,
-        networkId: number,
-        abiDecoder: AbiDecoder,
-        tokenWrapper: TokenWrapper,
-        contractAddressIfExists?: string,
-        zrxContractAddressIfExists?: string,
-    ) {
-        super(web3Wrapper, networkId, abiDecoder);
-        this._tokenWrapper = tokenWrapper;
-        this._orderValidationUtils = new OrderValidationUtils(this);
-        this._contractAddressIfExists = contractAddressIfExists;
-        this._zrxContractAddressIfExists = zrxContractAddressIfExists;
-    }
-    /**
-     * 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 cancelled.
-     */
-    public async getUnavailableTakerAmountAsync(orderHash: string, methodOpts?: MethodOpts): Promise<BigNumber> {
-        assert.doesConformToSchema('orderHash', orderHash, schemas.orderHashSchema);
+	private _exchangeContractIfExists?: ExchangeContract;
+	private _orderValidationUtils: OrderValidationUtils;
+	private _tokenWrapper: TokenWrapper;
+	private _exchangeContractErrCodesToMsg: ExchangeContractErrCodesToMsgs = {
+		[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 _zrxContractAddressIfExists?: 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,
+		networkId: number,
+		abiDecoder: AbiDecoder,
+		tokenWrapper: TokenWrapper,
+		contractAddressIfExists?: string,
+		zrxContractAddressIfExists?: string,
+	) {
+		super(web3Wrapper, networkId, abiDecoder);
+		this._tokenWrapper = tokenWrapper;
+		this._orderValidationUtils = new OrderValidationUtils(this);
+		this._contractAddressIfExists = contractAddressIfExists;
+		this._zrxContractAddressIfExists = zrxContractAddressIfExists;
+	}
+	/**
+	 * 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 cancelled.
+	 */
+	public async getUnavailableTakerAmountAsync(orderHash: string, methodOpts?: MethodOpts): Promise<BigNumber> {
+		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<BigNumber> {
-        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<BigNumber> {
+		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 getCancelledTakerAmountAsync(orderHash: string, methodOpts?: MethodOpts): Promise<BigNumber> {
-        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 getCancelledTakerAmountAsync(orderHash: string, methodOpts?: MethodOpts): Promise<BigNumber> {
+		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.asyncZeroExErrorHandler
-    public async fillOrderAsync(
-        signedOrder: SignedOrder,
-        fillTakerTokenAmount: BigNumber,
-        shouldThrowOnInsufficientBalanceOrAllowance: boolean,
-        takerAddress: string,
-        orderTransactionOpts: OrderTransactionOpts = {},
-    ): Promise<string> {
-        assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
-        assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
-        assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance);
-        await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
+		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.asyncZeroExErrorHandler
+	public async fillOrderAsync(
+		signedOrder: SignedOrder,
+		fillTakerTokenAmount: BigNumber,
+		shouldThrowOnInsufficientBalanceOrAllowance: boolean,
+		takerAddress: string,
+		orderTransactionOpts: OrderTransactionOpts = {},
+	): Promise<string> {
+		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.shouldValidate)
-            ? SHOULD_VALIDATE_BY_DEFAULT
-            : orderTransactionOpts.shouldValidate;
-        if (shouldValidate) {
-            const zrxTokenAddress = this.getZRXTokenAddress();
-            const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
-            await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync(
-                exchangeTradeEmulator,
-                signedOrder,
-                fillTakerTokenAmount,
-                takerAddress,
-                zrxTokenAddress,
-            );
-        }
+		const exchangeInstance = await this._getExchangeContractAsync();
+		const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
+			? SHOULD_VALIDATE_BY_DEFAULT
+			: orderTransactionOpts.shouldValidate;
+		if (shouldValidate) {
+			const zrxTokenAddress = this.getZRXTokenAddress();
+			const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
+			await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync(
+				exchangeTradeEmulator,
+				signedOrder,
+				fillTakerTokenAmount,
+				takerAddress,
+				zrxTokenAddress,
+			);
+		}
 
-        const [orderAddresses, orderValues] = ExchangeWrapper._getOrderAddressesAndValues(signedOrder);
+		const [orderAddresses, orderValues] = ExchangeWrapper._getOrderAddressesAndValues(signedOrder);
 
-        const txHash: string = await exchangeInstance.fillOrder.sendTransactionAsync(
-            orderAddresses,
-            orderValues,
-            fillTakerTokenAmount,
-            shouldThrowOnInsufficientBalanceOrAllowance,
-            signedOrder.ecSignature.v,
-            signedOrder.ecSignature.r,
-            signedOrder.ecSignature.s,
-            {
-                from: takerAddress,
-                gas: orderTransactionOpts.gasLimit,
-                gasPrice: orderTransactionOpts.gasPrice,
-            },
-        );
-        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.asyncZeroExErrorHandler
-    public async fillOrdersUpToAsync(
-        signedOrders: SignedOrder[],
-        fillTakerTokenAmount: BigNumber,
-        shouldThrowOnInsufficientBalanceOrAllowance: boolean,
-        takerAddress: string,
-        orderTransactionOpts: OrderTransactionOpts = {},
-    ): Promise<string> {
-        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 txHash: string = await exchangeInstance.fillOrder.sendTransactionAsync(
+			orderAddresses,
+			orderValues,
+			fillTakerTokenAmount,
+			shouldThrowOnInsufficientBalanceOrAllowance,
+			signedOrder.ecSignature.v,
+			signedOrder.ecSignature.r,
+			signedOrder.ecSignature.s,
+			{
+				from: takerAddress,
+				gas: orderTransactionOpts.gasLimit,
+				gasPrice: orderTransactionOpts.gasPrice,
+			},
+		);
+		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.asyncZeroExErrorHandler
+	public async fillOrdersUpToAsync(
+		signedOrders: SignedOrder[],
+		fillTakerTokenAmount: BigNumber,
+		shouldThrowOnInsufficientBalanceOrAllowance: boolean,
+		takerAddress: string,
+		orderTransactionOpts: OrderTransactionOpts = {},
+	): Promise<string> {
+		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.shouldValidate)
-            ? SHOULD_VALIDATE_BY_DEFAULT
-            : orderTransactionOpts.shouldValidate;
-        if (shouldValidate) {
-            let filledTakerTokenAmount = new BigNumber(0);
-            const zrxTokenAddress = this.getZRXTokenAddress();
-            const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
-            for (const signedOrder of signedOrders) {
-                const singleFilledTakerTokenAmount = await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync(
-                    exchangeTradeEmulator,
-                    signedOrder,
-                    fillTakerTokenAmount.minus(filledTakerTokenAmount),
-                    takerAddress,
-                    zrxTokenAddress,
-                );
-                filledTakerTokenAmount = filledTakerTokenAmount.plus(singleFilledTakerTokenAmount);
-            }
-        }
+		const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
+			? SHOULD_VALIDATE_BY_DEFAULT
+			: orderTransactionOpts.shouldValidate;
+		if (shouldValidate) {
+			let filledTakerTokenAmount = new BigNumber(0);
+			const zrxTokenAddress = this.getZRXTokenAddress();
+			const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
+			for (const signedOrder of signedOrders) {
+				const singleFilledTakerTokenAmount = await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync(
+					exchangeTradeEmulator,
+					signedOrder,
+					fillTakerTokenAmount.minus(filledTakerTokenAmount),
+					takerAddress,
+					zrxTokenAddress,
+				);
+				filledTakerTokenAmount = filledTakerTokenAmount.plus(singleFilledTakerTokenAmount);
+			}
+		}
 
-        if (_.isEmpty(signedOrders)) {
-            throw new Error(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem);
-        }
+		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<any> because _.unzip doesn't type check if values have different types :'(
-        const [orderAddressesArray, orderValuesArray, vArray, rArray, sArray] = _.unzip<any>(
-            orderAddressesValuesAndSignatureArray,
-        );
+		const orderAddressesValuesAndSignatureArray = _.map(signedOrders, signedOrder => {
+			return [
+				...ExchangeWrapper._getOrderAddressesAndValues(signedOrder),
+				signedOrder.ecSignature.v,
+				signedOrder.ecSignature.r,
+				signedOrder.ecSignature.s,
+			];
+		});
+		// We use _.unzip<any> because _.unzip doesn't type check if values have different types :'(
+		const [orderAddressesArray, orderValuesArray, vArray, rArray, sArray] = _.unzip<any>(
+			orderAddressesValuesAndSignatureArray,
+		);
 
-        const exchangeInstance = await this._getExchangeContractAsync();
-        const txHash = await exchangeInstance.fillOrdersUpTo.sendTransactionAsync(
-            orderAddressesArray,
-            orderValuesArray,
-            fillTakerTokenAmount,
-            shouldThrowOnInsufficientBalanceOrAllowance,
-            vArray,
-            rArray,
-            sArray,
-            {
-                from: takerAddress,
-                gas: orderTransactionOpts.gasLimit,
-                gasPrice: orderTransactionOpts.gasPrice,
-            },
-        );
-        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.asyncZeroExErrorHandler
-    public async batchFillOrdersAsync(
-        orderFillRequests: OrderFillRequest[],
-        shouldThrowOnInsufficientBalanceOrAllowance: boolean,
-        takerAddress: string,
-        orderTransactionOpts: OrderTransactionOpts = {},
-    ): Promise<string> {
-        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.shouldValidate)
-            ? SHOULD_VALIDATE_BY_DEFAULT
-            : orderTransactionOpts.shouldValidate;
-        if (shouldValidate) {
-            const zrxTokenAddress = this.getZRXTokenAddress();
-            const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
-            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 exchangeInstance = await this._getExchangeContractAsync();
+		const txHash = await exchangeInstance.fillOrdersUpTo.sendTransactionAsync(
+			orderAddressesArray,
+			orderValuesArray,
+			fillTakerTokenAmount,
+			shouldThrowOnInsufficientBalanceOrAllowance,
+			vArray,
+			rArray,
+			sArray,
+			{
+				from: takerAddress,
+				gas: orderTransactionOpts.gasLimit,
+				gasPrice: orderTransactionOpts.gasPrice,
+			},
+		);
+		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.asyncZeroExErrorHandler
+	public async batchFillOrdersAsync(
+		orderFillRequests: OrderFillRequest[],
+		shouldThrowOnInsufficientBalanceOrAllowance: boolean,
+		takerAddress: string,
+		orderTransactionOpts: OrderTransactionOpts = {},
+	): Promise<string> {
+		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.shouldValidate)
+			? SHOULD_VALIDATE_BY_DEFAULT
+			: orderTransactionOpts.shouldValidate;
+		if (shouldValidate) {
+			const zrxTokenAddress = this.getZRXTokenAddress();
+			const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
+			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<any> because _.unzip doesn't type check if values have different types :'(
-        const [orderAddressesArray, orderValuesArray, fillTakerTokenAmounts, vArray, rArray, sArray] = _.unzip<any>(
-            orderAddressesValuesAmountsAndSignatureArray,
-        );
+		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<any> because _.unzip doesn't type check if values have different types :'(
+		const [orderAddressesArray, orderValuesArray, fillTakerTokenAmounts, vArray, rArray, sArray] = _.unzip<any>(
+			orderAddressesValuesAmountsAndSignatureArray,
+		);
 
-        const exchangeInstance = await this._getExchangeContractAsync();
-        const txHash = await exchangeInstance.batchFillOrders.sendTransactionAsync(
-            orderAddressesArray,
-            orderValuesArray,
-            fillTakerTokenAmounts,
-            shouldThrowOnInsufficientBalanceOrAllowance,
-            vArray,
-            rArray,
-            sArray,
-            {
-                from: takerAddress,
-                gas: orderTransactionOpts.gasLimit,
-                gasPrice: orderTransactionOpts.gasPrice,
-            },
-        );
-        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.asyncZeroExErrorHandler
-    public async fillOrKillOrderAsync(
-        signedOrder: SignedOrder,
-        fillTakerTokenAmount: BigNumber,
-        takerAddress: string,
-        orderTransactionOpts: OrderTransactionOpts = {},
-    ): Promise<string> {
-        assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
-        assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
-        await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
+		const exchangeInstance = await this._getExchangeContractAsync();
+		const txHash = await exchangeInstance.batchFillOrders.sendTransactionAsync(
+			orderAddressesArray,
+			orderValuesArray,
+			fillTakerTokenAmounts,
+			shouldThrowOnInsufficientBalanceOrAllowance,
+			vArray,
+			rArray,
+			sArray,
+			{
+				from: takerAddress,
+				gas: orderTransactionOpts.gasLimit,
+				gasPrice: orderTransactionOpts.gasPrice,
+			},
+		);
+		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.asyncZeroExErrorHandler
+	public async fillOrKillOrderAsync(
+		signedOrder: SignedOrder,
+		fillTakerTokenAmount: BigNumber,
+		takerAddress: string,
+		orderTransactionOpts: OrderTransactionOpts = {},
+	): Promise<string> {
+		assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
+		assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
+		await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
 
-        const exchangeInstance = await this._getExchangeContractAsync();
+		const exchangeInstance = await this._getExchangeContractAsync();
 
-        const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
-            ? SHOULD_VALIDATE_BY_DEFAULT
-            : orderTransactionOpts.shouldValidate;
-        if (shouldValidate) {
-            const zrxTokenAddress = this.getZRXTokenAddress();
-            const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
-            await this._orderValidationUtils.validateFillOrKillOrderThrowIfInvalidAsync(
-                exchangeTradeEmulator,
-                signedOrder,
-                fillTakerTokenAmount,
-                takerAddress,
-                zrxTokenAddress,
-            );
-        }
+		const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
+			? SHOULD_VALIDATE_BY_DEFAULT
+			: orderTransactionOpts.shouldValidate;
+		if (shouldValidate) {
+			const zrxTokenAddress = this.getZRXTokenAddress();
+			const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
+			await this._orderValidationUtils.validateFillOrKillOrderThrowIfInvalidAsync(
+				exchangeTradeEmulator,
+				signedOrder,
+				fillTakerTokenAmount,
+				takerAddress,
+				zrxTokenAddress,
+			);
+		}
 
-        const [orderAddresses, orderValues] = ExchangeWrapper._getOrderAddressesAndValues(signedOrder);
-        const txHash = await exchangeInstance.fillOrKillOrder.sendTransactionAsync(
-            orderAddresses,
-            orderValues,
-            fillTakerTokenAmount,
-            signedOrder.ecSignature.v,
-            signedOrder.ecSignature.r,
-            signedOrder.ecSignature.s,
-            {
-                from: takerAddress,
-                gas: orderTransactionOpts.gasLimit,
-                gasPrice: orderTransactionOpts.gasPrice,
-            },
-        );
-        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.asyncZeroExErrorHandler
-    public async batchFillOrKillAsync(
-        orderFillRequests: OrderFillRequest[],
-        takerAddress: string,
-        orderTransactionOpts: OrderTransactionOpts = {},
-    ): Promise<string> {
-        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 [orderAddresses, orderValues] = ExchangeWrapper._getOrderAddressesAndValues(signedOrder);
+		const txHash = await exchangeInstance.fillOrKillOrder.sendTransactionAsync(
+			orderAddresses,
+			orderValues,
+			fillTakerTokenAmount,
+			signedOrder.ecSignature.v,
+			signedOrder.ecSignature.r,
+			signedOrder.ecSignature.s,
+			{
+				from: takerAddress,
+				gas: orderTransactionOpts.gasLimit,
+				gasPrice: orderTransactionOpts.gasPrice,
+			},
+		);
+		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.asyncZeroExErrorHandler
+	public async batchFillOrKillAsync(
+		orderFillRequests: OrderFillRequest[],
+		takerAddress: string,
+		orderTransactionOpts: OrderTransactionOpts = {},
+	): Promise<string> {
+		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.shouldValidate)
-            ? SHOULD_VALIDATE_BY_DEFAULT
-            : orderTransactionOpts.shouldValidate;
-        if (shouldValidate) {
-            const zrxTokenAddress = this.getZRXTokenAddress();
-            const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
-            for (const orderFillRequest of orderFillRequests) {
-                await this._orderValidationUtils.validateFillOrKillOrderThrowIfInvalidAsync(
-                    exchangeTradeEmulator,
-                    orderFillRequest.signedOrder,
-                    orderFillRequest.takerTokenFillAmount,
-                    takerAddress,
-                    zrxTokenAddress,
-                );
-            }
-        }
+		const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
+			? SHOULD_VALIDATE_BY_DEFAULT
+			: orderTransactionOpts.shouldValidate;
+		if (shouldValidate) {
+			const zrxTokenAddress = this.getZRXTokenAddress();
+			const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
+			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,
-            ];
-        });
+		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<any> because _.unzip doesn't type check if values have different types :'(
-        const [orderAddresses, orderValues, fillTakerTokenAmounts, vParams, rParams, sParams] = _.unzip<any>(
-            orderAddressesValuesAndTakerTokenFillAmounts,
-        );
-        const txHash = await exchangeInstance.batchFillOrKillOrders.sendTransactionAsync(
-            orderAddresses,
-            orderValues,
-            fillTakerTokenAmounts,
-            vParams,
-            rParams,
-            sParams,
-            {
-                from: takerAddress,
-                gas: orderTransactionOpts.gasLimit,
-                gasPrice: orderTransactionOpts.gasPrice,
-            },
-        );
-        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.asyncZeroExErrorHandler
-    public async cancelOrderAsync(
-        order: Order | SignedOrder,
-        cancelTakerTokenAmount: BigNumber,
-        orderTransactionOpts: OrderTransactionOpts = {},
-    ): Promise<string> {
-        assert.doesConformToSchema('order', order, schemas.orderSchema);
-        assert.isValidBaseUnitAmount('takerTokenCancelAmount', cancelTakerTokenAmount);
-        await assert.isSenderAddressAsync('order.maker', order.maker, this._web3Wrapper);
+		// We use _.unzip<any> because _.unzip doesn't type check if values have different types :'(
+		const [orderAddresses, orderValues, fillTakerTokenAmounts, vParams, rParams, sParams] = _.unzip<any>(
+			orderAddressesValuesAndTakerTokenFillAmounts,
+		);
+		const txHash = await exchangeInstance.batchFillOrKillOrders.sendTransactionAsync(
+			orderAddresses,
+			orderValues,
+			fillTakerTokenAmounts,
+			vParams,
+			rParams,
+			sParams,
+			{
+				from: takerAddress,
+				gas: orderTransactionOpts.gasLimit,
+				gasPrice: orderTransactionOpts.gasPrice,
+			},
+		);
+		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.asyncZeroExErrorHandler
+	public async cancelOrderAsync(
+		order: Order | SignedOrder,
+		cancelTakerTokenAmount: BigNumber,
+		orderTransactionOpts: OrderTransactionOpts = {},
+	): Promise<string> {
+		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 exchangeInstance = await this._getExchangeContractAsync();
 
-        const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
-            ? SHOULD_VALIDATE_BY_DEFAULT
-            : orderTransactionOpts.shouldValidate;
-        if (shouldValidate) {
-            const orderHash = utils.getOrderHashHex(order);
-            const unavailableTakerTokenAmount = await this.getUnavailableTakerAmountAsync(orderHash);
-            OrderValidationUtils.validateCancelOrderThrowIfInvalid(
-                order,
-                cancelTakerTokenAmount,
-                unavailableTakerTokenAmount,
-            );
-        }
+		const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
+			? SHOULD_VALIDATE_BY_DEFAULT
+			: orderTransactionOpts.shouldValidate;
+		if (shouldValidate) {
+			const orderHash = utils.getOrderHashHex(order);
+			const unavailableTakerTokenAmount = await this.getUnavailableTakerAmountAsync(orderHash);
+			OrderValidationUtils.validateCancelOrderThrowIfInvalid(
+				order,
+				cancelTakerTokenAmount,
+				unavailableTakerTokenAmount,
+			);
+		}
 
-        const [orderAddresses, orderValues] = ExchangeWrapper._getOrderAddressesAndValues(order);
-        const txHash = await exchangeInstance.cancelOrder.sendTransactionAsync(
-            orderAddresses,
-            orderValues,
-            cancelTakerTokenAmount,
-            {
-                from: order.maker,
-                gas: orderTransactionOpts.gasLimit,
-                gasPrice: orderTransactionOpts.gasPrice,
-            },
-        );
-        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.asyncZeroExErrorHandler
-    public async batchCancelOrdersAsync(
-        orderCancellationRequests: OrderCancellationRequest[],
-        orderTransactionOpts: OrderTransactionOpts = {},
-    ): Promise<string> {
-        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.shouldValidate)
-            ? 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);
-                OrderValidationUtils.validateCancelOrderThrowIfInvalid(
-                    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<any> because _.unzip doesn't type check if values have different types :'(
-        const [orderAddresses, orderValues, cancelTakerTokenAmounts] = _.unzip<any>(
-            orderAddressesValuesAndTakerTokenCancelAmounts,
-        );
-        const txHash = await exchangeInstance.batchCancelOrders.sendTransactionAsync(
-            orderAddresses,
-            orderValues,
-            cancelTakerTokenAmounts,
-            {
-                from: maker,
-                gas: orderTransactionOpts.gasLimit,
-                gasPrice: orderTransactionOpts.gasPrice,
-            },
-        );
-        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 subscribe<ArgsType extends ExchangeContractEventArgs>(
-        eventName: ExchangeEvents,
-        indexFilterValues: IndexedFilterValues,
-        callback: EventCallback<ArgsType>,
-    ): string {
-        assert.doesBelongToStringEnum('eventName', eventName, ExchangeEvents);
-        assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
-        assert.isFunction('callback', callback);
-        const exchangeContractAddress = this.getContractAddress();
-        const subscriptionToken = this._subscribe<ArgsType>(
-            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);
-    }
-    /**
-     * Cancels all existing subscriptions
-     */
-    public unsubscribeAll(): void {
-        super.unsubscribeAll();
-    }
-    /**
-     * Gets historical logs without creating a subscription
-     * @param   eventName           The exchange contract event you would like to subscribe to.
-     * @param   blockRange          Block range to get logs from.
-     * @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<ArgsType extends ExchangeContractEventArgs>(
-        eventName: ExchangeEvents,
-        blockRange: BlockRange,
-        indexFilterValues: IndexedFilterValues,
-    ): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
-        assert.doesBelongToStringEnum('eventName', eventName, ExchangeEvents);
-        assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema);
-        assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
-        const exchangeContractAddress = this.getContractAddress();
-        const logs = await this._getLogsAsync<ArgsType>(
-            exchangeContractAddress,
-            eventName,
-            blockRange,
-            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 getContractAddress(): string {
-        const contractAddress = this._getContractAddress(artifacts.ExchangeArtifact, this._contractAddressIfExists);
-        return contractAddress;
-    }
-    /**
-     * 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<void> {
-        assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
-        const zrxTokenAddress = this.getZRXTokenAddress();
-        const expectedFillTakerTokenAmount = !_.isUndefined(opts) ? opts.expectedFillTakerTokenAmount : undefined;
-        const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
-        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<void> {
-        assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
-        assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
-        await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
-        const zrxTokenAddress = this.getZRXTokenAddress();
-        const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
-        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<void> {
-        assert.doesConformToSchema('order', order, schemas.orderSchema);
-        assert.isValidBaseUnitAmount('cancelTakerTokenAmount', cancelTakerTokenAmount);
-        const orderHash = utils.getOrderHashHex(order);
-        const unavailableTakerTokenAmount = await this.getUnavailableTakerAmountAsync(orderHash);
-        OrderValidationUtils.validateCancelOrderThrowIfInvalid(
-            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<void> {
-        assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
-        assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
-        await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
-        const zrxTokenAddress = this.getZRXTokenAddress();
-        const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
-        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<boolean> {
-        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<LogWithDecodedArgs<DecodedLogArgs> | Web3.LogEntry>): void {
-        const errLog = _.find(logs, {
-            event: ExchangeEvents.LogError,
-        }) as LogWithDecodedArgs<LogErrorContractEventArgs> | 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 getZRXTokenAddress(): string {
-        const contractAddress = this._getContractAddress(artifacts.ZRXArtifact, this._zrxContractAddressIfExists);
-        return contractAddress;
-    }
-    private _invalidateContractInstances(): void {
-        this.unsubscribeAll();
-        delete this._exchangeContractIfExists;
-    }
-    private async _isValidSignatureUsingContractCallAsync(
-        dataHex: string,
-        ecSignature: ECSignature,
-        signerAddressHex: string,
-    ): Promise<boolean> {
-        assert.isHexString('dataHex', dataHex);
-        assert.doesConformToSchema('ecSignature', ecSignature, schemas.ecSignatureSchema);
-        assert.isETHAddressHex('signerAddressHex', signerAddressHex);
+		const [orderAddresses, orderValues] = ExchangeWrapper._getOrderAddressesAndValues(order);
+		const txHash = await exchangeInstance.cancelOrder.sendTransactionAsync(
+			orderAddresses,
+			orderValues,
+			cancelTakerTokenAmount,
+			{
+				from: order.maker,
+				gas: orderTransactionOpts.gasLimit,
+				gasPrice: orderTransactionOpts.gasPrice,
+			},
+		);
+		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.asyncZeroExErrorHandler
+	public async batchCancelOrdersAsync(
+		orderCancellationRequests: OrderCancellationRequest[],
+		orderTransactionOpts: OrderTransactionOpts = {},
+	): Promise<string> {
+		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.shouldValidate)
+			? 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);
+				OrderValidationUtils.validateCancelOrderThrowIfInvalid(
+					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<any> because _.unzip doesn't type check if values have different types :'(
+		const [orderAddresses, orderValues, cancelTakerTokenAmounts] = _.unzip<any>(
+			orderAddressesValuesAndTakerTokenCancelAmounts,
+		);
+		const txHash = await exchangeInstance.batchCancelOrders.sendTransactionAsync(
+			orderAddresses,
+			orderValues,
+			cancelTakerTokenAmounts,
+			{
+				from: maker,
+				gas: orderTransactionOpts.gasLimit,
+				gasPrice: orderTransactionOpts.gasPrice,
+			},
+		);
+		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 subscribe<ArgsType extends ExchangeContractEventArgs>(
+		eventName: ExchangeEvents,
+		indexFilterValues: IndexedFilterValues,
+		callback: EventCallback<ArgsType>,
+	): string {
+		assert.doesBelongToStringEnum('eventName', eventName, ExchangeEvents);
+		assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
+		assert.isFunction('callback', callback);
+		const exchangeContractAddress = this.getContractAddress();
+		const subscriptionToken = this._subscribe<ArgsType>(
+			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);
+	}
+	/**
+	 * Cancels all existing subscriptions
+	 */
+	public unsubscribeAll(): void {
+		super.unsubscribeAll();
+	}
+	/**
+	 * Gets historical logs without creating a subscription
+	 * @param   eventName           The exchange contract event you would like to subscribe to.
+	 * @param   blockRange          Block range to get logs from.
+	 * @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<ArgsType extends ExchangeContractEventArgs>(
+		eventName: ExchangeEvents,
+		blockRange: BlockRange,
+		indexFilterValues: IndexedFilterValues,
+	): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
+		assert.doesBelongToStringEnum('eventName', eventName, ExchangeEvents);
+		assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema);
+		assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
+		const exchangeContractAddress = this.getContractAddress();
+		const logs = await this._getLogsAsync<ArgsType>(
+			exchangeContractAddress,
+			eventName,
+			blockRange,
+			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 getContractAddress(): string {
+		const contractAddress = this._getContractAddress(artifacts.ExchangeArtifact, this._contractAddressIfExists);
+		return contractAddress;
+	}
+	/**
+	 * 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<void> {
+		assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
+		const zrxTokenAddress = this.getZRXTokenAddress();
+		const expectedFillTakerTokenAmount = !_.isUndefined(opts) ? opts.expectedFillTakerTokenAmount : undefined;
+		const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
+		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<void> {
+		assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
+		assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
+		await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
+		const zrxTokenAddress = this.getZRXTokenAddress();
+		const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
+		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<void> {
+		assert.doesConformToSchema('order', order, schemas.orderSchema);
+		assert.isValidBaseUnitAmount('cancelTakerTokenAmount', cancelTakerTokenAmount);
+		const orderHash = utils.getOrderHashHex(order);
+		const unavailableTakerTokenAmount = await this.getUnavailableTakerAmountAsync(orderHash);
+		OrderValidationUtils.validateCancelOrderThrowIfInvalid(
+			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<void> {
+		assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
+		assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
+		await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
+		const zrxTokenAddress = this.getZRXTokenAddress();
+		const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
+		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<boolean> {
+		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<LogWithDecodedArgs<DecodedLogArgs> | Web3.LogEntry>): void {
+		const errLog = _.find(logs, {
+			event: ExchangeEvents.LogError,
+		}) as LogWithDecodedArgs<LogErrorContractEventArgs> | 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 getZRXTokenAddress(): string {
+		const contractAddress = this._getContractAddress(artifacts.ZRXArtifact, this._zrxContractAddressIfExists);
+		return contractAddress;
+	}
+	private _invalidateContractInstances(): void {
+		this.unsubscribeAll();
+		delete this._exchangeContractIfExists;
+	}
+	private async _isValidSignatureUsingContractCallAsync(
+		dataHex: string,
+		ecSignature: ECSignature,
+		signerAddressHex: string,
+	): Promise<boolean> {
+		assert.isHexString('dataHex', dataHex);
+		assert.doesConformToSchema('ecSignature', ecSignature, schemas.ecSignatureSchema);
+		assert.isETHAddressHex('signerAddressHex', signerAddressHex);
 
-        const exchangeInstance = await this._getExchangeContractAsync();
+		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<string> {
-        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<ExchangeContract> {
-        if (!_.isUndefined(this._exchangeContractIfExists)) {
-            return this._exchangeContractIfExists;
-        }
-        const web3ContractInstance = await this._instantiateContractIfExistsAsync(
-            artifacts.ExchangeArtifact,
-            this._contractAddressIfExists,
-        );
-        const contractInstance = new ExchangeContract(web3ContractInstance, this._web3Wrapper.getContractDefaults());
-        this._exchangeContractIfExists = contractInstance;
-        return this._exchangeContractIfExists;
-    }
-    private async _getTokenTransferProxyAddressAsync(): Promise<string> {
-        const exchangeInstance = await this._getExchangeContractAsync();
-        const tokenTransferProxyAddress = await exchangeInstance.TOKEN_TRANSFER_PROXY_CONTRACT.callAsync();
-        const tokenTransferProxyAddressLowerCase = tokenTransferProxyAddress.toLowerCase();
-        return tokenTransferProxyAddressLowerCase;
-    }
+		const isValidSignature = await exchangeInstance.isValidSignature.callAsync(
+			signerAddressHex,
+			dataHex,
+			ecSignature.v,
+			ecSignature.r,
+			ecSignature.s,
+		);
+		return isValidSignature;
+	}
+	private async _getOrderHashHexUsingContractCallAsync(order: Order | SignedOrder): Promise<string> {
+		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<ExchangeContract> {
+		if (!_.isUndefined(this._exchangeContractIfExists)) {
+			return this._exchangeContractIfExists;
+		}
+		const web3ContractInstance = await this._instantiateContractIfExistsAsync(
+			artifacts.ExchangeArtifact,
+			this._contractAddressIfExists,
+		);
+		const contractInstance = new ExchangeContract(web3ContractInstance, this._web3Wrapper.getContractDefaults());
+		this._exchangeContractIfExists = contractInstance;
+		return this._exchangeContractIfExists;
+	}
+	private async _getTokenTransferProxyAddressAsync(): Promise<string> {
+		const exchangeInstance = await this._getExchangeContractAsync();
+		const tokenTransferProxyAddress = await exchangeInstance.TOKEN_TRANSFER_PROXY_CONTRACT.callAsync();
+		const tokenTransferProxyAddressLowerCase = tokenTransferProxyAddress.toLowerCase();
+		return tokenTransferProxyAddressLowerCase;
+	}
 } // tslint:disable:max-file-line-count
diff --git a/packages/0x.js/src/contract_wrappers/token_registry_wrapper.ts b/packages/0x.js/src/contract_wrappers/token_registry_wrapper.ts
index f54aaf0f8..bce48a590 100644
--- a/packages/0x.js/src/contract_wrappers/token_registry_wrapper.ts
+++ b/packages/0x.js/src/contract_wrappers/token_registry_wrapper.ts
@@ -13,117 +13,117 @@ import { TokenRegistryContract } from './generated/token_registry';
  * 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;
-    private static _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;
-    }
-    constructor(web3Wrapper: Web3Wrapper, networkId: number, contractAddressIfExists?: string) {
-        super(web3Wrapper, networkId);
-        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<Token[]> {
-        const addresses = await this.getTokenAddressesAsync();
-        const tokenPromises: Array<Promise<Token | undefined>> = _.map(addresses, async (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<string[]> {
-        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<Token | undefined> {
-        assert.isETHAddressHex('address', address);
+	private _tokenRegistryContractIfExists?: TokenRegistryContract;
+	private _contractAddressIfExists?: string;
+	private static _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;
+	}
+	constructor(web3Wrapper: Web3Wrapper, networkId: number, contractAddressIfExists?: string) {
+		super(web3Wrapper, networkId);
+		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<Token[]> {
+		const addresses = await this.getTokenAddressesAsync();
+		const tokenPromises: Array<Promise<Token | undefined>> = _.map(addresses, async (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<string[]> {
+		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<Token | undefined> {
+		assert.isETHAddressHex('address', address);
 
-        const tokenRegistryContract = await this._getTokenRegistryContractAsync();
-        const metadata = await tokenRegistryContract.getTokenMetaData.callAsync(address);
-        const token = TokenRegistryWrapper._createTokenFromMetadata(metadata);
-        return token;
-    }
-    public async getTokenAddressBySymbolIfExistsAsync(symbol: string): Promise<string | undefined> {
-        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<string | undefined> {
-        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<Token | undefined> {
-        assert.isString('symbol', symbol);
-        const tokenRegistryContract = await this._getTokenRegistryContractAsync();
-        const metadata = await tokenRegistryContract.getTokenBySymbol.callAsync(symbol);
-        const token = TokenRegistryWrapper._createTokenFromMetadata(metadata);
-        return token;
-    }
-    public async getTokenByNameIfExistsAsync(name: string): Promise<Token | undefined> {
-        assert.isString('name', name);
-        const tokenRegistryContract = await this._getTokenRegistryContractAsync();
-        const metadata = await tokenRegistryContract.getTokenByName.callAsync(name);
-        const token = TokenRegistryWrapper._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 getContractAddress(): string {
-        const contractAddress = this._getContractAddress(
-            artifacts.TokenRegistryArtifact,
-            this._contractAddressIfExists,
-        );
-        return contractAddress;
-    }
-    private _invalidateContractInstance(): void {
-        delete this._tokenRegistryContractIfExists;
-    }
-    private async _getTokenRegistryContractAsync(): Promise<TokenRegistryContract> {
-        if (!_.isUndefined(this._tokenRegistryContractIfExists)) {
-            return this._tokenRegistryContractIfExists;
-        }
-        const web3ContractInstance = await this._instantiateContractIfExistsAsync(
-            artifacts.TokenRegistryArtifact,
-            this._contractAddressIfExists,
-        );
-        const contractInstance = new TokenRegistryContract(
-            web3ContractInstance,
-            this._web3Wrapper.getContractDefaults(),
-        );
-        this._tokenRegistryContractIfExists = contractInstance;
-        return this._tokenRegistryContractIfExists;
-    }
+		const tokenRegistryContract = await this._getTokenRegistryContractAsync();
+		const metadata = await tokenRegistryContract.getTokenMetaData.callAsync(address);
+		const token = TokenRegistryWrapper._createTokenFromMetadata(metadata);
+		return token;
+	}
+	public async getTokenAddressBySymbolIfExistsAsync(symbol: string): Promise<string | undefined> {
+		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<string | undefined> {
+		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<Token | undefined> {
+		assert.isString('symbol', symbol);
+		const tokenRegistryContract = await this._getTokenRegistryContractAsync();
+		const metadata = await tokenRegistryContract.getTokenBySymbol.callAsync(symbol);
+		const token = TokenRegistryWrapper._createTokenFromMetadata(metadata);
+		return token;
+	}
+	public async getTokenByNameIfExistsAsync(name: string): Promise<Token | undefined> {
+		assert.isString('name', name);
+		const tokenRegistryContract = await this._getTokenRegistryContractAsync();
+		const metadata = await tokenRegistryContract.getTokenByName.callAsync(name);
+		const token = TokenRegistryWrapper._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 getContractAddress(): string {
+		const contractAddress = this._getContractAddress(
+			artifacts.TokenRegistryArtifact,
+			this._contractAddressIfExists,
+		);
+		return contractAddress;
+	}
+	private _invalidateContractInstance(): void {
+		delete this._tokenRegistryContractIfExists;
+	}
+	private async _getTokenRegistryContractAsync(): Promise<TokenRegistryContract> {
+		if (!_.isUndefined(this._tokenRegistryContractIfExists)) {
+			return this._tokenRegistryContractIfExists;
+		}
+		const web3ContractInstance = await this._instantiateContractIfExistsAsync(
+			artifacts.TokenRegistryArtifact,
+			this._contractAddressIfExists,
+		);
+		const contractInstance = new TokenRegistryContract(
+			web3ContractInstance,
+			this._web3Wrapper.getContractDefaults(),
+		);
+		this._tokenRegistryContractIfExists = contractInstance;
+		return this._tokenRegistryContractIfExists;
+	}
 }
diff --git a/packages/0x.js/src/contract_wrappers/token_transfer_proxy_wrapper.ts b/packages/0x.js/src/contract_wrappers/token_transfer_proxy_wrapper.ts
index f5d9d108a..635588fed 100644
--- a/packages/0x.js/src/contract_wrappers/token_transfer_proxy_wrapper.ts
+++ b/packages/0x.js/src/contract_wrappers/token_transfer_proxy_wrapper.ts
@@ -10,59 +10,59 @@ import { TokenTransferProxyContract } from './generated/token_transfer_proxy';
  * This class includes the functionality related to interacting with the TokenTransferProxy contract.
  */
 export class TokenTransferProxyWrapper extends ContractWrapper {
-    private _tokenTransferProxyContractIfExists?: TokenTransferProxyContract;
-    private _contractAddressIfExists?: string;
-    constructor(web3Wrapper: Web3Wrapper, networkId: number, contractAddressIfExists?: string) {
-        super(web3Wrapper, networkId);
-        this._contractAddressIfExists = contractAddressIfExists;
-    }
-    /**
-     * 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<boolean> {
-        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<string[]> {
-        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 getContractAddress(): string {
-        const contractAddress = this._getContractAddress(
-            artifacts.TokenTransferProxyArtifact,
-            this._contractAddressIfExists,
-        );
-        return contractAddress;
-    }
-    private _invalidateContractInstance(): void {
-        delete this._tokenTransferProxyContractIfExists;
-    }
-    private async _getTokenTransferProxyContractAsync(): Promise<TokenTransferProxyContract> {
-        if (!_.isUndefined(this._tokenTransferProxyContractIfExists)) {
-            return this._tokenTransferProxyContractIfExists;
-        }
-        const web3ContractInstance = await this._instantiateContractIfExistsAsync(
-            artifacts.TokenTransferProxyArtifact,
-            this._contractAddressIfExists,
-        );
-        const contractInstance = new TokenTransferProxyContract(
-            web3ContractInstance,
-            this._web3Wrapper.getContractDefaults(),
-        );
-        this._tokenTransferProxyContractIfExists = contractInstance;
-        return this._tokenTransferProxyContractIfExists;
-    }
+	private _tokenTransferProxyContractIfExists?: TokenTransferProxyContract;
+	private _contractAddressIfExists?: string;
+	constructor(web3Wrapper: Web3Wrapper, networkId: number, contractAddressIfExists?: string) {
+		super(web3Wrapper, networkId);
+		this._contractAddressIfExists = contractAddressIfExists;
+	}
+	/**
+	 * 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<boolean> {
+		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<string[]> {
+		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 getContractAddress(): string {
+		const contractAddress = this._getContractAddress(
+			artifacts.TokenTransferProxyArtifact,
+			this._contractAddressIfExists,
+		);
+		return contractAddress;
+	}
+	private _invalidateContractInstance(): void {
+		delete this._tokenTransferProxyContractIfExists;
+	}
+	private async _getTokenTransferProxyContractAsync(): Promise<TokenTransferProxyContract> {
+		if (!_.isUndefined(this._tokenTransferProxyContractIfExists)) {
+			return this._tokenTransferProxyContractIfExists;
+		}
+		const web3ContractInstance = await this._instantiateContractIfExistsAsync(
+			artifacts.TokenTransferProxyArtifact,
+			this._contractAddressIfExists,
+		);
+		const contractInstance = new TokenTransferProxyContract(
+			web3ContractInstance,
+			this._web3Wrapper.getContractDefaults(),
+		);
+		this._tokenTransferProxyContractIfExists = contractInstance;
+		return this._tokenTransferProxyContractIfExists;
+	}
 }
diff --git a/packages/0x.js/src/contract_wrappers/token_wrapper.ts b/packages/0x.js/src/contract_wrappers/token_wrapper.ts
index 7943f4a60..366cabd9e 100644
--- a/packages/0x.js/src/contract_wrappers/token_wrapper.ts
+++ b/packages/0x.js/src/contract_wrappers/token_wrapper.ts
@@ -5,15 +5,15 @@ import * as _ from 'lodash';
 
 import { artifacts } from '../artifacts';
 import {
-    BlockRange,
-    EventCallback,
-    IndexedFilterValues,
-    LogWithDecodedArgs,
-    MethodOpts,
-    TokenContractEventArgs,
-    TokenEvents,
-    TransactionOpts,
-    ZeroExError,
+	BlockRange,
+	EventCallback,
+	IndexedFilterValues,
+	LogWithDecodedArgs,
+	MethodOpts,
+	TokenContractEventArgs,
+	TokenEvents,
+	TransactionOpts,
+	ZeroExError,
 } from '../types';
 import { AbiDecoder } from '../utils/abi_decoder';
 import { assert } from '../utils/assert';
@@ -29,367 +29,367 @@ import { TokenTransferProxyWrapper } from './token_transfer_proxy_wrapper';
  * 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 _tokenTransferProxyWrapper: TokenTransferProxyWrapper;
-    constructor(
-        web3Wrapper: Web3Wrapper,
-        networkId: number,
-        abiDecoder: AbiDecoder,
-        tokenTransferProxyWrapper: TokenTransferProxyWrapper,
-    ) {
-        super(web3Wrapper, networkId, abiDecoder);
-        this._tokenContractsByAddress = {};
-        this._tokenTransferProxyWrapper = tokenTransferProxyWrapper;
-    }
-    /**
-     * 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<BigNumber> {
-        assert.isETHAddressHex('ownerAddress', ownerAddress);
-        assert.isETHAddressHex('tokenAddress', tokenAddress);
+	public UNLIMITED_ALLOWANCE_IN_BASE_UNITS = constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS;
+	private _tokenContractsByAddress: { [address: string]: TokenContract };
+	private _tokenTransferProxyWrapper: TokenTransferProxyWrapper;
+	constructor(
+		web3Wrapper: Web3Wrapper,
+		networkId: number,
+		abiDecoder: AbiDecoder,
+		tokenTransferProxyWrapper: TokenTransferProxyWrapper,
+	) {
+		super(web3Wrapper, networkId, abiDecoder);
+		this._tokenContractsByAddress = {};
+		this._tokenTransferProxyWrapper = tokenTransferProxyWrapper;
+	}
+	/**
+	 * 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<BigNumber> {
+		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.
-     * @param   txOpts              Transaction parameters.
-     * @return Transaction hash.
-     */
-    public async setAllowanceAsync(
-        tokenAddress: string,
-        ownerAddress: string,
-        spenderAddress: string,
-        amountInBaseUnits: BigNumber,
-        txOpts: TransactionOpts = {},
-    ): Promise<string> {
-        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);
+		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.
+	 * @param   txOpts              Transaction parameters.
+	 * @return Transaction hash.
+	 */
+	public async setAllowanceAsync(
+		tokenAddress: string,
+		ownerAddress: string,
+		spenderAddress: string,
+		amountInBaseUnits: BigNumber,
+		txOpts: TransactionOpts = {},
+	): Promise<string> {
+		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);
-        const txHash = await tokenContract.approve.sendTransactionAsync(spenderAddress, amountInBaseUnits, {
-            from: ownerAddress,
-            gas: txOpts.gasLimit,
-            gasPrice: txOpts.gasPrice,
-        });
-        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.
-     * @param   txOpts              Transaction parameters.
-     * @return Transaction hash.
-     */
-    public async setUnlimitedAllowanceAsync(
-        tokenAddress: string,
-        ownerAddress: string,
-        spenderAddress: string,
-        txOpts: TransactionOpts = {},
-    ): Promise<string> {
-        const txHash = await this.setAllowanceAsync(
-            tokenAddress,
-            ownerAddress,
-            spenderAddress,
-            this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS,
-            txOpts,
-        );
-        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<BigNumber> {
-        assert.isETHAddressHex('ownerAddress', ownerAddress);
-        assert.isETHAddressHex('tokenAddress', tokenAddress);
+		const tokenContract = await this._getTokenContractAsync(tokenAddress);
+		const txHash = await tokenContract.approve.sendTransactionAsync(spenderAddress, amountInBaseUnits, {
+			from: ownerAddress,
+			gas: txOpts.gasLimit,
+			gasPrice: txOpts.gasPrice,
+		});
+		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.
+	 * @param   txOpts              Transaction parameters.
+	 * @return Transaction hash.
+	 */
+	public async setUnlimitedAllowanceAsync(
+		tokenAddress: string,
+		ownerAddress: string,
+		spenderAddress: string,
+		txOpts: TransactionOpts = {},
+	): Promise<string> {
+		const txHash = await this.setAllowanceAsync(
+			tokenAddress,
+			ownerAddress,
+			spenderAddress,
+			this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS,
+			txOpts,
+		);
+		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<BigNumber> {
+		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<BigNumber> {
-        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<BigNumber> {
+		assert.isETHAddressHex('ownerAddress', ownerAddress);
+		assert.isETHAddressHex('tokenAddress', tokenAddress);
 
-        const proxyAddress = this._tokenTransferProxyWrapper.getContractAddress();
-        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.
-     * @param   txOpts              Transaction parameters.
-     * @return Transaction hash.
-     */
-    public async setProxyAllowanceAsync(
-        tokenAddress: string,
-        ownerAddress: string,
-        amountInBaseUnits: BigNumber,
-        txOpts: TransactionOpts = {},
-    ): Promise<string> {
-        assert.isETHAddressHex('ownerAddress', ownerAddress);
-        assert.isETHAddressHex('tokenAddress', tokenAddress);
-        assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits);
+		const proxyAddress = this._tokenTransferProxyWrapper.getContractAddress();
+		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.
+	 * @param   txOpts              Transaction parameters.
+	 * @return Transaction hash.
+	 */
+	public async setProxyAllowanceAsync(
+		tokenAddress: string,
+		ownerAddress: string,
+		amountInBaseUnits: BigNumber,
+		txOpts: TransactionOpts = {},
+	): Promise<string> {
+		assert.isETHAddressHex('ownerAddress', ownerAddress);
+		assert.isETHAddressHex('tokenAddress', tokenAddress);
+		assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits);
 
-        const proxyAddress = this._tokenTransferProxyWrapper.getContractAddress();
-        const txHash = await this.setAllowanceAsync(
-            tokenAddress,
-            ownerAddress,
-            proxyAddress,
-            amountInBaseUnits,
-            txOpts,
-        );
-        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.
-     * @param   txOpts              Transaction parameters.
-     * @return Transaction hash.
-     */
-    public async setUnlimitedProxyAllowanceAsync(
-        tokenAddress: string,
-        ownerAddress: string,
-        txOpts: TransactionOpts = {},
-    ): Promise<string> {
-        const txHash = await this.setProxyAllowanceAsync(
-            tokenAddress,
-            ownerAddress,
-            this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS,
-            txOpts,
-        );
-        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.
-     * @param   txOpts              Transaction parameters.
-     * @return Transaction hash.
-     */
-    public async transferAsync(
-        tokenAddress: string,
-        fromAddress: string,
-        toAddress: string,
-        amountInBaseUnits: BigNumber,
-        txOpts: TransactionOpts = {},
-    ): Promise<string> {
-        assert.isETHAddressHex('tokenAddress', tokenAddress);
-        await assert.isSenderAddressAsync('fromAddress', fromAddress, this._web3Wrapper);
-        assert.isETHAddressHex('toAddress', toAddress);
-        assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits);
+		const proxyAddress = this._tokenTransferProxyWrapper.getContractAddress();
+		const txHash = await this.setAllowanceAsync(
+			tokenAddress,
+			ownerAddress,
+			proxyAddress,
+			amountInBaseUnits,
+			txOpts,
+		);
+		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.
+	 * @param   txOpts              Transaction parameters.
+	 * @return Transaction hash.
+	 */
+	public async setUnlimitedProxyAllowanceAsync(
+		tokenAddress: string,
+		ownerAddress: string,
+		txOpts: TransactionOpts = {},
+	): Promise<string> {
+		const txHash = await this.setProxyAllowanceAsync(
+			tokenAddress,
+			ownerAddress,
+			this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS,
+			txOpts,
+		);
+		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.
+	 * @param   txOpts              Transaction parameters.
+	 * @return Transaction hash.
+	 */
+	public async transferAsync(
+		tokenAddress: string,
+		fromAddress: string,
+		toAddress: string,
+		amountInBaseUnits: BigNumber,
+		txOpts: TransactionOpts = {},
+	): Promise<string> {
+		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 tokenContract = await this._getTokenContractAsync(tokenAddress);
 
-        const fromAddressBalance = await this.getBalanceAsync(tokenAddress, fromAddress);
-        if (fromAddressBalance.lessThan(amountInBaseUnits)) {
-            throw new Error(ZeroExError.InsufficientBalanceForTransfer);
-        }
+		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,
-            gas: txOpts.gasLimit,
-            gasPrice: txOpts.gasPrice,
-        });
-        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.
-     * @param   txOpts              Transaction parameters.
-     * @return Transaction hash.
-     */
-    public async transferFromAsync(
-        tokenAddress: string,
-        fromAddress: string,
-        toAddress: string,
-        senderAddress: string,
-        amountInBaseUnits: BigNumber,
-        txOpts: TransactionOpts = {},
-    ): Promise<string> {
-        assert.isETHAddressHex('tokenAddress', tokenAddress);
-        assert.isETHAddressHex('fromAddress', fromAddress);
-        assert.isETHAddressHex('toAddress', toAddress);
-        await assert.isSenderAddressAsync('senderAddress', senderAddress, this._web3Wrapper);
-        assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits);
+		const txHash = await tokenContract.transfer.sendTransactionAsync(toAddress, amountInBaseUnits, {
+			from: fromAddress,
+			gas: txOpts.gasLimit,
+			gasPrice: txOpts.gasPrice,
+		});
+		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.
+	 * @param   txOpts              Transaction parameters.
+	 * @return Transaction hash.
+	 */
+	public async transferFromAsync(
+		tokenAddress: string,
+		fromAddress: string,
+		toAddress: string,
+		senderAddress: string,
+		amountInBaseUnits: BigNumber,
+		txOpts: TransactionOpts = {},
+	): Promise<string> {
+		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 tokenContract = await this._getTokenContractAsync(tokenAddress);
 
-        const fromAddressAllowance = await this.getAllowanceAsync(tokenAddress, fromAddress, senderAddress);
-        if (fromAddressAllowance.lessThan(amountInBaseUnits)) {
-            throw new Error(ZeroExError.InsufficientAllowanceForTransfer);
-        }
+		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 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,
-                gas: txOpts.gasLimit,
-                gasPrice: txOpts.gasPrice,
-            },
-        );
-        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<ArgsType extends TokenContractEventArgs>(
-        tokenAddress: string,
-        eventName: TokenEvents,
-        indexFilterValues: IndexedFilterValues,
-        callback: EventCallback<ArgsType>,
-    ): string {
-        assert.isETHAddressHex('tokenAddress', tokenAddress);
-        assert.doesBelongToStringEnum('eventName', eventName, TokenEvents);
-        assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
-        assert.isFunction('callback', callback);
-        const subscriptionToken = this._subscribe<ArgsType>(
-            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);
-    }
-    /**
-     * Cancels all existing subscriptions
-     */
-    public unsubscribeAll(): void {
-        super.unsubscribeAll();
-    }
-    /**
-     * 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   blockRange          Block range to get logs from.
-     * @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<ArgsType extends TokenContractEventArgs>(
-        tokenAddress: string,
-        eventName: TokenEvents,
-        blockRange: BlockRange,
-        indexFilterValues: IndexedFilterValues,
-    ): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
-        assert.isETHAddressHex('tokenAddress', tokenAddress);
-        assert.doesBelongToStringEnum('eventName', eventName, TokenEvents);
-        assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema);
-        assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
-        const logs = await this._getLogsAsync<ArgsType>(
-            tokenAddress,
-            eventName,
-            blockRange,
-            indexFilterValues,
-            artifacts.TokenArtifact.abi,
-        );
-        return logs;
-    }
-    private _invalidateContractInstances(): void {
-        this.unsubscribeAll();
-        this._tokenContractsByAddress = {};
-    }
-    private async _getTokenContractAsync(tokenAddress: string): Promise<TokenContract> {
-        let tokenContract = this._tokenContractsByAddress[tokenAddress];
-        if (!_.isUndefined(tokenContract)) {
-            return tokenContract;
-        }
-        const web3ContractInstance = await this._instantiateContractIfExistsAsync(
-            artifacts.TokenArtifact,
-            tokenAddress,
-        );
-        const contractInstance = new TokenContract(web3ContractInstance, this._web3Wrapper.getContractDefaults());
-        tokenContract = contractInstance;
-        this._tokenContractsByAddress[tokenAddress] = tokenContract;
-        return tokenContract;
-    }
+		const txHash = await tokenContract.transferFrom.sendTransactionAsync(
+			fromAddress,
+			toAddress,
+			amountInBaseUnits,
+			{
+				from: senderAddress,
+				gas: txOpts.gasLimit,
+				gasPrice: txOpts.gasPrice,
+			},
+		);
+		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<ArgsType extends TokenContractEventArgs>(
+		tokenAddress: string,
+		eventName: TokenEvents,
+		indexFilterValues: IndexedFilterValues,
+		callback: EventCallback<ArgsType>,
+	): string {
+		assert.isETHAddressHex('tokenAddress', tokenAddress);
+		assert.doesBelongToStringEnum('eventName', eventName, TokenEvents);
+		assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
+		assert.isFunction('callback', callback);
+		const subscriptionToken = this._subscribe<ArgsType>(
+			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);
+	}
+	/**
+	 * Cancels all existing subscriptions
+	 */
+	public unsubscribeAll(): void {
+		super.unsubscribeAll();
+	}
+	/**
+	 * 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   blockRange          Block range to get logs from.
+	 * @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<ArgsType extends TokenContractEventArgs>(
+		tokenAddress: string,
+		eventName: TokenEvents,
+		blockRange: BlockRange,
+		indexFilterValues: IndexedFilterValues,
+	): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
+		assert.isETHAddressHex('tokenAddress', tokenAddress);
+		assert.doesBelongToStringEnum('eventName', eventName, TokenEvents);
+		assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema);
+		assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
+		const logs = await this._getLogsAsync<ArgsType>(
+			tokenAddress,
+			eventName,
+			blockRange,
+			indexFilterValues,
+			artifacts.TokenArtifact.abi,
+		);
+		return logs;
+	}
+	private _invalidateContractInstances(): void {
+		this.unsubscribeAll();
+		this._tokenContractsByAddress = {};
+	}
+	private async _getTokenContractAsync(tokenAddress: string): Promise<TokenContract> {
+		let tokenContract = this._tokenContractsByAddress[tokenAddress];
+		if (!_.isUndefined(tokenContract)) {
+			return tokenContract;
+		}
+		const web3ContractInstance = await this._instantiateContractIfExistsAsync(
+			artifacts.TokenArtifact,
+			tokenAddress,
+		);
+		const contractInstance = new TokenContract(web3ContractInstance, this._web3Wrapper.getContractDefaults());
+		tokenContract = contractInstance;
+		this._tokenContractsByAddress[tokenAddress] = tokenContract;
+		return tokenContract;
+	}
 }
diff --git a/packages/0x.js/src/globals.d.ts b/packages/0x.js/src/globals.d.ts
index 4f4932b6e..9a53949b4 100644
--- a/packages/0x.js/src/globals.d.ts
+++ b/packages/0x.js/src/globals.d.ts
@@ -10,50 +10,50 @@ declare module 'web3-provider-engine/subproviders/rpc';
 // 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;
-    }
+	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 */
+	const json: any;
+	/* tslint:disable */
+	export default json;
+	/* tslint:enable */
 }
 
 declare module 'ethereumjs-abi' {
-    const soliditySHA3: (argTypes: string[], args: any[]) => Buffer;
+	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;
+	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[];
+	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[];
+	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[];
+	const decodeParams: (types: string[], data: string) => any[];
 }
diff --git a/packages/0x.js/src/globalsAugment.d.ts b/packages/0x.js/src/globalsAugment.d.ts
index 3e2f2216b..c2f200ab8 100644
--- a/packages/0x.js/src/globalsAugment.d.ts
+++ b/packages/0x.js/src/globalsAugment.d.ts
@@ -3,21 +3,21 @@ import { BigNumber } from '@0xproject/utils';
 // 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;
-    }
+	// 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/packages/0x.js/src/index.ts b/packages/0x.js/src/index.ts
index 599c3a2b0..ad5ef8534 100644
--- a/packages/0x.js/src/index.ts
+++ b/packages/0x.js/src/index.ts
@@ -1,50 +1,50 @@
 export { ZeroEx } from './0x';
 
 export {
-    Order,
-    BlockParamLiteral,
-    SignedOrder,
-    ECSignature,
-    ZeroExError,
-    EventCallback,
-    ExchangeContractErrs,
-    ContractEvent,
-    Token,
-    ExchangeEvents,
-    TokenEvents,
-    IndexedFilterValues,
-    BlockRange,
-    BlockParam,
-    OrderCancellationRequest,
-    OrderFillRequest,
-    LogErrorContractEventArgs,
-    LogCancelContractEventArgs,
-    LogFillContractEventArgs,
-    ExchangeContractEventArgs,
-    TransferContractEventArgs,
-    ApprovalContractEventArgs,
-    TokenContractEventArgs,
-    EtherTokenContractEventArgs,
-    WithdrawalContractEventArgs,
-    DepositContractEventArgs,
-    ContractEventArgs,
-    ContractEventArg,
-    Web3Provider,
-    ZeroExConfig,
-    EtherTokenEvents,
-    TransactionReceiptWithDecodedLogs,
-    LogWithDecodedArgs,
-    MethodOpts,
-    OrderTransactionOpts,
-    TransactionOpts,
-    FilterObject,
-    LogEvent,
-    DecodedLogEvent,
-    EventWatcherCallback,
-    OnOrderStateChangeCallback,
-    OrderStateValid,
-    OrderStateInvalid,
-    OrderState,
+	Order,
+	BlockParamLiteral,
+	SignedOrder,
+	ECSignature,
+	ZeroExError,
+	EventCallback,
+	ExchangeContractErrs,
+	ContractEvent,
+	Token,
+	ExchangeEvents,
+	TokenEvents,
+	IndexedFilterValues,
+	BlockRange,
+	BlockParam,
+	OrderCancellationRequest,
+	OrderFillRequest,
+	LogErrorContractEventArgs,
+	LogCancelContractEventArgs,
+	LogFillContractEventArgs,
+	ExchangeContractEventArgs,
+	TransferContractEventArgs,
+	ApprovalContractEventArgs,
+	TokenContractEventArgs,
+	EtherTokenContractEventArgs,
+	WithdrawalContractEventArgs,
+	DepositContractEventArgs,
+	ContractEventArgs,
+	ContractEventArg,
+	Web3Provider,
+	ZeroExConfig,
+	EtherTokenEvents,
+	TransactionReceiptWithDecodedLogs,
+	LogWithDecodedArgs,
+	MethodOpts,
+	OrderTransactionOpts,
+	TransactionOpts,
+	FilterObject,
+	LogEvent,
+	DecodedLogEvent,
+	EventWatcherCallback,
+	OnOrderStateChangeCallback,
+	OrderStateValid,
+	OrderStateInvalid,
+	OrderState,
 } from './types';
 
 export { TransactionReceipt } from '@0xproject/types';
diff --git a/packages/0x.js/src/order_watcher/event_watcher.ts b/packages/0x.js/src/order_watcher/event_watcher.ts
index 5d05bfb60..3e3cd978d 100644
--- a/packages/0x.js/src/order_watcher/event_watcher.ts
+++ b/packages/0x.js/src/order_watcher/event_watcher.ts
@@ -9,8 +9,8 @@ import { assert } from '../utils/assert';
 const DEFAULT_EVENT_POLLING_INTERVAL_MS = 200;
 
 enum LogEventState {
-    Removed,
-    Added,
+	Removed,
+	Added,
 }
 
 /*
@@ -18,76 +18,76 @@ enum LogEventState {
  * depth.
  */
 export class EventWatcher {
-    private _web3Wrapper: Web3Wrapper;
-    private _pollingIntervalMs: number;
-    private _intervalIdIfExists?: NodeJS.Timer;
-    private _lastEvents: Web3.LogEntry[] = [];
-    constructor(web3Wrapper: Web3Wrapper, pollingIntervalIfExistsMs: undefined | number) {
-        this._web3Wrapper = web3Wrapper;
-        this._pollingIntervalMs = _.isUndefined(pollingIntervalIfExistsMs)
-            ? DEFAULT_EVENT_POLLING_INTERVAL_MS
-            : pollingIntervalIfExistsMs;
-    }
-    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,
-            (err: Error) => {
-                this.unsubscribe();
-                callback(err);
-            },
-        );
-    }
-    public unsubscribe(): void {
-        this._lastEvents = [];
-        if (!_.isUndefined(this._intervalIdIfExists)) {
-            intervalUtils.clearAsyncExcludingInterval(this._intervalIdIfExists);
-            delete this._intervalIdIfExists;
-        }
-    }
-    private async _pollForBlockchainEventsAsync(callback: EventWatcherCallback): Promise<void> {
-        const pendingEvents = await this._getEventsAsync();
-        if (_.isUndefined(pendingEvents)) {
-            // HACK: This should never happen, but happens frequently on CI due to a ganache bug
-            return;
-        }
-        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<Web3.LogEntry[]> {
-        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<void> {
-        for (const log of logs) {
-            const logEvent = {
-                removed: logEventState === LogEventState.Removed,
-                ...log,
-            };
-            if (!_.isUndefined(this._intervalIdIfExists)) {
-                callback(null, logEvent);
-            }
-        }
-    }
+	private _web3Wrapper: Web3Wrapper;
+	private _pollingIntervalMs: number;
+	private _intervalIdIfExists?: NodeJS.Timer;
+	private _lastEvents: Web3.LogEntry[] = [];
+	constructor(web3Wrapper: Web3Wrapper, pollingIntervalIfExistsMs: undefined | number) {
+		this._web3Wrapper = web3Wrapper;
+		this._pollingIntervalMs = _.isUndefined(pollingIntervalIfExistsMs)
+			? DEFAULT_EVENT_POLLING_INTERVAL_MS
+			: pollingIntervalIfExistsMs;
+	}
+	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,
+			(err: Error) => {
+				this.unsubscribe();
+				callback(err);
+			},
+		);
+	}
+	public unsubscribe(): void {
+		this._lastEvents = [];
+		if (!_.isUndefined(this._intervalIdIfExists)) {
+			intervalUtils.clearAsyncExcludingInterval(this._intervalIdIfExists);
+			delete this._intervalIdIfExists;
+		}
+	}
+	private async _pollForBlockchainEventsAsync(callback: EventWatcherCallback): Promise<void> {
+		const pendingEvents = await this._getEventsAsync();
+		if (_.isUndefined(pendingEvents)) {
+			// HACK: This should never happen, but happens frequently on CI due to a ganache bug
+			return;
+		}
+		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<Web3.LogEntry[]> {
+		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<void> {
+		for (const log of logs) {
+			const logEvent = {
+				removed: logEventState === LogEventState.Removed,
+				...log,
+			};
+			if (!_.isUndefined(this._intervalIdIfExists)) {
+				callback(null, logEvent);
+			}
+		}
+	}
 }
diff --git a/packages/0x.js/src/order_watcher/expiration_watcher.ts b/packages/0x.js/src/order_watcher/expiration_watcher.ts
index 00b62162d..a08de94c0 100644
--- a/packages/0x.js/src/order_watcher/expiration_watcher.ts
+++ b/packages/0x.js/src/order_watcher/expiration_watcher.ts
@@ -13,63 +13,63 @@ const DEFAULT_ORDER_EXPIRATION_CHECKING_INTERVAL_MS = 50;
  * It stores them in a min heap by expiration time and checks for expired ones every `orderExpirationCheckingIntervalMs`
  */
 export class ExpirationWatcher {
-    private _orderHashByExpirationRBTree: RBTree<string>;
-    private _expiration: { [orderHash: string]: BigNumber } = {};
-    private _orderExpirationCheckingIntervalMs: number;
-    private _expirationMarginMs: number;
-    private _orderExpirationCheckingIntervalIdIfExists?: NodeJS.Timer;
-    constructor(expirationMarginIfExistsMs?: number, orderExpirationCheckingIntervalIfExistsMs?: number) {
-        this._expirationMarginMs = expirationMarginIfExistsMs || DEFAULT_EXPIRATION_MARGIN_MS;
-        this._orderExpirationCheckingIntervalMs =
-            expirationMarginIfExistsMs || DEFAULT_ORDER_EXPIRATION_CHECKING_INTERVAL_MS;
-        const scoreFunction = (orderHash: string) => this._expiration[orderHash].toNumber();
-        const comparator = (lhs: string, rhs: string) => scoreFunction(lhs) - scoreFunction(rhs);
-        this._orderHashByExpirationRBTree = new RBTree(comparator);
-    }
-    public subscribe(callback: (orderHash: string) => void): void {
-        if (!_.isUndefined(this._orderExpirationCheckingIntervalIdIfExists)) {
-            throw new Error(ZeroExError.SubscriptionAlreadyPresent);
-        }
-        this._orderExpirationCheckingIntervalIdIfExists = intervalUtils.setInterval(
-            this._pruneExpiredOrders.bind(this, callback),
-            this._orderExpirationCheckingIntervalMs,
-            _.noop, // _pruneExpiredOrders never throws
-        );
-    }
-    public unsubscribe(): void {
-        if (_.isUndefined(this._orderExpirationCheckingIntervalIdIfExists)) {
-            throw new Error(ZeroExError.SubscriptionNotFound);
-        }
-        intervalUtils.clearInterval(this._orderExpirationCheckingIntervalIdIfExists);
-        delete this._orderExpirationCheckingIntervalIdIfExists;
-    }
-    public addOrder(orderHash: string, expirationUnixTimestampMs: BigNumber): void {
-        this._expiration[orderHash] = expirationUnixTimestampMs;
-        this._orderHashByExpirationRBTree.insert(orderHash);
-    }
-    public removeOrder(orderHash: string): void {
-        this._orderHashByExpirationRBTree.remove(orderHash);
-        delete this._expiration[orderHash];
-    }
-    private _pruneExpiredOrders(callback: (orderHash: string) => void): void {
-        const currentUnixTimestampMs = utils.getCurrentUnixTimestampMs();
-        while (true) {
-            const hasTrakedOrders = this._orderHashByExpirationRBTree.size === 0;
-            if (hasTrakedOrders) {
-                break;
-            }
-            const nextOrderHashToExpire = this._orderHashByExpirationRBTree.min();
-            const hasNoExpiredOrders = this._expiration[nextOrderHashToExpire].greaterThan(
-                currentUnixTimestampMs.plus(this._expirationMarginMs),
-            );
-            const isSubscriptionActive = _.isUndefined(this._orderExpirationCheckingIntervalIdIfExists);
-            if (hasNoExpiredOrders || isSubscriptionActive) {
-                break;
-            }
-            const orderHash = this._orderHashByExpirationRBTree.min();
-            this._orderHashByExpirationRBTree.remove(orderHash);
-            delete this._expiration[orderHash];
-            callback(orderHash);
-        }
-    }
+	private _orderHashByExpirationRBTree: RBTree<string>;
+	private _expiration: { [orderHash: string]: BigNumber } = {};
+	private _orderExpirationCheckingIntervalMs: number;
+	private _expirationMarginMs: number;
+	private _orderExpirationCheckingIntervalIdIfExists?: NodeJS.Timer;
+	constructor(expirationMarginIfExistsMs?: number, orderExpirationCheckingIntervalIfExistsMs?: number) {
+		this._expirationMarginMs = expirationMarginIfExistsMs || DEFAULT_EXPIRATION_MARGIN_MS;
+		this._orderExpirationCheckingIntervalMs =
+			expirationMarginIfExistsMs || DEFAULT_ORDER_EXPIRATION_CHECKING_INTERVAL_MS;
+		const scoreFunction = (orderHash: string) => this._expiration[orderHash].toNumber();
+		const comparator = (lhs: string, rhs: string) => scoreFunction(lhs) - scoreFunction(rhs);
+		this._orderHashByExpirationRBTree = new RBTree(comparator);
+	}
+	public subscribe(callback: (orderHash: string) => void): void {
+		if (!_.isUndefined(this._orderExpirationCheckingIntervalIdIfExists)) {
+			throw new Error(ZeroExError.SubscriptionAlreadyPresent);
+		}
+		this._orderExpirationCheckingIntervalIdIfExists = intervalUtils.setInterval(
+			this._pruneExpiredOrders.bind(this, callback),
+			this._orderExpirationCheckingIntervalMs,
+			_.noop, // _pruneExpiredOrders never throws
+		);
+	}
+	public unsubscribe(): void {
+		if (_.isUndefined(this._orderExpirationCheckingIntervalIdIfExists)) {
+			throw new Error(ZeroExError.SubscriptionNotFound);
+		}
+		intervalUtils.clearInterval(this._orderExpirationCheckingIntervalIdIfExists);
+		delete this._orderExpirationCheckingIntervalIdIfExists;
+	}
+	public addOrder(orderHash: string, expirationUnixTimestampMs: BigNumber): void {
+		this._expiration[orderHash] = expirationUnixTimestampMs;
+		this._orderHashByExpirationRBTree.insert(orderHash);
+	}
+	public removeOrder(orderHash: string): void {
+		this._orderHashByExpirationRBTree.remove(orderHash);
+		delete this._expiration[orderHash];
+	}
+	private _pruneExpiredOrders(callback: (orderHash: string) => void): void {
+		const currentUnixTimestampMs = utils.getCurrentUnixTimestampMs();
+		while (true) {
+			const hasTrakedOrders = this._orderHashByExpirationRBTree.size === 0;
+			if (hasTrakedOrders) {
+				break;
+			}
+			const nextOrderHashToExpire = this._orderHashByExpirationRBTree.min();
+			const hasNoExpiredOrders = this._expiration[nextOrderHashToExpire].greaterThan(
+				currentUnixTimestampMs.plus(this._expirationMarginMs),
+			);
+			const isSubscriptionActive = _.isUndefined(this._orderExpirationCheckingIntervalIdIfExists);
+			if (hasNoExpiredOrders || isSubscriptionActive) {
+				break;
+			}
+			const orderHash = this._orderHashByExpirationRBTree.min();
+			this._orderHashByExpirationRBTree.remove(orderHash);
+			delete this._expiration[orderHash];
+			callback(orderHash);
+		}
+	}
 }
diff --git a/packages/0x.js/src/order_watcher/order_state_watcher.ts b/packages/0x.js/src/order_watcher/order_state_watcher.ts
index 12ac60960..2c5da6b57 100644
--- a/packages/0x.js/src/order_watcher/order_state_watcher.ts
+++ b/packages/0x.js/src/order_watcher/order_state_watcher.ts
@@ -9,25 +9,25 @@ import { TokenWrapper } from '../contract_wrappers/token_wrapper';
 import { BalanceAndProxyAllowanceLazyStore } from '../stores/balance_proxy_allowance_lazy_store';
 import { OrderFilledCancelledLazyStore } from '../stores/order_filled_cancelled_lazy_store';
 import {
-    ApprovalContractEventArgs,
-    BlockParamLiteral,
-    ContractEventArgs,
-    DepositContractEventArgs,
-    EtherTokenEvents,
-    ExchangeContractErrs,
-    ExchangeEvents,
-    LogCancelContractEventArgs,
-    LogEvent,
-    LogFillContractEventArgs,
-    LogWithDecodedArgs,
-    OnOrderStateChangeCallback,
-    OrderState,
-    OrderStateWatcherConfig,
-    SignedOrder,
-    TokenEvents,
-    TransferContractEventArgs,
-    WithdrawalContractEventArgs,
-    ZeroExError,
+	ApprovalContractEventArgs,
+	BlockParamLiteral,
+	ContractEventArgs,
+	DepositContractEventArgs,
+	EtherTokenEvents,
+	ExchangeContractErrs,
+	ExchangeEvents,
+	LogCancelContractEventArgs,
+	LogEvent,
+	LogFillContractEventArgs,
+	LogWithDecodedArgs,
+	OnOrderStateChangeCallback,
+	OrderState,
+	OrderStateWatcherConfig,
+	SignedOrder,
+	TokenEvents,
+	TransferContractEventArgs,
+	WithdrawalContractEventArgs,
+	ZeroExError,
 } from '../types';
 import { AbiDecoder } from '../utils/abi_decoder';
 import { assert } from '../utils/assert';
@@ -38,17 +38,17 @@ import { EventWatcher } from './event_watcher';
 import { ExpirationWatcher } from './expiration_watcher';
 
 interface DependentOrderHashes {
-    [makerAddress: string]: {
-        [makerToken: string]: Set<string>;
-    };
+	[makerAddress: string]: {
+		[makerToken: string]: Set<string>;
+	};
 }
 
 interface OrderByOrderHash {
-    [orderHash: string]: SignedOrder;
+	[orderHash: string]: SignedOrder;
 }
 
 interface OrderStateByOrderHash {
-    [orderHash: string]: OrderState;
+	[orderHash: string]: OrderState;
 }
 
 const DEFAULT_CLEANUP_JOB_INTERVAL_MS = 1000 * 60 * 60; // 1h
@@ -60,319 +60,319 @@ const DEFAULT_CLEANUP_JOB_INTERVAL_MS = 1000 * 60 * 60; // 1h
  * the order should be deemed invalid.
  */
 export class OrderStateWatcher {
-    private _orderStateByOrderHashCache: OrderStateByOrderHash = {};
-    private _orderByOrderHash: OrderByOrderHash = {};
-    private _dependentOrderHashes: DependentOrderHashes = {};
-    private _callbackIfExists?: OnOrderStateChangeCallback;
-    private _eventWatcher: EventWatcher;
-    private _web3Wrapper: Web3Wrapper;
-    private _abiDecoder: AbiDecoder;
-    private _expirationWatcher: ExpirationWatcher;
-    private _orderStateUtils: OrderStateUtils;
-    private _orderFilledCancelledLazyStore: OrderFilledCancelledLazyStore;
-    private _balanceAndProxyAllowanceLazyStore: BalanceAndProxyAllowanceLazyStore;
-    private _cleanupJobInterval: number;
-    private _cleanupJobIntervalIdIfExists?: NodeJS.Timer;
-    constructor(
-        web3Wrapper: Web3Wrapper,
-        abiDecoder: AbiDecoder,
-        token: TokenWrapper,
-        exchange: ExchangeWrapper,
-        config?: OrderStateWatcherConfig,
-    ) {
-        this._abiDecoder = abiDecoder;
-        this._web3Wrapper = web3Wrapper;
-        const pollingIntervalIfExistsMs = _.isUndefined(config) ? undefined : config.eventPollingIntervalMs;
-        this._eventWatcher = new EventWatcher(web3Wrapper, pollingIntervalIfExistsMs);
-        this._balanceAndProxyAllowanceLazyStore = new BalanceAndProxyAllowanceLazyStore(
-            token,
-            BlockParamLiteral.Pending,
-        );
-        this._orderFilledCancelledLazyStore = new OrderFilledCancelledLazyStore(exchange);
-        this._orderStateUtils = new OrderStateUtils(
-            this._balanceAndProxyAllowanceLazyStore,
-            this._orderFilledCancelledLazyStore,
-        );
-        const orderExpirationCheckingIntervalMsIfExists = _.isUndefined(config)
-            ? undefined
-            : config.orderExpirationCheckingIntervalMs;
-        const expirationMarginIfExistsMs = _.isUndefined(config) ? undefined : config.expirationMarginMs;
-        this._expirationWatcher = new ExpirationWatcher(
-            expirationMarginIfExistsMs,
-            orderExpirationCheckingIntervalMsIfExists,
-        );
-        this._cleanupJobInterval =
-            _.isUndefined(config) || _.isUndefined(config.cleanupJobIntervalMs)
-                ? DEFAULT_CLEANUP_JOB_INTERVAL_MS
-                : config.cleanupJobIntervalMs;
-    }
-    /**
-     * 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);
-        const expirationUnixTimestampMs = signedOrder.expirationUnixTimestampSec.times(1000);
-        this._expirationWatcher.addOrder(orderHash, expirationUnixTimestampMs);
-    }
-    /**
-     * 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];
-        delete this._orderStateByOrderHashCache[orderHash];
-        const exchange = (this._orderFilledCancelledLazyStore as any)._exchange as ExchangeWrapper;
-        const zrxTokenAddress = exchange.getZRXTokenAddress();
-        this._removeFromDependentOrderHashes(signedOrder.maker, zrxTokenAddress, orderHash);
-        this._removeFromDependentOrderHashes(signedOrder.maker, signedOrder.makerTokenAddress, orderHash);
-        this._expirationWatcher.removeOrder(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._callbackIfExists)) {
-            throw new Error(ZeroExError.SubscriptionAlreadyPresent);
-        }
-        this._callbackIfExists = callback;
-        this._eventWatcher.subscribe(this._onEventWatcherCallbackAsync.bind(this));
-        this._expirationWatcher.subscribe(this._onOrderExpired.bind(this));
-        this._cleanupJobIntervalIdIfExists = intervalUtils.setAsyncExcludingInterval(
-            this._cleanupAsync.bind(this),
-            this._cleanupJobInterval,
-            (err: Error) => {
-                this.unsubscribe();
-                callback(err);
-            },
-        );
-    }
-    /**
-     * Ends an orderStateWatcher subscription.
-     */
-    public unsubscribe(): void {
-        if (_.isUndefined(this._callbackIfExists) || _.isUndefined(this._cleanupJobIntervalIdIfExists)) {
-            throw new Error(ZeroExError.SubscriptionNotFound);
-        }
-        this._balanceAndProxyAllowanceLazyStore.deleteAll();
-        this._orderFilledCancelledLazyStore.deleteAll();
-        delete this._callbackIfExists;
-        this._eventWatcher.unsubscribe();
-        this._expirationWatcher.unsubscribe();
-        intervalUtils.clearAsyncExcludingInterval(this._cleanupJobIntervalIdIfExists);
-    }
-    private async _cleanupAsync(): Promise<void> {
-        for (const orderHash of _.keys(this._orderByOrderHash)) {
-            this._cleanupOrderRelatedState(orderHash);
-            await this._emitRevalidateOrdersAsync([orderHash]);
-        }
-    }
-    private _cleanupOrderRelatedState(orderHash: string): void {
-        const signedOrder = this._orderByOrderHash[orderHash];
+	private _orderStateByOrderHashCache: OrderStateByOrderHash = {};
+	private _orderByOrderHash: OrderByOrderHash = {};
+	private _dependentOrderHashes: DependentOrderHashes = {};
+	private _callbackIfExists?: OnOrderStateChangeCallback;
+	private _eventWatcher: EventWatcher;
+	private _web3Wrapper: Web3Wrapper;
+	private _abiDecoder: AbiDecoder;
+	private _expirationWatcher: ExpirationWatcher;
+	private _orderStateUtils: OrderStateUtils;
+	private _orderFilledCancelledLazyStore: OrderFilledCancelledLazyStore;
+	private _balanceAndProxyAllowanceLazyStore: BalanceAndProxyAllowanceLazyStore;
+	private _cleanupJobInterval: number;
+	private _cleanupJobIntervalIdIfExists?: NodeJS.Timer;
+	constructor(
+		web3Wrapper: Web3Wrapper,
+		abiDecoder: AbiDecoder,
+		token: TokenWrapper,
+		exchange: ExchangeWrapper,
+		config?: OrderStateWatcherConfig,
+	) {
+		this._abiDecoder = abiDecoder;
+		this._web3Wrapper = web3Wrapper;
+		const pollingIntervalIfExistsMs = _.isUndefined(config) ? undefined : config.eventPollingIntervalMs;
+		this._eventWatcher = new EventWatcher(web3Wrapper, pollingIntervalIfExistsMs);
+		this._balanceAndProxyAllowanceLazyStore = new BalanceAndProxyAllowanceLazyStore(
+			token,
+			BlockParamLiteral.Pending,
+		);
+		this._orderFilledCancelledLazyStore = new OrderFilledCancelledLazyStore(exchange);
+		this._orderStateUtils = new OrderStateUtils(
+			this._balanceAndProxyAllowanceLazyStore,
+			this._orderFilledCancelledLazyStore,
+		);
+		const orderExpirationCheckingIntervalMsIfExists = _.isUndefined(config)
+			? undefined
+			: config.orderExpirationCheckingIntervalMs;
+		const expirationMarginIfExistsMs = _.isUndefined(config) ? undefined : config.expirationMarginMs;
+		this._expirationWatcher = new ExpirationWatcher(
+			expirationMarginIfExistsMs,
+			orderExpirationCheckingIntervalMsIfExists,
+		);
+		this._cleanupJobInterval =
+			_.isUndefined(config) || _.isUndefined(config.cleanupJobIntervalMs)
+				? DEFAULT_CLEANUP_JOB_INTERVAL_MS
+				: config.cleanupJobIntervalMs;
+	}
+	/**
+	 * 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);
+		const expirationUnixTimestampMs = signedOrder.expirationUnixTimestampSec.times(1000);
+		this._expirationWatcher.addOrder(orderHash, expirationUnixTimestampMs);
+	}
+	/**
+	 * 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];
+		delete this._orderStateByOrderHashCache[orderHash];
+		const exchange = (this._orderFilledCancelledLazyStore as any)._exchange as ExchangeWrapper;
+		const zrxTokenAddress = exchange.getZRXTokenAddress();
+		this._removeFromDependentOrderHashes(signedOrder.maker, zrxTokenAddress, orderHash);
+		this._removeFromDependentOrderHashes(signedOrder.maker, signedOrder.makerTokenAddress, orderHash);
+		this._expirationWatcher.removeOrder(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._callbackIfExists)) {
+			throw new Error(ZeroExError.SubscriptionAlreadyPresent);
+		}
+		this._callbackIfExists = callback;
+		this._eventWatcher.subscribe(this._onEventWatcherCallbackAsync.bind(this));
+		this._expirationWatcher.subscribe(this._onOrderExpired.bind(this));
+		this._cleanupJobIntervalIdIfExists = intervalUtils.setAsyncExcludingInterval(
+			this._cleanupAsync.bind(this),
+			this._cleanupJobInterval,
+			(err: Error) => {
+				this.unsubscribe();
+				callback(err);
+			},
+		);
+	}
+	/**
+	 * Ends an orderStateWatcher subscription.
+	 */
+	public unsubscribe(): void {
+		if (_.isUndefined(this._callbackIfExists) || _.isUndefined(this._cleanupJobIntervalIdIfExists)) {
+			throw new Error(ZeroExError.SubscriptionNotFound);
+		}
+		this._balanceAndProxyAllowanceLazyStore.deleteAll();
+		this._orderFilledCancelledLazyStore.deleteAll();
+		delete this._callbackIfExists;
+		this._eventWatcher.unsubscribe();
+		this._expirationWatcher.unsubscribe();
+		intervalUtils.clearAsyncExcludingInterval(this._cleanupJobIntervalIdIfExists);
+	}
+	private async _cleanupAsync(): Promise<void> {
+		for (const orderHash of _.keys(this._orderByOrderHash)) {
+			this._cleanupOrderRelatedState(orderHash);
+			await this._emitRevalidateOrdersAsync([orderHash]);
+		}
+	}
+	private _cleanupOrderRelatedState(orderHash: string): void {
+		const signedOrder = this._orderByOrderHash[orderHash];
 
-        this._orderFilledCancelledLazyStore.deleteFilledTakerAmount(orderHash);
-        this._orderFilledCancelledLazyStore.deleteCancelledTakerAmount(orderHash);
+		this._orderFilledCancelledLazyStore.deleteFilledTakerAmount(orderHash);
+		this._orderFilledCancelledLazyStore.deleteCancelledTakerAmount(orderHash);
 
-        this._balanceAndProxyAllowanceLazyStore.deleteBalance(signedOrder.makerTokenAddress, signedOrder.maker);
-        this._balanceAndProxyAllowanceLazyStore.deleteProxyAllowance(signedOrder.makerTokenAddress, signedOrder.maker);
-        this._balanceAndProxyAllowanceLazyStore.deleteBalance(signedOrder.takerTokenAddress, signedOrder.taker);
-        this._balanceAndProxyAllowanceLazyStore.deleteProxyAllowance(signedOrder.takerTokenAddress, signedOrder.taker);
+		this._balanceAndProxyAllowanceLazyStore.deleteBalance(signedOrder.makerTokenAddress, signedOrder.maker);
+		this._balanceAndProxyAllowanceLazyStore.deleteProxyAllowance(signedOrder.makerTokenAddress, signedOrder.maker);
+		this._balanceAndProxyAllowanceLazyStore.deleteBalance(signedOrder.takerTokenAddress, signedOrder.taker);
+		this._balanceAndProxyAllowanceLazyStore.deleteProxyAllowance(signedOrder.takerTokenAddress, signedOrder.taker);
 
-        const zrxTokenAddress = this._getZRXTokenAddress();
-        if (!signedOrder.makerFee.isZero()) {
-            this._balanceAndProxyAllowanceLazyStore.deleteBalance(zrxTokenAddress, signedOrder.maker);
-            this._balanceAndProxyAllowanceLazyStore.deleteProxyAllowance(zrxTokenAddress, signedOrder.maker);
-        }
-        if (!signedOrder.takerFee.isZero()) {
-            this._balanceAndProxyAllowanceLazyStore.deleteBalance(zrxTokenAddress, signedOrder.taker);
-            this._balanceAndProxyAllowanceLazyStore.deleteProxyAllowance(zrxTokenAddress, signedOrder.taker);
-        }
-    }
-    private _onOrderExpired(orderHash: string): void {
-        const orderState: OrderState = {
-            isValid: false,
-            orderHash,
-            error: ExchangeContractErrs.OrderFillExpired,
-        };
-        if (!_.isUndefined(this._orderByOrderHash[orderHash])) {
-            this.removeOrder(orderHash);
-            if (!_.isUndefined(this._callbackIfExists)) {
-                this._callbackIfExists(null, orderState);
-            }
-        }
-    }
-    private async _onEventWatcherCallbackAsync(err: Error | null, logIfExists?: LogEvent): Promise<void> {
-        if (!_.isNull(err)) {
-            if (!_.isUndefined(this._callbackIfExists)) {
-                this._callbackIfExists(err);
-                this.unsubscribe();
-            }
-            return;
-        }
-        const log = logIfExists as LogEvent; // At this moment we are sure that no error occured and log is defined.
-        const maybeDecodedLog = this._abiDecoder.tryToDecodeLogOrNoop(log);
-        const isLogDecoded = !_.isUndefined((maybeDecodedLog as LogWithDecodedArgs<any>).event);
-        if (!isLogDecoded) {
-            return; // noop
-        }
-        const decodedLog = maybeDecodedLog as LogWithDecodedArgs<ContractEventArgs>;
-        let makerToken: string;
-        let makerAddress: string;
-        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;
-                if (
-                    !_.isUndefined(this._dependentOrderHashes[makerAddress]) &&
-                    !_.isUndefined(this._dependentOrderHashes[makerAddress][makerToken])
-                ) {
-                    const orderHashes = Array.from(this._dependentOrderHashes[makerAddress][makerToken]);
-                    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;
-                if (
-                    !_.isUndefined(this._dependentOrderHashes[makerAddress]) &&
-                    !_.isUndefined(this._dependentOrderHashes[makerAddress][makerToken])
-                ) {
-                    const orderHashes = Array.from(this._dependentOrderHashes[makerAddress][makerToken]);
-                    await this._emitRevalidateOrdersAsync(orderHashes);
-                }
-                break;
-            }
-            case EtherTokenEvents.Deposit: {
-                // Invalidate cache
-                const args = decodedLog.args as DepositContractEventArgs;
-                this._balanceAndProxyAllowanceLazyStore.deleteBalance(decodedLog.address, args._owner);
-                // Revalidate orders
-                makerToken = decodedLog.address;
-                makerAddress = args._owner;
-                if (
-                    !_.isUndefined(this._dependentOrderHashes[makerAddress]) &&
-                    !_.isUndefined(this._dependentOrderHashes[makerAddress][makerToken])
-                ) {
-                    const orderHashes = Array.from(this._dependentOrderHashes[makerAddress][makerToken]);
-                    await this._emitRevalidateOrdersAsync(orderHashes);
-                }
-                break;
-            }
-            case EtherTokenEvents.Withdrawal: {
-                // Invalidate cache
-                const args = decodedLog.args as WithdrawalContractEventArgs;
-                this._balanceAndProxyAllowanceLazyStore.deleteBalance(decodedLog.address, args._owner);
-                // Revalidate orders
-                makerToken = decodedLog.address;
-                makerAddress = args._owner;
-                if (
-                    !_.isUndefined(this._dependentOrderHashes[makerAddress]) &&
-                    !_.isUndefined(this._dependentOrderHashes[makerAddress][makerToken])
-                ) {
-                    const orderHashes = Array.from(this._dependentOrderHashes[makerAddress][makerToken]);
-                    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
+		const zrxTokenAddress = this._getZRXTokenAddress();
+		if (!signedOrder.makerFee.isZero()) {
+			this._balanceAndProxyAllowanceLazyStore.deleteBalance(zrxTokenAddress, signedOrder.maker);
+			this._balanceAndProxyAllowanceLazyStore.deleteProxyAllowance(zrxTokenAddress, signedOrder.maker);
+		}
+		if (!signedOrder.takerFee.isZero()) {
+			this._balanceAndProxyAllowanceLazyStore.deleteBalance(zrxTokenAddress, signedOrder.taker);
+			this._balanceAndProxyAllowanceLazyStore.deleteProxyAllowance(zrxTokenAddress, signedOrder.taker);
+		}
+	}
+	private _onOrderExpired(orderHash: string): void {
+		const orderState: OrderState = {
+			isValid: false,
+			orderHash,
+			error: ExchangeContractErrs.OrderFillExpired,
+		};
+		if (!_.isUndefined(this._orderByOrderHash[orderHash])) {
+			this.removeOrder(orderHash);
+			if (!_.isUndefined(this._callbackIfExists)) {
+				this._callbackIfExists(null, orderState);
+			}
+		}
+	}
+	private async _onEventWatcherCallbackAsync(err: Error | null, logIfExists?: LogEvent): Promise<void> {
+		if (!_.isNull(err)) {
+			if (!_.isUndefined(this._callbackIfExists)) {
+				this._callbackIfExists(err);
+				this.unsubscribe();
+			}
+			return;
+		}
+		const log = logIfExists as LogEvent; // At this moment we are sure that no error occured and log is defined.
+		const maybeDecodedLog = this._abiDecoder.tryToDecodeLogOrNoop(log);
+		const isLogDecoded = !_.isUndefined((maybeDecodedLog as LogWithDecodedArgs<any>).event);
+		if (!isLogDecoded) {
+			return; // noop
+		}
+		const decodedLog = maybeDecodedLog as LogWithDecodedArgs<ContractEventArgs>;
+		let makerToken: string;
+		let makerAddress: string;
+		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;
+				if (
+					!_.isUndefined(this._dependentOrderHashes[makerAddress]) &&
+					!_.isUndefined(this._dependentOrderHashes[makerAddress][makerToken])
+				) {
+					const orderHashes = Array.from(this._dependentOrderHashes[makerAddress][makerToken]);
+					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;
+				if (
+					!_.isUndefined(this._dependentOrderHashes[makerAddress]) &&
+					!_.isUndefined(this._dependentOrderHashes[makerAddress][makerToken])
+				) {
+					const orderHashes = Array.from(this._dependentOrderHashes[makerAddress][makerToken]);
+					await this._emitRevalidateOrdersAsync(orderHashes);
+				}
+				break;
+			}
+			case EtherTokenEvents.Deposit: {
+				// Invalidate cache
+				const args = decodedLog.args as DepositContractEventArgs;
+				this._balanceAndProxyAllowanceLazyStore.deleteBalance(decodedLog.address, args._owner);
+				// Revalidate orders
+				makerToken = decodedLog.address;
+				makerAddress = args._owner;
+				if (
+					!_.isUndefined(this._dependentOrderHashes[makerAddress]) &&
+					!_.isUndefined(this._dependentOrderHashes[makerAddress][makerToken])
+				) {
+					const orderHashes = Array.from(this._dependentOrderHashes[makerAddress][makerToken]);
+					await this._emitRevalidateOrdersAsync(orderHashes);
+				}
+				break;
+			}
+			case EtherTokenEvents.Withdrawal: {
+				// Invalidate cache
+				const args = decodedLog.args as WithdrawalContractEventArgs;
+				this._balanceAndProxyAllowanceLazyStore.deleteBalance(decodedLog.address, args._owner);
+				// Revalidate orders
+				makerToken = decodedLog.address;
+				makerAddress = args._owner;
+				if (
+					!_.isUndefined(this._dependentOrderHashes[makerAddress]) &&
+					!_.isUndefined(this._dependentOrderHashes[makerAddress][makerToken])
+				) {
+					const orderHashes = Array.from(this._dependentOrderHashes[makerAddress][makerToken]);
+					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<void> {
-        for (const orderHash of orderHashes) {
-            const signedOrder = this._orderByOrderHash[orderHash];
-            // 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._callbackIfExists)) {
-                break; // Unsubscribe was called
-            }
-            if (_.isEqual(orderState, this._orderStateByOrderHashCache[orderHash])) {
-                // Actual order state didn't change
-                continue;
-            } else {
-                this._orderStateByOrderHashCache[orderHash] = orderState;
-            }
-            this._callbackIfExists(null, orderState);
-        }
-    }
-    private _addToDependentOrderHashes(signedOrder: SignedOrder, orderHash: string): void {
-        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);
-        const zrxTokenAddress = this._getZRXTokenAddress();
-        if (_.isUndefined(this._dependentOrderHashes[signedOrder.maker][zrxTokenAddress])) {
-            this._dependentOrderHashes[signedOrder.maker][zrxTokenAddress] = new Set();
-        }
-        this._dependentOrderHashes[signedOrder.maker][zrxTokenAddress].add(orderHash);
-    }
-    private _removeFromDependentOrderHashes(makerAddress: string, tokenAddress: string, orderHash: string) {
-        this._dependentOrderHashes[makerAddress][tokenAddress].delete(orderHash);
-        if (this._dependentOrderHashes[makerAddress][tokenAddress].size === 0) {
-            delete this._dependentOrderHashes[makerAddress][tokenAddress];
-        }
-        if (_.isEmpty(this._dependentOrderHashes[makerAddress])) {
-            delete this._dependentOrderHashes[makerAddress];
-        }
-    }
-    private _getZRXTokenAddress(): string {
-        const exchange = (this._orderFilledCancelledLazyStore as any)._exchange as ExchangeWrapper;
-        const zrxTokenAddress = exchange.getZRXTokenAddress();
-        return zrxTokenAddress;
-    }
+			default:
+				throw utils.spawnSwitchErr('decodedLog.event', decodedLog.event);
+		}
+	}
+	private async _emitRevalidateOrdersAsync(orderHashes: string[]): Promise<void> {
+		for (const orderHash of orderHashes) {
+			const signedOrder = this._orderByOrderHash[orderHash];
+			// 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._callbackIfExists)) {
+				break; // Unsubscribe was called
+			}
+			if (_.isEqual(orderState, this._orderStateByOrderHashCache[orderHash])) {
+				// Actual order state didn't change
+				continue;
+			} else {
+				this._orderStateByOrderHashCache[orderHash] = orderState;
+			}
+			this._callbackIfExists(null, orderState);
+		}
+	}
+	private _addToDependentOrderHashes(signedOrder: SignedOrder, orderHash: string): void {
+		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);
+		const zrxTokenAddress = this._getZRXTokenAddress();
+		if (_.isUndefined(this._dependentOrderHashes[signedOrder.maker][zrxTokenAddress])) {
+			this._dependentOrderHashes[signedOrder.maker][zrxTokenAddress] = new Set();
+		}
+		this._dependentOrderHashes[signedOrder.maker][zrxTokenAddress].add(orderHash);
+	}
+	private _removeFromDependentOrderHashes(makerAddress: string, tokenAddress: string, orderHash: string) {
+		this._dependentOrderHashes[makerAddress][tokenAddress].delete(orderHash);
+		if (this._dependentOrderHashes[makerAddress][tokenAddress].size === 0) {
+			delete this._dependentOrderHashes[makerAddress][tokenAddress];
+		}
+		if (_.isEmpty(this._dependentOrderHashes[makerAddress])) {
+			delete this._dependentOrderHashes[makerAddress];
+		}
+	}
+	private _getZRXTokenAddress(): string {
+		const exchange = (this._orderFilledCancelledLazyStore as any)._exchange as ExchangeWrapper;
+		const zrxTokenAddress = exchange.getZRXTokenAddress();
+		return zrxTokenAddress;
+	}
 }
diff --git a/packages/0x.js/src/order_watcher/remaining_fillable_calculator.ts b/packages/0x.js/src/order_watcher/remaining_fillable_calculator.ts
index 20b09d606..e010092af 100644
--- a/packages/0x.js/src/order_watcher/remaining_fillable_calculator.ts
+++ b/packages/0x.js/src/order_watcher/remaining_fillable_calculator.ts
@@ -3,94 +3,94 @@ import { BigNumber } from '@0xproject/utils';
 import { SignedOrder } from '../types';
 
 export class RemainingFillableCalculator {
-    private _signedOrder: SignedOrder;
-    private _isMakerTokenZRX: boolean;
-    // Transferrable Amount is the minimum of Approval and Balance
-    private _transferrableMakerTokenAmount: BigNumber;
-    private _transferrableMakerFeeTokenAmount: BigNumber;
-    private _remainingMakerTokenAmount: BigNumber;
-    private _remainingMakerFeeAmount: BigNumber;
-    constructor(
-        signedOrder: SignedOrder,
-        isMakerTokenZRX: boolean,
-        transferrableMakerTokenAmount: BigNumber,
-        transferrableMakerFeeTokenAmount: BigNumber,
-        remainingMakerTokenAmount: BigNumber,
-    ) {
-        this._signedOrder = signedOrder;
-        this._isMakerTokenZRX = isMakerTokenZRX;
-        this._transferrableMakerTokenAmount = transferrableMakerTokenAmount;
-        this._transferrableMakerFeeTokenAmount = transferrableMakerFeeTokenAmount;
-        this._remainingMakerTokenAmount = remainingMakerTokenAmount;
-        this._remainingMakerFeeAmount = remainingMakerTokenAmount
-            .times(signedOrder.makerFee)
-            .dividedToIntegerBy(signedOrder.makerTokenAmount);
-    }
-    public computeRemainingMakerFillable(): BigNumber {
-        if (this._hasSufficientFundsForFeeAndTransferAmount()) {
-            return this._remainingMakerTokenAmount;
-        }
-        if (this._signedOrder.makerFee.isZero()) {
-            return BigNumber.min(this._remainingMakerTokenAmount, this._transferrableMakerTokenAmount);
-        }
-        return this._calculatePartiallyFillableMakerTokenAmount();
-    }
-    public computeRemainingTakerFillable(): BigNumber {
-        return this.computeRemainingMakerFillable()
-            .times(this._signedOrder.takerTokenAmount)
-            .dividedToIntegerBy(this._signedOrder.makerTokenAmount);
-    }
-    private _hasSufficientFundsForFeeAndTransferAmount(): boolean {
-        if (this._isMakerTokenZRX) {
-            const totalZRXTransferAmountRequired = this._remainingMakerTokenAmount.plus(this._remainingMakerFeeAmount);
-            const hasSufficientFunds = this._transferrableMakerTokenAmount.greaterThanOrEqualTo(
-                totalZRXTransferAmountRequired,
-            );
-            return hasSufficientFunds;
-        } else {
-            const hasSufficientFundsForTransferAmount = this._transferrableMakerTokenAmount.greaterThanOrEqualTo(
-                this._remainingMakerTokenAmount,
-            );
-            const hasSufficientFundsForFeeAmount = this._transferrableMakerFeeTokenAmount.greaterThanOrEqualTo(
-                this._remainingMakerFeeAmount,
-            );
-            const hasSufficientFunds = hasSufficientFundsForTransferAmount && hasSufficientFundsForFeeAmount;
-            return hasSufficientFunds;
-        }
-    }
-    private _calculatePartiallyFillableMakerTokenAmount(): BigNumber {
-        // Given an order for 200 wei for 2 ZRXwei fee, find 100 wei for 1 ZRXwei. Order ratio is then 100:1
-        const orderToFeeRatio = this._signedOrder.makerTokenAmount.dividedBy(this._signedOrder.makerFee);
-        // The number of times the maker can fill the order, if each fill only required the transfer of a single
-        // baseUnit of fee tokens.
-        // Given 2 ZRXwei, the maximum amount of times Maker can fill this order, in terms of fees, is 2
-        const fillableTimesInFeeTokenBaseUnits = BigNumber.min(
-            this._transferrableMakerFeeTokenAmount,
-            this._remainingMakerFeeAmount,
-        );
-        // The number of times the Maker can fill the order, given the Maker Token Balance
-        // Assuming a balance of 150 wei, and an orderToFeeRatio of 100:1, maker can fill this order 1 time.
-        let fillableTimesInMakerTokenUnits = this._transferrableMakerTokenAmount.dividedBy(orderToFeeRatio);
-        if (this._isMakerTokenZRX) {
-            // If ZRX is the maker token, the Fee and the Maker amount need to be removed from the same pool;
-            // 200 ZRXwei for 2ZRXwei fee can only be filled once (need 202 ZRXwei)
-            const totalZRXTokenPooled = this._transferrableMakerTokenAmount;
-            // The purchasing power here is less as the tokens are taken from the same Pool
-            // For every one number of fills, we have to take an extra ZRX out of the pool
-            fillableTimesInMakerTokenUnits = totalZRXTokenPooled.dividedBy(orderToFeeRatio.plus(new BigNumber(1)));
-        }
-        // When Ratio is not fully divisible there can be remainders which cannot be represented, so they are floored.
-        // This can result in a RoundingError being thrown by the Exchange Contract.
-        const partiallyFillableMakerTokenAmount = fillableTimesInMakerTokenUnits
-            .times(this._signedOrder.makerTokenAmount)
-            .dividedToIntegerBy(this._signedOrder.makerFee);
-        const partiallyFillableFeeTokenAmount = fillableTimesInFeeTokenBaseUnits
-            .times(this._signedOrder.makerTokenAmount)
-            .dividedToIntegerBy(this._signedOrder.makerFee);
-        const partiallyFillableAmount = BigNumber.min(
-            partiallyFillableMakerTokenAmount,
-            partiallyFillableFeeTokenAmount,
-        );
-        return partiallyFillableAmount;
-    }
+	private _signedOrder: SignedOrder;
+	private _isMakerTokenZRX: boolean;
+	// Transferrable Amount is the minimum of Approval and Balance
+	private _transferrableMakerTokenAmount: BigNumber;
+	private _transferrableMakerFeeTokenAmount: BigNumber;
+	private _remainingMakerTokenAmount: BigNumber;
+	private _remainingMakerFeeAmount: BigNumber;
+	constructor(
+		signedOrder: SignedOrder,
+		isMakerTokenZRX: boolean,
+		transferrableMakerTokenAmount: BigNumber,
+		transferrableMakerFeeTokenAmount: BigNumber,
+		remainingMakerTokenAmount: BigNumber,
+	) {
+		this._signedOrder = signedOrder;
+		this._isMakerTokenZRX = isMakerTokenZRX;
+		this._transferrableMakerTokenAmount = transferrableMakerTokenAmount;
+		this._transferrableMakerFeeTokenAmount = transferrableMakerFeeTokenAmount;
+		this._remainingMakerTokenAmount = remainingMakerTokenAmount;
+		this._remainingMakerFeeAmount = remainingMakerTokenAmount
+			.times(signedOrder.makerFee)
+			.dividedToIntegerBy(signedOrder.makerTokenAmount);
+	}
+	public computeRemainingMakerFillable(): BigNumber {
+		if (this._hasSufficientFundsForFeeAndTransferAmount()) {
+			return this._remainingMakerTokenAmount;
+		}
+		if (this._signedOrder.makerFee.isZero()) {
+			return BigNumber.min(this._remainingMakerTokenAmount, this._transferrableMakerTokenAmount);
+		}
+		return this._calculatePartiallyFillableMakerTokenAmount();
+	}
+	public computeRemainingTakerFillable(): BigNumber {
+		return this.computeRemainingMakerFillable()
+			.times(this._signedOrder.takerTokenAmount)
+			.dividedToIntegerBy(this._signedOrder.makerTokenAmount);
+	}
+	private _hasSufficientFundsForFeeAndTransferAmount(): boolean {
+		if (this._isMakerTokenZRX) {
+			const totalZRXTransferAmountRequired = this._remainingMakerTokenAmount.plus(this._remainingMakerFeeAmount);
+			const hasSufficientFunds = this._transferrableMakerTokenAmount.greaterThanOrEqualTo(
+				totalZRXTransferAmountRequired,
+			);
+			return hasSufficientFunds;
+		} else {
+			const hasSufficientFundsForTransferAmount = this._transferrableMakerTokenAmount.greaterThanOrEqualTo(
+				this._remainingMakerTokenAmount,
+			);
+			const hasSufficientFundsForFeeAmount = this._transferrableMakerFeeTokenAmount.greaterThanOrEqualTo(
+				this._remainingMakerFeeAmount,
+			);
+			const hasSufficientFunds = hasSufficientFundsForTransferAmount && hasSufficientFundsForFeeAmount;
+			return hasSufficientFunds;
+		}
+	}
+	private _calculatePartiallyFillableMakerTokenAmount(): BigNumber {
+		// Given an order for 200 wei for 2 ZRXwei fee, find 100 wei for 1 ZRXwei. Order ratio is then 100:1
+		const orderToFeeRatio = this._signedOrder.makerTokenAmount.dividedBy(this._signedOrder.makerFee);
+		// The number of times the maker can fill the order, if each fill only required the transfer of a single
+		// baseUnit of fee tokens.
+		// Given 2 ZRXwei, the maximum amount of times Maker can fill this order, in terms of fees, is 2
+		const fillableTimesInFeeTokenBaseUnits = BigNumber.min(
+			this._transferrableMakerFeeTokenAmount,
+			this._remainingMakerFeeAmount,
+		);
+		// The number of times the Maker can fill the order, given the Maker Token Balance
+		// Assuming a balance of 150 wei, and an orderToFeeRatio of 100:1, maker can fill this order 1 time.
+		let fillableTimesInMakerTokenUnits = this._transferrableMakerTokenAmount.dividedBy(orderToFeeRatio);
+		if (this._isMakerTokenZRX) {
+			// If ZRX is the maker token, the Fee and the Maker amount need to be removed from the same pool;
+			// 200 ZRXwei for 2ZRXwei fee can only be filled once (need 202 ZRXwei)
+			const totalZRXTokenPooled = this._transferrableMakerTokenAmount;
+			// The purchasing power here is less as the tokens are taken from the same Pool
+			// For every one number of fills, we have to take an extra ZRX out of the pool
+			fillableTimesInMakerTokenUnits = totalZRXTokenPooled.dividedBy(orderToFeeRatio.plus(new BigNumber(1)));
+		}
+		// When Ratio is not fully divisible there can be remainders which cannot be represented, so they are floored.
+		// This can result in a RoundingError being thrown by the Exchange Contract.
+		const partiallyFillableMakerTokenAmount = fillableTimesInMakerTokenUnits
+			.times(this._signedOrder.makerTokenAmount)
+			.dividedToIntegerBy(this._signedOrder.makerFee);
+		const partiallyFillableFeeTokenAmount = fillableTimesInFeeTokenBaseUnits
+			.times(this._signedOrder.makerTokenAmount)
+			.dividedToIntegerBy(this._signedOrder.makerFee);
+		const partiallyFillableAmount = BigNumber.min(
+			partiallyFillableMakerTokenAmount,
+			partiallyFillableFeeTokenAmount,
+		);
+		return partiallyFillableAmount;
+	}
 }
diff --git a/packages/0x.js/src/schemas/zero_ex_config_schema.ts b/packages/0x.js/src/schemas/zero_ex_config_schema.ts
index 546b1c2d0..657b24c58 100644
--- a/packages/0x.js/src/schemas/zero_ex_config_schema.ts
+++ b/packages/0x.js/src/schemas/zero_ex_config_schema.ts
@@ -1,27 +1,27 @@
 export const zeroExConfigSchema = {
-    id: '/ZeroExConfig',
-    properties: {
-        networkId: {
-            type: 'number',
-            minimum: 0,
-        },
-        gasPrice: { $ref: '/Number' },
-        exchangeContractAddress: { $ref: '/Address' },
-        tokenRegistryContractAddress: { $ref: '/Address' },
-        orderWatcherConfig: {
-            type: 'object',
-            properties: {
-                pollingIntervalMs: {
-                    type: 'number',
-                    minimum: 0,
-                },
-                numConfirmations: {
-                    type: 'number',
-                    minimum: 0,
-                },
-            },
-        },
-    },
-    type: 'object',
-    required: ['networkId'],
+	id: '/ZeroExConfig',
+	properties: {
+		networkId: {
+			type: 'number',
+			minimum: 0,
+		},
+		gasPrice: { $ref: '/Number' },
+		exchangeContractAddress: { $ref: '/Address' },
+		tokenRegistryContractAddress: { $ref: '/Address' },
+		orderWatcherConfig: {
+			type: 'object',
+			properties: {
+				pollingIntervalMs: {
+					type: 'number',
+					minimum: 0,
+				},
+				numConfirmations: {
+					type: 'number',
+					minimum: 0,
+				},
+			},
+		},
+	},
+	type: 'object',
+	required: ['networkId'],
 };
diff --git a/packages/0x.js/src/stores/balance_proxy_allowance_lazy_store.ts b/packages/0x.js/src/stores/balance_proxy_allowance_lazy_store.ts
index 33feea105..379afa4bc 100644
--- a/packages/0x.js/src/stores/balance_proxy_allowance_lazy_store.ts
+++ b/packages/0x.js/src/stores/balance_proxy_allowance_lazy_store.ts
@@ -8,79 +8,79 @@ import { BlockParamLiteral } from '../types';
  * Copy on read store for balances/proxyAllowances of tokens/accounts
  */
 export class BalanceAndProxyAllowanceLazyStore {
-    private _token: TokenWrapper;
-    private _defaultBlock: BlockParamLiteral;
-    private _balance: {
-        [tokenAddress: string]: {
-            [userAddress: string]: BigNumber;
-        };
-    };
-    private _proxyAllowance: {
-        [tokenAddress: string]: {
-            [userAddress: string]: BigNumber;
-        };
-    };
-    constructor(token: TokenWrapper, defaultBlock: BlockParamLiteral) {
-        this._token = token;
-        this._defaultBlock = defaultBlock;
-        this._balance = {};
-        this._proxyAllowance = {};
-    }
-    public async getBalanceAsync(tokenAddress: string, userAddress: string): Promise<BigNumber> {
-        if (_.isUndefined(this._balance[tokenAddress]) || _.isUndefined(this._balance[tokenAddress][userAddress])) {
-            const methodOpts = {
-                defaultBlock: this._defaultBlock,
-            };
-            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<BigNumber> {
-        if (
-            _.isUndefined(this._proxyAllowance[tokenAddress]) ||
-            _.isUndefined(this._proxyAllowance[tokenAddress][userAddress])
-        ) {
-            const methodOpts = {
-                defaultBlock: this._defaultBlock,
-            };
-            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 = {};
-    }
+	private _token: TokenWrapper;
+	private _defaultBlock: BlockParamLiteral;
+	private _balance: {
+		[tokenAddress: string]: {
+			[userAddress: string]: BigNumber;
+		};
+	};
+	private _proxyAllowance: {
+		[tokenAddress: string]: {
+			[userAddress: string]: BigNumber;
+		};
+	};
+	constructor(token: TokenWrapper, defaultBlock: BlockParamLiteral) {
+		this._token = token;
+		this._defaultBlock = defaultBlock;
+		this._balance = {};
+		this._proxyAllowance = {};
+	}
+	public async getBalanceAsync(tokenAddress: string, userAddress: string): Promise<BigNumber> {
+		if (_.isUndefined(this._balance[tokenAddress]) || _.isUndefined(this._balance[tokenAddress][userAddress])) {
+			const methodOpts = {
+				defaultBlock: this._defaultBlock,
+			};
+			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<BigNumber> {
+		if (
+			_.isUndefined(this._proxyAllowance[tokenAddress]) ||
+			_.isUndefined(this._proxyAllowance[tokenAddress][userAddress])
+		) {
+			const methodOpts = {
+				defaultBlock: this._defaultBlock,
+			};
+			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/packages/0x.js/src/stores/order_filled_cancelled_lazy_store.ts b/packages/0x.js/src/stores/order_filled_cancelled_lazy_store.ts
index e22364c09..a99db0702 100644
--- a/packages/0x.js/src/stores/order_filled_cancelled_lazy_store.ts
+++ b/packages/0x.js/src/stores/order_filled_cancelled_lazy_store.ts
@@ -8,54 +8,54 @@ 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<BigNumber> {
-        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<BigNumber> {
-        if (_.isUndefined(this._cancelledTakerAmount[orderHash])) {
-            const methodOpts = {
-                defaultBlock: BlockParamLiteral.Pending,
-            };
-            const cancelledTakerAmount = await this._exchange.getCancelledTakerAmountAsync(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 = {};
-    }
+	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<BigNumber> {
+		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<BigNumber> {
+		if (_.isUndefined(this._cancelledTakerAmount[orderHash])) {
+			const methodOpts = {
+				defaultBlock: BlockParamLiteral.Pending,
+			};
+			const cancelledTakerAmount = await this._exchange.getCancelledTakerAmountAsync(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/packages/0x.js/src/types.ts b/packages/0x.js/src/types.ts
index 3c93910e9..7eda4bea6 100644
--- a/packages/0x.js/src/types.ts
+++ b/packages/0x.js/src/types.ts
@@ -3,41 +3,41 @@ import { BigNumber } from '@0xproject/utils';
 import * as Web3 from 'web3';
 
 export enum ZeroExError {
-    ExchangeContractDoesNotExist = 'EXCHANGE_CONTRACT_DOES_NOT_EXIST',
-    ZRXContractDoesNotExist = 'ZRX_CONTRACT_DOES_NOT_EXIST',
-    EtherTokenContractDoesNotExist = 'ETHER_TOKEN_CONTRACT_DOES_NOT_EXIST',
-    TokenTransferProxyContractDoesNotExist = 'TOKEN_TRANSFER_PROXY_CONTRACT_DOES_NOT_EXIST',
-    TokenRegistryContractDoesNotExist = 'TOKEN_REGISTRY_CONTRACT_DOES_NOT_EXIST',
-    TokenContractDoesNotExist = 'TOKEN_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',
+	ExchangeContractDoesNotExist = 'EXCHANGE_CONTRACT_DOES_NOT_EXIST',
+	ZRXContractDoesNotExist = 'ZRX_CONTRACT_DOES_NOT_EXIST',
+	EtherTokenContractDoesNotExist = 'ETHER_TOKEN_CONTRACT_DOES_NOT_EXIST',
+	TokenTransferProxyContractDoesNotExist = 'TOKEN_TRANSFER_PROXY_CONTRACT_DOES_NOT_EXIST',
+	TokenRegistryContractDoesNotExist = 'TOKEN_REGISTRY_CONTRACT_DOES_NOT_EXIST',
+	TokenContractDoesNotExist = 'TOKEN_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',
-    WethNotInTokenRegistry = 'WETH_NOT_IN_TOKEN_REGISTRY',
+	NoAbiDecoder = 'NO_ABI_DECODER',
+	ZrxNotInTokenRegistry = 'ZRX_NOT_IN_TOKEN_REGISTRY',
+	WethNotInTokenRegistry = 'WETH_NOT_IN_TOKEN_REGISTRY',
 }
 
 /**
  * Elliptic Curve signature
  */
 export interface ECSignature {
-    v: number;
-    r: string;
-    s: string;
+	v: number;
+	r: string;
+	s: string;
 }
 
 export type OrderAddresses = [string, string, string, string, string];
@@ -46,214 +46,214 @@ export type OrderValues = [BigNumber, BigNumber, BigNumber, BigNumber, BigNumber
 
 export type LogEvent = Web3.LogEntryEvent;
 export interface DecodedLogEvent<ArgsType> {
-    isRemoved: boolean;
-    log: LogWithDecodedArgs<ArgsType>;
+	isRemoved: boolean;
+	log: LogWithDecodedArgs<ArgsType>;
 }
 
 export type EventCallback<ArgsType> = (err: null | Error, log?: DecodedLogEvent<ArgsType>) => void;
 export type EventWatcherCallback = (err: null | Error, log?: LogEvent) => void;
 
 export enum SolidityTypes {
-    Address = 'address',
-    Uint256 = 'uint256',
-    Uint8 = 'uint8',
-    Uint = 'uint',
+	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
+	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',
+	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;
+	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;
+	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;
+	maker: string;
+	feeRecipient: string;
+	makerToken: string;
+	takerToken: string;
+	cancelledMakerTokenAmount: BigNumber;
+	cancelledTakerTokenAmount: BigNumber;
+	tokens: string;
+	orderHash: string;
 }
 export interface LogErrorContractEventArgs {
-    errorId: BigNumber;
-    orderHash: string;
+	errorId: BigNumber;
+	orderHash: string;
 }
 export type ExchangeContractEventArgs =
-    | LogFillContractEventArgs
-    | LogCancelContractEventArgs
-    | LogErrorContractEventArgs;
+	| LogFillContractEventArgs
+	| LogCancelContractEventArgs
+	| LogErrorContractEventArgs;
 export interface TransferContractEventArgs {
-    _from: string;
-    _to: string;
-    _value: BigNumber;
+	_from: string;
+	_to: string;
+	_value: BigNumber;
 }
 export interface ApprovalContractEventArgs {
-    _owner: string;
-    _spender: string;
-    _value: BigNumber;
+	_owner: string;
+	_spender: string;
+	_value: BigNumber;
 }
 export interface DepositContractEventArgs {
-    _owner: string;
-    _value: BigNumber;
+	_owner: string;
+	_value: BigNumber;
 }
 export interface WithdrawalContractEventArgs {
-    _owner: string;
-    _value: BigNumber;
+	_owner: string;
+	_value: BigNumber;
 }
 export type TokenContractEventArgs = TransferContractEventArgs | ApprovalContractEventArgs;
 export type EtherTokenContractEventArgs =
-    | TokenContractEventArgs
-    | DepositContractEventArgs
-    | WithdrawalContractEventArgs;
+	| TokenContractEventArgs
+	| DepositContractEventArgs
+	| WithdrawalContractEventArgs;
 export type ContractEventArgs = ExchangeContractEventArgs | TokenContractEventArgs | EtherTokenContractEventArgs;
 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;
+	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;
+	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;
+	name: string;
+	address: string;
+	symbol: string;
+	decimals: number;
 }
 
 export interface TxOpts {
-    from: string;
-    gas?: number;
-    value?: BigNumber;
-    gasPrice?: BigNumber;
+	from: string;
+	gas?: number;
+	value?: BigNumber;
+	gasPrice?: BigNumber;
 }
 
 export interface TokenAddressBySymbol {
-    [symbol: string]: string;
+	[symbol: string]: string;
 }
 
 export enum ExchangeEvents {
-    LogFill = 'LogFill',
-    LogCancel = 'LogCancel',
-    LogError = 'LogError',
+	LogFill = 'LogFill',
+	LogCancel = 'LogCancel',
+	LogError = 'LogError',
 }
 
 export enum TokenEvents {
-    Transfer = 'Transfer',
-    Approval = 'Approval',
+	Transfer = 'Transfer',
+	Approval = 'Approval',
 }
 
 export enum EtherTokenEvents {
-    Transfer = 'Transfer',
-    Approval = 'Approval',
-    Deposit = 'Deposit',
-    Withdrawal = 'Withdrawal',
+	Transfer = 'Transfer',
+	Approval = 'Approval',
+	Deposit = 'Deposit',
+	Withdrawal = 'Withdrawal',
 }
 
 export type ContractEvents = TokenEvents | ExchangeEvents | EtherTokenEvents;
 
 export interface IndexedFilterValues {
-    [index: string]: ContractEventArg;
+	[index: string]: ContractEventArg;
 }
 
 // Earliest is omitted by design. It is simply an alias for the `0` constant and
 // is thus not very helpful. Moreover, this type is used in places that only accept
 // `latest` or `pending`.
 export enum BlockParamLiteral {
-    Latest = 'latest',
-    Pending = 'pending',
+	Latest = 'latest',
+	Pending = 'pending',
 }
 
 export type BlockParam = BlockParamLiteral | number;
 
 export interface BlockRange {
-    fromBlock: BlockParam;
-    toBlock: BlockParam;
+	fromBlock: BlockParam;
+	toBlock: BlockParam;
 }
 
 export type DoneCallback = (err?: Error) => void;
 
 export interface OrderCancellationRequest {
-    order: Order | SignedOrder;
-    takerTokenCancelAmount: BigNumber;
+	order: Order | SignedOrder;
+	takerTokenCancelAmount: BigNumber;
 }
 
 export interface OrderFillRequest {
-    signedOrder: SignedOrder;
-    takerTokenFillAmount: BigNumber;
+	signedOrder: SignedOrder;
+	takerTokenFillAmount: BigNumber;
 }
 
 export type AsyncMethod = (...args: any[]) => Promise<any>;
@@ -268,8 +268,8 @@ export type SyncMethod = (...args: any[]) => any;
 export type Web3Provider = Web3.Provider;
 
 export interface JSONRPCPayload {
-    params: any[];
-    method: string;
+	params: any[];
+	method: string;
 }
 
 /*
@@ -280,10 +280,10 @@ export interface JSONRPCPayload {
  * cleanupJobIntervalMs: How often to run a cleanup job which revalidates all the orders. Defaults: 1h
  */
 export interface OrderStateWatcherConfig {
-    orderExpirationCheckingIntervalMs?: number;
-    eventPollingIntervalMs?: number;
-    expirationMarginMs?: number;
-    cleanupJobIntervalMs?: number;
+	orderExpirationCheckingIntervalMs?: number;
+	eventPollingIntervalMs?: number;
+	expirationMarginMs?: number;
+	cleanupJobIntervalMs?: number;
 }
 
 /*
@@ -296,42 +296,42 @@ export interface OrderStateWatcherConfig {
  * orderWatcherConfig: All the configs related to the orderWatcher
  */
 export interface ZeroExConfig {
-    networkId: number;
-    gasPrice?: BigNumber;
-    exchangeContractAddress?: string;
-    zrxContractAddress?: string;
-    tokenRegistryContractAddress?: string;
-    tokenTransferProxyContractAddress?: string;
-    orderWatcherConfig?: OrderStateWatcherConfig;
+	networkId: number;
+	gasPrice?: BigNumber;
+	exchangeContractAddress?: string;
+	zrxContractAddress?: string;
+	tokenRegistryContractAddress?: string;
+	tokenTransferProxyContractAddress?: string;
+	orderWatcherConfig?: OrderStateWatcherConfig;
 }
 
 export enum AbiType {
-    Function = 'function',
-    Constructor = 'constructor',
-    Event = 'event',
-    Fallback = 'fallback',
+	Function = 'function',
+	Constructor = 'constructor',
+	Event = 'event',
+	Fallback = 'fallback',
 }
 
 export interface DecodedLogArgs {
-    [argName: string]: ContractEventArg;
+	[argName: string]: ContractEventArg;
 }
 
 export interface LogWithDecodedArgs<ArgsType> extends Web3.DecodedLogEntry<ArgsType> {}
 
 export interface TransactionReceiptWithDecodedLogs extends TransactionReceipt {
-    logs: Array<LogWithDecodedArgs<DecodedLogArgs> | Web3.LogEntry>;
+	logs: Array<LogWithDecodedArgs<DecodedLogArgs> | Web3.LogEntry>;
 }
 
 export type ArtifactContractName = 'ZRX' | 'TokenTransferProxy' | 'TokenRegistry' | 'Token' | 'Exchange' | 'EtherToken';
 
 export interface Artifact {
-    contract_name: ArtifactContractName;
-    abi: Web3.ContractAbi;
-    networks: {
-        [networkId: number]: {
-            address: string;
-        };
-    };
+	contract_name: ArtifactContractName;
+	abi: Web3.ContractAbi;
+	networks: {
+		[networkId: number]: {
+			address: string;
+		};
+	};
 }
 
 /*
@@ -341,7 +341,7 @@ export interface Artifact {
  * allowance/balance to fill the entire remaining order amount.
  */
 export interface ValidateOrderFillableOpts {
-    expectedFillTakerTokenAmount?: BigNumber;
+	expectedFillTakerTokenAmount?: BigNumber;
 }
 
 /*
@@ -351,7 +351,7 @@ export interface ValidateOrderFillableOpts {
  * flag when  running Parity).
  */
 export interface MethodOpts {
-    defaultBlock?: Web3.BlockParam;
+	defaultBlock?: Web3.BlockParam;
 }
 
 /*
@@ -359,8 +359,8 @@ export interface MethodOpts {
  * gasLimit: The amount of gas to send with a transaction
  */
 export interface TransactionOpts {
-    gasPrice?: BigNumber;
-    gasLimit?: number;
+	gasPrice?: BigNumber;
+	gasLimit?: number;
 }
 
 /*
@@ -368,42 +368,42 @@ export interface TransactionOpts {
  * broadcasting it. For example, order has a valid signature, maker has sufficient funds, etc. Default: true
  */
 export interface OrderTransactionOpts extends TransactionOpts {
-    shouldValidate?: boolean;
+	shouldValidate?: boolean;
 }
 
 export type FilterObject = Web3.FilterObject;
 
 export enum TradeSide {
-    Maker = 'maker',
-    Taker = 'taker',
+	Maker = 'maker',
+	Taker = 'taker',
 }
 
 export enum TransferType {
-    Trade = 'trade',
-    Fee = 'fee',
+	Trade = 'trade',
+	Fee = 'fee',
 }
 
 export interface OrderRelevantState {
-    makerBalance: BigNumber;
-    makerProxyAllowance: BigNumber;
-    makerFeeBalance: BigNumber;
-    makerFeeProxyAllowance: BigNumber;
-    filledTakerTokenAmount: BigNumber;
-    cancelledTakerTokenAmount: BigNumber;
-    remainingFillableMakerTokenAmount: BigNumber;
-    remainingFillableTakerTokenAmount: BigNumber;
+	makerBalance: BigNumber;
+	makerProxyAllowance: BigNumber;
+	makerFeeBalance: BigNumber;
+	makerFeeProxyAllowance: BigNumber;
+	filledTakerTokenAmount: BigNumber;
+	cancelledTakerTokenAmount: BigNumber;
+	remainingFillableMakerTokenAmount: BigNumber;
+	remainingFillableTakerTokenAmount: BigNumber;
 }
 
 export interface OrderStateValid {
-    isValid: true;
-    orderHash: string;
-    orderRelevantState: OrderRelevantState;
+	isValid: true;
+	orderHash: string;
+	orderRelevantState: OrderRelevantState;
 }
 
 export interface OrderStateInvalid {
-    isValid: false;
-    orderHash: string;
-    error: ExchangeContractErrs;
+	isValid: false;
+	orderHash: string;
+	error: ExchangeContractErrs;
 }
 
 export type OrderState = OrderStateValid | OrderStateInvalid;
diff --git a/packages/0x.js/src/utils/abi_decoder.ts b/packages/0x.js/src/utils/abi_decoder.ts
index bbd2a0b1d..ace6dd165 100644
--- a/packages/0x.js/src/utils/abi_decoder.ts
+++ b/packages/0x.js/src/utils/abi_decoder.ts
@@ -6,67 +6,67 @@ import * as SolidityCoder from 'web3/lib/solidity/coder';
 import { AbiType, ContractEventArgs, DecodedLogArgs, LogWithDecodedArgs, RawLog, SolidityTypes } from '../types';
 
 export class AbiDecoder {
-    private _savedABIs: Web3.AbiDefinition[] = [];
-    private _methodIds: { [signatureHash: string]: Web3.EventAbi } = {};
-    private static _padZeros(address: string) {
-        let formatted = address;
-        if (_.startsWith(formatted, '0x')) {
-            formatted = formatted.slice(2);
-        }
+	private _savedABIs: Web3.AbiDefinition[] = [];
+	private _methodIds: { [signatureHash: string]: Web3.EventAbi } = {};
+	private static _padZeros(address: string) {
+		let formatted = address;
+		if (_.startsWith(formatted, '0x')) {
+			formatted = formatted.slice(2);
+		}
 
-        formatted = _.padStart(formatted, 40, '0');
-        return `0x${formatted}`;
-    }
-    constructor(abiArrays: Web3.AbiDefinition[][]) {
-        _.map(abiArrays, this._addABI.bind(this));
-    }
-    // This method can only decode logs from the 0x & ERC20 smart contracts
-    public tryToDecodeLogOrNoop<ArgsType extends ContractEventArgs>(
-        log: Web3.LogEntry,
-    ): LogWithDecodedArgs<ArgsType> | RawLog {
-        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;
+		formatted = _.padStart(formatted, 40, '0');
+		return `0x${formatted}`;
+	}
+	constructor(abiArrays: Web3.AbiDefinition[][]) {
+		_.map(abiArrays, this._addABI.bind(this));
+	}
+	// This method can only decode logs from the 0x & ERC20 smart contracts
+	public tryToDecodeLogOrNoop<ArgsType extends ContractEventArgs>(
+		log: Web3.LogEntry,
+	): LogWithDecodedArgs<ArgsType> | RawLog {
+		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));
+		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 = AbiDecoder._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;
-        });
+		_.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 = AbiDecoder._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);
-    }
+		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);
+	}
 }
diff --git a/packages/0x.js/src/utils/assert.ts b/packages/0x.js/src/utils/assert.ts
index c21f2dbca..776ee7b79 100644
--- a/packages/0x.js/src/utils/assert.ts
+++ b/packages/0x.js/src/utils/assert.ts
@@ -11,25 +11,25 @@ import { ECSignature } from '../types';
 import { signatureUtils } from '../utils/signature_utils';
 
 export const assert = {
-    ...sharedAssert,
-    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`);
-    },
-    async isSenderAddressAsync(
-        variableName: string,
-        senderAddressHex: string,
-        web3Wrapper: Web3Wrapper,
-    ): Promise<void> {
-        sharedAssert.isETHAddressHex(variableName, senderAddressHex);
-        const isSenderAddressAvailable = await web3Wrapper.isSenderAddressAvailableAsync(senderAddressHex);
-        sharedAssert.assert(
-            isSenderAddressAvailable,
-            `Specified ${variableName} ${senderAddressHex} isn't available through the supplied web3 provider`,
-        );
-    },
-    async isUserAddressAvailableAsync(web3Wrapper: Web3Wrapper): Promise<void> {
-        const availableAddresses = await web3Wrapper.getAvailableAddressesAsync();
-        this.assert(!_.isEmpty(availableAddresses), 'No addresses were available on the provided web3 provider');
-    },
+	...sharedAssert,
+	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`);
+	},
+	async isSenderAddressAsync(
+		variableName: string,
+		senderAddressHex: string,
+		web3Wrapper: Web3Wrapper,
+	): Promise<void> {
+		sharedAssert.isETHAddressHex(variableName, senderAddressHex);
+		const isSenderAddressAvailable = await web3Wrapper.isSenderAddressAvailableAsync(senderAddressHex);
+		sharedAssert.assert(
+			isSenderAddressAvailable,
+			`Specified ${variableName} ${senderAddressHex} isn't available through the supplied web3 provider`,
+		);
+	},
+	async isUserAddressAvailableAsync(web3Wrapper: Web3Wrapper): Promise<void> {
+		const availableAddresses = await web3Wrapper.getAvailableAddressesAsync();
+		this.assert(!_.isEmpty(availableAddresses), 'No addresses were available on the provided web3 provider');
+	},
 };
diff --git a/packages/0x.js/src/utils/constants.ts b/packages/0x.js/src/utils/constants.ts
index 06beec8e2..f32847ec2 100644
--- a/packages/0x.js/src/utils/constants.ts
+++ b/packages/0x.js/src/utils/constants.ts
@@ -1,12 +1,12 @@
 import { BigNumber } from '@0xproject/utils';
 
 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',
-    INVALID_TAKER_FORMAT: 'instance.taker is not of a type(s) string',
-    UNLIMITED_ALLOWANCE_IN_BASE_UNITS: new BigNumber(2).pow(256).minus(1),
-    DEFAULT_BLOCK_POLLING_INTERVAL: 1000,
+	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',
+	INVALID_TAKER_FORMAT: 'instance.taker is not of a type(s) string',
+	UNLIMITED_ALLOWANCE_IN_BASE_UNITS: new BigNumber(2).pow(256).minus(1),
+	DEFAULT_BLOCK_POLLING_INTERVAL: 1000,
 };
diff --git a/packages/0x.js/src/utils/decorators.ts b/packages/0x.js/src/utils/decorators.ts
index f774d734e..c1a022a81 100644
--- a/packages/0x.js/src/utils/decorators.ts
+++ b/packages/0x.js/src/utils/decorators.ts
@@ -7,85 +7,85 @@ import { constants } from './constants';
 type ErrorTransformer = (err: Error) => Error;
 
 const contractCallErrorTransformer = (error: Error) => {
-    if (_.includes(error.message, constants.INVALID_JUMP_PATTERN)) {
-        return new Error(ZeroExError.InvalidJump);
-    }
-    if (_.includes(error.message, constants.OUT_OF_GAS_PATTERN)) {
-        return new Error(ZeroExError.OutOfGas);
-    }
-    return error;
+	if (_.includes(error.message, constants.INVALID_JUMP_PATTERN)) {
+		return new Error(ZeroExError.InvalidJump);
+	}
+	if (_.includes(error.message, constants.OUT_OF_GAS_PATTERN)) {
+		return new Error(ZeroExError.OutOfGas);
+	}
+	return error;
 };
 
 const schemaErrorTransformer = (error: Error) => {
-    if (_.includes(error.message, constants.INVALID_TAKER_FORMAT)) {
-        const errMsg =
-            'Order taker must be of type string. If you want anyone to be able to fill an order - pass ZeroEx.NULL_ADDRESS';
-        return new Error(errMsg);
-    }
-    return error;
+	if (_.includes(error.message, constants.INVALID_TAKER_FORMAT)) {
+		const errMsg =
+			'Order taker must be of type string. If you want anyone to be able to fill an order - pass ZeroEx.NULL_ADDRESS';
+		return new Error(errMsg);
+	}
+	return error;
 };
 
 /**
  * Source: https://stackoverflow.com/a/29837695/3546986
  */
 const asyncErrorHandlerFactory = (errorTransformer: ErrorTransformer) => {
-    const asyncErrorHandlingDecorator = (
-        target: object,
-        key: string | symbol,
-        descriptor: TypedPropertyDescriptor<AsyncMethod>,
-    ) => {
-        const originalMethod = descriptor.value as AsyncMethod;
+	const asyncErrorHandlingDecorator = (
+		target: object,
+		key: string | symbol,
+		descriptor: TypedPropertyDescriptor<AsyncMethod>,
+	) => {
+		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) {
-                const transformedError = errorTransformer(error);
-                throw transformedError;
-            }
-        };
+		// 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) {
+				const transformedError = errorTransformer(error);
+				throw transformedError;
+			}
+		};
 
-        return descriptor;
-    };
+		return descriptor;
+	};
 
-    return asyncErrorHandlingDecorator;
+	return asyncErrorHandlingDecorator;
 };
 
 const syncErrorHandlerFactory = (errorTransformer: ErrorTransformer) => {
-    const syncErrorHandlingDecorator = (
-        target: object,
-        key: string | symbol,
-        descriptor: TypedPropertyDescriptor<SyncMethod>,
-    ) => {
-        const originalMethod = descriptor.value as SyncMethod;
+	const syncErrorHandlingDecorator = (
+		target: object,
+		key: string | symbol,
+		descriptor: TypedPropertyDescriptor<SyncMethod>,
+	) => {
+		const originalMethod = descriptor.value as SyncMethod;
 
-        // 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 = function(...args: any[]) {
-            try {
-                const result = originalMethod.apply(this, args);
-                return result;
-            } catch (error) {
-                const transformedError = errorTransformer(error);
-                throw transformedError;
-            }
-        };
+		// 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 = function(...args: any[]) {
+			try {
+				const result = originalMethod.apply(this, args);
+				return result;
+			} catch (error) {
+				const transformedError = errorTransformer(error);
+				throw transformedError;
+			}
+		};
 
-        return descriptor;
-    };
+		return descriptor;
+	};
 
-    return syncErrorHandlingDecorator;
+	return syncErrorHandlingDecorator;
 };
 
 // _.flow(f, g) = f ∘ g
 const zeroExErrorTransformer = _.flow(schemaErrorTransformer, contractCallErrorTransformer);
 
 export const decorators = {
-    asyncZeroExErrorHandler: asyncErrorHandlerFactory(zeroExErrorTransformer),
-    syncZeroExErrorHandler: syncErrorHandlerFactory(zeroExErrorTransformer),
+	asyncZeroExErrorHandler: asyncErrorHandlerFactory(zeroExErrorTransformer),
+	syncZeroExErrorHandler: syncErrorHandlerFactory(zeroExErrorTransformer),
 };
diff --git a/packages/0x.js/src/utils/exchange_transfer_simulator.ts b/packages/0x.js/src/utils/exchange_transfer_simulator.ts
index 662cd210c..c9a2f87ce 100644
--- a/packages/0x.js/src/utils/exchange_transfer_simulator.ts
+++ b/packages/0x.js/src/utils/exchange_transfer_simulator.ts
@@ -6,101 +6,101 @@ import { BalanceAndProxyAllowanceLazyStore } from '../stores/balance_proxy_allow
 import { BlockParamLiteral, ExchangeContractErrs, TradeSide, TransferType } from '../types';
 
 enum FailureReason {
-    Balance = 'balance',
-    ProxyAllowance = 'proxyAllowance',
+	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,
-        },
-    },
+	[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;
-    private static _throwValidationError(
-        failureReason: FailureReason,
-        tradeSide: TradeSide,
-        transferType: TransferType,
-    ): never {
-        const errMsg = ERR_MSG_MAPPING[failureReason][tradeSide][transferType];
-        throw new Error(errMsg);
-    }
-    constructor(token: TokenWrapper, defaultBlock: BlockParamLiteral) {
-        this._store = new BalanceAndProxyAllowanceLazyStore(token, defaultBlock);
-        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<void> {
-        const balance = await this._store.getBalanceAsync(tokenAddress, from);
-        const proxyAllowance = await this._store.getProxyAllowanceAsync(tokenAddress, from);
-        if (proxyAllowance.lessThan(amountInBaseUnits)) {
-            ExchangeTransferSimulator._throwValidationError(FailureReason.ProxyAllowance, tradeSide, transferType);
-        }
-        if (balance.lessThan(amountInBaseUnits)) {
-            ExchangeTransferSimulator._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<void> {
-        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<void> {
-        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<void> {
-        const balance = await this._store.getBalanceAsync(tokenAddress, userAddress);
-        this._store.setBalance(tokenAddress, userAddress, balance.minus(amountInBaseUnits));
-    }
+	private _store: BalanceAndProxyAllowanceLazyStore;
+	private _UNLIMITED_ALLOWANCE_IN_BASE_UNITS: BigNumber;
+	private static _throwValidationError(
+		failureReason: FailureReason,
+		tradeSide: TradeSide,
+		transferType: TransferType,
+	): never {
+		const errMsg = ERR_MSG_MAPPING[failureReason][tradeSide][transferType];
+		throw new Error(errMsg);
+	}
+	constructor(token: TokenWrapper, defaultBlock: BlockParamLiteral) {
+		this._store = new BalanceAndProxyAllowanceLazyStore(token, defaultBlock);
+		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<void> {
+		const balance = await this._store.getBalanceAsync(tokenAddress, from);
+		const proxyAllowance = await this._store.getProxyAllowanceAsync(tokenAddress, from);
+		if (proxyAllowance.lessThan(amountInBaseUnits)) {
+			ExchangeTransferSimulator._throwValidationError(FailureReason.ProxyAllowance, tradeSide, transferType);
+		}
+		if (balance.lessThan(amountInBaseUnits)) {
+			ExchangeTransferSimulator._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<void> {
+		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<void> {
+		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<void> {
+		const balance = await this._store.getBalanceAsync(tokenAddress, userAddress);
+		this._store.setBalance(tokenAddress, userAddress, balance.minus(amountInBaseUnits));
+	}
 }
diff --git a/packages/0x.js/src/utils/filter_utils.ts b/packages/0x.js/src/utils/filter_utils.ts
index 97205ace3..c34ae8893 100644
--- a/packages/0x.js/src/utils/filter_utils.ts
+++ b/packages/0x.js/src/utils/filter_utils.ts
@@ -9,79 +9,79 @@ import { BlockRange, ContractEvents, IndexedFilterValues } from '../types';
 const TOPIC_LENGTH = 32;
 
 export const filterUtils = {
-    generateUUID(): string {
-        return uuid();
-    },
-    getFilter(
-        address: string,
-        eventName: ContractEvents,
-        indexFilterValues: IndexedFilterValues,
-        abi: Web3.ContractAbi,
-        blockRange?: BlockRange,
-    ): 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(blockRange)) {
-            filter = {
-                ...blockRange,
-                ...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<string | null> {
-        const topics: Array<string | null> = [];
-        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<string[] | string | null>): 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;
-    },
+	generateUUID(): string {
+		return uuid();
+	},
+	getFilter(
+		address: string,
+		eventName: ContractEvents,
+		indexFilterValues: IndexedFilterValues,
+		abi: Web3.ContractAbi,
+		blockRange?: BlockRange,
+	): 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(blockRange)) {
+			filter = {
+				...blockRange,
+				...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<string | null> {
+		const topics: Array<string | null> = [];
+		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<string[] | string | null>): 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/packages/0x.js/src/utils/order_state_utils.ts b/packages/0x.js/src/utils/order_state_utils.ts
index b7a55ff42..04d3b641e 100644
--- a/packages/0x.js/src/utils/order_state_utils.ts
+++ b/packages/0x.js/src/utils/order_state_utils.ts
@@ -7,138 +7,138 @@ import { RemainingFillableCalculator } from '../order_watcher/remaining_fillable
 import { BalanceAndProxyAllowanceLazyStore } from '../stores/balance_proxy_allowance_lazy_store';
 import { OrderFilledCancelledLazyStore } from '../stores/order_filled_cancelled_lazy_store';
 import {
-    ExchangeContractErrs,
-    OrderRelevantState,
-    OrderState,
-    OrderStateInvalid,
-    OrderStateValid,
-    SignedOrder,
+	ExchangeContractErrs,
+	OrderRelevantState,
+	OrderState,
+	OrderStateInvalid,
+	OrderStateValid,
+	SignedOrder,
 } from '../types';
 
 const ACCEPTABLE_RELATIVE_ROUNDING_ERROR = 0.0001;
 
 export class OrderStateUtils {
-    private _balanceAndProxyAllowanceLazyStore: BalanceAndProxyAllowanceLazyStore;
-    private _orderFilledCancelledLazyStore: OrderFilledCancelledLazyStore;
-    private static _validateIfOrderIsValid(signedOrder: SignedOrder, orderRelevantState: OrderRelevantState): void {
-        const unavailableTakerTokenAmount = orderRelevantState.cancelledTakerTokenAmount.add(
-            orderRelevantState.filledTakerTokenAmount,
-        );
-        const availableTakerTokenAmount = signedOrder.takerTokenAmount.minus(unavailableTakerTokenAmount);
-        if (availableTakerTokenAmount.eq(0)) {
-            throw new Error(ExchangeContractErrs.OrderRemainingFillAmountZero);
-        }
+	private _balanceAndProxyAllowanceLazyStore: BalanceAndProxyAllowanceLazyStore;
+	private _orderFilledCancelledLazyStore: OrderFilledCancelledLazyStore;
+	private static _validateIfOrderIsValid(signedOrder: SignedOrder, orderRelevantState: OrderRelevantState): void {
+		const unavailableTakerTokenAmount = orderRelevantState.cancelledTakerTokenAmount.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);
-            }
-        }
-        const minFillableTakerTokenAmountWithinNoRoundingErrorRange = signedOrder.takerTokenAmount
-            .dividedBy(ACCEPTABLE_RELATIVE_ROUNDING_ERROR)
-            .dividedBy(signedOrder.makerTokenAmount);
-        if (
-            orderRelevantState.remainingFillableTakerTokenAmount.lessThan(
-                minFillableTakerTokenAmountWithinNoRoundingErrorRange,
-            )
-        ) {
-            throw new Error(ExchangeContractErrs.OrderFillRoundingError);
-        }
-    }
-    constructor(
-        balanceAndProxyAllowanceLazyStore: BalanceAndProxyAllowanceLazyStore,
-        orderFilledCancelledLazyStore: OrderFilledCancelledLazyStore,
-    ) {
-        this._balanceAndProxyAllowanceLazyStore = balanceAndProxyAllowanceLazyStore;
-        this._orderFilledCancelledLazyStore = orderFilledCancelledLazyStore;
-    }
-    public async getOrderStateAsync(signedOrder: SignedOrder): Promise<OrderState> {
-        const orderRelevantState = await this.getOrderRelevantStateAsync(signedOrder);
-        const orderHash = ZeroEx.getOrderHashHex(signedOrder);
-        try {
-            OrderStateUtils._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<OrderRelevantState> {
-        // 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 = exchange.getZRXTokenAddress();
-        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 cancelledTakerTokenAmount = 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 transferrableMakerTokenAmount = BigNumber.min([makerProxyAllowance, makerBalance]);
-        const transferrableFeeTokenAmount = BigNumber.min([makerFeeProxyAllowance, makerFeeBalance]);
+		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);
+			}
+		}
+		const minFillableTakerTokenAmountWithinNoRoundingErrorRange = signedOrder.takerTokenAmount
+			.dividedBy(ACCEPTABLE_RELATIVE_ROUNDING_ERROR)
+			.dividedBy(signedOrder.makerTokenAmount);
+		if (
+			orderRelevantState.remainingFillableTakerTokenAmount.lessThan(
+				minFillableTakerTokenAmountWithinNoRoundingErrorRange,
+			)
+		) {
+			throw new Error(ExchangeContractErrs.OrderFillRoundingError);
+		}
+	}
+	constructor(
+		balanceAndProxyAllowanceLazyStore: BalanceAndProxyAllowanceLazyStore,
+		orderFilledCancelledLazyStore: OrderFilledCancelledLazyStore,
+	) {
+		this._balanceAndProxyAllowanceLazyStore = balanceAndProxyAllowanceLazyStore;
+		this._orderFilledCancelledLazyStore = orderFilledCancelledLazyStore;
+	}
+	public async getOrderStateAsync(signedOrder: SignedOrder): Promise<OrderState> {
+		const orderRelevantState = await this.getOrderRelevantStateAsync(signedOrder);
+		const orderHash = ZeroEx.getOrderHashHex(signedOrder);
+		try {
+			OrderStateUtils._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<OrderRelevantState> {
+		// 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 = exchange.getZRXTokenAddress();
+		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 cancelledTakerTokenAmount = 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 transferrableMakerTokenAmount = BigNumber.min([makerProxyAllowance, makerBalance]);
+		const transferrableFeeTokenAmount = BigNumber.min([makerFeeProxyAllowance, makerFeeBalance]);
 
-        const isMakerTokenZRX = signedOrder.makerTokenAddress === zrxTokenAddress;
-        const remainingFillableCalculator = new RemainingFillableCalculator(
-            signedOrder,
-            isMakerTokenZRX,
-            transferrableMakerTokenAmount,
-            transferrableFeeTokenAmount,
-            remainingMakerTokenAmount,
-        );
-        const remainingFillableMakerTokenAmount = remainingFillableCalculator.computeRemainingMakerFillable();
-        const remainingFillableTakerTokenAmount = remainingFillableCalculator.computeRemainingTakerFillable();
-        const orderRelevantState = {
-            makerBalance,
-            makerProxyAllowance,
-            makerFeeBalance,
-            makerFeeProxyAllowance,
-            filledTakerTokenAmount,
-            cancelledTakerTokenAmount,
-            remainingFillableMakerTokenAmount,
-            remainingFillableTakerTokenAmount,
-        };
-        return orderRelevantState;
-    }
+		const isMakerTokenZRX = signedOrder.makerTokenAddress === zrxTokenAddress;
+		const remainingFillableCalculator = new RemainingFillableCalculator(
+			signedOrder,
+			isMakerTokenZRX,
+			transferrableMakerTokenAmount,
+			transferrableFeeTokenAmount,
+			remainingMakerTokenAmount,
+		);
+		const remainingFillableMakerTokenAmount = remainingFillableCalculator.computeRemainingMakerFillable();
+		const remainingFillableTakerTokenAmount = remainingFillableCalculator.computeRemainingTakerFillable();
+		const orderRelevantState = {
+			makerBalance,
+			makerProxyAllowance,
+			makerFeeBalance,
+			makerFeeProxyAllowance,
+			filledTakerTokenAmount,
+			cancelledTakerTokenAmount,
+			remainingFillableMakerTokenAmount,
+			remainingFillableTakerTokenAmount,
+		};
+		return orderRelevantState;
+	}
 }
diff --git a/packages/0x.js/src/utils/order_validation_utils.ts b/packages/0x.js/src/utils/order_validation_utils.ts
index 917d414c8..8ff22266f 100644
--- a/packages/0x.js/src/utils/order_validation_utils.ts
+++ b/packages/0x.js/src/utils/order_validation_utils.ts
@@ -10,207 +10,207 @@ import { utils } from '../utils/utils';
 import { ExchangeTransferSimulator } from './exchange_transfer_simulator';
 
 export class OrderValidationUtils {
-    private _exchangeWrapper: ExchangeWrapper;
-    public static validateCancelOrderThrowIfInvalid(
-        order: Order,
-        cancelTakerTokenAmount: BigNumber,
-        unavailableTakerTokenAmount: BigNumber,
-    ): void {
-        if (cancelTakerTokenAmount.eq(0)) {
-            throw new Error(ExchangeContractErrs.OrderCancelAmountZero);
-        }
-        if (order.takerTokenAmount.eq(unavailableTakerTokenAmount)) {
-            throw new Error(ExchangeContractErrs.OrderAlreadyCancelledOrFilled);
-        }
-        const currentUnixTimestampSec = utils.getCurrentUnixTimestampSec();
-        if (order.expirationUnixTimestampSec.lessThan(currentUnixTimestampSec)) {
-            throw new Error(ExchangeContractErrs.OrderCancelExpired);
-        }
-    }
-    public static async validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
-        exchangeTradeEmulator: ExchangeTransferSimulator,
-        signedOrder: SignedOrder,
-        fillTakerTokenAmount: BigNumber,
-        senderAddress: string,
-        zrxTokenAddress: string,
-    ): Promise<void> {
-        const fillMakerTokenAmount = OrderValidationUtils._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 = OrderValidationUtils._getPartialAmount(
-            fillTakerTokenAmount,
-            signedOrder.takerTokenAmount,
-            signedOrder.makerFee,
-        );
-        await exchangeTradeEmulator.transferFromAsync(
-            zrxTokenAddress,
-            signedOrder.maker,
-            signedOrder.feeRecipient,
-            makerFeeAmount,
-            TradeSide.Maker,
-            TransferType.Fee,
-        );
-        const takerFeeAmount = OrderValidationUtils._getPartialAmount(
-            fillTakerTokenAmount,
-            signedOrder.takerTokenAmount,
-            signedOrder.takerFee,
-        );
-        await exchangeTradeEmulator.transferFromAsync(
-            zrxTokenAddress,
-            senderAddress,
-            signedOrder.feeRecipient,
-            takerFeeAmount,
-            TradeSide.Taker,
-            TransferType.Fee,
-        );
-    }
-    private static _validateRemainingFillAmountNotZeroOrThrow(
-        takerTokenAmount: BigNumber,
-        unavailableTakerTokenAmount: BigNumber,
-    ) {
-        if (takerTokenAmount.eq(unavailableTakerTokenAmount)) {
-            throw new Error(ExchangeContractErrs.OrderRemainingFillAmountZero);
-        }
-    }
-    private static _validateOrderNotExpiredOrThrow(expirationUnixTimestampSec: BigNumber) {
-        const currentUnixTimestampSec = utils.getCurrentUnixTimestampSec();
-        if (expirationUnixTimestampSec.lessThan(currentUnixTimestampSec)) {
-            throw new Error(ExchangeContractErrs.OrderFillExpired);
-        }
-    }
-    private static _getPartialAmount(numerator: BigNumber, denominator: BigNumber, target: BigNumber): BigNumber {
-        const fillMakerTokenAmount = numerator
-            .mul(target)
-            .div(denominator)
-            .round(0);
-        return fillMakerTokenAmount;
-    }
-    constructor(exchangeWrapper: ExchangeWrapper) {
-        this._exchangeWrapper = exchangeWrapper;
-    }
-    public async validateOrderFillableOrThrowAsync(
-        exchangeTradeEmulator: ExchangeTransferSimulator,
-        signedOrder: SignedOrder,
-        zrxTokenAddress: string,
-        expectedFillTakerTokenAmount?: BigNumber,
-    ): Promise<void> {
-        const orderHash = utils.getOrderHashHex(signedOrder);
-        const unavailableTakerTokenAmount = await this._exchangeWrapper.getUnavailableTakerAmountAsync(orderHash);
-        OrderValidationUtils._validateRemainingFillAmountNotZeroOrThrow(
-            signedOrder.takerTokenAmount,
-            unavailableTakerTokenAmount,
-        );
-        OrderValidationUtils._validateOrderNotExpiredOrThrow(signedOrder.expirationUnixTimestampSec);
-        let fillTakerTokenAmount = signedOrder.takerTokenAmount.minus(unavailableTakerTokenAmount);
-        if (!_.isUndefined(expectedFillTakerTokenAmount)) {
-            fillTakerTokenAmount = expectedFillTakerTokenAmount;
-        }
-        const fillMakerTokenAmount = OrderValidationUtils._getPartialAmount(
-            fillTakerTokenAmount,
-            signedOrder.takerTokenAmount,
-            signedOrder.makerTokenAmount,
-        );
-        await exchangeTradeEmulator.transferFromAsync(
-            signedOrder.makerTokenAddress,
-            signedOrder.maker,
-            signedOrder.taker,
-            fillMakerTokenAmount,
-            TradeSide.Maker,
-            TransferType.Trade,
-        );
-        const makerFeeAmount = OrderValidationUtils._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<BigNumber> {
-        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);
-        OrderValidationUtils._validateRemainingFillAmountNotZeroOrThrow(
-            signedOrder.takerTokenAmount,
-            unavailableTakerTokenAmount,
-        );
-        if (signedOrder.taker !== constants.NULL_ADDRESS && signedOrder.taker !== takerAddress) {
-            throw new Error(ExchangeContractErrs.TransactionSenderIsNotFillOrderTaker);
-        }
-        OrderValidationUtils._validateOrderNotExpiredOrThrow(signedOrder.expirationUnixTimestampSec);
-        const remainingTakerTokenAmount = signedOrder.takerTokenAmount.minus(unavailableTakerTokenAmount);
-        const filledTakerTokenAmount = remainingTakerTokenAmount.lessThan(fillTakerTokenAmount)
-            ? remainingTakerTokenAmount
-            : fillTakerTokenAmount;
-        await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
-            exchangeTradeEmulator,
-            signedOrder,
-            filledTakerTokenAmount,
-            takerAddress,
-            zrxTokenAddress,
-        );
+	private _exchangeWrapper: ExchangeWrapper;
+	public static validateCancelOrderThrowIfInvalid(
+		order: Order,
+		cancelTakerTokenAmount: BigNumber,
+		unavailableTakerTokenAmount: BigNumber,
+	): void {
+		if (cancelTakerTokenAmount.eq(0)) {
+			throw new Error(ExchangeContractErrs.OrderCancelAmountZero);
+		}
+		if (order.takerTokenAmount.eq(unavailableTakerTokenAmount)) {
+			throw new Error(ExchangeContractErrs.OrderAlreadyCancelledOrFilled);
+		}
+		const currentUnixTimestampSec = utils.getCurrentUnixTimestampSec();
+		if (order.expirationUnixTimestampSec.lessThan(currentUnixTimestampSec)) {
+			throw new Error(ExchangeContractErrs.OrderCancelExpired);
+		}
+	}
+	public static async validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
+		exchangeTradeEmulator: ExchangeTransferSimulator,
+		signedOrder: SignedOrder,
+		fillTakerTokenAmount: BigNumber,
+		senderAddress: string,
+		zrxTokenAddress: string,
+	): Promise<void> {
+		const fillMakerTokenAmount = OrderValidationUtils._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 = OrderValidationUtils._getPartialAmount(
+			fillTakerTokenAmount,
+			signedOrder.takerTokenAmount,
+			signedOrder.makerFee,
+		);
+		await exchangeTradeEmulator.transferFromAsync(
+			zrxTokenAddress,
+			signedOrder.maker,
+			signedOrder.feeRecipient,
+			makerFeeAmount,
+			TradeSide.Maker,
+			TransferType.Fee,
+		);
+		const takerFeeAmount = OrderValidationUtils._getPartialAmount(
+			fillTakerTokenAmount,
+			signedOrder.takerTokenAmount,
+			signedOrder.takerFee,
+		);
+		await exchangeTradeEmulator.transferFromAsync(
+			zrxTokenAddress,
+			senderAddress,
+			signedOrder.feeRecipient,
+			takerFeeAmount,
+			TradeSide.Taker,
+			TransferType.Fee,
+		);
+	}
+	private static _validateRemainingFillAmountNotZeroOrThrow(
+		takerTokenAmount: BigNumber,
+		unavailableTakerTokenAmount: BigNumber,
+	) {
+		if (takerTokenAmount.eq(unavailableTakerTokenAmount)) {
+			throw new Error(ExchangeContractErrs.OrderRemainingFillAmountZero);
+		}
+	}
+	private static _validateOrderNotExpiredOrThrow(expirationUnixTimestampSec: BigNumber) {
+		const currentUnixTimestampSec = utils.getCurrentUnixTimestampSec();
+		if (expirationUnixTimestampSec.lessThan(currentUnixTimestampSec)) {
+			throw new Error(ExchangeContractErrs.OrderFillExpired);
+		}
+	}
+	private static _getPartialAmount(numerator: BigNumber, denominator: BigNumber, target: BigNumber): BigNumber {
+		const fillMakerTokenAmount = numerator
+			.mul(target)
+			.div(denominator)
+			.round(0);
+		return fillMakerTokenAmount;
+	}
+	constructor(exchangeWrapper: ExchangeWrapper) {
+		this._exchangeWrapper = exchangeWrapper;
+	}
+	public async validateOrderFillableOrThrowAsync(
+		exchangeTradeEmulator: ExchangeTransferSimulator,
+		signedOrder: SignedOrder,
+		zrxTokenAddress: string,
+		expectedFillTakerTokenAmount?: BigNumber,
+	): Promise<void> {
+		const orderHash = utils.getOrderHashHex(signedOrder);
+		const unavailableTakerTokenAmount = await this._exchangeWrapper.getUnavailableTakerAmountAsync(orderHash);
+		OrderValidationUtils._validateRemainingFillAmountNotZeroOrThrow(
+			signedOrder.takerTokenAmount,
+			unavailableTakerTokenAmount,
+		);
+		OrderValidationUtils._validateOrderNotExpiredOrThrow(signedOrder.expirationUnixTimestampSec);
+		let fillTakerTokenAmount = signedOrder.takerTokenAmount.minus(unavailableTakerTokenAmount);
+		if (!_.isUndefined(expectedFillTakerTokenAmount)) {
+			fillTakerTokenAmount = expectedFillTakerTokenAmount;
+		}
+		const fillMakerTokenAmount = OrderValidationUtils._getPartialAmount(
+			fillTakerTokenAmount,
+			signedOrder.takerTokenAmount,
+			signedOrder.makerTokenAmount,
+		);
+		await exchangeTradeEmulator.transferFromAsync(
+			signedOrder.makerTokenAddress,
+			signedOrder.maker,
+			signedOrder.taker,
+			fillMakerTokenAmount,
+			TradeSide.Maker,
+			TransferType.Trade,
+		);
+		const makerFeeAmount = OrderValidationUtils._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<BigNumber> {
+		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);
+		OrderValidationUtils._validateRemainingFillAmountNotZeroOrThrow(
+			signedOrder.takerTokenAmount,
+			unavailableTakerTokenAmount,
+		);
+		if (signedOrder.taker !== constants.NULL_ADDRESS && signedOrder.taker !== takerAddress) {
+			throw new Error(ExchangeContractErrs.TransactionSenderIsNotFillOrderTaker);
+		}
+		OrderValidationUtils._validateOrderNotExpiredOrThrow(signedOrder.expirationUnixTimestampSec);
+		const remainingTakerTokenAmount = signedOrder.takerTokenAmount.minus(unavailableTakerTokenAmount);
+		const filledTakerTokenAmount = remainingTakerTokenAmount.lessThan(fillTakerTokenAmount)
+			? remainingTakerTokenAmount
+			: fillTakerTokenAmount;
+		await OrderValidationUtils.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<void> {
-        const filledTakerTokenAmount = await this.validateFillOrderThrowIfInvalidAsync(
-            exchangeTradeEmulator,
-            signedOrder,
-            fillTakerTokenAmount,
-            takerAddress,
-            zrxTokenAddress,
-        );
-        if (filledTakerTokenAmount !== fillTakerTokenAmount) {
-            throw new Error(ExchangeContractErrs.InsufficientRemainingFillAmount);
-        }
-    }
+		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<void> {
+		const filledTakerTokenAmount = await this.validateFillOrderThrowIfInvalidAsync(
+			exchangeTradeEmulator,
+			signedOrder,
+			fillTakerTokenAmount,
+			takerAddress,
+			zrxTokenAddress,
+		);
+		if (filledTakerTokenAmount !== fillTakerTokenAmount) {
+			throw new Error(ExchangeContractErrs.InsufficientRemainingFillAmount);
+		}
+	}
 }
diff --git a/packages/0x.js/src/utils/signature_utils.ts b/packages/0x.js/src/utils/signature_utils.ts
index b0f1d61ef..19b5c76c7 100644
--- a/packages/0x.js/src/utils/signature_utils.ts
+++ b/packages/0x.js/src/utils/signature_utils.ts
@@ -3,44 +3,44 @@ 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;
-    },
+	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/packages/0x.js/src/utils/utils.ts b/packages/0x.js/src/utils/utils.ts
index 42cf5d956..ae07941ef 100644
--- a/packages/0x.js/src/utils/utils.ts
+++ b/packages/0x.js/src/utils/utils.ts
@@ -7,62 +7,62 @@ import * as _ from 'lodash';
 import { Order, SignedOrder, SolidityTypes } from '../types';
 
 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);
-    },
-    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;
-    },
-    getCurrentUnixTimestampSec(): BigNumber {
-        return new BigNumber(Date.now() / 1000).round();
-    },
-    getCurrentUnixTimestampMs(): BigNumber {
-        return new BigNumber(Date.now());
-    },
+	/**
+	 * 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);
+	},
+	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;
+	},
+	getCurrentUnixTimestampSec(): BigNumber {
+		return new BigNumber(Date.now() / 1000).round();
+	},
+	getCurrentUnixTimestampMs(): BigNumber {
+		return new BigNumber(Date.now());
+	},
 };
diff --git a/packages/0x.js/test/0x.js_test.ts b/packages/0x.js/test/0x.js_test.ts
index 927fe20be..5ece5192f 100644
--- a/packages/0x.js/test/0x.js_test.ts
+++ b/packages/0x.js/test/0x.js_test.ts
@@ -19,278 +19,278 @@ const expect = chai.expect;
 const SHOULD_ADD_PERSONAL_MESSAGE_PREFIX = false;
 
 describe('ZeroEx library', () => {
-    const web3 = web3Factory.create();
-    const config = {
-        networkId: constants.TESTRPC_NETWORK_ID,
-    };
-    const zeroEx = new ZeroEx(web3.currentProvider, config);
-    describe('#setProvider', () => {
-        it('overrides provider in nested web3s and invalidates contractInstances', async () => {
-            // Instantiate the contract instances with the current provider
-            await (zeroEx.exchange as any)._getExchangeContractAsync();
-            await (zeroEx.tokenRegistry as any)._getTokenRegistryContractAsync();
-            expect((zeroEx.exchange as any)._exchangeContractIfExists).to.not.be.undefined();
-            expect((zeroEx.tokenRegistry as any)._tokenRegistryContractIfExists).to.not.be.undefined();
+	const web3 = web3Factory.create();
+	const config = {
+		networkId: constants.TESTRPC_NETWORK_ID,
+	};
+	const zeroEx = new ZeroEx(web3.currentProvider, config);
+	describe('#setProvider', () => {
+		it('overrides provider in nested web3s and invalidates contractInstances', async () => {
+			// Instantiate the contract instances with the current provider
+			await (zeroEx.exchange as any)._getExchangeContractAsync();
+			await (zeroEx.tokenRegistry as any)._getTokenRegistryContractAsync();
+			expect((zeroEx.exchange as any)._exchangeContractIfExists).to.not.be.undefined();
+			expect((zeroEx.tokenRegistry as any)._tokenRegistryContractIfExists).to.not.be.undefined();
 
-            const newProvider = web3Factory.getRpcProvider();
-            // Add property to newProvider so that we can differentiate it from old provider
-            (newProvider as any).zeroExTestId = 1;
-            zeroEx.setProvider(newProvider, constants.TESTRPC_NETWORK_ID);
+			const newProvider = web3Factory.getRpcProvider();
+			// Add property to newProvider so that we can differentiate it from old provider
+			(newProvider as any).zeroExTestId = 1;
+			zeroEx.setProvider(newProvider, constants.TESTRPC_NETWORK_ID);
 
-            // Check that contractInstances with old provider are removed after provider update
-            expect((zeroEx.exchange as any)._exchangeContractIfExists).to.be.undefined();
-            expect((zeroEx.tokenRegistry as any)._tokenRegistryContractIfExists).to.be.undefined();
+			// Check that contractInstances with old provider are removed after provider update
+			expect((zeroEx.exchange as any)._exchangeContractIfExists).to.be.undefined();
+			expect((zeroEx.tokenRegistry as any)._tokenRegistryContractIfExists).to.be.undefined();
 
-            // Check that all nested web3 wrapper instances return the updated provider
-            const nestedWeb3WrapperProvider = (zeroEx as any)._web3Wrapper.getCurrentProvider();
-            expect(nestedWeb3WrapperProvider.zeroExTestId).to.be.a('number');
-            const exchangeWeb3WrapperProvider = (zeroEx.exchange as any)._web3Wrapper.getCurrentProvider();
-            expect(exchangeWeb3WrapperProvider.zeroExTestId).to.be.a('number');
-            const tokenRegistryWeb3WrapperProvider = (zeroEx.tokenRegistry as any)._web3Wrapper.getCurrentProvider();
-            expect(tokenRegistryWeb3WrapperProvider.zeroExTestId).to.be.a('number');
-        });
-    });
-    describe('#isValidSignature', () => {
-        // The Exchange smart contract `isValidSignature` method only validates orderHashes and assumes
-        // the length of the data is exactly 32 bytes. Thus for these tests, we use data of this size.
-        const dataHex = '0x6927e990021d23b1eb7b8789f6a6feaf98fe104bb0cf8259421b79f9a34222b0';
-        const signature = {
-            v: 27,
-            r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
-            s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
-        };
-        const address = '0x5409ed021d9299bf6814279a6a1411a7e866a631';
-        it("should return false if the data doesn't pertain to the signature & address", async () => {
-            expect(ZeroEx.isValidSignature('0x0', signature, address)).to.be.false();
-            return expect(
-                (zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync('0x0', signature, address),
-            ).to.become(false);
-        });
-        it("should return false if the address doesn't pertain to the signature & data", async () => {
-            const validUnrelatedAddress = '0x8b0292b11a196601ed2ce54b665cafeca0347d42';
-            expect(ZeroEx.isValidSignature(dataHex, signature, validUnrelatedAddress)).to.be.false();
-            return expect(
-                (zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync(
-                    dataHex,
-                    signature,
-                    validUnrelatedAddress,
-                ),
-            ).to.become(false);
-        });
-        it("should return false if the signature doesn't pertain to the dataHex & address", async () => {
-            const wrongSignature = _.assign({}, signature, { v: 28 });
-            expect(ZeroEx.isValidSignature(dataHex, wrongSignature, address)).to.be.false();
-            return expect(
-                (zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync(dataHex, wrongSignature, address),
-            ).to.become(false);
-        });
-        it('should return true if the signature does pertain to the dataHex & address', async () => {
-            const isValidSignatureLocal = ZeroEx.isValidSignature(dataHex, signature, address);
-            expect(isValidSignatureLocal).to.be.true();
-            return expect(
-                (zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync(dataHex, signature, address),
-            ).to.become(true);
-        });
-    });
-    describe('#generateSalt', () => {
-        it('generates different salts', () => {
-            const equal = ZeroEx.generatePseudoRandomSalt().eq(ZeroEx.generatePseudoRandomSalt());
-            expect(equal).to.be.false();
-        });
-        it('generates salt in range [0..2^256)', () => {
-            const salt = ZeroEx.generatePseudoRandomSalt();
-            expect(salt.greaterThanOrEqualTo(0)).to.be.true();
-            const twoPow256 = new BigNumber(2).pow(256);
-            expect(salt.lessThan(twoPow256)).to.be.true();
-        });
-    });
-    describe('#isValidOrderHash', () => {
-        it('returns false if the value is not a hex string', () => {
-            const isValid = ZeroEx.isValidOrderHash('not a hex');
-            expect(isValid).to.be.false();
-        });
-        it('returns false if the length is wrong', () => {
-            const isValid = ZeroEx.isValidOrderHash('0xdeadbeef');
-            expect(isValid).to.be.false();
-        });
-        it('returns true if order hash is correct', () => {
-            const isValid = ZeroEx.isValidOrderHash('0x' + Array(65).join('0'));
-            expect(isValid).to.be.true();
-        });
-    });
-    describe('#toUnitAmount', () => {
-        it('should throw if invalid baseUnit amount supplied as argument', () => {
-            const invalidBaseUnitAmount = new BigNumber(1000000000.4);
-            const decimals = 6;
-            expect(() => ZeroEx.toUnitAmount(invalidBaseUnitAmount, decimals)).to.throw(
-                'amount should be in baseUnits (no decimals), found value: 1000000000.4',
-            );
-        });
-        it('Should return the expected unit amount for the decimals passed in', () => {
-            const baseUnitAmount = new BigNumber(1000000000);
-            const decimals = 6;
-            const unitAmount = ZeroEx.toUnitAmount(baseUnitAmount, decimals);
-            const expectedUnitAmount = new BigNumber(1000);
-            expect(unitAmount).to.be.bignumber.equal(expectedUnitAmount);
-        });
-    });
-    describe('#toBaseUnitAmount', () => {
-        it('Should return the expected base unit amount for the decimals passed in', () => {
-            const unitAmount = new BigNumber(1000);
-            const decimals = 6;
-            const baseUnitAmount = ZeroEx.toBaseUnitAmount(unitAmount, decimals);
-            const expectedUnitAmount = new BigNumber(1000000000);
-            expect(baseUnitAmount).to.be.bignumber.equal(expectedUnitAmount);
-        });
-        it('should throw if unitAmount has more decimals then specified as the max decimal precision', () => {
-            const unitAmount = new BigNumber(0.823091);
-            const decimals = 5;
-            expect(() => ZeroEx.toBaseUnitAmount(unitAmount, decimals)).to.throw(
-                'Invalid unit amount: 0.823091 - Too many decimal places',
-            );
-        });
-    });
-    describe('#getOrderHashHex', () => {
-        const expectedOrderHash = '0x39da987067a3c9e5f1617694f1301326ba8c8b0498ebef5df4863bed394e3c83';
-        const fakeExchangeContractAddress = '0xb69e673309512a9d726f87304c6984054f87a93b';
-        const order: Order = {
-            maker: constants.NULL_ADDRESS,
-            taker: constants.NULL_ADDRESS,
-            feeRecipient: constants.NULL_ADDRESS,
-            makerTokenAddress: constants.NULL_ADDRESS,
-            takerTokenAddress: constants.NULL_ADDRESS,
-            exchangeContractAddress: fakeExchangeContractAddress,
-            salt: new BigNumber(0),
-            makerFee: new BigNumber(0),
-            takerFee: new BigNumber(0),
-            makerTokenAmount: new BigNumber(0),
-            takerTokenAmount: new BigNumber(0),
-            expirationUnixTimestampSec: new BigNumber(0),
-        };
-        it('calculates the order hash', async () => {
-            const orderHash = ZeroEx.getOrderHashHex(order);
-            expect(orderHash).to.be.equal(expectedOrderHash);
-        });
-        it('throws a readable error message if taker format is invalid', async () => {
-            const orderWithInvalidtakerFormat = {
-                ...order,
-                taker: (null as any) as string,
-            };
-            const expectedErrorMessage =
-                'Order taker must be of type string. If you want anyone to be able to fill an order - pass ZeroEx.NULL_ADDRESS';
-            expect(() => ZeroEx.getOrderHashHex(orderWithInvalidtakerFormat)).to.throw(expectedErrorMessage);
-        });
-    });
-    describe('#signOrderHashAsync', () => {
-        let stubs: Sinon.SinonStub[] = [];
-        let makerAddress: string;
-        before(async () => {
-            const availableAddreses = await zeroEx.getAvailableAddressesAsync();
-            makerAddress = availableAddreses[0];
-        });
-        afterEach(() => {
-            // clean up any stubs after the test has completed
-            _.each(stubs, s => s.restore());
-            stubs = [];
-        });
-        it('Should return the correct ECSignature', async () => {
-            const orderHash = '0x6927e990021d23b1eb7b8789f6a6feaf98fe104bb0cf8259421b79f9a34222b0';
-            const expectedECSignature = {
-                v: 27,
-                r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
-                s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
-            };
-            const ecSignature = await zeroEx.signOrderHashAsync(
-                orderHash,
-                makerAddress,
-                SHOULD_ADD_PERSONAL_MESSAGE_PREFIX,
-            );
-            expect(ecSignature).to.deep.equal(expectedECSignature);
-        });
-        it('should return the correct ECSignature for signatureHex concatenated as R + S + V', async () => {
-            const orderHash = '0x34decbedc118904df65f379a175bb39ca18209d6ce41d5ed549d54e6e0a95004';
-            const signature =
-                '0x22109d11d79cb8bf96ed88625e1cd9558800c4073332a9a02857499883ee5ce3050aa3cc1f2c435e67e114cdce54b9527b4f50548342401bc5d2b77adbdacb021b';
-            const expectedECSignature = {
-                v: 27,
-                r: '0x22109d11d79cb8bf96ed88625e1cd9558800c4073332a9a02857499883ee5ce3',
-                s: '0x050aa3cc1f2c435e67e114cdce54b9527b4f50548342401bc5d2b77adbdacb02',
-            };
-            stubs = [
-                Sinon.stub((zeroEx as any)._web3Wrapper, 'signTransactionAsync').returns(Promise.resolve(signature)),
-                Sinon.stub(ZeroEx, 'isValidSignature').returns(true),
-            ];
+			// Check that all nested web3 wrapper instances return the updated provider
+			const nestedWeb3WrapperProvider = (zeroEx as any)._web3Wrapper.getCurrentProvider();
+			expect(nestedWeb3WrapperProvider.zeroExTestId).to.be.a('number');
+			const exchangeWeb3WrapperProvider = (zeroEx.exchange as any)._web3Wrapper.getCurrentProvider();
+			expect(exchangeWeb3WrapperProvider.zeroExTestId).to.be.a('number');
+			const tokenRegistryWeb3WrapperProvider = (zeroEx.tokenRegistry as any)._web3Wrapper.getCurrentProvider();
+			expect(tokenRegistryWeb3WrapperProvider.zeroExTestId).to.be.a('number');
+		});
+	});
+	describe('#isValidSignature', () => {
+		// The Exchange smart contract `isValidSignature` method only validates orderHashes and assumes
+		// the length of the data is exactly 32 bytes. Thus for these tests, we use data of this size.
+		const dataHex = '0x6927e990021d23b1eb7b8789f6a6feaf98fe104bb0cf8259421b79f9a34222b0';
+		const signature = {
+			v: 27,
+			r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
+			s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
+		};
+		const address = '0x5409ed021d9299bf6814279a6a1411a7e866a631';
+		it("should return false if the data doesn't pertain to the signature & address", async () => {
+			expect(ZeroEx.isValidSignature('0x0', signature, address)).to.be.false();
+			return expect(
+				(zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync('0x0', signature, address),
+			).to.become(false);
+		});
+		it("should return false if the address doesn't pertain to the signature & data", async () => {
+			const validUnrelatedAddress = '0x8b0292b11a196601ed2ce54b665cafeca0347d42';
+			expect(ZeroEx.isValidSignature(dataHex, signature, validUnrelatedAddress)).to.be.false();
+			return expect(
+				(zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync(
+					dataHex,
+					signature,
+					validUnrelatedAddress,
+				),
+			).to.become(false);
+		});
+		it("should return false if the signature doesn't pertain to the dataHex & address", async () => {
+			const wrongSignature = _.assign({}, signature, { v: 28 });
+			expect(ZeroEx.isValidSignature(dataHex, wrongSignature, address)).to.be.false();
+			return expect(
+				(zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync(dataHex, wrongSignature, address),
+			).to.become(false);
+		});
+		it('should return true if the signature does pertain to the dataHex & address', async () => {
+			const isValidSignatureLocal = ZeroEx.isValidSignature(dataHex, signature, address);
+			expect(isValidSignatureLocal).to.be.true();
+			return expect(
+				(zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync(dataHex, signature, address),
+			).to.become(true);
+		});
+	});
+	describe('#generateSalt', () => {
+		it('generates different salts', () => {
+			const equal = ZeroEx.generatePseudoRandomSalt().eq(ZeroEx.generatePseudoRandomSalt());
+			expect(equal).to.be.false();
+		});
+		it('generates salt in range [0..2^256)', () => {
+			const salt = ZeroEx.generatePseudoRandomSalt();
+			expect(salt.greaterThanOrEqualTo(0)).to.be.true();
+			const twoPow256 = new BigNumber(2).pow(256);
+			expect(salt.lessThan(twoPow256)).to.be.true();
+		});
+	});
+	describe('#isValidOrderHash', () => {
+		it('returns false if the value is not a hex string', () => {
+			const isValid = ZeroEx.isValidOrderHash('not a hex');
+			expect(isValid).to.be.false();
+		});
+		it('returns false if the length is wrong', () => {
+			const isValid = ZeroEx.isValidOrderHash('0xdeadbeef');
+			expect(isValid).to.be.false();
+		});
+		it('returns true if order hash is correct', () => {
+			const isValid = ZeroEx.isValidOrderHash('0x' + Array(65).join('0'));
+			expect(isValid).to.be.true();
+		});
+	});
+	describe('#toUnitAmount', () => {
+		it('should throw if invalid baseUnit amount supplied as argument', () => {
+			const invalidBaseUnitAmount = new BigNumber(1000000000.4);
+			const decimals = 6;
+			expect(() => ZeroEx.toUnitAmount(invalidBaseUnitAmount, decimals)).to.throw(
+				'amount should be in baseUnits (no decimals), found value: 1000000000.4',
+			);
+		});
+		it('Should return the expected unit amount for the decimals passed in', () => {
+			const baseUnitAmount = new BigNumber(1000000000);
+			const decimals = 6;
+			const unitAmount = ZeroEx.toUnitAmount(baseUnitAmount, decimals);
+			const expectedUnitAmount = new BigNumber(1000);
+			expect(unitAmount).to.be.bignumber.equal(expectedUnitAmount);
+		});
+	});
+	describe('#toBaseUnitAmount', () => {
+		it('Should return the expected base unit amount for the decimals passed in', () => {
+			const unitAmount = new BigNumber(1000);
+			const decimals = 6;
+			const baseUnitAmount = ZeroEx.toBaseUnitAmount(unitAmount, decimals);
+			const expectedUnitAmount = new BigNumber(1000000000);
+			expect(baseUnitAmount).to.be.bignumber.equal(expectedUnitAmount);
+		});
+		it('should throw if unitAmount has more decimals then specified as the max decimal precision', () => {
+			const unitAmount = new BigNumber(0.823091);
+			const decimals = 5;
+			expect(() => ZeroEx.toBaseUnitAmount(unitAmount, decimals)).to.throw(
+				'Invalid unit amount: 0.823091 - Too many decimal places',
+			);
+		});
+	});
+	describe('#getOrderHashHex', () => {
+		const expectedOrderHash = '0x39da987067a3c9e5f1617694f1301326ba8c8b0498ebef5df4863bed394e3c83';
+		const fakeExchangeContractAddress = '0xb69e673309512a9d726f87304c6984054f87a93b';
+		const order: Order = {
+			maker: constants.NULL_ADDRESS,
+			taker: constants.NULL_ADDRESS,
+			feeRecipient: constants.NULL_ADDRESS,
+			makerTokenAddress: constants.NULL_ADDRESS,
+			takerTokenAddress: constants.NULL_ADDRESS,
+			exchangeContractAddress: fakeExchangeContractAddress,
+			salt: new BigNumber(0),
+			makerFee: new BigNumber(0),
+			takerFee: new BigNumber(0),
+			makerTokenAmount: new BigNumber(0),
+			takerTokenAmount: new BigNumber(0),
+			expirationUnixTimestampSec: new BigNumber(0),
+		};
+		it('calculates the order hash', async () => {
+			const orderHash = ZeroEx.getOrderHashHex(order);
+			expect(orderHash).to.be.equal(expectedOrderHash);
+		});
+		it('throws a readable error message if taker format is invalid', async () => {
+			const orderWithInvalidtakerFormat = {
+				...order,
+				taker: (null as any) as string,
+			};
+			const expectedErrorMessage =
+				'Order taker must be of type string. If you want anyone to be able to fill an order - pass ZeroEx.NULL_ADDRESS';
+			expect(() => ZeroEx.getOrderHashHex(orderWithInvalidtakerFormat)).to.throw(expectedErrorMessage);
+		});
+	});
+	describe('#signOrderHashAsync', () => {
+		let stubs: Sinon.SinonStub[] = [];
+		let makerAddress: string;
+		before(async () => {
+			const availableAddreses = await zeroEx.getAvailableAddressesAsync();
+			makerAddress = availableAddreses[0];
+		});
+		afterEach(() => {
+			// clean up any stubs after the test has completed
+			_.each(stubs, s => s.restore());
+			stubs = [];
+		});
+		it('Should return the correct ECSignature', async () => {
+			const orderHash = '0x6927e990021d23b1eb7b8789f6a6feaf98fe104bb0cf8259421b79f9a34222b0';
+			const expectedECSignature = {
+				v: 27,
+				r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
+				s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
+			};
+			const ecSignature = await zeroEx.signOrderHashAsync(
+				orderHash,
+				makerAddress,
+				SHOULD_ADD_PERSONAL_MESSAGE_PREFIX,
+			);
+			expect(ecSignature).to.deep.equal(expectedECSignature);
+		});
+		it('should return the correct ECSignature for signatureHex concatenated as R + S + V', async () => {
+			const orderHash = '0x34decbedc118904df65f379a175bb39ca18209d6ce41d5ed549d54e6e0a95004';
+			const signature =
+				'0x22109d11d79cb8bf96ed88625e1cd9558800c4073332a9a02857499883ee5ce3050aa3cc1f2c435e67e114cdce54b9527b4f50548342401bc5d2b77adbdacb021b';
+			const expectedECSignature = {
+				v: 27,
+				r: '0x22109d11d79cb8bf96ed88625e1cd9558800c4073332a9a02857499883ee5ce3',
+				s: '0x050aa3cc1f2c435e67e114cdce54b9527b4f50548342401bc5d2b77adbdacb02',
+			};
+			stubs = [
+				Sinon.stub((zeroEx as any)._web3Wrapper, 'signTransactionAsync').returns(Promise.resolve(signature)),
+				Sinon.stub(ZeroEx, 'isValidSignature').returns(true),
+			];
 
-            const ecSignature = await zeroEx.signOrderHashAsync(
-                orderHash,
-                makerAddress,
-                SHOULD_ADD_PERSONAL_MESSAGE_PREFIX,
-            );
-            expect(ecSignature).to.deep.equal(expectedECSignature);
-        });
-        it('should return the correct ECSignature for signatureHex concatenated as V + R + S', async () => {
-            const orderHash = '0xc793e33ffded933b76f2f48d9aa3339fc090399d5e7f5dec8d3660f5480793f7';
-            const signature =
-                '0x1bc80bedc6756722672753413efdd749b5adbd4fd552595f59c13427407ee9aee02dea66f25a608bbae457e020fb6decb763deb8b7192abab624997242da248960';
-            const expectedECSignature = {
-                v: 27,
-                r: '0xc80bedc6756722672753413efdd749b5adbd4fd552595f59c13427407ee9aee0',
-                s: '0x2dea66f25a608bbae457e020fb6decb763deb8b7192abab624997242da248960',
-            };
-            stubs = [
-                Sinon.stub((zeroEx as any)._web3Wrapper, 'signTransactionAsync').returns(Promise.resolve(signature)),
-                Sinon.stub(ZeroEx, 'isValidSignature').returns(true),
-            ];
+			const ecSignature = await zeroEx.signOrderHashAsync(
+				orderHash,
+				makerAddress,
+				SHOULD_ADD_PERSONAL_MESSAGE_PREFIX,
+			);
+			expect(ecSignature).to.deep.equal(expectedECSignature);
+		});
+		it('should return the correct ECSignature for signatureHex concatenated as V + R + S', async () => {
+			const orderHash = '0xc793e33ffded933b76f2f48d9aa3339fc090399d5e7f5dec8d3660f5480793f7';
+			const signature =
+				'0x1bc80bedc6756722672753413efdd749b5adbd4fd552595f59c13427407ee9aee02dea66f25a608bbae457e020fb6decb763deb8b7192abab624997242da248960';
+			const expectedECSignature = {
+				v: 27,
+				r: '0xc80bedc6756722672753413efdd749b5adbd4fd552595f59c13427407ee9aee0',
+				s: '0x2dea66f25a608bbae457e020fb6decb763deb8b7192abab624997242da248960',
+			};
+			stubs = [
+				Sinon.stub((zeroEx as any)._web3Wrapper, 'signTransactionAsync').returns(Promise.resolve(signature)),
+				Sinon.stub(ZeroEx, 'isValidSignature').returns(true),
+			];
 
-            const ecSignature = await zeroEx.signOrderHashAsync(
-                orderHash,
-                makerAddress,
-                SHOULD_ADD_PERSONAL_MESSAGE_PREFIX,
-            );
-            expect(ecSignature).to.deep.equal(expectedECSignature);
-        });
-    });
-    describe('#awaitTransactionMinedAsync', () => {
-        beforeEach(async () => {
-            await blockchainLifecycle.startAsync();
-        });
-        afterEach(async () => {
-            await blockchainLifecycle.revertAsync();
-        });
-        it('returns transaction receipt with decoded logs', async () => {
-            const availableAddresses = await zeroEx.getAvailableAddressesAsync();
-            const coinbase = availableAddresses[0];
-            const tokens = await zeroEx.tokenRegistry.getTokensAsync();
-            const tokenUtils = new TokenUtils(tokens);
-            const zrxTokenAddress = tokenUtils.getProtocolTokenOrThrow().address;
-            const proxyAddress = zeroEx.proxy.getContractAddress();
-            const txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(zrxTokenAddress, coinbase);
-            const txReceiptWithDecodedLogs = await zeroEx.awaitTransactionMinedAsync(txHash);
-            const log = txReceiptWithDecodedLogs.logs[0] as LogWithDecodedArgs<ApprovalContractEventArgs>;
-            expect(log.event).to.be.equal(TokenEvents.Approval);
-            expect(log.args._owner).to.be.equal(coinbase);
-            expect(log.args._spender).to.be.equal(proxyAddress);
-            expect(log.args._value).to.be.bignumber.equal(zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
-        });
-    });
-    describe('#config', () => {
-        it('allows to specify exchange contract address', async () => {
-            const zeroExConfig = {
-                exchangeContractAddress: ZeroEx.NULL_ADDRESS,
-                networkId: constants.TESTRPC_NETWORK_ID,
-            };
-            const zeroExWithWrongExchangeAddress = new ZeroEx(web3.currentProvider, zeroExConfig);
-            expect(zeroExWithWrongExchangeAddress.exchange.getContractAddress()).to.be.equal(ZeroEx.NULL_ADDRESS);
-        });
-        it('allows to specify token registry token contract address', async () => {
-            const zeroExConfig = {
-                tokenRegistryContractAddress: ZeroEx.NULL_ADDRESS,
-                networkId: constants.TESTRPC_NETWORK_ID,
-            };
-            const zeroExWithWrongTokenRegistryAddress = new ZeroEx(web3.currentProvider, zeroExConfig);
-            expect(zeroExWithWrongTokenRegistryAddress.tokenRegistry.getContractAddress()).to.be.equal(
-                ZeroEx.NULL_ADDRESS,
-            );
-        });
-    });
+			const ecSignature = await zeroEx.signOrderHashAsync(
+				orderHash,
+				makerAddress,
+				SHOULD_ADD_PERSONAL_MESSAGE_PREFIX,
+			);
+			expect(ecSignature).to.deep.equal(expectedECSignature);
+		});
+	});
+	describe('#awaitTransactionMinedAsync', () => {
+		beforeEach(async () => {
+			await blockchainLifecycle.startAsync();
+		});
+		afterEach(async () => {
+			await blockchainLifecycle.revertAsync();
+		});
+		it('returns transaction receipt with decoded logs', async () => {
+			const availableAddresses = await zeroEx.getAvailableAddressesAsync();
+			const coinbase = availableAddresses[0];
+			const tokens = await zeroEx.tokenRegistry.getTokensAsync();
+			const tokenUtils = new TokenUtils(tokens);
+			const zrxTokenAddress = tokenUtils.getProtocolTokenOrThrow().address;
+			const proxyAddress = zeroEx.proxy.getContractAddress();
+			const txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(zrxTokenAddress, coinbase);
+			const txReceiptWithDecodedLogs = await zeroEx.awaitTransactionMinedAsync(txHash);
+			const log = txReceiptWithDecodedLogs.logs[0] as LogWithDecodedArgs<ApprovalContractEventArgs>;
+			expect(log.event).to.be.equal(TokenEvents.Approval);
+			expect(log.args._owner).to.be.equal(coinbase);
+			expect(log.args._spender).to.be.equal(proxyAddress);
+			expect(log.args._value).to.be.bignumber.equal(zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
+		});
+	});
+	describe('#config', () => {
+		it('allows to specify exchange contract address', async () => {
+			const zeroExConfig = {
+				exchangeContractAddress: ZeroEx.NULL_ADDRESS,
+				networkId: constants.TESTRPC_NETWORK_ID,
+			};
+			const zeroExWithWrongExchangeAddress = new ZeroEx(web3.currentProvider, zeroExConfig);
+			expect(zeroExWithWrongExchangeAddress.exchange.getContractAddress()).to.be.equal(ZeroEx.NULL_ADDRESS);
+		});
+		it('allows to specify token registry token contract address', async () => {
+			const zeroExConfig = {
+				tokenRegistryContractAddress: ZeroEx.NULL_ADDRESS,
+				networkId: constants.TESTRPC_NETWORK_ID,
+			};
+			const zeroExWithWrongTokenRegistryAddress = new ZeroEx(web3.currentProvider, zeroExConfig);
+			expect(zeroExWithWrongTokenRegistryAddress.tokenRegistry.getContractAddress()).to.be.equal(
+				ZeroEx.NULL_ADDRESS,
+			);
+		});
+	});
 });
diff --git a/packages/0x.js/test/artifacts_test.ts b/packages/0x.js/test/artifacts_test.ts
index e8ab9aa97..3a791f436 100644
--- a/packages/0x.js/test/artifacts_test.ts
+++ b/packages/0x.js/test/artifacts_test.ts
@@ -12,44 +12,44 @@ chaiSetup.configure();
 const TIMEOUT = 10000;
 
 describe('Artifacts', () => {
-    describe('contracts are deployed on kovan', () => {
-        const kovanRpcUrl = constants.KOVAN_RPC_URL;
-        const packageJSONContent = fs.readFileSync('package.json', 'utf-8');
-        const packageJSON = JSON.parse(packageJSONContent);
-        const mnemonic = packageJSON.config.mnemonic;
-        const web3Provider = new HDWalletProvider(mnemonic, kovanRpcUrl);
-        const config = {
-            networkId: constants.KOVAN_NETWORK_ID,
-        };
-        const zeroEx = new ZeroEx(web3Provider, config);
-        it('token registry contract is deployed', async () => {
-            await (zeroEx.tokenRegistry as any)._getTokenRegistryContractAsync();
-        }).timeout(TIMEOUT);
-        it('proxy contract is deployed', async () => {
-            await (zeroEx.proxy as any)._getTokenTransferProxyContractAsync();
-        }).timeout(TIMEOUT);
-        it('exchange contract is deployed', async () => {
-            await (zeroEx.exchange as any)._getExchangeContractAsync();
-        }).timeout(TIMEOUT);
-    });
-    describe('contracts are deployed on ropsten', () => {
-        const ropstenRpcUrl = constants.ROPSTEN_RPC_URL;
-        const packageJSONContent = fs.readFileSync('package.json', 'utf-8');
-        const packageJSON = JSON.parse(packageJSONContent);
-        const mnemonic = packageJSON.config.mnemonic;
-        const web3Provider = new HDWalletProvider(mnemonic, ropstenRpcUrl);
-        const config = {
-            networkId: constants.ROPSTEN_NETWORK_ID,
-        };
-        const zeroEx = new ZeroEx(web3Provider, config);
-        it('token registry contract is deployed', async () => {
-            await (zeroEx.tokenRegistry as any)._getTokenRegistryContractAsync();
-        }).timeout(TIMEOUT);
-        it('proxy contract is deployed', async () => {
-            await (zeroEx.proxy as any)._getTokenTransferProxyContractAsync();
-        }).timeout(TIMEOUT);
-        it('exchange contract is deployed', async () => {
-            await (zeroEx.exchange as any)._getExchangeContractAsync();
-        }).timeout(TIMEOUT);
-    });
+	describe('contracts are deployed on kovan', () => {
+		const kovanRpcUrl = constants.KOVAN_RPC_URL;
+		const packageJSONContent = fs.readFileSync('package.json', 'utf-8');
+		const packageJSON = JSON.parse(packageJSONContent);
+		const mnemonic = packageJSON.config.mnemonic;
+		const web3Provider = new HDWalletProvider(mnemonic, kovanRpcUrl);
+		const config = {
+			networkId: constants.KOVAN_NETWORK_ID,
+		};
+		const zeroEx = new ZeroEx(web3Provider, config);
+		it('token registry contract is deployed', async () => {
+			await (zeroEx.tokenRegistry as any)._getTokenRegistryContractAsync();
+		}).timeout(TIMEOUT);
+		it('proxy contract is deployed', async () => {
+			await (zeroEx.proxy as any)._getTokenTransferProxyContractAsync();
+		}).timeout(TIMEOUT);
+		it('exchange contract is deployed', async () => {
+			await (zeroEx.exchange as any)._getExchangeContractAsync();
+		}).timeout(TIMEOUT);
+	});
+	describe('contracts are deployed on ropsten', () => {
+		const ropstenRpcUrl = constants.ROPSTEN_RPC_URL;
+		const packageJSONContent = fs.readFileSync('package.json', 'utf-8');
+		const packageJSON = JSON.parse(packageJSONContent);
+		const mnemonic = packageJSON.config.mnemonic;
+		const web3Provider = new HDWalletProvider(mnemonic, ropstenRpcUrl);
+		const config = {
+			networkId: constants.ROPSTEN_NETWORK_ID,
+		};
+		const zeroEx = new ZeroEx(web3Provider, config);
+		it('token registry contract is deployed', async () => {
+			await (zeroEx.tokenRegistry as any)._getTokenRegistryContractAsync();
+		}).timeout(TIMEOUT);
+		it('proxy contract is deployed', async () => {
+			await (zeroEx.proxy as any)._getTokenTransferProxyContractAsync();
+		}).timeout(TIMEOUT);
+		it('exchange contract is deployed', async () => {
+			await (zeroEx.exchange as any)._getExchangeContractAsync();
+		}).timeout(TIMEOUT);
+	});
 });
diff --git a/packages/0x.js/test/assert_test.ts b/packages/0x.js/test/assert_test.ts
index 1f2820070..2c72a5e88 100644
--- a/packages/0x.js/test/assert_test.ts
+++ b/packages/0x.js/test/assert_test.ts
@@ -10,34 +10,34 @@ import { web3Factory } from './utils/web3_factory';
 const expect = chai.expect;
 
 describe('Assertion library', () => {
-    const web3 = web3Factory.create();
-    const config = {
-        networkId: constants.TESTRPC_NETWORK_ID,
-    };
-    const zeroEx = new ZeroEx(web3.currentProvider, config);
-    describe('#isSenderAddressHexAsync', () => {
-        it('throws when address is invalid', async () => {
-            const address = '0xdeadbeef';
-            const varName = 'address';
-            return expect(
-                assert.isSenderAddressAsync(varName, address, (zeroEx as any)._web3Wrapper),
-            ).to.be.rejectedWith(`Expected ${varName} to be of type ETHAddressHex, encountered: ${address}`);
-        });
-        it('throws when address is unavailable', async () => {
-            const validUnrelatedAddress = '0x8b0292b11a196601eddce54b665cafeca0347d42';
-            const varName = 'address';
-            return expect(
-                assert.isSenderAddressAsync(varName, validUnrelatedAddress, (zeroEx as any)._web3Wrapper),
-            ).to.be.rejectedWith(
-                `Specified ${varName} ${validUnrelatedAddress} isn't available through the supplied web3 provider`,
-            );
-        });
-        it("doesn't throw if address is available", async () => {
-            const availableAddress = (await zeroEx.getAvailableAddressesAsync())[0];
-            const varName = 'address';
-            return expect(
-                assert.isSenderAddressAsync(varName, availableAddress, (zeroEx as any)._web3Wrapper),
-            ).to.become(undefined);
-        });
-    });
+	const web3 = web3Factory.create();
+	const config = {
+		networkId: constants.TESTRPC_NETWORK_ID,
+	};
+	const zeroEx = new ZeroEx(web3.currentProvider, config);
+	describe('#isSenderAddressHexAsync', () => {
+		it('throws when address is invalid', async () => {
+			const address = '0xdeadbeef';
+			const varName = 'address';
+			return expect(
+				assert.isSenderAddressAsync(varName, address, (zeroEx as any)._web3Wrapper),
+			).to.be.rejectedWith(`Expected ${varName} to be of type ETHAddressHex, encountered: ${address}`);
+		});
+		it('throws when address is unavailable', async () => {
+			const validUnrelatedAddress = '0x8b0292b11a196601eddce54b665cafeca0347d42';
+			const varName = 'address';
+			return expect(
+				assert.isSenderAddressAsync(varName, validUnrelatedAddress, (zeroEx as any)._web3Wrapper),
+			).to.be.rejectedWith(
+				`Specified ${varName} ${validUnrelatedAddress} isn't available through the supplied web3 provider`,
+			);
+		});
+		it("doesn't throw if address is available", async () => {
+			const availableAddress = (await zeroEx.getAvailableAddressesAsync())[0];
+			const varName = 'address';
+			return expect(
+				assert.isSenderAddressAsync(varName, availableAddress, (zeroEx as any)._web3Wrapper),
+			).to.become(undefined);
+		});
+	});
 });
diff --git a/packages/0x.js/test/ether_token_wrapper_test.ts b/packages/0x.js/test/ether_token_wrapper_test.ts
index b810fc9f1..67e62dc12 100644
--- a/packages/0x.js/test/ether_token_wrapper_test.ts
+++ b/packages/0x.js/test/ether_token_wrapper_test.ts
@@ -5,17 +5,17 @@ import 'mocha';
 import * as Web3 from 'web3';
 
 import {
-    ApprovalContractEventArgs,
-    BlockParamLiteral,
-    BlockRange,
-    DecodedLogEvent,
-    DepositContractEventArgs,
-    EtherTokenEvents,
-    Token,
-    TransferContractEventArgs,
-    WithdrawalContractEventArgs,
-    ZeroEx,
-    ZeroExError,
+	ApprovalContractEventArgs,
+	BlockParamLiteral,
+	BlockRange,
+	DecodedLogEvent,
+	DepositContractEventArgs,
+	EtherTokenEvents,
+	Token,
+	TransferContractEventArgs,
+	WithdrawalContractEventArgs,
+	ZeroEx,
+	ZeroExError,
 } from '../src';
 import { artifacts } from '../src/artifacts';
 import { DoneCallback } from '../src/types';
@@ -37,339 +37,339 @@ const blockchainLifecycle = new BlockchainLifecycle(constants.RPC_URL);
 const MAX_REASONABLE_GAS_COST_IN_WEI = 62517;
 
 describe('EtherTokenWrapper', () => {
-    let web3: Web3;
-    let zeroEx: ZeroEx;
-    let tokens: Token[];
-    let userAddresses: string[];
-    let addressWithETH: string;
-    let wethContractAddress: string;
-    let depositWeiAmount: BigNumber;
-    let decimalPlaces: number;
-    let addressWithoutFunds: string;
-    const gasPrice = new BigNumber(1);
-    const zeroExConfig = {
-        gasPrice,
-        networkId: constants.TESTRPC_NETWORK_ID,
-    };
-    const transferAmount = new BigNumber(42);
-    const allowanceAmount = new BigNumber(42);
-    const depositAmount = new BigNumber(42);
-    const withdrawalAmount = new BigNumber(42);
-    before(async () => {
-        web3 = web3Factory.create();
-        zeroEx = new ZeroEx(web3.currentProvider, zeroExConfig);
-        tokens = await zeroEx.tokenRegistry.getTokensAsync();
-        userAddresses = await zeroEx.getAvailableAddressesAsync();
-        addressWithETH = userAddresses[0];
-        wethContractAddress = (zeroEx.etherToken as any)._getContractAddress(artifacts.EtherTokenArtifact);
-        depositWeiAmount = (zeroEx as any)._web3Wrapper.toWei(new BigNumber(5));
-        decimalPlaces = 7;
-        addressWithoutFunds = userAddresses[1];
-    });
-    beforeEach(async () => {
-        await blockchainLifecycle.startAsync();
-    });
-    afterEach(async () => {
-        await blockchainLifecycle.revertAsync();
-    });
-    describe('#depositAsync', () => {
-        it('should successfully deposit ETH and issue Wrapped ETH tokens', async () => {
-            const preETHBalance = await (zeroEx as any)._web3Wrapper.getBalanceInWeiAsync(addressWithETH);
-            const preWETHBalance = await zeroEx.token.getBalanceAsync(wethContractAddress, addressWithETH);
-            expect(preETHBalance).to.be.bignumber.gt(0);
-            expect(preWETHBalance).to.be.bignumber.equal(0);
+	let web3: Web3;
+	let zeroEx: ZeroEx;
+	let tokens: Token[];
+	let userAddresses: string[];
+	let addressWithETH: string;
+	let wethContractAddress: string;
+	let depositWeiAmount: BigNumber;
+	let decimalPlaces: number;
+	let addressWithoutFunds: string;
+	const gasPrice = new BigNumber(1);
+	const zeroExConfig = {
+		gasPrice,
+		networkId: constants.TESTRPC_NETWORK_ID,
+	};
+	const transferAmount = new BigNumber(42);
+	const allowanceAmount = new BigNumber(42);
+	const depositAmount = new BigNumber(42);
+	const withdrawalAmount = new BigNumber(42);
+	before(async () => {
+		web3 = web3Factory.create();
+		zeroEx = new ZeroEx(web3.currentProvider, zeroExConfig);
+		tokens = await zeroEx.tokenRegistry.getTokensAsync();
+		userAddresses = await zeroEx.getAvailableAddressesAsync();
+		addressWithETH = userAddresses[0];
+		wethContractAddress = (zeroEx.etherToken as any)._getContractAddress(artifacts.EtherTokenArtifact);
+		depositWeiAmount = (zeroEx as any)._web3Wrapper.toWei(new BigNumber(5));
+		decimalPlaces = 7;
+		addressWithoutFunds = userAddresses[1];
+	});
+	beforeEach(async () => {
+		await blockchainLifecycle.startAsync();
+	});
+	afterEach(async () => {
+		await blockchainLifecycle.revertAsync();
+	});
+	describe('#depositAsync', () => {
+		it('should successfully deposit ETH and issue Wrapped ETH tokens', async () => {
+			const preETHBalance = await (zeroEx as any)._web3Wrapper.getBalanceInWeiAsync(addressWithETH);
+			const preWETHBalance = await zeroEx.token.getBalanceAsync(wethContractAddress, addressWithETH);
+			expect(preETHBalance).to.be.bignumber.gt(0);
+			expect(preWETHBalance).to.be.bignumber.equal(0);
 
-            const txHash = await zeroEx.etherToken.depositAsync(wethContractAddress, depositWeiAmount, addressWithETH);
-            await zeroEx.awaitTransactionMinedAsync(txHash);
+			const txHash = await zeroEx.etherToken.depositAsync(wethContractAddress, depositWeiAmount, addressWithETH);
+			await zeroEx.awaitTransactionMinedAsync(txHash);
 
-            const postETHBalanceInWei = await (zeroEx as any)._web3Wrapper.getBalanceInWeiAsync(addressWithETH);
-            const postWETHBalanceInBaseUnits = await zeroEx.token.getBalanceAsync(wethContractAddress, addressWithETH);
+			const postETHBalanceInWei = await (zeroEx as any)._web3Wrapper.getBalanceInWeiAsync(addressWithETH);
+			const postWETHBalanceInBaseUnits = await zeroEx.token.getBalanceAsync(wethContractAddress, addressWithETH);
 
-            expect(postWETHBalanceInBaseUnits).to.be.bignumber.equal(depositWeiAmount);
-            const remainingETHInWei = preETHBalance.minus(depositWeiAmount);
-            const gasCost = remainingETHInWei.minus(postETHBalanceInWei);
-            expect(gasCost).to.be.bignumber.lte(MAX_REASONABLE_GAS_COST_IN_WEI);
-        });
-        it('should throw if user has insufficient ETH balance for deposit', async () => {
-            const preETHBalance = await (zeroEx as any)._web3Wrapper.getBalanceInWeiAsync(addressWithETH);
+			expect(postWETHBalanceInBaseUnits).to.be.bignumber.equal(depositWeiAmount);
+			const remainingETHInWei = preETHBalance.minus(depositWeiAmount);
+			const gasCost = remainingETHInWei.minus(postETHBalanceInWei);
+			expect(gasCost).to.be.bignumber.lte(MAX_REASONABLE_GAS_COST_IN_WEI);
+		});
+		it('should throw if user has insufficient ETH balance for deposit', async () => {
+			const preETHBalance = await (zeroEx as any)._web3Wrapper.getBalanceInWeiAsync(addressWithETH);
 
-            const extraETHBalance = (zeroEx as any)._web3Wrapper.toWei(5, 'ether');
-            const overETHBalanceinWei = preETHBalance.add(extraETHBalance);
+			const extraETHBalance = (zeroEx as any)._web3Wrapper.toWei(5, 'ether');
+			const overETHBalanceinWei = preETHBalance.add(extraETHBalance);
 
-            return expect(
-                zeroEx.etherToken.depositAsync(wethContractAddress, overETHBalanceinWei, addressWithETH),
-            ).to.be.rejectedWith(ZeroExError.InsufficientEthBalanceForDeposit);
-        });
-    });
-    describe('#withdrawAsync', () => {
-        it('should successfully withdraw ETH in return for Wrapped ETH tokens', async () => {
-            const ETHBalanceInWei = await (zeroEx as any)._web3Wrapper.getBalanceInWeiAsync(addressWithETH);
+			return expect(
+				zeroEx.etherToken.depositAsync(wethContractAddress, overETHBalanceinWei, addressWithETH),
+			).to.be.rejectedWith(ZeroExError.InsufficientEthBalanceForDeposit);
+		});
+	});
+	describe('#withdrawAsync', () => {
+		it('should successfully withdraw ETH in return for Wrapped ETH tokens', async () => {
+			const ETHBalanceInWei = await (zeroEx as any)._web3Wrapper.getBalanceInWeiAsync(addressWithETH);
 
-            await zeroEx.etherToken.depositAsync(wethContractAddress, depositWeiAmount, addressWithETH);
+			await zeroEx.etherToken.depositAsync(wethContractAddress, depositWeiAmount, addressWithETH);
 
-            const expectedPreETHBalance = ETHBalanceInWei.minus(depositWeiAmount);
-            const preETHBalance = await (zeroEx as any)._web3Wrapper.getBalanceInWeiAsync(addressWithETH);
-            const preWETHBalance = await zeroEx.token.getBalanceAsync(wethContractAddress, addressWithETH);
-            let gasCost = expectedPreETHBalance.minus(preETHBalance);
-            expect(gasCost).to.be.bignumber.lte(MAX_REASONABLE_GAS_COST_IN_WEI);
-            expect(preWETHBalance).to.be.bignumber.equal(depositWeiAmount);
+			const expectedPreETHBalance = ETHBalanceInWei.minus(depositWeiAmount);
+			const preETHBalance = await (zeroEx as any)._web3Wrapper.getBalanceInWeiAsync(addressWithETH);
+			const preWETHBalance = await zeroEx.token.getBalanceAsync(wethContractAddress, addressWithETH);
+			let gasCost = expectedPreETHBalance.minus(preETHBalance);
+			expect(gasCost).to.be.bignumber.lte(MAX_REASONABLE_GAS_COST_IN_WEI);
+			expect(preWETHBalance).to.be.bignumber.equal(depositWeiAmount);
 
-            const txHash = await zeroEx.etherToken.withdrawAsync(wethContractAddress, depositWeiAmount, addressWithETH);
-            await zeroEx.awaitTransactionMinedAsync(txHash);
+			const txHash = await zeroEx.etherToken.withdrawAsync(wethContractAddress, depositWeiAmount, addressWithETH);
+			await zeroEx.awaitTransactionMinedAsync(txHash);
 
-            const postETHBalance = await (zeroEx as any)._web3Wrapper.getBalanceInWeiAsync(addressWithETH);
-            const postWETHBalanceInBaseUnits = await zeroEx.token.getBalanceAsync(wethContractAddress, addressWithETH);
+			const postETHBalance = await (zeroEx as any)._web3Wrapper.getBalanceInWeiAsync(addressWithETH);
+			const postWETHBalanceInBaseUnits = await zeroEx.token.getBalanceAsync(wethContractAddress, addressWithETH);
 
-            expect(postWETHBalanceInBaseUnits).to.be.bignumber.equal(0);
-            const expectedETHBalance = preETHBalance.add(depositWeiAmount).round(decimalPlaces);
-            gasCost = expectedETHBalance.minus(postETHBalance);
-            expect(gasCost).to.be.bignumber.lte(MAX_REASONABLE_GAS_COST_IN_WEI);
-        });
-        it('should throw if user has insufficient WETH balance for withdrawl', async () => {
-            const preWETHBalance = await zeroEx.token.getBalanceAsync(wethContractAddress, addressWithETH);
-            expect(preWETHBalance).to.be.bignumber.equal(0);
+			expect(postWETHBalanceInBaseUnits).to.be.bignumber.equal(0);
+			const expectedETHBalance = preETHBalance.add(depositWeiAmount).round(decimalPlaces);
+			gasCost = expectedETHBalance.minus(postETHBalance);
+			expect(gasCost).to.be.bignumber.lte(MAX_REASONABLE_GAS_COST_IN_WEI);
+		});
+		it('should throw if user has insufficient WETH balance for withdrawl', async () => {
+			const preWETHBalance = await zeroEx.token.getBalanceAsync(wethContractAddress, addressWithETH);
+			expect(preWETHBalance).to.be.bignumber.equal(0);
 
-            const overWETHBalance = preWETHBalance.add(999999999);
+			const overWETHBalance = preWETHBalance.add(999999999);
 
-            return expect(
-                zeroEx.etherToken.withdrawAsync(wethContractAddress, overWETHBalance, addressWithETH),
-            ).to.be.rejectedWith(ZeroExError.InsufficientWEthBalanceForWithdrawal);
-        });
-    });
-    describe('#subscribe', () => {
-        const indexFilterValues = {};
-        let etherTokenAddress: string;
-        before(() => {
-            const tokenUtils = new TokenUtils(tokens);
-            const etherToken = tokenUtils.getWethTokenOrThrow();
-            etherTokenAddress = etherToken.address;
-        });
-        afterEach(() => {
-            zeroEx.etherToken.unsubscribeAll();
-        });
-        // Hack: Mocha does not allow a test to be both async and have a `done` callback
-        // Since we need to await the receipt of the event in the `subscribe` callback,
-        // we do need both. A hack is to make the top-level async fn w/ a done callback and then
-        // wrap the rest of the test in an async block
-        // Source: https://github.com/mochajs/mocha/issues/2407
-        it('Should receive the Transfer event when tokens are transfered', (done: DoneCallback) => {
-            (async () => {
-                const callback = reportNodeCallbackErrors(done)(
-                    (logEvent: DecodedLogEvent<TransferContractEventArgs>) => {
-                        expect(logEvent).to.not.be.undefined();
-                        expect(logEvent.isRemoved).to.be.false();
-                        expect(logEvent.log.logIndex).to.be.equal(0);
-                        expect(logEvent.log.transactionIndex).to.be.equal(0);
-                        expect(logEvent.log.blockNumber).to.be.a('number');
-                        const args = logEvent.log.args;
-                        expect(args._from).to.be.equal(addressWithETH);
-                        expect(args._to).to.be.equal(addressWithoutFunds);
-                        expect(args._value).to.be.bignumber.equal(transferAmount);
-                    },
-                );
-                await zeroEx.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH);
-                zeroEx.etherToken.subscribe(etherTokenAddress, EtherTokenEvents.Transfer, indexFilterValues, callback);
-                await zeroEx.token.transferAsync(
-                    etherTokenAddress,
-                    addressWithETH,
-                    addressWithoutFunds,
-                    transferAmount,
-                );
-            })().catch(done);
-        });
-        it('Should receive the Approval event when allowance is being set', (done: DoneCallback) => {
-            (async () => {
-                const callback = reportNodeCallbackErrors(done)(
-                    (logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
-                        expect(logEvent).to.not.be.undefined();
-                        expect(logEvent.isRemoved).to.be.false();
-                        const args = logEvent.log.args;
-                        expect(args._owner).to.be.equal(addressWithETH);
-                        expect(args._spender).to.be.equal(addressWithoutFunds);
-                        expect(args._value).to.be.bignumber.equal(allowanceAmount);
-                    },
-                );
-                zeroEx.etherToken.subscribe(etherTokenAddress, EtherTokenEvents.Approval, indexFilterValues, callback);
-                await zeroEx.token.setAllowanceAsync(
-                    etherTokenAddress,
-                    addressWithETH,
-                    addressWithoutFunds,
-                    allowanceAmount,
-                );
-            })().catch(done);
-        });
-        it('Should receive the Deposit event when ether is being deposited', (done: DoneCallback) => {
-            (async () => {
-                const callback = reportNodeCallbackErrors(done)(
-                    (logEvent: DecodedLogEvent<DepositContractEventArgs>) => {
-                        expect(logEvent).to.not.be.undefined();
-                        expect(logEvent.isRemoved).to.be.false();
-                        const args = logEvent.log.args;
-                        expect(args._owner).to.be.equal(addressWithETH);
-                        expect(args._value).to.be.bignumber.equal(depositAmount);
-                    },
-                );
-                zeroEx.etherToken.subscribe(etherTokenAddress, EtherTokenEvents.Deposit, indexFilterValues, callback);
-                await zeroEx.etherToken.depositAsync(etherTokenAddress, depositAmount, addressWithETH);
-            })().catch(done);
-        });
-        it('Should receive the Withdrawal event when ether is being withdrawn', (done: DoneCallback) => {
-            (async () => {
-                const callback = reportNodeCallbackErrors(done)(
-                    (logEvent: DecodedLogEvent<WithdrawalContractEventArgs>) => {
-                        expect(logEvent).to.not.be.undefined();
-                        expect(logEvent.isRemoved).to.be.false();
-                        const args = logEvent.log.args;
-                        expect(args._owner).to.be.equal(addressWithETH);
-                        expect(args._value).to.be.bignumber.equal(depositAmount);
-                    },
-                );
-                await zeroEx.etherToken.depositAsync(etherTokenAddress, depositAmount, addressWithETH);
-                zeroEx.etherToken.subscribe(
-                    etherTokenAddress,
-                    EtherTokenEvents.Withdrawal,
-                    indexFilterValues,
-                    callback,
-                );
-                await zeroEx.etherToken.withdrawAsync(etherTokenAddress, withdrawalAmount, addressWithETH);
-            })().catch(done);
-        });
-        it('should cancel outstanding subscriptions when ZeroEx.setProvider is called', (done: DoneCallback) => {
-            (async () => {
-                const callbackNeverToBeCalled = reportNodeCallbackErrors(done)(
-                    (logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
-                        done(new Error('Expected this subscription to have been cancelled'));
-                    },
-                );
-                zeroEx.etherToken.subscribe(
-                    etherTokenAddress,
-                    EtherTokenEvents.Transfer,
-                    indexFilterValues,
-                    callbackNeverToBeCalled,
-                );
-                const callbackToBeCalled = reportNodeCallbackErrors(done)();
-                const newProvider = web3Factory.getRpcProvider();
-                zeroEx.setProvider(newProvider, constants.TESTRPC_NETWORK_ID);
-                await zeroEx.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH);
-                zeroEx.etherToken.subscribe(
-                    etherTokenAddress,
-                    EtherTokenEvents.Transfer,
-                    indexFilterValues,
-                    callbackToBeCalled,
-                );
-                await zeroEx.token.transferAsync(
-                    etherTokenAddress,
-                    addressWithETH,
-                    addressWithoutFunds,
-                    transferAmount,
-                );
-            })().catch(done);
-        });
-        it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => {
-            (async () => {
-                const callbackNeverToBeCalled = reportNodeCallbackErrors(done)(
-                    (logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
-                        done(new Error('Expected this subscription to have been cancelled'));
-                    },
-                );
-                await zeroEx.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH);
-                const subscriptionToken = zeroEx.etherToken.subscribe(
-                    etherTokenAddress,
-                    EtherTokenEvents.Transfer,
-                    indexFilterValues,
-                    callbackNeverToBeCalled,
-                );
-                zeroEx.etherToken.unsubscribe(subscriptionToken);
-                await zeroEx.token.transferAsync(
-                    etherTokenAddress,
-                    addressWithETH,
-                    addressWithoutFunds,
-                    transferAmount,
-                );
-                done();
-            })().catch(done);
-        });
-    });
-    describe('#getLogsAsync', () => {
-        let etherTokenAddress: string;
-        let tokenTransferProxyAddress: string;
-        const blockRange: BlockRange = {
-            fromBlock: 0,
-            toBlock: BlockParamLiteral.Latest,
-        };
-        let txHash: string;
-        before(() => {
-            addressWithETH = userAddresses[0];
-            const tokenUtils = new TokenUtils(tokens);
-            const etherToken = tokenUtils.getWethTokenOrThrow();
-            etherTokenAddress = etherToken.address;
-            tokenTransferProxyAddress = zeroEx.proxy.getContractAddress();
-        });
-        it('should get logs with decoded args emitted by Approval', async () => {
-            txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(etherTokenAddress, addressWithETH);
-            await zeroEx.awaitTransactionMinedAsync(txHash);
-            const eventName = EtherTokenEvents.Approval;
-            const indexFilterValues = {};
-            const logs = await zeroEx.etherToken.getLogsAsync<ApprovalContractEventArgs>(
-                etherTokenAddress,
-                eventName,
-                blockRange,
-                indexFilterValues,
-            );
-            expect(logs).to.have.length(1);
-            const args = logs[0].args;
-            expect(logs[0].event).to.be.equal(eventName);
-            expect(args._owner).to.be.equal(addressWithETH);
-            expect(args._spender).to.be.equal(tokenTransferProxyAddress);
-            expect(args._value).to.be.bignumber.equal(zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
-        });
-        it('should get logs with decoded args emitted by Deposit', async () => {
-            await zeroEx.etherToken.depositAsync(etherTokenAddress, depositAmount, addressWithETH);
-            const eventName = EtherTokenEvents.Deposit;
-            const indexFilterValues = {};
-            const logs = await zeroEx.etherToken.getLogsAsync<DepositContractEventArgs>(
-                etherTokenAddress,
-                eventName,
-                blockRange,
-                indexFilterValues,
-            );
-            expect(logs).to.have.length(1);
-            const args = logs[0].args;
-            expect(logs[0].event).to.be.equal(eventName);
-            expect(args._owner).to.be.equal(addressWithETH);
-            expect(args._value).to.be.bignumber.equal(depositAmount);
-        });
-        it('should only get the logs with the correct event name', async () => {
-            txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(etherTokenAddress, addressWithETH);
-            await zeroEx.awaitTransactionMinedAsync(txHash);
-            const differentEventName = EtherTokenEvents.Transfer;
-            const indexFilterValues = {};
-            const logs = await zeroEx.etherToken.getLogsAsync(
-                etherTokenAddress,
-                differentEventName,
-                blockRange,
-                indexFilterValues,
-            );
-            expect(logs).to.have.length(0);
-        });
-        it('should only get the logs with the correct indexed fields', async () => {
-            txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(etherTokenAddress, addressWithETH);
-            await zeroEx.awaitTransactionMinedAsync(txHash);
-            txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(etherTokenAddress, addressWithoutFunds);
-            await zeroEx.awaitTransactionMinedAsync(txHash);
-            const eventName = EtherTokenEvents.Approval;
-            const indexFilterValues = {
-                _owner: addressWithETH,
-            };
-            const logs = await zeroEx.etherToken.getLogsAsync<ApprovalContractEventArgs>(
-                etherTokenAddress,
-                eventName,
-                blockRange,
-                indexFilterValues,
-            );
-            expect(logs).to.have.length(1);
-            const args = logs[0].args;
-            expect(args._owner).to.be.equal(addressWithETH);
-        });
-    });
+			return expect(
+				zeroEx.etherToken.withdrawAsync(wethContractAddress, overWETHBalance, addressWithETH),
+			).to.be.rejectedWith(ZeroExError.InsufficientWEthBalanceForWithdrawal);
+		});
+	});
+	describe('#subscribe', () => {
+		const indexFilterValues = {};
+		let etherTokenAddress: string;
+		before(() => {
+			const tokenUtils = new TokenUtils(tokens);
+			const etherToken = tokenUtils.getWethTokenOrThrow();
+			etherTokenAddress = etherToken.address;
+		});
+		afterEach(() => {
+			zeroEx.etherToken.unsubscribeAll();
+		});
+		// Hack: Mocha does not allow a test to be both async and have a `done` callback
+		// Since we need to await the receipt of the event in the `subscribe` callback,
+		// we do need both. A hack is to make the top-level async fn w/ a done callback and then
+		// wrap the rest of the test in an async block
+		// Source: https://github.com/mochajs/mocha/issues/2407
+		it('Should receive the Transfer event when tokens are transfered', (done: DoneCallback) => {
+			(async () => {
+				const callback = reportNodeCallbackErrors(done)(
+					(logEvent: DecodedLogEvent<TransferContractEventArgs>) => {
+						expect(logEvent).to.not.be.undefined();
+						expect(logEvent.isRemoved).to.be.false();
+						expect(logEvent.log.logIndex).to.be.equal(0);
+						expect(logEvent.log.transactionIndex).to.be.equal(0);
+						expect(logEvent.log.blockNumber).to.be.a('number');
+						const args = logEvent.log.args;
+						expect(args._from).to.be.equal(addressWithETH);
+						expect(args._to).to.be.equal(addressWithoutFunds);
+						expect(args._value).to.be.bignumber.equal(transferAmount);
+					},
+				);
+				await zeroEx.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH);
+				zeroEx.etherToken.subscribe(etherTokenAddress, EtherTokenEvents.Transfer, indexFilterValues, callback);
+				await zeroEx.token.transferAsync(
+					etherTokenAddress,
+					addressWithETH,
+					addressWithoutFunds,
+					transferAmount,
+				);
+			})().catch(done);
+		});
+		it('Should receive the Approval event when allowance is being set', (done: DoneCallback) => {
+			(async () => {
+				const callback = reportNodeCallbackErrors(done)(
+					(logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
+						expect(logEvent).to.not.be.undefined();
+						expect(logEvent.isRemoved).to.be.false();
+						const args = logEvent.log.args;
+						expect(args._owner).to.be.equal(addressWithETH);
+						expect(args._spender).to.be.equal(addressWithoutFunds);
+						expect(args._value).to.be.bignumber.equal(allowanceAmount);
+					},
+				);
+				zeroEx.etherToken.subscribe(etherTokenAddress, EtherTokenEvents.Approval, indexFilterValues, callback);
+				await zeroEx.token.setAllowanceAsync(
+					etherTokenAddress,
+					addressWithETH,
+					addressWithoutFunds,
+					allowanceAmount,
+				);
+			})().catch(done);
+		});
+		it('Should receive the Deposit event when ether is being deposited', (done: DoneCallback) => {
+			(async () => {
+				const callback = reportNodeCallbackErrors(done)(
+					(logEvent: DecodedLogEvent<DepositContractEventArgs>) => {
+						expect(logEvent).to.not.be.undefined();
+						expect(logEvent.isRemoved).to.be.false();
+						const args = logEvent.log.args;
+						expect(args._owner).to.be.equal(addressWithETH);
+						expect(args._value).to.be.bignumber.equal(depositAmount);
+					},
+				);
+				zeroEx.etherToken.subscribe(etherTokenAddress, EtherTokenEvents.Deposit, indexFilterValues, callback);
+				await zeroEx.etherToken.depositAsync(etherTokenAddress, depositAmount, addressWithETH);
+			})().catch(done);
+		});
+		it('Should receive the Withdrawal event when ether is being withdrawn', (done: DoneCallback) => {
+			(async () => {
+				const callback = reportNodeCallbackErrors(done)(
+					(logEvent: DecodedLogEvent<WithdrawalContractEventArgs>) => {
+						expect(logEvent).to.not.be.undefined();
+						expect(logEvent.isRemoved).to.be.false();
+						const args = logEvent.log.args;
+						expect(args._owner).to.be.equal(addressWithETH);
+						expect(args._value).to.be.bignumber.equal(depositAmount);
+					},
+				);
+				await zeroEx.etherToken.depositAsync(etherTokenAddress, depositAmount, addressWithETH);
+				zeroEx.etherToken.subscribe(
+					etherTokenAddress,
+					EtherTokenEvents.Withdrawal,
+					indexFilterValues,
+					callback,
+				);
+				await zeroEx.etherToken.withdrawAsync(etherTokenAddress, withdrawalAmount, addressWithETH);
+			})().catch(done);
+		});
+		it('should cancel outstanding subscriptions when ZeroEx.setProvider is called', (done: DoneCallback) => {
+			(async () => {
+				const callbackNeverToBeCalled = reportNodeCallbackErrors(done)(
+					(logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
+						done(new Error('Expected this subscription to have been cancelled'));
+					},
+				);
+				zeroEx.etherToken.subscribe(
+					etherTokenAddress,
+					EtherTokenEvents.Transfer,
+					indexFilterValues,
+					callbackNeverToBeCalled,
+				);
+				const callbackToBeCalled = reportNodeCallbackErrors(done)();
+				const newProvider = web3Factory.getRpcProvider();
+				zeroEx.setProvider(newProvider, constants.TESTRPC_NETWORK_ID);
+				await zeroEx.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH);
+				zeroEx.etherToken.subscribe(
+					etherTokenAddress,
+					EtherTokenEvents.Transfer,
+					indexFilterValues,
+					callbackToBeCalled,
+				);
+				await zeroEx.token.transferAsync(
+					etherTokenAddress,
+					addressWithETH,
+					addressWithoutFunds,
+					transferAmount,
+				);
+			})().catch(done);
+		});
+		it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => {
+			(async () => {
+				const callbackNeverToBeCalled = reportNodeCallbackErrors(done)(
+					(logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
+						done(new Error('Expected this subscription to have been cancelled'));
+					},
+				);
+				await zeroEx.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH);
+				const subscriptionToken = zeroEx.etherToken.subscribe(
+					etherTokenAddress,
+					EtherTokenEvents.Transfer,
+					indexFilterValues,
+					callbackNeverToBeCalled,
+				);
+				zeroEx.etherToken.unsubscribe(subscriptionToken);
+				await zeroEx.token.transferAsync(
+					etherTokenAddress,
+					addressWithETH,
+					addressWithoutFunds,
+					transferAmount,
+				);
+				done();
+			})().catch(done);
+		});
+	});
+	describe('#getLogsAsync', () => {
+		let etherTokenAddress: string;
+		let tokenTransferProxyAddress: string;
+		const blockRange: BlockRange = {
+			fromBlock: 0,
+			toBlock: BlockParamLiteral.Latest,
+		};
+		let txHash: string;
+		before(() => {
+			addressWithETH = userAddresses[0];
+			const tokenUtils = new TokenUtils(tokens);
+			const etherToken = tokenUtils.getWethTokenOrThrow();
+			etherTokenAddress = etherToken.address;
+			tokenTransferProxyAddress = zeroEx.proxy.getContractAddress();
+		});
+		it('should get logs with decoded args emitted by Approval', async () => {
+			txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(etherTokenAddress, addressWithETH);
+			await zeroEx.awaitTransactionMinedAsync(txHash);
+			const eventName = EtherTokenEvents.Approval;
+			const indexFilterValues = {};
+			const logs = await zeroEx.etherToken.getLogsAsync<ApprovalContractEventArgs>(
+				etherTokenAddress,
+				eventName,
+				blockRange,
+				indexFilterValues,
+			);
+			expect(logs).to.have.length(1);
+			const args = logs[0].args;
+			expect(logs[0].event).to.be.equal(eventName);
+			expect(args._owner).to.be.equal(addressWithETH);
+			expect(args._spender).to.be.equal(tokenTransferProxyAddress);
+			expect(args._value).to.be.bignumber.equal(zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
+		});
+		it('should get logs with decoded args emitted by Deposit', async () => {
+			await zeroEx.etherToken.depositAsync(etherTokenAddress, depositAmount, addressWithETH);
+			const eventName = EtherTokenEvents.Deposit;
+			const indexFilterValues = {};
+			const logs = await zeroEx.etherToken.getLogsAsync<DepositContractEventArgs>(
+				etherTokenAddress,
+				eventName,
+				blockRange,
+				indexFilterValues,
+			);
+			expect(logs).to.have.length(1);
+			const args = logs[0].args;
+			expect(logs[0].event).to.be.equal(eventName);
+			expect(args._owner).to.be.equal(addressWithETH);
+			expect(args._value).to.be.bignumber.equal(depositAmount);
+		});
+		it('should only get the logs with the correct event name', async () => {
+			txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(etherTokenAddress, addressWithETH);
+			await zeroEx.awaitTransactionMinedAsync(txHash);
+			const differentEventName = EtherTokenEvents.Transfer;
+			const indexFilterValues = {};
+			const logs = await zeroEx.etherToken.getLogsAsync(
+				etherTokenAddress,
+				differentEventName,
+				blockRange,
+				indexFilterValues,
+			);
+			expect(logs).to.have.length(0);
+		});
+		it('should only get the logs with the correct indexed fields', async () => {
+			txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(etherTokenAddress, addressWithETH);
+			await zeroEx.awaitTransactionMinedAsync(txHash);
+			txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(etherTokenAddress, addressWithoutFunds);
+			await zeroEx.awaitTransactionMinedAsync(txHash);
+			const eventName = EtherTokenEvents.Approval;
+			const indexFilterValues = {
+				_owner: addressWithETH,
+			};
+			const logs = await zeroEx.etherToken.getLogsAsync<ApprovalContractEventArgs>(
+				etherTokenAddress,
+				eventName,
+				blockRange,
+				indexFilterValues,
+			);
+			expect(logs).to.have.length(1);
+			const args = logs[0].args;
+			expect(args._owner).to.be.equal(addressWithETH);
+		});
+	});
 });
diff --git a/packages/0x.js/test/event_watcher_test.ts b/packages/0x.js/test/event_watcher_test.ts
index f92fb2b02..f0c97eced 100644
--- a/packages/0x.js/test/event_watcher_test.ts
+++ b/packages/0x.js/test/event_watcher_test.ts
@@ -17,110 +17,110 @@ chaiSetup.configure();
 const expect = chai.expect;
 
 describe('EventWatcher', () => {
-    let web3: Web3;
-    let stubs: Sinon.SinonStub[] = [];
-    let eventWatcher: EventWatcher;
-    let web3Wrapper: Web3Wrapper;
-    const logA: Web3.LogEntry = {
-        address: '0x71d271f8b14adef568f8f28f1587ce7271ac4ca5',
-        blockHash: null,
-        blockNumber: null,
-        data: '',
-        logIndex: null,
-        topics: [],
-        transactionHash: '0x004881d38cd4a8f72f1a0d68c8b9b8124504706041ff37019c1d1ed6bfda8e17',
-        transactionIndex: 0,
-    };
-    const logB: Web3.LogEntry = {
-        address: '0x8d12a197cb00d4747a1fe03395095ce2a5cc6819',
-        blockHash: null,
-        blockNumber: null,
-        data: '',
-        logIndex: null,
-        topics: ['0xf341246adaac6f497bc2a656f546ab9e182111d630394f0c57c710a59a2cb567'],
-        transactionHash: '0x01ef3c048b18d9b09ea195b4ed94cf8dd5f3d857a1905ff886b152cfb1166f25',
-        transactionIndex: 0,
-    };
-    const logC: Web3.LogEntry = {
-        address: '0x1d271f8b174adef58f1587ce68f8f27271ac4ca5',
-        blockHash: null,
-        blockNumber: null,
-        data: '',
-        logIndex: null,
-        topics: ['0xf341246adaac6f497bc2a656f546ab9e182111d630394f0c57c710a59a2cb567'],
-        transactionHash: '0x01ef3c048b18d9b09ea195b4ed94cf8dd5f3d857a1905ff886b152cfb1166f25',
-        transactionIndex: 0,
-    };
-    before(async () => {
-        web3 = web3Factory.create();
-        const pollingIntervalMs = 10;
-        web3Wrapper = new Web3Wrapper(web3.currentProvider);
-        eventWatcher = new EventWatcher(web3Wrapper, pollingIntervalMs);
-    });
-    afterEach(() => {
-        // clean up any stubs after the test has completed
-        _.each(stubs, s => s.restore());
-        stubs = [];
-        eventWatcher.unsubscribe();
-    });
-    it('correctly emits initial log events', (done: DoneCallback) => {
-        const logs: Web3.LogEntry[] = [logA, logB];
-        const expectedLogEvents = [
-            {
-                removed: false,
-                ...logA,
-            },
-            {
-                removed: false,
-                ...logB,
-            },
-        ];
-        const getLogsStub = Sinon.stub(web3Wrapper, 'getLogsAsync');
-        getLogsStub.onCall(0).returns(logs);
-        stubs.push(getLogsStub);
-        const expectedToBeCalledOnce = false;
-        const callback = reportNodeCallbackErrors(done, expectedToBeCalledOnce)((event: LogEvent) => {
-            const expectedLogEvent = expectedLogEvents.shift();
-            expect(event).to.be.deep.equal(expectedLogEvent);
-            if (_.isEmpty(expectedLogEvents)) {
-                done();
-            }
-        });
-        eventWatcher.subscribe(callback);
-    });
-    it('correctly computes the difference and emits only changes', (done: DoneCallback) => {
-        const initialLogs: Web3.LogEntry[] = [logA, logB];
-        const changedLogs: Web3.LogEntry[] = [logA, logC];
-        const expectedLogEvents = [
-            {
-                removed: false,
-                ...logA,
-            },
-            {
-                removed: false,
-                ...logB,
-            },
-            {
-                removed: true,
-                ...logB,
-            },
-            {
-                removed: false,
-                ...logC,
-            },
-        ];
-        const getLogsStub = Sinon.stub(web3Wrapper, 'getLogsAsync');
-        getLogsStub.onCall(0).returns(initialLogs);
-        getLogsStub.onCall(1).returns(changedLogs);
-        stubs.push(getLogsStub);
-        const expectedToBeCalledOnce = false;
-        const callback = reportNodeCallbackErrors(done, expectedToBeCalledOnce)((event: LogEvent) => {
-            const expectedLogEvent = expectedLogEvents.shift();
-            expect(event).to.be.deep.equal(expectedLogEvent);
-            if (_.isEmpty(expectedLogEvents)) {
-                done();
-            }
-        });
-        eventWatcher.subscribe(callback);
-    });
+	let web3: Web3;
+	let stubs: Sinon.SinonStub[] = [];
+	let eventWatcher: EventWatcher;
+	let web3Wrapper: Web3Wrapper;
+	const logA: Web3.LogEntry = {
+		address: '0x71d271f8b14adef568f8f28f1587ce7271ac4ca5',
+		blockHash: null,
+		blockNumber: null,
+		data: '',
+		logIndex: null,
+		topics: [],
+		transactionHash: '0x004881d38cd4a8f72f1a0d68c8b9b8124504706041ff37019c1d1ed6bfda8e17',
+		transactionIndex: 0,
+	};
+	const logB: Web3.LogEntry = {
+		address: '0x8d12a197cb00d4747a1fe03395095ce2a5cc6819',
+		blockHash: null,
+		blockNumber: null,
+		data: '',
+		logIndex: null,
+		topics: ['0xf341246adaac6f497bc2a656f546ab9e182111d630394f0c57c710a59a2cb567'],
+		transactionHash: '0x01ef3c048b18d9b09ea195b4ed94cf8dd5f3d857a1905ff886b152cfb1166f25',
+		transactionIndex: 0,
+	};
+	const logC: Web3.LogEntry = {
+		address: '0x1d271f8b174adef58f1587ce68f8f27271ac4ca5',
+		blockHash: null,
+		blockNumber: null,
+		data: '',
+		logIndex: null,
+		topics: ['0xf341246adaac6f497bc2a656f546ab9e182111d630394f0c57c710a59a2cb567'],
+		transactionHash: '0x01ef3c048b18d9b09ea195b4ed94cf8dd5f3d857a1905ff886b152cfb1166f25',
+		transactionIndex: 0,
+	};
+	before(async () => {
+		web3 = web3Factory.create();
+		const pollingIntervalMs = 10;
+		web3Wrapper = new Web3Wrapper(web3.currentProvider);
+		eventWatcher = new EventWatcher(web3Wrapper, pollingIntervalMs);
+	});
+	afterEach(() => {
+		// clean up any stubs after the test has completed
+		_.each(stubs, s => s.restore());
+		stubs = [];
+		eventWatcher.unsubscribe();
+	});
+	it('correctly emits initial log events', (done: DoneCallback) => {
+		const logs: Web3.LogEntry[] = [logA, logB];
+		const expectedLogEvents = [
+			{
+				removed: false,
+				...logA,
+			},
+			{
+				removed: false,
+				...logB,
+			},
+		];
+		const getLogsStub = Sinon.stub(web3Wrapper, 'getLogsAsync');
+		getLogsStub.onCall(0).returns(logs);
+		stubs.push(getLogsStub);
+		const expectedToBeCalledOnce = false;
+		const callback = reportNodeCallbackErrors(done, expectedToBeCalledOnce)((event: LogEvent) => {
+			const expectedLogEvent = expectedLogEvents.shift();
+			expect(event).to.be.deep.equal(expectedLogEvent);
+			if (_.isEmpty(expectedLogEvents)) {
+				done();
+			}
+		});
+		eventWatcher.subscribe(callback);
+	});
+	it('correctly computes the difference and emits only changes', (done: DoneCallback) => {
+		const initialLogs: Web3.LogEntry[] = [logA, logB];
+		const changedLogs: Web3.LogEntry[] = [logA, logC];
+		const expectedLogEvents = [
+			{
+				removed: false,
+				...logA,
+			},
+			{
+				removed: false,
+				...logB,
+			},
+			{
+				removed: true,
+				...logB,
+			},
+			{
+				removed: false,
+				...logC,
+			},
+		];
+		const getLogsStub = Sinon.stub(web3Wrapper, 'getLogsAsync');
+		getLogsStub.onCall(0).returns(initialLogs);
+		getLogsStub.onCall(1).returns(changedLogs);
+		stubs.push(getLogsStub);
+		const expectedToBeCalledOnce = false;
+		const callback = reportNodeCallbackErrors(done, expectedToBeCalledOnce)((event: LogEvent) => {
+			const expectedLogEvent = expectedLogEvents.shift();
+			expect(event).to.be.deep.equal(expectedLogEvent);
+			if (_.isEmpty(expectedLogEvents)) {
+				done();
+			}
+		});
+		eventWatcher.subscribe(callback);
+	});
 });
diff --git a/packages/0x.js/test/exchange_transfer_simulator_test.ts b/packages/0x.js/test/exchange_transfer_simulator_test.ts
index 20b4a05ca..9f4d76933 100644
--- a/packages/0x.js/test/exchange_transfer_simulator_test.ts
+++ b/packages/0x.js/test/exchange_transfer_simulator_test.ts
@@ -15,103 +15,103 @@ const expect = chai.expect;
 const blockchainLifecycle = new BlockchainLifecycle(constants.RPC_URL);
 
 describe('ExchangeTransferSimulator', () => {
-    const web3 = web3Factory.create();
-    const config = {
-        networkId: constants.TESTRPC_NETWORK_ID,
-    };
-    const zeroEx = new ZeroEx(web3.currentProvider, config);
-    const transferAmount = new BigNumber(5);
-    let userAddresses: string[];
-    let tokens: Token[];
-    let coinbase: string;
-    let sender: string;
-    let recipient: string;
-    let exampleTokenAddress: string;
-    let exchangeTransferSimulator: ExchangeTransferSimulator;
-    let txHash: string;
-    before(async () => {
-        userAddresses = await zeroEx.getAvailableAddressesAsync();
-        [coinbase, sender, recipient] = userAddresses;
-        tokens = await zeroEx.tokenRegistry.getTokensAsync();
-        exampleTokenAddress = tokens[0].address;
-    });
-    beforeEach(async () => {
-        await blockchainLifecycle.startAsync();
-    });
-    afterEach(async () => {
-        await blockchainLifecycle.revertAsync();
-    });
-    describe('#transferFromAsync', () => {
-        beforeEach(() => {
-            exchangeTransferSimulator = new ExchangeTransferSimulator(zeroEx.token, BlockParamLiteral.Latest);
-        });
-        it("throws if the user doesn't have enough allowance", async () => {
-            return expect(
-                exchangeTransferSimulator.transferFromAsync(
-                    exampleTokenAddress,
-                    sender,
-                    recipient,
-                    transferAmount,
-                    TradeSide.Taker,
-                    TransferType.Trade,
-                ),
-            ).to.be.rejectedWith(ExchangeContractErrs.InsufficientTakerAllowance);
-        });
-        it("throws if the user doesn't have enough balance", async () => {
-            txHash = await zeroEx.token.setProxyAllowanceAsync(exampleTokenAddress, sender, transferAmount);
-            await zeroEx.awaitTransactionMinedAsync(txHash);
-            return expect(
-                exchangeTransferSimulator.transferFromAsync(
-                    exampleTokenAddress,
-                    sender,
-                    recipient,
-                    transferAmount,
-                    TradeSide.Maker,
-                    TransferType.Trade,
-                ),
-            ).to.be.rejectedWith(ExchangeContractErrs.InsufficientMakerBalance);
-        });
-        it('updates balances and proxyAllowance after transfer', async () => {
-            txHash = await zeroEx.token.transferAsync(exampleTokenAddress, coinbase, sender, transferAmount);
-            await zeroEx.awaitTransactionMinedAsync(txHash);
-            txHash = await zeroEx.token.setProxyAllowanceAsync(exampleTokenAddress, sender, transferAmount);
-            await zeroEx.awaitTransactionMinedAsync(txHash);
-            await exchangeTransferSimulator.transferFromAsync(
-                exampleTokenAddress,
-                sender,
-                recipient,
-                transferAmount,
-                TradeSide.Taker,
-                TransferType.Trade,
-            );
-            const store = (exchangeTransferSimulator as any)._store;
-            const senderBalance = await store.getBalanceAsync(exampleTokenAddress, sender);
-            const recipientBalance = await store.getBalanceAsync(exampleTokenAddress, recipient);
-            const senderProxyAllowance = await store.getProxyAllowanceAsync(exampleTokenAddress, sender);
-            expect(senderBalance).to.be.bignumber.equal(0);
-            expect(recipientBalance).to.be.bignumber.equal(transferAmount);
-            expect(senderProxyAllowance).to.be.bignumber.equal(0);
-        });
-        it("doesn't update proxyAllowance after transfer if unlimited", async () => {
-            txHash = await zeroEx.token.transferAsync(exampleTokenAddress, coinbase, sender, transferAmount);
-            await zeroEx.awaitTransactionMinedAsync(txHash);
-            txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(exampleTokenAddress, sender);
-            await zeroEx.awaitTransactionMinedAsync(txHash);
-            await exchangeTransferSimulator.transferFromAsync(
-                exampleTokenAddress,
-                sender,
-                recipient,
-                transferAmount,
-                TradeSide.Taker,
-                TransferType.Trade,
-            );
-            const store = (exchangeTransferSimulator as any)._store;
-            const senderBalance = await store.getBalanceAsync(exampleTokenAddress, sender);
-            const recipientBalance = await store.getBalanceAsync(exampleTokenAddress, recipient);
-            const senderProxyAllowance = await store.getProxyAllowanceAsync(exampleTokenAddress, sender);
-            expect(senderBalance).to.be.bignumber.equal(0);
-            expect(recipientBalance).to.be.bignumber.equal(transferAmount);
-            expect(senderProxyAllowance).to.be.bignumber.equal(zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
-        });
-    });
+	const web3 = web3Factory.create();
+	const config = {
+		networkId: constants.TESTRPC_NETWORK_ID,
+	};
+	const zeroEx = new ZeroEx(web3.currentProvider, config);
+	const transferAmount = new BigNumber(5);
+	let userAddresses: string[];
+	let tokens: Token[];
+	let coinbase: string;
+	let sender: string;
+	let recipient: string;
+	let exampleTokenAddress: string;
+	let exchangeTransferSimulator: ExchangeTransferSimulator;
+	let txHash: string;
+	before(async () => {
+		userAddresses = await zeroEx.getAvailableAddressesAsync();
+		[coinbase, sender, recipient] = userAddresses;
+		tokens = await zeroEx.tokenRegistry.getTokensAsync();
+		exampleTokenAddress = tokens[0].address;
+	});
+	beforeEach(async () => {
+		await blockchainLifecycle.startAsync();
+	});
+	afterEach(async () => {
+		await blockchainLifecycle.revertAsync();
+	});
+	describe('#transferFromAsync', () => {
+		beforeEach(() => {
+			exchangeTransferSimulator = new ExchangeTransferSimulator(zeroEx.token, BlockParamLiteral.Latest);
+		});
+		it("throws if the user doesn't have enough allowance", async () => {
+			return expect(
+				exchangeTransferSimulator.transferFromAsync(
+					exampleTokenAddress,
+					sender,
+					recipient,
+					transferAmount,
+					TradeSide.Taker,
+					TransferType.Trade,
+				),
+			).to.be.rejectedWith(ExchangeContractErrs.InsufficientTakerAllowance);
+		});
+		it("throws if the user doesn't have enough balance", async () => {
+			txHash = await zeroEx.token.setProxyAllowanceAsync(exampleTokenAddress, sender, transferAmount);
+			await zeroEx.awaitTransactionMinedAsync(txHash);
+			return expect(
+				exchangeTransferSimulator.transferFromAsync(
+					exampleTokenAddress,
+					sender,
+					recipient,
+					transferAmount,
+					TradeSide.Maker,
+					TransferType.Trade,
+				),
+			).to.be.rejectedWith(ExchangeContractErrs.InsufficientMakerBalance);
+		});
+		it('updates balances and proxyAllowance after transfer', async () => {
+			txHash = await zeroEx.token.transferAsync(exampleTokenAddress, coinbase, sender, transferAmount);
+			await zeroEx.awaitTransactionMinedAsync(txHash);
+			txHash = await zeroEx.token.setProxyAllowanceAsync(exampleTokenAddress, sender, transferAmount);
+			await zeroEx.awaitTransactionMinedAsync(txHash);
+			await exchangeTransferSimulator.transferFromAsync(
+				exampleTokenAddress,
+				sender,
+				recipient,
+				transferAmount,
+				TradeSide.Taker,
+				TransferType.Trade,
+			);
+			const store = (exchangeTransferSimulator as any)._store;
+			const senderBalance = await store.getBalanceAsync(exampleTokenAddress, sender);
+			const recipientBalance = await store.getBalanceAsync(exampleTokenAddress, recipient);
+			const senderProxyAllowance = await store.getProxyAllowanceAsync(exampleTokenAddress, sender);
+			expect(senderBalance).to.be.bignumber.equal(0);
+			expect(recipientBalance).to.be.bignumber.equal(transferAmount);
+			expect(senderProxyAllowance).to.be.bignumber.equal(0);
+		});
+		it("doesn't update proxyAllowance after transfer if unlimited", async () => {
+			txHash = await zeroEx.token.transferAsync(exampleTokenAddress, coinbase, sender, transferAmount);
+			await zeroEx.awaitTransactionMinedAsync(txHash);
+			txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(exampleTokenAddress, sender);
+			await zeroEx.awaitTransactionMinedAsync(txHash);
+			await exchangeTransferSimulator.transferFromAsync(
+				exampleTokenAddress,
+				sender,
+				recipient,
+				transferAmount,
+				TradeSide.Taker,
+				TransferType.Trade,
+			);
+			const store = (exchangeTransferSimulator as any)._store;
+			const senderBalance = await store.getBalanceAsync(exampleTokenAddress, sender);
+			const recipientBalance = await store.getBalanceAsync(exampleTokenAddress, recipient);
+			const senderProxyAllowance = await store.getProxyAllowanceAsync(exampleTokenAddress, sender);
+			expect(senderBalance).to.be.bignumber.equal(0);
+			expect(recipientBalance).to.be.bignumber.equal(transferAmount);
+			expect(senderProxyAllowance).to.be.bignumber.equal(zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
+		});
+	});
 });
diff --git a/packages/0x.js/test/exchange_wrapper_test.ts b/packages/0x.js/test/exchange_wrapper_test.ts
index 7e0ffd818..f67e61a55 100644
--- a/packages/0x.js/test/exchange_wrapper_test.ts
+++ b/packages/0x.js/test/exchange_wrapper_test.ts
@@ -6,17 +6,17 @@ import 'mocha';
 import * as Web3 from 'web3';
 
 import {
-    BlockRange,
-    DecodedLogEvent,
-    ExchangeContractErrs,
-    ExchangeEvents,
-    LogCancelContractEventArgs,
-    LogFillContractEventArgs,
-    OrderCancellationRequest,
-    OrderFillRequest,
-    SignedOrder,
-    Token,
-    ZeroEx,
+	BlockRange,
+	DecodedLogEvent,
+	ExchangeContractErrs,
+	ExchangeEvents,
+	LogCancelContractEventArgs,
+	LogFillContractEventArgs,
+	OrderCancellationRequest,
+	OrderFillRequest,
+	SignedOrder,
+	Token,
+	ZeroEx,
 } from '../src';
 import { BlockParamLiteral, DoneCallback } from '../src/types';
 
@@ -34,1114 +34,1114 @@ const blockchainLifecycle = new BlockchainLifecycle(constants.RPC_URL);
 const NON_EXISTENT_ORDER_HASH = '0x79370342234e7acd6bbeac335bd3bb1d368383294b64b8160a00f4060e4d3777';
 
 describe('ExchangeWrapper', () => {
-    let web3: Web3;
-    let zeroEx: ZeroEx;
-    let tokenUtils: TokenUtils;
-    let tokens: Token[];
-    let userAddresses: string[];
-    let zrxTokenAddress: string;
-    let fillScenarios: FillScenarios;
-    let exchangeContractAddress: string;
-    const config = {
-        networkId: constants.TESTRPC_NETWORK_ID,
-    };
-    before(async () => {
-        web3 = web3Factory.create();
-        zeroEx = new ZeroEx(web3.currentProvider, config);
-        exchangeContractAddress = zeroEx.exchange.getContractAddress();
-        userAddresses = await zeroEx.getAvailableAddressesAsync();
-        tokens = await zeroEx.tokenRegistry.getTokensAsync();
-        tokenUtils = new TokenUtils(tokens);
-        zrxTokenAddress = tokenUtils.getProtocolTokenOrThrow().address;
-        fillScenarios = new FillScenarios(zeroEx, userAddresses, tokens, zrxTokenAddress, exchangeContractAddress);
-        await fillScenarios.initTokenBalancesAsync();
-    });
-    beforeEach(async () => {
-        await blockchainLifecycle.startAsync();
-    });
-    afterEach(async () => {
-        await blockchainLifecycle.revertAsync();
-    });
-    describe('fillOrKill order(s)', () => {
-        let makerTokenAddress: string;
-        let takerTokenAddress: string;
-        let coinbase: string;
-        let makerAddress: string;
-        let takerAddress: string;
-        let feeRecipient: string;
-        const takerTokenFillAmount = new BigNumber(5);
-        before(async () => {
-            [coinbase, makerAddress, takerAddress, feeRecipient] = userAddresses;
-            tokens = await zeroEx.tokenRegistry.getTokensAsync();
-            const [makerToken, takerToken] = tokenUtils.getDummyTokens();
-            makerTokenAddress = makerToken.address;
-            takerTokenAddress = takerToken.address;
-        });
-        describe('#batchFillOrKillAsync', () => {
-            it('successfully batch fillOrKill', async () => {
-                const fillableAmount = new BigNumber(5);
-                const partialFillTakerAmount = new BigNumber(2);
-                const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                    makerTokenAddress,
-                    takerTokenAddress,
-                    makerAddress,
-                    takerAddress,
-                    fillableAmount,
-                );
-                const anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                    makerTokenAddress,
-                    takerTokenAddress,
-                    makerAddress,
-                    takerAddress,
-                    fillableAmount,
-                );
-                const orderFillRequests = [
-                    {
-                        signedOrder,
-                        takerTokenFillAmount: partialFillTakerAmount,
-                    },
-                    {
-                        signedOrder: anotherSignedOrder,
-                        takerTokenFillAmount: partialFillTakerAmount,
-                    },
-                ];
-                await zeroEx.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress);
-            });
-            describe('order transaction options', () => {
-                let signedOrder: SignedOrder;
-                let orderFillRequests: OrderFillRequest[];
-                const fillableAmount = new BigNumber(5);
-                beforeEach(async () => {
-                    signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                        makerTokenAddress,
-                        takerTokenAddress,
-                        makerAddress,
-                        takerAddress,
-                        fillableAmount,
-                    );
-                    orderFillRequests = [
-                        {
-                            signedOrder,
-                            takerTokenFillAmount: new BigNumber(0),
-                        },
-                    ];
-                });
-                it('should validate when orderTransactionOptions are not present', async () => {
-                    return expect(
-                        zeroEx.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress),
-                    ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
-                });
-                it('should validate when orderTransactionOptions specify to validate', async () => {
-                    return expect(
-                        zeroEx.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress, {
-                            shouldValidate: true,
-                        }),
-                    ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
-                });
-                it('should not validate when orderTransactionOptions specify not to validate', async () => {
-                    return expect(
-                        zeroEx.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress, {
-                            shouldValidate: false,
-                        }),
-                    ).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
-                });
-            });
-        });
-        describe('#fillOrKillOrderAsync', () => {
-            let signedOrder: SignedOrder;
-            const fillableAmount = new BigNumber(5);
-            beforeEach(async () => {
-                signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                    makerTokenAddress,
-                    takerTokenAddress,
-                    makerAddress,
-                    takerAddress,
-                    fillableAmount,
-                );
-            });
-            describe('successful fills', () => {
-                it('should fill a valid order', async () => {
-                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress)).to.be.bignumber.equal(
-                        fillableAmount,
-                    );
-                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress)).to.be.bignumber.equal(
-                        0,
-                    );
-                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress)).to.be.bignumber.equal(
-                        0,
-                    );
-                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress)).to.be.bignumber.equal(
-                        fillableAmount,
-                    );
-                    await zeroEx.exchange.fillOrKillOrderAsync(signedOrder, takerTokenFillAmount, takerAddress);
-                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress)).to.be.bignumber.equal(
-                        fillableAmount.minus(takerTokenFillAmount),
-                    );
-                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress)).to.be.bignumber.equal(
-                        takerTokenFillAmount,
-                    );
-                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress)).to.be.bignumber.equal(
-                        takerTokenFillAmount,
-                    );
-                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress)).to.be.bignumber.equal(
-                        fillableAmount.minus(takerTokenFillAmount),
-                    );
-                });
-                it('should partially fill a valid order', async () => {
-                    const partialFillAmount = new BigNumber(3);
-                    await zeroEx.exchange.fillOrKillOrderAsync(signedOrder, partialFillAmount, takerAddress);
-                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress)).to.be.bignumber.equal(
-                        fillableAmount.minus(partialFillAmount),
-                    );
-                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress)).to.be.bignumber.equal(
-                        partialFillAmount,
-                    );
-                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress)).to.be.bignumber.equal(
-                        partialFillAmount,
-                    );
-                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress)).to.be.bignumber.equal(
-                        fillableAmount.minus(partialFillAmount),
-                    );
-                });
-            });
-            describe('order transaction options', () => {
-                const emptyFillableAmount = new BigNumber(0);
-                it('should validate when orderTransactionOptions are not present', async () => {
-                    return expect(
-                        zeroEx.exchange.fillOrKillOrderAsync(signedOrder, emptyFillableAmount, takerAddress),
-                    ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
-                });
-                it('should validate when orderTransactionOptions specify to validate', async () => {
-                    return expect(
-                        zeroEx.exchange.fillOrKillOrderAsync(signedOrder, emptyFillableAmount, takerAddress, {
-                            shouldValidate: true,
-                        }),
-                    ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
-                });
-                it('should not validate when orderTransactionOptions specify not to validate', async () => {
-                    return expect(
-                        zeroEx.exchange.fillOrKillOrderAsync(signedOrder, emptyFillableAmount, takerAddress, {
-                            shouldValidate: false,
-                        }),
-                    ).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
-                });
-            });
-        });
-    });
-    describe('fill order(s)', () => {
-        let makerTokenAddress: string;
-        let takerTokenAddress: string;
-        let coinbase: string;
-        let makerAddress: string;
-        let takerAddress: string;
-        let feeRecipient: string;
-        const fillableAmount = new BigNumber(5);
-        const takerTokenFillAmount = new BigNumber(5);
-        const shouldThrowOnInsufficientBalanceOrAllowance = true;
-        before(async () => {
-            [coinbase, makerAddress, takerAddress, feeRecipient] = userAddresses;
-            tokens = await zeroEx.tokenRegistry.getTokensAsync();
-            const [makerToken, takerToken] = tokenUtils.getDummyTokens();
-            makerTokenAddress = makerToken.address;
-            takerTokenAddress = takerToken.address;
-        });
-        describe('#fillOrderAsync', () => {
-            describe('successful fills', () => {
-                it('should fill a valid order', async () => {
-                    const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                        makerTokenAddress,
-                        takerTokenAddress,
-                        makerAddress,
-                        takerAddress,
-                        fillableAmount,
-                    );
-                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress)).to.be.bignumber.equal(
-                        fillableAmount,
-                    );
-                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress)).to.be.bignumber.equal(
-                        0,
-                    );
-                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress)).to.be.bignumber.equal(
-                        0,
-                    );
-                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress)).to.be.bignumber.equal(
-                        fillableAmount,
-                    );
-                    const txHash = await zeroEx.exchange.fillOrderAsync(
-                        signedOrder,
-                        takerTokenFillAmount,
-                        shouldThrowOnInsufficientBalanceOrAllowance,
-                        takerAddress,
-                    );
-                    await zeroEx.awaitTransactionMinedAsync(txHash);
-                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress)).to.be.bignumber.equal(
-                        fillableAmount.minus(takerTokenFillAmount),
-                    );
-                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress)).to.be.bignumber.equal(
-                        takerTokenFillAmount,
-                    );
-                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress)).to.be.bignumber.equal(
-                        takerTokenFillAmount,
-                    );
-                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress)).to.be.bignumber.equal(
-                        fillableAmount.minus(takerTokenFillAmount),
-                    );
-                });
-                it('should partially fill the valid order', async () => {
-                    const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                        makerTokenAddress,
-                        takerTokenAddress,
-                        makerAddress,
-                        takerAddress,
-                        fillableAmount,
-                    );
-                    const partialFillAmount = new BigNumber(3);
-                    const txHash = await zeroEx.exchange.fillOrderAsync(
-                        signedOrder,
-                        partialFillAmount,
-                        shouldThrowOnInsufficientBalanceOrAllowance,
-                        takerAddress,
-                    );
-                    await zeroEx.awaitTransactionMinedAsync(txHash);
-                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress)).to.be.bignumber.equal(
-                        fillableAmount.minus(partialFillAmount),
-                    );
-                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress)).to.be.bignumber.equal(
-                        partialFillAmount,
-                    );
-                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress)).to.be.bignumber.equal(
-                        partialFillAmount,
-                    );
-                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress)).to.be.bignumber.equal(
-                        fillableAmount.minus(partialFillAmount),
-                    );
-                });
-                it('should fill the valid orders with fees', async () => {
-                    const makerFee = new BigNumber(1);
-                    const takerFee = new BigNumber(2);
-                    const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
-                        makerTokenAddress,
-                        takerTokenAddress,
-                        makerFee,
-                        takerFee,
-                        makerAddress,
-                        takerAddress,
-                        fillableAmount,
-                        feeRecipient,
-                    );
-                    const txHash = await zeroEx.exchange.fillOrderAsync(
-                        signedOrder,
-                        takerTokenFillAmount,
-                        shouldThrowOnInsufficientBalanceOrAllowance,
-                        takerAddress,
-                    );
-                    await zeroEx.awaitTransactionMinedAsync(txHash);
-                    expect(await zeroEx.token.getBalanceAsync(zrxTokenAddress, feeRecipient)).to.be.bignumber.equal(
-                        makerFee.plus(takerFee),
-                    );
-                });
-            });
-            describe('order transaction options', () => {
-                let signedOrder: SignedOrder;
-                const emptyFillTakerAmount = new BigNumber(0);
-                beforeEach(async () => {
-                    signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                        makerTokenAddress,
-                        takerTokenAddress,
-                        makerAddress,
-                        takerAddress,
-                        fillableAmount,
-                    );
-                });
-                it('should validate when orderTransactionOptions are not present', async () => {
-                    return expect(
-                        zeroEx.exchange.fillOrderAsync(
-                            signedOrder,
-                            emptyFillTakerAmount,
-                            shouldThrowOnInsufficientBalanceOrAllowance,
-                            takerAddress,
-                        ),
-                    ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
-                });
-                it('should validate when orderTransactionOptions specify to validate', async () => {
-                    return expect(
-                        zeroEx.exchange.fillOrderAsync(
-                            signedOrder,
-                            emptyFillTakerAmount,
-                            shouldThrowOnInsufficientBalanceOrAllowance,
-                            takerAddress,
-                            {
-                                shouldValidate: true,
-                            },
-                        ),
-                    ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
-                });
-                it('should not validate when orderTransactionOptions specify not to validate', async () => {
-                    return expect(
-                        zeroEx.exchange.fillOrderAsync(
-                            signedOrder,
-                            emptyFillTakerAmount,
-                            shouldThrowOnInsufficientBalanceOrAllowance,
-                            takerAddress,
-                            {
-                                shouldValidate: false,
-                            },
-                        ),
-                    ).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
-                });
-            });
-            describe('negative fill amount', async () => {
-                let signedOrder: SignedOrder;
-                const negativeFillTakerAmount = new BigNumber(-100);
-                beforeEach(async () => {
-                    signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                        makerTokenAddress,
-                        takerTokenAddress,
-                        makerAddress,
-                        takerAddress,
-                        fillableAmount,
-                    );
-                });
-                it('should not allow the exchange wrapper to fill if amount is negative', async () => {
-                    return expect(
-                        zeroEx.exchange.fillOrderAsync(
-                            signedOrder,
-                            negativeFillTakerAmount,
-                            shouldThrowOnInsufficientBalanceOrAllowance,
-                            takerAddress,
-                        ),
-                    ).to.be.rejected();
-                });
-            });
-        });
-        describe('#batchFillOrdersAsync', () => {
-            let signedOrder: SignedOrder;
-            let signedOrderHashHex: string;
-            let anotherSignedOrder: SignedOrder;
-            let anotherOrderHashHex: string;
-            let orderFillBatch: OrderFillRequest[];
-            beforeEach(async () => {
-                signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                    makerTokenAddress,
-                    takerTokenAddress,
-                    makerAddress,
-                    takerAddress,
-                    fillableAmount,
-                );
-                signedOrderHashHex = ZeroEx.getOrderHashHex(signedOrder);
-                anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                    makerTokenAddress,
-                    takerTokenAddress,
-                    makerAddress,
-                    takerAddress,
-                    fillableAmount,
-                );
-                anotherOrderHashHex = ZeroEx.getOrderHashHex(anotherSignedOrder);
-            });
-            describe('successful batch fills', () => {
-                beforeEach(() => {
-                    orderFillBatch = [
-                        {
-                            signedOrder,
-                            takerTokenFillAmount,
-                        },
-                        {
-                            signedOrder: anotherSignedOrder,
-                            takerTokenFillAmount,
-                        },
-                    ];
-                });
-                it('should throw if a batch is empty', async () => {
-                    return expect(
-                        zeroEx.exchange.batchFillOrdersAsync(
-                            [],
-                            shouldThrowOnInsufficientBalanceOrAllowance,
-                            takerAddress,
-                        ),
-                    ).to.be.rejectedWith(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem);
-                });
-                it('should successfully fill multiple orders', async () => {
-                    const txHash = await zeroEx.exchange.batchFillOrdersAsync(
-                        orderFillBatch,
-                        shouldThrowOnInsufficientBalanceOrAllowance,
-                        takerAddress,
-                    );
-                    await zeroEx.awaitTransactionMinedAsync(txHash);
-                    const filledAmount = await zeroEx.exchange.getFilledTakerAmountAsync(signedOrderHashHex);
-                    const anotherFilledAmount = await zeroEx.exchange.getFilledTakerAmountAsync(anotherOrderHashHex);
-                    expect(filledAmount).to.be.bignumber.equal(takerTokenFillAmount);
-                    expect(anotherFilledAmount).to.be.bignumber.equal(takerTokenFillAmount);
-                });
-            });
-            describe('order transaction options', () => {
-                beforeEach(async () => {
-                    const emptyFillTakerAmount = new BigNumber(0);
-                    orderFillBatch = [
-                        {
-                            signedOrder,
-                            takerTokenFillAmount: emptyFillTakerAmount,
-                        },
-                        {
-                            signedOrder: anotherSignedOrder,
-                            takerTokenFillAmount: emptyFillTakerAmount,
-                        },
-                    ];
-                });
-                it('should validate when orderTransactionOptions are not present', async () => {
-                    return expect(
-                        zeroEx.exchange.batchFillOrdersAsync(
-                            orderFillBatch,
-                            shouldThrowOnInsufficientBalanceOrAllowance,
-                            takerAddress,
-                        ),
-                    ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
-                });
-                it('should validate when orderTransactionOptions specify to validate', async () => {
-                    return expect(
-                        zeroEx.exchange.batchFillOrdersAsync(
-                            orderFillBatch,
-                            shouldThrowOnInsufficientBalanceOrAllowance,
-                            takerAddress,
-                            {
-                                shouldValidate: true,
-                            },
-                        ),
-                    ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
-                });
-                it('should not validate when orderTransactionOptions specify not to validate', async () => {
-                    return expect(
-                        zeroEx.exchange.batchFillOrdersAsync(
-                            orderFillBatch,
-                            shouldThrowOnInsufficientBalanceOrAllowance,
-                            takerAddress,
-                            {
-                                shouldValidate: false,
-                            },
-                        ),
-                    ).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
-                });
-            });
-            describe('negative batch fill amount', async () => {
-                beforeEach(async () => {
-                    const negativeFillTakerAmount = new BigNumber(-100);
-                    orderFillBatch = [
-                        {
-                            signedOrder,
-                            takerTokenFillAmount,
-                        },
-                        {
-                            signedOrder: anotherSignedOrder,
-                            takerTokenFillAmount: negativeFillTakerAmount,
-                        },
-                    ];
-                });
-                it('should not allow the exchange wrapper to batch fill if any amount is negative', async () => {
-                    return expect(
-                        zeroEx.exchange.batchFillOrdersAsync(
-                            orderFillBatch,
-                            shouldThrowOnInsufficientBalanceOrAllowance,
-                            takerAddress,
-                        ),
-                    ).to.be.rejected();
-                });
-            });
-        });
-        describe('#fillOrdersUpTo', () => {
-            let signedOrder: SignedOrder;
-            let signedOrderHashHex: string;
-            let anotherSignedOrder: SignedOrder;
-            let anotherOrderHashHex: string;
-            let signedOrders: SignedOrder[];
-            const fillUpToAmount = fillableAmount.plus(fillableAmount).minus(1);
-            beforeEach(async () => {
-                signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                    makerTokenAddress,
-                    takerTokenAddress,
-                    makerAddress,
-                    takerAddress,
-                    fillableAmount,
-                );
-                signedOrderHashHex = ZeroEx.getOrderHashHex(signedOrder);
-                anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                    makerTokenAddress,
-                    takerTokenAddress,
-                    makerAddress,
-                    takerAddress,
-                    fillableAmount,
-                );
-                anotherOrderHashHex = ZeroEx.getOrderHashHex(anotherSignedOrder);
-                signedOrders = [signedOrder, anotherSignedOrder];
-            });
-            describe('successful batch fills', () => {
-                it('should throw if a batch is empty', async () => {
-                    return expect(
-                        zeroEx.exchange.fillOrdersUpToAsync(
-                            [],
-                            fillUpToAmount,
-                            shouldThrowOnInsufficientBalanceOrAllowance,
-                            takerAddress,
-                        ),
-                    ).to.be.rejectedWith(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem);
-                });
-                it('should successfully fill up to specified amount when all orders are fully funded', async () => {
-                    const txHash = await zeroEx.exchange.fillOrdersUpToAsync(
-                        signedOrders,
-                        fillUpToAmount,
-                        shouldThrowOnInsufficientBalanceOrAllowance,
-                        takerAddress,
-                    );
-                    await zeroEx.awaitTransactionMinedAsync(txHash);
-                    const filledAmount = await zeroEx.exchange.getFilledTakerAmountAsync(signedOrderHashHex);
-                    const anotherFilledAmount = await zeroEx.exchange.getFilledTakerAmountAsync(anotherOrderHashHex);
-                    expect(filledAmount).to.be.bignumber.equal(fillableAmount);
-                    const remainingFillAmount = fillableAmount.minus(1);
-                    expect(anotherFilledAmount).to.be.bignumber.equal(remainingFillAmount);
-                });
-                it('should successfully fill up to specified amount even if filling all orders would fail', async () => {
-                    const missingBalance = new BigNumber(1); // User will still have enough balance to fill up to 9,
-                    // but won't have 10 to fully fill all orders in a batch.
-                    await zeroEx.token.transferAsync(makerTokenAddress, makerAddress, coinbase, missingBalance);
-                    const txHash = await zeroEx.exchange.fillOrdersUpToAsync(
-                        signedOrders,
-                        fillUpToAmount,
-                        shouldThrowOnInsufficientBalanceOrAllowance,
-                        takerAddress,
-                    );
-                    await zeroEx.awaitTransactionMinedAsync(txHash);
-                    const filledAmount = await zeroEx.exchange.getFilledTakerAmountAsync(signedOrderHashHex);
-                    const anotherFilledAmount = await zeroEx.exchange.getFilledTakerAmountAsync(anotherOrderHashHex);
-                    expect(filledAmount).to.be.bignumber.equal(fillableAmount);
-                    const remainingFillAmount = fillableAmount.minus(1);
-                    expect(anotherFilledAmount).to.be.bignumber.equal(remainingFillAmount);
-                });
-            });
-            describe('failed batch fills', () => {
-                it("should fail validation if user doesn't have enough balance without fill up to", async () => {
-                    const missingBalance = new BigNumber(2); // User will only have enough balance to fill up to 8
-                    await zeroEx.token.transferAsync(makerTokenAddress, makerAddress, coinbase, missingBalance);
-                    return expect(
-                        zeroEx.exchange.fillOrdersUpToAsync(
-                            signedOrders,
-                            fillUpToAmount,
-                            shouldThrowOnInsufficientBalanceOrAllowance,
-                            takerAddress,
-                        ),
-                    ).to.be.rejectedWith(ExchangeContractErrs.InsufficientMakerBalance);
-                });
-            });
-            describe('order transaction options', () => {
-                const emptyFillUpToAmount = new BigNumber(0);
-                it('should validate when orderTransactionOptions are not present', async () => {
-                    return expect(
-                        zeroEx.exchange.fillOrdersUpToAsync(
-                            signedOrders,
-                            emptyFillUpToAmount,
-                            shouldThrowOnInsufficientBalanceOrAllowance,
-                            takerAddress,
-                        ),
-                    ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
-                });
-                it('should validate when orderTransactionOptions specify to validate', async () => {
-                    return expect(
-                        zeroEx.exchange.fillOrdersUpToAsync(
-                            signedOrders,
-                            emptyFillUpToAmount,
-                            shouldThrowOnInsufficientBalanceOrAllowance,
-                            takerAddress,
-                            {
-                                shouldValidate: true,
-                            },
-                        ),
-                    ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
-                });
-                it('should not validate when orderTransactionOptions specify not to validate', async () => {
-                    return expect(
-                        zeroEx.exchange.fillOrdersUpToAsync(
-                            signedOrders,
-                            emptyFillUpToAmount,
-                            shouldThrowOnInsufficientBalanceOrAllowance,
-                            takerAddress,
-                            {
-                                shouldValidate: false,
-                            },
-                        ),
-                    ).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
-                });
-            });
-        });
-    });
-    describe('cancel order(s)', () => {
-        let makerTokenAddress: string;
-        let takerTokenAddress: string;
-        let coinbase: string;
-        let makerAddress: string;
-        let takerAddress: string;
-        const fillableAmount = new BigNumber(5);
-        let signedOrder: SignedOrder;
-        let orderHashHex: string;
-        const cancelAmount = new BigNumber(3);
-        beforeEach(async () => {
-            [coinbase, makerAddress, takerAddress] = userAddresses;
-            const [makerToken, takerToken] = tokenUtils.getDummyTokens();
-            makerTokenAddress = makerToken.address;
-            takerTokenAddress = takerToken.address;
-            signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                makerTokenAddress,
-                takerTokenAddress,
-                makerAddress,
-                takerAddress,
-                fillableAmount,
-            );
-            orderHashHex = ZeroEx.getOrderHashHex(signedOrder);
-        });
-        describe('#cancelOrderAsync', () => {
-            describe('successful cancels', () => {
-                it('should cancel an order', async () => {
-                    const txHash = await zeroEx.exchange.cancelOrderAsync(signedOrder, cancelAmount);
-                    await zeroEx.awaitTransactionMinedAsync(txHash);
-                    const cancelledAmount = await zeroEx.exchange.getCancelledTakerAmountAsync(orderHashHex);
-                    expect(cancelledAmount).to.be.bignumber.equal(cancelAmount);
-                });
-            });
-            describe('order transaction options', () => {
-                const emptyCancelTakerTokenAmount = new BigNumber(0);
-                it('should validate when orderTransactionOptions are not present', async () => {
-                    return expect(
-                        zeroEx.exchange.cancelOrderAsync(signedOrder, emptyCancelTakerTokenAmount),
-                    ).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
-                });
-                it('should validate when orderTransactionOptions specify to validate', async () => {
-                    return expect(
-                        zeroEx.exchange.cancelOrderAsync(signedOrder, emptyCancelTakerTokenAmount, {
-                            shouldValidate: true,
-                        }),
-                    ).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
-                });
-                it('should not validate when orderTransactionOptions specify not to validate', async () => {
-                    return expect(
-                        zeroEx.exchange.cancelOrderAsync(signedOrder, emptyCancelTakerTokenAmount, {
-                            shouldValidate: false,
-                        }),
-                    ).to.not.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
-                });
-            });
-        });
-        describe('#batchCancelOrdersAsync', () => {
-            let anotherSignedOrder: SignedOrder;
-            let anotherOrderHashHex: string;
-            let cancelBatch: OrderCancellationRequest[];
-            beforeEach(async () => {
-                anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                    makerTokenAddress,
-                    takerTokenAddress,
-                    makerAddress,
-                    takerAddress,
-                    fillableAmount,
-                );
-                anotherOrderHashHex = ZeroEx.getOrderHashHex(anotherSignedOrder);
-                cancelBatch = [
-                    {
-                        order: signedOrder,
-                        takerTokenCancelAmount: cancelAmount,
-                    },
-                    {
-                        order: anotherSignedOrder,
-                        takerTokenCancelAmount: cancelAmount,
-                    },
-                ];
-            });
-            describe('failed batch cancels', () => {
-                it('should throw when orders have different makers', async () => {
-                    const signedOrderWithDifferentMaker = await fillScenarios.createFillableSignedOrderAsync(
-                        makerTokenAddress,
-                        takerTokenAddress,
-                        takerAddress,
-                        takerAddress,
-                        fillableAmount,
-                    );
-                    return expect(
-                        zeroEx.exchange.batchCancelOrdersAsync([
-                            cancelBatch[0],
-                            {
-                                order: signedOrderWithDifferentMaker,
-                                takerTokenCancelAmount: cancelAmount,
-                            },
-                        ]),
-                    ).to.be.rejectedWith(ExchangeContractErrs.MultipleMakersInSingleCancelBatchDisallowed);
-                });
-            });
-            describe('successful batch cancels', () => {
-                it('should cancel a batch of orders', async () => {
-                    await zeroEx.exchange.batchCancelOrdersAsync(cancelBatch);
-                    const cancelledAmount = await zeroEx.exchange.getCancelledTakerAmountAsync(orderHashHex);
-                    const anotherCancelledAmount = await zeroEx.exchange.getCancelledTakerAmountAsync(
-                        anotherOrderHashHex,
-                    );
-                    expect(cancelledAmount).to.be.bignumber.equal(cancelAmount);
-                    expect(anotherCancelledAmount).to.be.bignumber.equal(cancelAmount);
-                });
-            });
-            describe('order transaction options', () => {
-                beforeEach(async () => {
-                    const emptyTakerTokenCancelAmount = new BigNumber(0);
-                    cancelBatch = [
-                        {
-                            order: signedOrder,
-                            takerTokenCancelAmount: emptyTakerTokenCancelAmount,
-                        },
-                        {
-                            order: anotherSignedOrder,
-                            takerTokenCancelAmount: emptyTakerTokenCancelAmount,
-                        },
-                    ];
-                });
-                it('should validate when orderTransactionOptions are not present', async () => {
-                    return expect(zeroEx.exchange.batchCancelOrdersAsync(cancelBatch)).to.be.rejectedWith(
-                        ExchangeContractErrs.OrderCancelAmountZero,
-                    );
-                });
-                it('should validate when orderTransactionOptions specify to validate', async () => {
-                    return expect(
-                        zeroEx.exchange.batchCancelOrdersAsync(cancelBatch, {
-                            shouldValidate: true,
-                        }),
-                    ).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
-                });
-                it('should not validate when orderTransactionOptions specify not to validate', async () => {
-                    return expect(
-                        zeroEx.exchange.batchCancelOrdersAsync(cancelBatch, {
-                            shouldValidate: false,
-                        }),
-                    ).to.not.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
-                });
-            });
-        });
-    });
-    describe('tests that require partially filled order', () => {
-        let makerTokenAddress: string;
-        let takerTokenAddress: string;
-        let takerAddress: string;
-        let fillableAmount: BigNumber;
-        let partialFillAmount: BigNumber;
-        let signedOrder: SignedOrder;
-        let orderHash: string;
-        before(() => {
-            takerAddress = userAddresses[1];
-            tokenUtils = new TokenUtils(tokens);
-            const [makerToken, takerToken] = tokenUtils.getDummyTokens();
-            makerTokenAddress = makerToken.address;
-            takerTokenAddress = takerToken.address;
-        });
-        beforeEach(async () => {
-            fillableAmount = new BigNumber(5);
-            partialFillAmount = new BigNumber(2);
-            signedOrder = await fillScenarios.createPartiallyFilledSignedOrderAsync(
-                makerTokenAddress,
-                takerTokenAddress,
-                takerAddress,
-                fillableAmount,
-                partialFillAmount,
-            );
-            orderHash = ZeroEx.getOrderHashHex(signedOrder);
-        });
-        describe('#getUnavailableTakerAmountAsync', () => {
-            it('should throw if passed an invalid orderHash', async () => {
-                const invalidOrderHashHex = '0x123';
-                return expect(zeroEx.exchange.getUnavailableTakerAmountAsync(invalidOrderHashHex)).to.be.rejected();
-            });
-            it('should return zero if passed a valid but non-existent orderHash', async () => {
-                const unavailableValueT = await zeroEx.exchange.getUnavailableTakerAmountAsync(NON_EXISTENT_ORDER_HASH);
-                expect(unavailableValueT).to.be.bignumber.equal(0);
-            });
-            it('should return the unavailableValueT for a valid and partially filled orderHash', async () => {
-                const unavailableValueT = await zeroEx.exchange.getUnavailableTakerAmountAsync(orderHash);
-                expect(unavailableValueT).to.be.bignumber.equal(partialFillAmount);
-            });
-        });
-        describe('#getFilledTakerAmountAsync', () => {
-            it('should throw if passed an invalid orderHash', async () => {
-                const invalidOrderHashHex = '0x123';
-                return expect(zeroEx.exchange.getFilledTakerAmountAsync(invalidOrderHashHex)).to.be.rejected();
-            });
-            it('should return zero if passed a valid but non-existent orderHash', async () => {
-                const filledValueT = await zeroEx.exchange.getFilledTakerAmountAsync(NON_EXISTENT_ORDER_HASH);
-                expect(filledValueT).to.be.bignumber.equal(0);
-            });
-            it('should return the filledValueT for a valid and partially filled orderHash', async () => {
-                const filledValueT = await zeroEx.exchange.getFilledTakerAmountAsync(orderHash);
-                expect(filledValueT).to.be.bignumber.equal(partialFillAmount);
-            });
-        });
-        describe('#getCancelledTakerAmountAsync', () => {
-            it('should throw if passed an invalid orderHash', async () => {
-                const invalidOrderHashHex = '0x123';
-                return expect(zeroEx.exchange.getCancelledTakerAmountAsync(invalidOrderHashHex)).to.be.rejected();
-            });
-            it('should return zero if passed a valid but non-existent orderHash', async () => {
-                const cancelledValueT = await zeroEx.exchange.getCancelledTakerAmountAsync(NON_EXISTENT_ORDER_HASH);
-                expect(cancelledValueT).to.be.bignumber.equal(0);
-            });
-            it('should return the cancelledValueT for a valid and partially filled orderHash', async () => {
-                const cancelledValueT = await zeroEx.exchange.getCancelledTakerAmountAsync(orderHash);
-                expect(cancelledValueT).to.be.bignumber.equal(0);
-            });
-            it('should return the cancelledValueT for a valid and cancelled orderHash', async () => {
-                const cancelAmount = fillableAmount.minus(partialFillAmount);
-                await zeroEx.exchange.cancelOrderAsync(signedOrder, cancelAmount);
-                const cancelledValueT = await zeroEx.exchange.getCancelledTakerAmountAsync(orderHash);
-                expect(cancelledValueT).to.be.bignumber.equal(cancelAmount);
-            });
-        });
-    });
-    describe('#subscribe', () => {
-        const indexFilterValues = {};
-        const shouldThrowOnInsufficientBalanceOrAllowance = true;
-        let makerTokenAddress: string;
-        let takerTokenAddress: string;
-        let coinbase: string;
-        let takerAddress: string;
-        let makerAddress: string;
-        let fillableAmount: BigNumber;
-        let signedOrder: SignedOrder;
-        const takerTokenFillAmountInBaseUnits = new BigNumber(1);
-        const cancelTakerAmountInBaseUnits = new BigNumber(1);
-        before(() => {
-            [coinbase, makerAddress, takerAddress] = userAddresses;
-            const [makerToken, takerToken] = tokenUtils.getDummyTokens();
-            makerTokenAddress = makerToken.address;
-            takerTokenAddress = takerToken.address;
-        });
-        beforeEach(async () => {
-            fillableAmount = new BigNumber(5);
-            signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                makerTokenAddress,
-                takerTokenAddress,
-                makerAddress,
-                takerAddress,
-                fillableAmount,
-            );
-        });
-        afterEach(async () => {
-            zeroEx.exchange.unsubscribeAll();
-        });
-        // Hack: Mocha does not allow a test to be both async and have a `done` callback
-        // Since we need to await the receipt of the event in the `subscribe` callback,
-        // we do need both. A hack is to make the top-level a sync fn w/ a done callback and then
-        // wrap the rest of the test in an async block
-        // Source: https://github.com/mochajs/mocha/issues/2407
-        it('Should receive the LogFill event when an order is filled', (done: DoneCallback) => {
-            (async () => {
-                const callback = reportNodeCallbackErrors(done)(
-                    (logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
-                        expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogFill);
-                    },
-                );
-                zeroEx.exchange.subscribe(ExchangeEvents.LogFill, indexFilterValues, callback);
-                await zeroEx.exchange.fillOrderAsync(
-                    signedOrder,
-                    takerTokenFillAmountInBaseUnits,
-                    shouldThrowOnInsufficientBalanceOrAllowance,
-                    takerAddress,
-                );
-            })().catch(done);
-        });
-        it('Should receive the LogCancel event when an order is cancelled', (done: DoneCallback) => {
-            (async () => {
-                const callback = reportNodeCallbackErrors(done)(
-                    (logEvent: DecodedLogEvent<LogCancelContractEventArgs>) => {
-                        expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogCancel);
-                    },
-                );
-                zeroEx.exchange.subscribe(ExchangeEvents.LogCancel, indexFilterValues, callback);
-                await zeroEx.exchange.cancelOrderAsync(signedOrder, cancelTakerAmountInBaseUnits);
-            })().catch(done);
-        });
-        it('Outstanding subscriptions are cancelled when zeroEx.setProvider called', (done: DoneCallback) => {
-            (async () => {
-                const callbackNeverToBeCalled = reportNodeCallbackErrors(done)(
-                    (logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
-                        done(new Error('Expected this subscription to have been cancelled'));
-                    },
-                );
-                zeroEx.exchange.subscribe(ExchangeEvents.LogFill, indexFilterValues, callbackNeverToBeCalled);
+	let web3: Web3;
+	let zeroEx: ZeroEx;
+	let tokenUtils: TokenUtils;
+	let tokens: Token[];
+	let userAddresses: string[];
+	let zrxTokenAddress: string;
+	let fillScenarios: FillScenarios;
+	let exchangeContractAddress: string;
+	const config = {
+		networkId: constants.TESTRPC_NETWORK_ID,
+	};
+	before(async () => {
+		web3 = web3Factory.create();
+		zeroEx = new ZeroEx(web3.currentProvider, config);
+		exchangeContractAddress = zeroEx.exchange.getContractAddress();
+		userAddresses = await zeroEx.getAvailableAddressesAsync();
+		tokens = await zeroEx.tokenRegistry.getTokensAsync();
+		tokenUtils = new TokenUtils(tokens);
+		zrxTokenAddress = tokenUtils.getProtocolTokenOrThrow().address;
+		fillScenarios = new FillScenarios(zeroEx, userAddresses, tokens, zrxTokenAddress, exchangeContractAddress);
+		await fillScenarios.initTokenBalancesAsync();
+	});
+	beforeEach(async () => {
+		await blockchainLifecycle.startAsync();
+	});
+	afterEach(async () => {
+		await blockchainLifecycle.revertAsync();
+	});
+	describe('fillOrKill order(s)', () => {
+		let makerTokenAddress: string;
+		let takerTokenAddress: string;
+		let coinbase: string;
+		let makerAddress: string;
+		let takerAddress: string;
+		let feeRecipient: string;
+		const takerTokenFillAmount = new BigNumber(5);
+		before(async () => {
+			[coinbase, makerAddress, takerAddress, feeRecipient] = userAddresses;
+			tokens = await zeroEx.tokenRegistry.getTokensAsync();
+			const [makerToken, takerToken] = tokenUtils.getDummyTokens();
+			makerTokenAddress = makerToken.address;
+			takerTokenAddress = takerToken.address;
+		});
+		describe('#batchFillOrKillAsync', () => {
+			it('successfully batch fillOrKill', async () => {
+				const fillableAmount = new BigNumber(5);
+				const partialFillTakerAmount = new BigNumber(2);
+				const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+					makerTokenAddress,
+					takerTokenAddress,
+					makerAddress,
+					takerAddress,
+					fillableAmount,
+				);
+				const anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
+					makerTokenAddress,
+					takerTokenAddress,
+					makerAddress,
+					takerAddress,
+					fillableAmount,
+				);
+				const orderFillRequests = [
+					{
+						signedOrder,
+						takerTokenFillAmount: partialFillTakerAmount,
+					},
+					{
+						signedOrder: anotherSignedOrder,
+						takerTokenFillAmount: partialFillTakerAmount,
+					},
+				];
+				await zeroEx.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress);
+			});
+			describe('order transaction options', () => {
+				let signedOrder: SignedOrder;
+				let orderFillRequests: OrderFillRequest[];
+				const fillableAmount = new BigNumber(5);
+				beforeEach(async () => {
+					signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+						makerTokenAddress,
+						takerTokenAddress,
+						makerAddress,
+						takerAddress,
+						fillableAmount,
+					);
+					orderFillRequests = [
+						{
+							signedOrder,
+							takerTokenFillAmount: new BigNumber(0),
+						},
+					];
+				});
+				it('should validate when orderTransactionOptions are not present', async () => {
+					return expect(
+						zeroEx.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress),
+					).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
+				});
+				it('should validate when orderTransactionOptions specify to validate', async () => {
+					return expect(
+						zeroEx.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress, {
+							shouldValidate: true,
+						}),
+					).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
+				});
+				it('should not validate when orderTransactionOptions specify not to validate', async () => {
+					return expect(
+						zeroEx.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress, {
+							shouldValidate: false,
+						}),
+					).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
+				});
+			});
+		});
+		describe('#fillOrKillOrderAsync', () => {
+			let signedOrder: SignedOrder;
+			const fillableAmount = new BigNumber(5);
+			beforeEach(async () => {
+				signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+					makerTokenAddress,
+					takerTokenAddress,
+					makerAddress,
+					takerAddress,
+					fillableAmount,
+				);
+			});
+			describe('successful fills', () => {
+				it('should fill a valid order', async () => {
+					expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress)).to.be.bignumber.equal(
+						fillableAmount,
+					);
+					expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress)).to.be.bignumber.equal(
+						0,
+					);
+					expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress)).to.be.bignumber.equal(
+						0,
+					);
+					expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress)).to.be.bignumber.equal(
+						fillableAmount,
+					);
+					await zeroEx.exchange.fillOrKillOrderAsync(signedOrder, takerTokenFillAmount, takerAddress);
+					expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress)).to.be.bignumber.equal(
+						fillableAmount.minus(takerTokenFillAmount),
+					);
+					expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress)).to.be.bignumber.equal(
+						takerTokenFillAmount,
+					);
+					expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress)).to.be.bignumber.equal(
+						takerTokenFillAmount,
+					);
+					expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress)).to.be.bignumber.equal(
+						fillableAmount.minus(takerTokenFillAmount),
+					);
+				});
+				it('should partially fill a valid order', async () => {
+					const partialFillAmount = new BigNumber(3);
+					await zeroEx.exchange.fillOrKillOrderAsync(signedOrder, partialFillAmount, takerAddress);
+					expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress)).to.be.bignumber.equal(
+						fillableAmount.minus(partialFillAmount),
+					);
+					expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress)).to.be.bignumber.equal(
+						partialFillAmount,
+					);
+					expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress)).to.be.bignumber.equal(
+						partialFillAmount,
+					);
+					expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress)).to.be.bignumber.equal(
+						fillableAmount.minus(partialFillAmount),
+					);
+				});
+			});
+			describe('order transaction options', () => {
+				const emptyFillableAmount = new BigNumber(0);
+				it('should validate when orderTransactionOptions are not present', async () => {
+					return expect(
+						zeroEx.exchange.fillOrKillOrderAsync(signedOrder, emptyFillableAmount, takerAddress),
+					).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
+				});
+				it('should validate when orderTransactionOptions specify to validate', async () => {
+					return expect(
+						zeroEx.exchange.fillOrKillOrderAsync(signedOrder, emptyFillableAmount, takerAddress, {
+							shouldValidate: true,
+						}),
+					).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
+				});
+				it('should not validate when orderTransactionOptions specify not to validate', async () => {
+					return expect(
+						zeroEx.exchange.fillOrKillOrderAsync(signedOrder, emptyFillableAmount, takerAddress, {
+							shouldValidate: false,
+						}),
+					).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
+				});
+			});
+		});
+	});
+	describe('fill order(s)', () => {
+		let makerTokenAddress: string;
+		let takerTokenAddress: string;
+		let coinbase: string;
+		let makerAddress: string;
+		let takerAddress: string;
+		let feeRecipient: string;
+		const fillableAmount = new BigNumber(5);
+		const takerTokenFillAmount = new BigNumber(5);
+		const shouldThrowOnInsufficientBalanceOrAllowance = true;
+		before(async () => {
+			[coinbase, makerAddress, takerAddress, feeRecipient] = userAddresses;
+			tokens = await zeroEx.tokenRegistry.getTokensAsync();
+			const [makerToken, takerToken] = tokenUtils.getDummyTokens();
+			makerTokenAddress = makerToken.address;
+			takerTokenAddress = takerToken.address;
+		});
+		describe('#fillOrderAsync', () => {
+			describe('successful fills', () => {
+				it('should fill a valid order', async () => {
+					const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+						makerTokenAddress,
+						takerTokenAddress,
+						makerAddress,
+						takerAddress,
+						fillableAmount,
+					);
+					expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress)).to.be.bignumber.equal(
+						fillableAmount,
+					);
+					expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress)).to.be.bignumber.equal(
+						0,
+					);
+					expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress)).to.be.bignumber.equal(
+						0,
+					);
+					expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress)).to.be.bignumber.equal(
+						fillableAmount,
+					);
+					const txHash = await zeroEx.exchange.fillOrderAsync(
+						signedOrder,
+						takerTokenFillAmount,
+						shouldThrowOnInsufficientBalanceOrAllowance,
+						takerAddress,
+					);
+					await zeroEx.awaitTransactionMinedAsync(txHash);
+					expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress)).to.be.bignumber.equal(
+						fillableAmount.minus(takerTokenFillAmount),
+					);
+					expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress)).to.be.bignumber.equal(
+						takerTokenFillAmount,
+					);
+					expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress)).to.be.bignumber.equal(
+						takerTokenFillAmount,
+					);
+					expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress)).to.be.bignumber.equal(
+						fillableAmount.minus(takerTokenFillAmount),
+					);
+				});
+				it('should partially fill the valid order', async () => {
+					const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+						makerTokenAddress,
+						takerTokenAddress,
+						makerAddress,
+						takerAddress,
+						fillableAmount,
+					);
+					const partialFillAmount = new BigNumber(3);
+					const txHash = await zeroEx.exchange.fillOrderAsync(
+						signedOrder,
+						partialFillAmount,
+						shouldThrowOnInsufficientBalanceOrAllowance,
+						takerAddress,
+					);
+					await zeroEx.awaitTransactionMinedAsync(txHash);
+					expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress)).to.be.bignumber.equal(
+						fillableAmount.minus(partialFillAmount),
+					);
+					expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress)).to.be.bignumber.equal(
+						partialFillAmount,
+					);
+					expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress)).to.be.bignumber.equal(
+						partialFillAmount,
+					);
+					expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress)).to.be.bignumber.equal(
+						fillableAmount.minus(partialFillAmount),
+					);
+				});
+				it('should fill the valid orders with fees', async () => {
+					const makerFee = new BigNumber(1);
+					const takerFee = new BigNumber(2);
+					const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
+						makerTokenAddress,
+						takerTokenAddress,
+						makerFee,
+						takerFee,
+						makerAddress,
+						takerAddress,
+						fillableAmount,
+						feeRecipient,
+					);
+					const txHash = await zeroEx.exchange.fillOrderAsync(
+						signedOrder,
+						takerTokenFillAmount,
+						shouldThrowOnInsufficientBalanceOrAllowance,
+						takerAddress,
+					);
+					await zeroEx.awaitTransactionMinedAsync(txHash);
+					expect(await zeroEx.token.getBalanceAsync(zrxTokenAddress, feeRecipient)).to.be.bignumber.equal(
+						makerFee.plus(takerFee),
+					);
+				});
+			});
+			describe('order transaction options', () => {
+				let signedOrder: SignedOrder;
+				const emptyFillTakerAmount = new BigNumber(0);
+				beforeEach(async () => {
+					signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+						makerTokenAddress,
+						takerTokenAddress,
+						makerAddress,
+						takerAddress,
+						fillableAmount,
+					);
+				});
+				it('should validate when orderTransactionOptions are not present', async () => {
+					return expect(
+						zeroEx.exchange.fillOrderAsync(
+							signedOrder,
+							emptyFillTakerAmount,
+							shouldThrowOnInsufficientBalanceOrAllowance,
+							takerAddress,
+						),
+					).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
+				});
+				it('should validate when orderTransactionOptions specify to validate', async () => {
+					return expect(
+						zeroEx.exchange.fillOrderAsync(
+							signedOrder,
+							emptyFillTakerAmount,
+							shouldThrowOnInsufficientBalanceOrAllowance,
+							takerAddress,
+							{
+								shouldValidate: true,
+							},
+						),
+					).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
+				});
+				it('should not validate when orderTransactionOptions specify not to validate', async () => {
+					return expect(
+						zeroEx.exchange.fillOrderAsync(
+							signedOrder,
+							emptyFillTakerAmount,
+							shouldThrowOnInsufficientBalanceOrAllowance,
+							takerAddress,
+							{
+								shouldValidate: false,
+							},
+						),
+					).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
+				});
+			});
+			describe('negative fill amount', async () => {
+				let signedOrder: SignedOrder;
+				const negativeFillTakerAmount = new BigNumber(-100);
+				beforeEach(async () => {
+					signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+						makerTokenAddress,
+						takerTokenAddress,
+						makerAddress,
+						takerAddress,
+						fillableAmount,
+					);
+				});
+				it('should not allow the exchange wrapper to fill if amount is negative', async () => {
+					return expect(
+						zeroEx.exchange.fillOrderAsync(
+							signedOrder,
+							negativeFillTakerAmount,
+							shouldThrowOnInsufficientBalanceOrAllowance,
+							takerAddress,
+						),
+					).to.be.rejected();
+				});
+			});
+		});
+		describe('#batchFillOrdersAsync', () => {
+			let signedOrder: SignedOrder;
+			let signedOrderHashHex: string;
+			let anotherSignedOrder: SignedOrder;
+			let anotherOrderHashHex: string;
+			let orderFillBatch: OrderFillRequest[];
+			beforeEach(async () => {
+				signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+					makerTokenAddress,
+					takerTokenAddress,
+					makerAddress,
+					takerAddress,
+					fillableAmount,
+				);
+				signedOrderHashHex = ZeroEx.getOrderHashHex(signedOrder);
+				anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
+					makerTokenAddress,
+					takerTokenAddress,
+					makerAddress,
+					takerAddress,
+					fillableAmount,
+				);
+				anotherOrderHashHex = ZeroEx.getOrderHashHex(anotherSignedOrder);
+			});
+			describe('successful batch fills', () => {
+				beforeEach(() => {
+					orderFillBatch = [
+						{
+							signedOrder,
+							takerTokenFillAmount,
+						},
+						{
+							signedOrder: anotherSignedOrder,
+							takerTokenFillAmount,
+						},
+					];
+				});
+				it('should throw if a batch is empty', async () => {
+					return expect(
+						zeroEx.exchange.batchFillOrdersAsync(
+							[],
+							shouldThrowOnInsufficientBalanceOrAllowance,
+							takerAddress,
+						),
+					).to.be.rejectedWith(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem);
+				});
+				it('should successfully fill multiple orders', async () => {
+					const txHash = await zeroEx.exchange.batchFillOrdersAsync(
+						orderFillBatch,
+						shouldThrowOnInsufficientBalanceOrAllowance,
+						takerAddress,
+					);
+					await zeroEx.awaitTransactionMinedAsync(txHash);
+					const filledAmount = await zeroEx.exchange.getFilledTakerAmountAsync(signedOrderHashHex);
+					const anotherFilledAmount = await zeroEx.exchange.getFilledTakerAmountAsync(anotherOrderHashHex);
+					expect(filledAmount).to.be.bignumber.equal(takerTokenFillAmount);
+					expect(anotherFilledAmount).to.be.bignumber.equal(takerTokenFillAmount);
+				});
+			});
+			describe('order transaction options', () => {
+				beforeEach(async () => {
+					const emptyFillTakerAmount = new BigNumber(0);
+					orderFillBatch = [
+						{
+							signedOrder,
+							takerTokenFillAmount: emptyFillTakerAmount,
+						},
+						{
+							signedOrder: anotherSignedOrder,
+							takerTokenFillAmount: emptyFillTakerAmount,
+						},
+					];
+				});
+				it('should validate when orderTransactionOptions are not present', async () => {
+					return expect(
+						zeroEx.exchange.batchFillOrdersAsync(
+							orderFillBatch,
+							shouldThrowOnInsufficientBalanceOrAllowance,
+							takerAddress,
+						),
+					).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
+				});
+				it('should validate when orderTransactionOptions specify to validate', async () => {
+					return expect(
+						zeroEx.exchange.batchFillOrdersAsync(
+							orderFillBatch,
+							shouldThrowOnInsufficientBalanceOrAllowance,
+							takerAddress,
+							{
+								shouldValidate: true,
+							},
+						),
+					).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
+				});
+				it('should not validate when orderTransactionOptions specify not to validate', async () => {
+					return expect(
+						zeroEx.exchange.batchFillOrdersAsync(
+							orderFillBatch,
+							shouldThrowOnInsufficientBalanceOrAllowance,
+							takerAddress,
+							{
+								shouldValidate: false,
+							},
+						),
+					).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
+				});
+			});
+			describe('negative batch fill amount', async () => {
+				beforeEach(async () => {
+					const negativeFillTakerAmount = new BigNumber(-100);
+					orderFillBatch = [
+						{
+							signedOrder,
+							takerTokenFillAmount,
+						},
+						{
+							signedOrder: anotherSignedOrder,
+							takerTokenFillAmount: negativeFillTakerAmount,
+						},
+					];
+				});
+				it('should not allow the exchange wrapper to batch fill if any amount is negative', async () => {
+					return expect(
+						zeroEx.exchange.batchFillOrdersAsync(
+							orderFillBatch,
+							shouldThrowOnInsufficientBalanceOrAllowance,
+							takerAddress,
+						),
+					).to.be.rejected();
+				});
+			});
+		});
+		describe('#fillOrdersUpTo', () => {
+			let signedOrder: SignedOrder;
+			let signedOrderHashHex: string;
+			let anotherSignedOrder: SignedOrder;
+			let anotherOrderHashHex: string;
+			let signedOrders: SignedOrder[];
+			const fillUpToAmount = fillableAmount.plus(fillableAmount).minus(1);
+			beforeEach(async () => {
+				signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+					makerTokenAddress,
+					takerTokenAddress,
+					makerAddress,
+					takerAddress,
+					fillableAmount,
+				);
+				signedOrderHashHex = ZeroEx.getOrderHashHex(signedOrder);
+				anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
+					makerTokenAddress,
+					takerTokenAddress,
+					makerAddress,
+					takerAddress,
+					fillableAmount,
+				);
+				anotherOrderHashHex = ZeroEx.getOrderHashHex(anotherSignedOrder);
+				signedOrders = [signedOrder, anotherSignedOrder];
+			});
+			describe('successful batch fills', () => {
+				it('should throw if a batch is empty', async () => {
+					return expect(
+						zeroEx.exchange.fillOrdersUpToAsync(
+							[],
+							fillUpToAmount,
+							shouldThrowOnInsufficientBalanceOrAllowance,
+							takerAddress,
+						),
+					).to.be.rejectedWith(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem);
+				});
+				it('should successfully fill up to specified amount when all orders are fully funded', async () => {
+					const txHash = await zeroEx.exchange.fillOrdersUpToAsync(
+						signedOrders,
+						fillUpToAmount,
+						shouldThrowOnInsufficientBalanceOrAllowance,
+						takerAddress,
+					);
+					await zeroEx.awaitTransactionMinedAsync(txHash);
+					const filledAmount = await zeroEx.exchange.getFilledTakerAmountAsync(signedOrderHashHex);
+					const anotherFilledAmount = await zeroEx.exchange.getFilledTakerAmountAsync(anotherOrderHashHex);
+					expect(filledAmount).to.be.bignumber.equal(fillableAmount);
+					const remainingFillAmount = fillableAmount.minus(1);
+					expect(anotherFilledAmount).to.be.bignumber.equal(remainingFillAmount);
+				});
+				it('should successfully fill up to specified amount even if filling all orders would fail', async () => {
+					const missingBalance = new BigNumber(1); // User will still have enough balance to fill up to 9,
+					// but won't have 10 to fully fill all orders in a batch.
+					await zeroEx.token.transferAsync(makerTokenAddress, makerAddress, coinbase, missingBalance);
+					const txHash = await zeroEx.exchange.fillOrdersUpToAsync(
+						signedOrders,
+						fillUpToAmount,
+						shouldThrowOnInsufficientBalanceOrAllowance,
+						takerAddress,
+					);
+					await zeroEx.awaitTransactionMinedAsync(txHash);
+					const filledAmount = await zeroEx.exchange.getFilledTakerAmountAsync(signedOrderHashHex);
+					const anotherFilledAmount = await zeroEx.exchange.getFilledTakerAmountAsync(anotherOrderHashHex);
+					expect(filledAmount).to.be.bignumber.equal(fillableAmount);
+					const remainingFillAmount = fillableAmount.minus(1);
+					expect(anotherFilledAmount).to.be.bignumber.equal(remainingFillAmount);
+				});
+			});
+			describe('failed batch fills', () => {
+				it("should fail validation if user doesn't have enough balance without fill up to", async () => {
+					const missingBalance = new BigNumber(2); // User will only have enough balance to fill up to 8
+					await zeroEx.token.transferAsync(makerTokenAddress, makerAddress, coinbase, missingBalance);
+					return expect(
+						zeroEx.exchange.fillOrdersUpToAsync(
+							signedOrders,
+							fillUpToAmount,
+							shouldThrowOnInsufficientBalanceOrAllowance,
+							takerAddress,
+						),
+					).to.be.rejectedWith(ExchangeContractErrs.InsufficientMakerBalance);
+				});
+			});
+			describe('order transaction options', () => {
+				const emptyFillUpToAmount = new BigNumber(0);
+				it('should validate when orderTransactionOptions are not present', async () => {
+					return expect(
+						zeroEx.exchange.fillOrdersUpToAsync(
+							signedOrders,
+							emptyFillUpToAmount,
+							shouldThrowOnInsufficientBalanceOrAllowance,
+							takerAddress,
+						),
+					).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
+				});
+				it('should validate when orderTransactionOptions specify to validate', async () => {
+					return expect(
+						zeroEx.exchange.fillOrdersUpToAsync(
+							signedOrders,
+							emptyFillUpToAmount,
+							shouldThrowOnInsufficientBalanceOrAllowance,
+							takerAddress,
+							{
+								shouldValidate: true,
+							},
+						),
+					).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
+				});
+				it('should not validate when orderTransactionOptions specify not to validate', async () => {
+					return expect(
+						zeroEx.exchange.fillOrdersUpToAsync(
+							signedOrders,
+							emptyFillUpToAmount,
+							shouldThrowOnInsufficientBalanceOrAllowance,
+							takerAddress,
+							{
+								shouldValidate: false,
+							},
+						),
+					).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
+				});
+			});
+		});
+	});
+	describe('cancel order(s)', () => {
+		let makerTokenAddress: string;
+		let takerTokenAddress: string;
+		let coinbase: string;
+		let makerAddress: string;
+		let takerAddress: string;
+		const fillableAmount = new BigNumber(5);
+		let signedOrder: SignedOrder;
+		let orderHashHex: string;
+		const cancelAmount = new BigNumber(3);
+		beforeEach(async () => {
+			[coinbase, makerAddress, takerAddress] = userAddresses;
+			const [makerToken, takerToken] = tokenUtils.getDummyTokens();
+			makerTokenAddress = makerToken.address;
+			takerTokenAddress = takerToken.address;
+			signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+				makerTokenAddress,
+				takerTokenAddress,
+				makerAddress,
+				takerAddress,
+				fillableAmount,
+			);
+			orderHashHex = ZeroEx.getOrderHashHex(signedOrder);
+		});
+		describe('#cancelOrderAsync', () => {
+			describe('successful cancels', () => {
+				it('should cancel an order', async () => {
+					const txHash = await zeroEx.exchange.cancelOrderAsync(signedOrder, cancelAmount);
+					await zeroEx.awaitTransactionMinedAsync(txHash);
+					const cancelledAmount = await zeroEx.exchange.getCancelledTakerAmountAsync(orderHashHex);
+					expect(cancelledAmount).to.be.bignumber.equal(cancelAmount);
+				});
+			});
+			describe('order transaction options', () => {
+				const emptyCancelTakerTokenAmount = new BigNumber(0);
+				it('should validate when orderTransactionOptions are not present', async () => {
+					return expect(
+						zeroEx.exchange.cancelOrderAsync(signedOrder, emptyCancelTakerTokenAmount),
+					).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
+				});
+				it('should validate when orderTransactionOptions specify to validate', async () => {
+					return expect(
+						zeroEx.exchange.cancelOrderAsync(signedOrder, emptyCancelTakerTokenAmount, {
+							shouldValidate: true,
+						}),
+					).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
+				});
+				it('should not validate when orderTransactionOptions specify not to validate', async () => {
+					return expect(
+						zeroEx.exchange.cancelOrderAsync(signedOrder, emptyCancelTakerTokenAmount, {
+							shouldValidate: false,
+						}),
+					).to.not.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
+				});
+			});
+		});
+		describe('#batchCancelOrdersAsync', () => {
+			let anotherSignedOrder: SignedOrder;
+			let anotherOrderHashHex: string;
+			let cancelBatch: OrderCancellationRequest[];
+			beforeEach(async () => {
+				anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
+					makerTokenAddress,
+					takerTokenAddress,
+					makerAddress,
+					takerAddress,
+					fillableAmount,
+				);
+				anotherOrderHashHex = ZeroEx.getOrderHashHex(anotherSignedOrder);
+				cancelBatch = [
+					{
+						order: signedOrder,
+						takerTokenCancelAmount: cancelAmount,
+					},
+					{
+						order: anotherSignedOrder,
+						takerTokenCancelAmount: cancelAmount,
+					},
+				];
+			});
+			describe('failed batch cancels', () => {
+				it('should throw when orders have different makers', async () => {
+					const signedOrderWithDifferentMaker = await fillScenarios.createFillableSignedOrderAsync(
+						makerTokenAddress,
+						takerTokenAddress,
+						takerAddress,
+						takerAddress,
+						fillableAmount,
+					);
+					return expect(
+						zeroEx.exchange.batchCancelOrdersAsync([
+							cancelBatch[0],
+							{
+								order: signedOrderWithDifferentMaker,
+								takerTokenCancelAmount: cancelAmount,
+							},
+						]),
+					).to.be.rejectedWith(ExchangeContractErrs.MultipleMakersInSingleCancelBatchDisallowed);
+				});
+			});
+			describe('successful batch cancels', () => {
+				it('should cancel a batch of orders', async () => {
+					await zeroEx.exchange.batchCancelOrdersAsync(cancelBatch);
+					const cancelledAmount = await zeroEx.exchange.getCancelledTakerAmountAsync(orderHashHex);
+					const anotherCancelledAmount = await zeroEx.exchange.getCancelledTakerAmountAsync(
+						anotherOrderHashHex,
+					);
+					expect(cancelledAmount).to.be.bignumber.equal(cancelAmount);
+					expect(anotherCancelledAmount).to.be.bignumber.equal(cancelAmount);
+				});
+			});
+			describe('order transaction options', () => {
+				beforeEach(async () => {
+					const emptyTakerTokenCancelAmount = new BigNumber(0);
+					cancelBatch = [
+						{
+							order: signedOrder,
+							takerTokenCancelAmount: emptyTakerTokenCancelAmount,
+						},
+						{
+							order: anotherSignedOrder,
+							takerTokenCancelAmount: emptyTakerTokenCancelAmount,
+						},
+					];
+				});
+				it('should validate when orderTransactionOptions are not present', async () => {
+					return expect(zeroEx.exchange.batchCancelOrdersAsync(cancelBatch)).to.be.rejectedWith(
+						ExchangeContractErrs.OrderCancelAmountZero,
+					);
+				});
+				it('should validate when orderTransactionOptions specify to validate', async () => {
+					return expect(
+						zeroEx.exchange.batchCancelOrdersAsync(cancelBatch, {
+							shouldValidate: true,
+						}),
+					).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
+				});
+				it('should not validate when orderTransactionOptions specify not to validate', async () => {
+					return expect(
+						zeroEx.exchange.batchCancelOrdersAsync(cancelBatch, {
+							shouldValidate: false,
+						}),
+					).to.not.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
+				});
+			});
+		});
+	});
+	describe('tests that require partially filled order', () => {
+		let makerTokenAddress: string;
+		let takerTokenAddress: string;
+		let takerAddress: string;
+		let fillableAmount: BigNumber;
+		let partialFillAmount: BigNumber;
+		let signedOrder: SignedOrder;
+		let orderHash: string;
+		before(() => {
+			takerAddress = userAddresses[1];
+			tokenUtils = new TokenUtils(tokens);
+			const [makerToken, takerToken] = tokenUtils.getDummyTokens();
+			makerTokenAddress = makerToken.address;
+			takerTokenAddress = takerToken.address;
+		});
+		beforeEach(async () => {
+			fillableAmount = new BigNumber(5);
+			partialFillAmount = new BigNumber(2);
+			signedOrder = await fillScenarios.createPartiallyFilledSignedOrderAsync(
+				makerTokenAddress,
+				takerTokenAddress,
+				takerAddress,
+				fillableAmount,
+				partialFillAmount,
+			);
+			orderHash = ZeroEx.getOrderHashHex(signedOrder);
+		});
+		describe('#getUnavailableTakerAmountAsync', () => {
+			it('should throw if passed an invalid orderHash', async () => {
+				const invalidOrderHashHex = '0x123';
+				return expect(zeroEx.exchange.getUnavailableTakerAmountAsync(invalidOrderHashHex)).to.be.rejected();
+			});
+			it('should return zero if passed a valid but non-existent orderHash', async () => {
+				const unavailableValueT = await zeroEx.exchange.getUnavailableTakerAmountAsync(NON_EXISTENT_ORDER_HASH);
+				expect(unavailableValueT).to.be.bignumber.equal(0);
+			});
+			it('should return the unavailableValueT for a valid and partially filled orderHash', async () => {
+				const unavailableValueT = await zeroEx.exchange.getUnavailableTakerAmountAsync(orderHash);
+				expect(unavailableValueT).to.be.bignumber.equal(partialFillAmount);
+			});
+		});
+		describe('#getFilledTakerAmountAsync', () => {
+			it('should throw if passed an invalid orderHash', async () => {
+				const invalidOrderHashHex = '0x123';
+				return expect(zeroEx.exchange.getFilledTakerAmountAsync(invalidOrderHashHex)).to.be.rejected();
+			});
+			it('should return zero if passed a valid but non-existent orderHash', async () => {
+				const filledValueT = await zeroEx.exchange.getFilledTakerAmountAsync(NON_EXISTENT_ORDER_HASH);
+				expect(filledValueT).to.be.bignumber.equal(0);
+			});
+			it('should return the filledValueT for a valid and partially filled orderHash', async () => {
+				const filledValueT = await zeroEx.exchange.getFilledTakerAmountAsync(orderHash);
+				expect(filledValueT).to.be.bignumber.equal(partialFillAmount);
+			});
+		});
+		describe('#getCancelledTakerAmountAsync', () => {
+			it('should throw if passed an invalid orderHash', async () => {
+				const invalidOrderHashHex = '0x123';
+				return expect(zeroEx.exchange.getCancelledTakerAmountAsync(invalidOrderHashHex)).to.be.rejected();
+			});
+			it('should return zero if passed a valid but non-existent orderHash', async () => {
+				const cancelledValueT = await zeroEx.exchange.getCancelledTakerAmountAsync(NON_EXISTENT_ORDER_HASH);
+				expect(cancelledValueT).to.be.bignumber.equal(0);
+			});
+			it('should return the cancelledValueT for a valid and partially filled orderHash', async () => {
+				const cancelledValueT = await zeroEx.exchange.getCancelledTakerAmountAsync(orderHash);
+				expect(cancelledValueT).to.be.bignumber.equal(0);
+			});
+			it('should return the cancelledValueT for a valid and cancelled orderHash', async () => {
+				const cancelAmount = fillableAmount.minus(partialFillAmount);
+				await zeroEx.exchange.cancelOrderAsync(signedOrder, cancelAmount);
+				const cancelledValueT = await zeroEx.exchange.getCancelledTakerAmountAsync(orderHash);
+				expect(cancelledValueT).to.be.bignumber.equal(cancelAmount);
+			});
+		});
+	});
+	describe('#subscribe', () => {
+		const indexFilterValues = {};
+		const shouldThrowOnInsufficientBalanceOrAllowance = true;
+		let makerTokenAddress: string;
+		let takerTokenAddress: string;
+		let coinbase: string;
+		let takerAddress: string;
+		let makerAddress: string;
+		let fillableAmount: BigNumber;
+		let signedOrder: SignedOrder;
+		const takerTokenFillAmountInBaseUnits = new BigNumber(1);
+		const cancelTakerAmountInBaseUnits = new BigNumber(1);
+		before(() => {
+			[coinbase, makerAddress, takerAddress] = userAddresses;
+			const [makerToken, takerToken] = tokenUtils.getDummyTokens();
+			makerTokenAddress = makerToken.address;
+			takerTokenAddress = takerToken.address;
+		});
+		beforeEach(async () => {
+			fillableAmount = new BigNumber(5);
+			signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+				makerTokenAddress,
+				takerTokenAddress,
+				makerAddress,
+				takerAddress,
+				fillableAmount,
+			);
+		});
+		afterEach(async () => {
+			zeroEx.exchange.unsubscribeAll();
+		});
+		// Hack: Mocha does not allow a test to be both async and have a `done` callback
+		// Since we need to await the receipt of the event in the `subscribe` callback,
+		// we do need both. A hack is to make the top-level a sync fn w/ a done callback and then
+		// wrap the rest of the test in an async block
+		// Source: https://github.com/mochajs/mocha/issues/2407
+		it('Should receive the LogFill event when an order is filled', (done: DoneCallback) => {
+			(async () => {
+				const callback = reportNodeCallbackErrors(done)(
+					(logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
+						expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogFill);
+					},
+				);
+				zeroEx.exchange.subscribe(ExchangeEvents.LogFill, indexFilterValues, callback);
+				await zeroEx.exchange.fillOrderAsync(
+					signedOrder,
+					takerTokenFillAmountInBaseUnits,
+					shouldThrowOnInsufficientBalanceOrAllowance,
+					takerAddress,
+				);
+			})().catch(done);
+		});
+		it('Should receive the LogCancel event when an order is cancelled', (done: DoneCallback) => {
+			(async () => {
+				const callback = reportNodeCallbackErrors(done)(
+					(logEvent: DecodedLogEvent<LogCancelContractEventArgs>) => {
+						expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogCancel);
+					},
+				);
+				zeroEx.exchange.subscribe(ExchangeEvents.LogCancel, indexFilterValues, callback);
+				await zeroEx.exchange.cancelOrderAsync(signedOrder, cancelTakerAmountInBaseUnits);
+			})().catch(done);
+		});
+		it('Outstanding subscriptions are cancelled when zeroEx.setProvider called', (done: DoneCallback) => {
+			(async () => {
+				const callbackNeverToBeCalled = reportNodeCallbackErrors(done)(
+					(logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
+						done(new Error('Expected this subscription to have been cancelled'));
+					},
+				);
+				zeroEx.exchange.subscribe(ExchangeEvents.LogFill, indexFilterValues, callbackNeverToBeCalled);
 
-                const newProvider = web3Factory.getRpcProvider();
-                zeroEx.setProvider(newProvider, constants.TESTRPC_NETWORK_ID);
+				const newProvider = web3Factory.getRpcProvider();
+				zeroEx.setProvider(newProvider, constants.TESTRPC_NETWORK_ID);
 
-                const callback = reportNodeCallbackErrors(done)(
-                    (logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
-                        expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogFill);
-                    },
-                );
-                zeroEx.exchange.subscribe(ExchangeEvents.LogFill, indexFilterValues, callback);
-                await zeroEx.exchange.fillOrderAsync(
-                    signedOrder,
-                    takerTokenFillAmountInBaseUnits,
-                    shouldThrowOnInsufficientBalanceOrAllowance,
-                    takerAddress,
-                );
-            })().catch(done);
-        });
-        it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => {
-            (async () => {
-                const callbackNeverToBeCalled = reportNodeCallbackErrors(done)(
-                    (logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
-                        done(new Error('Expected this subscription to have been cancelled'));
-                    },
-                );
-                const subscriptionToken = zeroEx.exchange.subscribe(
-                    ExchangeEvents.LogFill,
-                    indexFilterValues,
-                    callbackNeverToBeCalled,
-                );
-                zeroEx.exchange.unsubscribe(subscriptionToken);
-                await zeroEx.exchange.fillOrderAsync(
-                    signedOrder,
-                    takerTokenFillAmountInBaseUnits,
-                    shouldThrowOnInsufficientBalanceOrAllowance,
-                    takerAddress,
-                );
-                done();
-            })().catch(done);
-        });
-    });
-    describe('#getOrderHashHexUsingContractCallAsync', () => {
-        let makerTokenAddress: string;
-        let takerTokenAddress: string;
-        let makerAddress: string;
-        let takerAddress: string;
-        const fillableAmount = new BigNumber(5);
-        before(async () => {
-            [, makerAddress, takerAddress] = userAddresses;
-            const [makerToken, takerToken] = tokenUtils.getDummyTokens();
-            makerTokenAddress = makerToken.address;
-            takerTokenAddress = takerToken.address;
-        });
-        it("get's the same hash as the local function", async () => {
-            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                makerTokenAddress,
-                takerTokenAddress,
-                makerAddress,
-                takerAddress,
-                fillableAmount,
-            );
-            const orderHash = ZeroEx.getOrderHashHex(signedOrder);
-            const orderHashFromContract = await (zeroEx.exchange as any)._getOrderHashHexUsingContractCallAsync(
-                signedOrder,
-            );
-            expect(orderHash).to.equal(orderHashFromContract);
-        });
-    });
-    describe('#getZRXTokenAddressAsync', () => {
-        it('gets the same token as is in token registry', () => {
-            const zrxAddress = zeroEx.exchange.getZRXTokenAddress();
-            const zrxToken = tokenUtils.getProtocolTokenOrThrow();
-            expect(zrxAddress).to.equal(zrxToken.address);
-        });
-    });
-    describe('#getLogsAsync', () => {
-        let makerTokenAddress: string;
-        let takerTokenAddress: string;
-        let makerAddress: string;
-        let takerAddress: string;
-        const fillableAmount = new BigNumber(5);
-        const shouldThrowOnInsufficientBalanceOrAllowance = true;
-        const blockRange: BlockRange = {
-            fromBlock: 0,
-            toBlock: BlockParamLiteral.Latest,
-        };
-        let txHash: string;
-        before(async () => {
-            [, makerAddress, takerAddress] = userAddresses;
-            const [makerToken, takerToken] = tokenUtils.getDummyTokens();
-            makerTokenAddress = makerToken.address;
-            takerTokenAddress = takerToken.address;
-        });
-        it('should get logs with decoded args emitted by LogFill', async () => {
-            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                makerTokenAddress,
-                takerTokenAddress,
-                makerAddress,
-                takerAddress,
-                fillableAmount,
-            );
-            txHash = await zeroEx.exchange.fillOrderAsync(
-                signedOrder,
-                fillableAmount,
-                shouldThrowOnInsufficientBalanceOrAllowance,
-                takerAddress,
-            );
-            await zeroEx.awaitTransactionMinedAsync(txHash);
-            const eventName = ExchangeEvents.LogFill;
-            const indexFilterValues = {};
-            const logs = await zeroEx.exchange.getLogsAsync(eventName, blockRange, indexFilterValues);
-            expect(logs).to.have.length(1);
-            expect(logs[0].event).to.be.equal(eventName);
-        });
-        it('should only get the logs with the correct event name', async () => {
-            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                makerTokenAddress,
-                takerTokenAddress,
-                makerAddress,
-                takerAddress,
-                fillableAmount,
-            );
-            txHash = await zeroEx.exchange.fillOrderAsync(
-                signedOrder,
-                fillableAmount,
-                shouldThrowOnInsufficientBalanceOrAllowance,
-                takerAddress,
-            );
-            await zeroEx.awaitTransactionMinedAsync(txHash);
-            const differentEventName = ExchangeEvents.LogCancel;
-            const indexFilterValues = {};
-            const logs = await zeroEx.exchange.getLogsAsync(differentEventName, blockRange, indexFilterValues);
-            expect(logs).to.have.length(0);
-        });
-        it('should only get the logs with the correct indexed fields', async () => {
-            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                makerTokenAddress,
-                takerTokenAddress,
-                makerAddress,
-                takerAddress,
-                fillableAmount,
-            );
-            txHash = await zeroEx.exchange.fillOrderAsync(
-                signedOrder,
-                fillableAmount,
-                shouldThrowOnInsufficientBalanceOrAllowance,
-                takerAddress,
-            );
-            await zeroEx.awaitTransactionMinedAsync(txHash);
+				const callback = reportNodeCallbackErrors(done)(
+					(logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
+						expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogFill);
+					},
+				);
+				zeroEx.exchange.subscribe(ExchangeEvents.LogFill, indexFilterValues, callback);
+				await zeroEx.exchange.fillOrderAsync(
+					signedOrder,
+					takerTokenFillAmountInBaseUnits,
+					shouldThrowOnInsufficientBalanceOrAllowance,
+					takerAddress,
+				);
+			})().catch(done);
+		});
+		it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => {
+			(async () => {
+				const callbackNeverToBeCalled = reportNodeCallbackErrors(done)(
+					(logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
+						done(new Error('Expected this subscription to have been cancelled'));
+					},
+				);
+				const subscriptionToken = zeroEx.exchange.subscribe(
+					ExchangeEvents.LogFill,
+					indexFilterValues,
+					callbackNeverToBeCalled,
+				);
+				zeroEx.exchange.unsubscribe(subscriptionToken);
+				await zeroEx.exchange.fillOrderAsync(
+					signedOrder,
+					takerTokenFillAmountInBaseUnits,
+					shouldThrowOnInsufficientBalanceOrAllowance,
+					takerAddress,
+				);
+				done();
+			})().catch(done);
+		});
+	});
+	describe('#getOrderHashHexUsingContractCallAsync', () => {
+		let makerTokenAddress: string;
+		let takerTokenAddress: string;
+		let makerAddress: string;
+		let takerAddress: string;
+		const fillableAmount = new BigNumber(5);
+		before(async () => {
+			[, makerAddress, takerAddress] = userAddresses;
+			const [makerToken, takerToken] = tokenUtils.getDummyTokens();
+			makerTokenAddress = makerToken.address;
+			takerTokenAddress = takerToken.address;
+		});
+		it("get's the same hash as the local function", async () => {
+			const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+				makerTokenAddress,
+				takerTokenAddress,
+				makerAddress,
+				takerAddress,
+				fillableAmount,
+			);
+			const orderHash = ZeroEx.getOrderHashHex(signedOrder);
+			const orderHashFromContract = await (zeroEx.exchange as any)._getOrderHashHexUsingContractCallAsync(
+				signedOrder,
+			);
+			expect(orderHash).to.equal(orderHashFromContract);
+		});
+	});
+	describe('#getZRXTokenAddressAsync', () => {
+		it('gets the same token as is in token registry', () => {
+			const zrxAddress = zeroEx.exchange.getZRXTokenAddress();
+			const zrxToken = tokenUtils.getProtocolTokenOrThrow();
+			expect(zrxAddress).to.equal(zrxToken.address);
+		});
+	});
+	describe('#getLogsAsync', () => {
+		let makerTokenAddress: string;
+		let takerTokenAddress: string;
+		let makerAddress: string;
+		let takerAddress: string;
+		const fillableAmount = new BigNumber(5);
+		const shouldThrowOnInsufficientBalanceOrAllowance = true;
+		const blockRange: BlockRange = {
+			fromBlock: 0,
+			toBlock: BlockParamLiteral.Latest,
+		};
+		let txHash: string;
+		before(async () => {
+			[, makerAddress, takerAddress] = userAddresses;
+			const [makerToken, takerToken] = tokenUtils.getDummyTokens();
+			makerTokenAddress = makerToken.address;
+			takerTokenAddress = takerToken.address;
+		});
+		it('should get logs with decoded args emitted by LogFill', async () => {
+			const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+				makerTokenAddress,
+				takerTokenAddress,
+				makerAddress,
+				takerAddress,
+				fillableAmount,
+			);
+			txHash = await zeroEx.exchange.fillOrderAsync(
+				signedOrder,
+				fillableAmount,
+				shouldThrowOnInsufficientBalanceOrAllowance,
+				takerAddress,
+			);
+			await zeroEx.awaitTransactionMinedAsync(txHash);
+			const eventName = ExchangeEvents.LogFill;
+			const indexFilterValues = {};
+			const logs = await zeroEx.exchange.getLogsAsync(eventName, blockRange, indexFilterValues);
+			expect(logs).to.have.length(1);
+			expect(logs[0].event).to.be.equal(eventName);
+		});
+		it('should only get the logs with the correct event name', async () => {
+			const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+				makerTokenAddress,
+				takerTokenAddress,
+				makerAddress,
+				takerAddress,
+				fillableAmount,
+			);
+			txHash = await zeroEx.exchange.fillOrderAsync(
+				signedOrder,
+				fillableAmount,
+				shouldThrowOnInsufficientBalanceOrAllowance,
+				takerAddress,
+			);
+			await zeroEx.awaitTransactionMinedAsync(txHash);
+			const differentEventName = ExchangeEvents.LogCancel;
+			const indexFilterValues = {};
+			const logs = await zeroEx.exchange.getLogsAsync(differentEventName, blockRange, indexFilterValues);
+			expect(logs).to.have.length(0);
+		});
+		it('should only get the logs with the correct indexed fields', async () => {
+			const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+				makerTokenAddress,
+				takerTokenAddress,
+				makerAddress,
+				takerAddress,
+				fillableAmount,
+			);
+			txHash = await zeroEx.exchange.fillOrderAsync(
+				signedOrder,
+				fillableAmount,
+				shouldThrowOnInsufficientBalanceOrAllowance,
+				takerAddress,
+			);
+			await zeroEx.awaitTransactionMinedAsync(txHash);
 
-            const differentMakerAddress = userAddresses[2];
-            const anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                makerTokenAddress,
-                takerTokenAddress,
-                differentMakerAddress,
-                takerAddress,
-                fillableAmount,
-            );
-            txHash = await zeroEx.exchange.fillOrderAsync(
-                anotherSignedOrder,
-                fillableAmount,
-                shouldThrowOnInsufficientBalanceOrAllowance,
-                takerAddress,
-            );
-            await zeroEx.awaitTransactionMinedAsync(txHash);
+			const differentMakerAddress = userAddresses[2];
+			const anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
+				makerTokenAddress,
+				takerTokenAddress,
+				differentMakerAddress,
+				takerAddress,
+				fillableAmount,
+			);
+			txHash = await zeroEx.exchange.fillOrderAsync(
+				anotherSignedOrder,
+				fillableAmount,
+				shouldThrowOnInsufficientBalanceOrAllowance,
+				takerAddress,
+			);
+			await zeroEx.awaitTransactionMinedAsync(txHash);
 
-            const eventName = ExchangeEvents.LogFill;
-            const indexFilterValues = {
-                maker: differentMakerAddress,
-            };
-            const logs = await zeroEx.exchange.getLogsAsync<LogFillContractEventArgs>(
-                eventName,
-                blockRange,
-                indexFilterValues,
-            );
-            expect(logs).to.have.length(1);
-            const args = logs[0].args;
-            expect(args.maker).to.be.equal(differentMakerAddress);
-        });
-    });
+			const eventName = ExchangeEvents.LogFill;
+			const indexFilterValues = {
+				maker: differentMakerAddress,
+			};
+			const logs = await zeroEx.exchange.getLogsAsync<LogFillContractEventArgs>(
+				eventName,
+				blockRange,
+				indexFilterValues,
+			);
+			expect(logs).to.have.length(1);
+			const args = logs[0].args;
+			expect(args.maker).to.be.equal(differentMakerAddress);
+		});
+	});
 }); // tslint:disable:max-file-line-count
diff --git a/packages/0x.js/test/expiration_watcher_test.ts b/packages/0x.js/test/expiration_watcher_test.ts
index 770615f88..a76d84da1 100644
--- a/packages/0x.js/test/expiration_watcher_test.ts
+++ b/packages/0x.js/test/expiration_watcher_test.ts
@@ -24,137 +24,137 @@ const expect = chai.expect;
 const blockchainLifecycle = new BlockchainLifecycle(testConstants.RPC_URL);
 
 describe('ExpirationWatcher', () => {
-    let web3: Web3;
-    let zeroEx: ZeroEx;
-    let tokenUtils: TokenUtils;
-    let tokens: Token[];
-    let userAddresses: string[];
-    let zrxTokenAddress: string;
-    let fillScenarios: FillScenarios;
-    let exchangeContractAddress: string;
-    let makerTokenAddress: string;
-    let takerTokenAddress: string;
-    let coinbase: string;
-    let makerAddress: string;
-    let takerAddress: string;
-    let feeRecipient: string;
-    const fillableAmount = new BigNumber(5);
-    let currentUnixTimestampSec: BigNumber;
-    let timer: Sinon.SinonFakeTimers;
-    let expirationWatcher: ExpirationWatcher;
-    before(async () => {
-        web3 = web3Factory.create();
-        const config = {
-            networkId: constants.TESTRPC_NETWORK_ID,
-        };
-        zeroEx = new ZeroEx(web3.currentProvider, config);
-        exchangeContractAddress = zeroEx.exchange.getContractAddress();
-        userAddresses = await zeroEx.getAvailableAddressesAsync();
-        tokens = await zeroEx.tokenRegistry.getTokensAsync();
-        tokenUtils = new TokenUtils(tokens);
-        zrxTokenAddress = tokenUtils.getProtocolTokenOrThrow().address;
-        fillScenarios = new FillScenarios(zeroEx, userAddresses, tokens, zrxTokenAddress, exchangeContractAddress);
-        [coinbase, makerAddress, takerAddress, feeRecipient] = userAddresses;
-        tokens = await zeroEx.tokenRegistry.getTokensAsync();
-        const [makerToken, takerToken] = tokenUtils.getDummyTokens();
-        makerTokenAddress = makerToken.address;
-        takerTokenAddress = takerToken.address;
-    });
-    beforeEach(async () => {
-        await blockchainLifecycle.startAsync();
-        const sinonTimerConfig = { shouldAdvanceTime: true } as any;
-        // This constructor has incorrect types
-        timer = Sinon.useFakeTimers(sinonTimerConfig);
-        currentUnixTimestampSec = utils.getCurrentUnixTimestampSec();
-        expirationWatcher = new ExpirationWatcher();
-    });
-    afterEach(async () => {
-        await blockchainLifecycle.revertAsync();
-        timer.restore();
-        expirationWatcher.unsubscribe();
-    });
-    it('correctly emits events when order expires', (done: DoneCallback) => {
-        (async () => {
-            const orderLifetimeSec = 60;
-            const expirationUnixTimestampSec = currentUnixTimestampSec.plus(orderLifetimeSec);
-            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                makerTokenAddress,
-                takerTokenAddress,
-                makerAddress,
-                takerAddress,
-                fillableAmount,
-                expirationUnixTimestampSec,
-            );
-            const orderHash = ZeroEx.getOrderHashHex(signedOrder);
-            expirationWatcher.addOrder(orderHash, signedOrder.expirationUnixTimestampSec.times(1000));
-            const callbackAsync = reportNoErrorCallbackErrors(done)((hash: string) => {
-                expect(hash).to.be.equal(orderHash);
-                expect(utils.getCurrentUnixTimestampSec()).to.be.bignumber.gte(expirationUnixTimestampSec);
-            });
-            expirationWatcher.subscribe(callbackAsync);
-            timer.tick(orderLifetimeSec * 1000);
-        })().catch(done);
-    });
-    it("doesn't emit events before order expires", (done: DoneCallback) => {
-        (async () => {
-            const orderLifetimeSec = 60;
-            const expirationUnixTimestampSec = currentUnixTimestampSec.plus(orderLifetimeSec);
-            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                makerTokenAddress,
-                takerTokenAddress,
-                makerAddress,
-                takerAddress,
-                fillableAmount,
-                expirationUnixTimestampSec,
-            );
-            const orderHash = ZeroEx.getOrderHashHex(signedOrder);
-            expirationWatcher.addOrder(orderHash, signedOrder.expirationUnixTimestampSec.times(1000));
-            const callbackAsync = reportNoErrorCallbackErrors(done)(async (hash: string) => {
-                done(new Error('Emitted expiration went before the order actually expired'));
-            });
-            expirationWatcher.subscribe(callbackAsync);
-            const notEnoughTime = orderLifetimeSec - 1;
-            timer.tick(notEnoughTime * 1000);
-            done();
-        })().catch(done);
-    });
-    it('emits events in correct order', (done: DoneCallback) => {
-        (async () => {
-            const order1Lifetime = 60;
-            const order2Lifetime = 120;
-            const order1ExpirationUnixTimestampSec = currentUnixTimestampSec.plus(order1Lifetime);
-            const order2ExpirationUnixTimestampSec = currentUnixTimestampSec.plus(order2Lifetime);
-            const signedOrder1 = await fillScenarios.createFillableSignedOrderAsync(
-                makerTokenAddress,
-                takerTokenAddress,
-                makerAddress,
-                takerAddress,
-                fillableAmount,
-                order1ExpirationUnixTimestampSec,
-            );
-            const signedOrder2 = await fillScenarios.createFillableSignedOrderAsync(
-                makerTokenAddress,
-                takerTokenAddress,
-                makerAddress,
-                takerAddress,
-                fillableAmount,
-                order2ExpirationUnixTimestampSec,
-            );
-            const orderHash1 = ZeroEx.getOrderHashHex(signedOrder1);
-            const orderHash2 = ZeroEx.getOrderHashHex(signedOrder2);
-            expirationWatcher.addOrder(orderHash2, signedOrder2.expirationUnixTimestampSec.times(1000));
-            expirationWatcher.addOrder(orderHash1, signedOrder1.expirationUnixTimestampSec.times(1000));
-            const expirationOrder = [orderHash1, orderHash2];
-            const expectToBeCalledOnce = false;
-            const callbackAsync = reportNoErrorCallbackErrors(done, expectToBeCalledOnce)((hash: string) => {
-                const orderHash = expirationOrder.shift();
-                expect(hash).to.be.equal(orderHash);
-                if (_.isEmpty(expirationOrder)) {
-                    done();
-                }
-            });
-            expirationWatcher.subscribe(callbackAsync);
-            timer.tick(order2Lifetime * 1000);
-        })().catch(done);
-    });
+	let web3: Web3;
+	let zeroEx: ZeroEx;
+	let tokenUtils: TokenUtils;
+	let tokens: Token[];
+	let userAddresses: string[];
+	let zrxTokenAddress: string;
+	let fillScenarios: FillScenarios;
+	let exchangeContractAddress: string;
+	let makerTokenAddress: string;
+	let takerTokenAddress: string;
+	let coinbase: string;
+	let makerAddress: string;
+	let takerAddress: string;
+	let feeRecipient: string;
+	const fillableAmount = new BigNumber(5);
+	let currentUnixTimestampSec: BigNumber;
+	let timer: Sinon.SinonFakeTimers;
+	let expirationWatcher: ExpirationWatcher;
+	before(async () => {
+		web3 = web3Factory.create();
+		const config = {
+			networkId: constants.TESTRPC_NETWORK_ID,
+		};
+		zeroEx = new ZeroEx(web3.currentProvider, config);
+		exchangeContractAddress = zeroEx.exchange.getContractAddress();
+		userAddresses = await zeroEx.getAvailableAddressesAsync();
+		tokens = await zeroEx.tokenRegistry.getTokensAsync();
+		tokenUtils = new TokenUtils(tokens);
+		zrxTokenAddress = tokenUtils.getProtocolTokenOrThrow().address;
+		fillScenarios = new FillScenarios(zeroEx, userAddresses, tokens, zrxTokenAddress, exchangeContractAddress);
+		[coinbase, makerAddress, takerAddress, feeRecipient] = userAddresses;
+		tokens = await zeroEx.tokenRegistry.getTokensAsync();
+		const [makerToken, takerToken] = tokenUtils.getDummyTokens();
+		makerTokenAddress = makerToken.address;
+		takerTokenAddress = takerToken.address;
+	});
+	beforeEach(async () => {
+		await blockchainLifecycle.startAsync();
+		const sinonTimerConfig = { shouldAdvanceTime: true } as any;
+		// This constructor has incorrect types
+		timer = Sinon.useFakeTimers(sinonTimerConfig);
+		currentUnixTimestampSec = utils.getCurrentUnixTimestampSec();
+		expirationWatcher = new ExpirationWatcher();
+	});
+	afterEach(async () => {
+		await blockchainLifecycle.revertAsync();
+		timer.restore();
+		expirationWatcher.unsubscribe();
+	});
+	it('correctly emits events when order expires', (done: DoneCallback) => {
+		(async () => {
+			const orderLifetimeSec = 60;
+			const expirationUnixTimestampSec = currentUnixTimestampSec.plus(orderLifetimeSec);
+			const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+				makerTokenAddress,
+				takerTokenAddress,
+				makerAddress,
+				takerAddress,
+				fillableAmount,
+				expirationUnixTimestampSec,
+			);
+			const orderHash = ZeroEx.getOrderHashHex(signedOrder);
+			expirationWatcher.addOrder(orderHash, signedOrder.expirationUnixTimestampSec.times(1000));
+			const callbackAsync = reportNoErrorCallbackErrors(done)((hash: string) => {
+				expect(hash).to.be.equal(orderHash);
+				expect(utils.getCurrentUnixTimestampSec()).to.be.bignumber.gte(expirationUnixTimestampSec);
+			});
+			expirationWatcher.subscribe(callbackAsync);
+			timer.tick(orderLifetimeSec * 1000);
+		})().catch(done);
+	});
+	it("doesn't emit events before order expires", (done: DoneCallback) => {
+		(async () => {
+			const orderLifetimeSec = 60;
+			const expirationUnixTimestampSec = currentUnixTimestampSec.plus(orderLifetimeSec);
+			const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+				makerTokenAddress,
+				takerTokenAddress,
+				makerAddress,
+				takerAddress,
+				fillableAmount,
+				expirationUnixTimestampSec,
+			);
+			const orderHash = ZeroEx.getOrderHashHex(signedOrder);
+			expirationWatcher.addOrder(orderHash, signedOrder.expirationUnixTimestampSec.times(1000));
+			const callbackAsync = reportNoErrorCallbackErrors(done)(async (hash: string) => {
+				done(new Error('Emitted expiration went before the order actually expired'));
+			});
+			expirationWatcher.subscribe(callbackAsync);
+			const notEnoughTime = orderLifetimeSec - 1;
+			timer.tick(notEnoughTime * 1000);
+			done();
+		})().catch(done);
+	});
+	it('emits events in correct order', (done: DoneCallback) => {
+		(async () => {
+			const order1Lifetime = 60;
+			const order2Lifetime = 120;
+			const order1ExpirationUnixTimestampSec = currentUnixTimestampSec.plus(order1Lifetime);
+			const order2ExpirationUnixTimestampSec = currentUnixTimestampSec.plus(order2Lifetime);
+			const signedOrder1 = await fillScenarios.createFillableSignedOrderAsync(
+				makerTokenAddress,
+				takerTokenAddress,
+				makerAddress,
+				takerAddress,
+				fillableAmount,
+				order1ExpirationUnixTimestampSec,
+			);
+			const signedOrder2 = await fillScenarios.createFillableSignedOrderAsync(
+				makerTokenAddress,
+				takerTokenAddress,
+				makerAddress,
+				takerAddress,
+				fillableAmount,
+				order2ExpirationUnixTimestampSec,
+			);
+			const orderHash1 = ZeroEx.getOrderHashHex(signedOrder1);
+			const orderHash2 = ZeroEx.getOrderHashHex(signedOrder2);
+			expirationWatcher.addOrder(orderHash2, signedOrder2.expirationUnixTimestampSec.times(1000));
+			expirationWatcher.addOrder(orderHash1, signedOrder1.expirationUnixTimestampSec.times(1000));
+			const expirationOrder = [orderHash1, orderHash2];
+			const expectToBeCalledOnce = false;
+			const callbackAsync = reportNoErrorCallbackErrors(done, expectToBeCalledOnce)((hash: string) => {
+				const orderHash = expirationOrder.shift();
+				expect(hash).to.be.equal(orderHash);
+				if (_.isEmpty(expirationOrder)) {
+					done();
+				}
+			});
+			expirationWatcher.subscribe(callbackAsync);
+			timer.tick(order2Lifetime * 1000);
+		})().catch(done);
+	});
 });
diff --git a/packages/0x.js/test/order_state_watcher_test.ts b/packages/0x.js/test/order_state_watcher_test.ts
index 2e9202fe2..22ed80446 100644
--- a/packages/0x.js/test/order_state_watcher_test.ts
+++ b/packages/0x.js/test/order_state_watcher_test.ts
@@ -6,14 +6,14 @@ import 'mocha';
 import * as Web3 from 'web3';
 
 import {
-    ExchangeContractErrs,
-    OrderState,
-    OrderStateInvalid,
-    OrderStateValid,
-    SignedOrder,
-    Token,
-    ZeroEx,
-    ZeroExError,
+	ExchangeContractErrs,
+	OrderState,
+	OrderStateInvalid,
+	OrderStateValid,
+	SignedOrder,
+	Token,
+	ZeroEx,
+	ZeroExError,
 } from '../src';
 import { DoneCallback } from '../src/types';
 
@@ -31,528 +31,528 @@ const expect = chai.expect;
 const blockchainLifecycle = new BlockchainLifecycle(constants.RPC_URL);
 
 describe('OrderStateWatcher', () => {
-    let web3: Web3;
-    let zeroEx: ZeroEx;
-    let tokens: Token[];
-    let tokenUtils: TokenUtils;
-    let fillScenarios: FillScenarios;
-    let userAddresses: string[];
-    let zrxTokenAddress: string;
-    let exchangeContractAddress: string;
-    let makerToken: Token;
-    let takerToken: Token;
-    let maker: string;
-    let taker: string;
-    let signedOrder: SignedOrder;
-    const config = {
-        networkId: constants.TESTRPC_NETWORK_ID,
-    };
-    const decimals = constants.ZRX_DECIMALS;
-    const fillableAmount = ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals);
-    before(async () => {
-        web3 = web3Factory.create();
-        zeroEx = new ZeroEx(web3.currentProvider, config);
-        exchangeContractAddress = zeroEx.exchange.getContractAddress();
-        userAddresses = await zeroEx.getAvailableAddressesAsync();
-        [, maker, taker] = userAddresses;
-        tokens = await zeroEx.tokenRegistry.getTokensAsync();
-        tokenUtils = new TokenUtils(tokens);
-        zrxTokenAddress = tokenUtils.getProtocolTokenOrThrow().address;
-        fillScenarios = new FillScenarios(zeroEx, userAddresses, tokens, zrxTokenAddress, exchangeContractAddress);
-        await fillScenarios.initTokenBalancesAsync();
-        [makerToken, takerToken] = tokenUtils.getDummyTokens();
-    });
-    beforeEach(async () => {
-        await blockchainLifecycle.startAsync();
-    });
-    afterEach(async () => {
-        await blockchainLifecycle.revertAsync();
-    });
-    describe('#removeOrder', async () => {
-        it('should successfully remove existing order', async () => {
-            signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                makerToken.address,
-                takerToken.address,
-                maker,
-                taker,
-                fillableAmount,
-            );
-            const orderHash = ZeroEx.getOrderHashHex(signedOrder);
-            zeroEx.orderStateWatcher.addOrder(signedOrder);
-            expect((zeroEx.orderStateWatcher as any)._orderByOrderHash).to.include({
-                [orderHash]: signedOrder,
-            });
-            let dependentOrderHashes = (zeroEx.orderStateWatcher as any)._dependentOrderHashes;
-            expect(dependentOrderHashes[signedOrder.maker][signedOrder.makerTokenAddress]).to.have.keys(orderHash);
-            zeroEx.orderStateWatcher.removeOrder(orderHash);
-            expect((zeroEx.orderStateWatcher as any)._orderByOrderHash).to.not.include({
-                [orderHash]: signedOrder,
-            });
-            dependentOrderHashes = (zeroEx.orderStateWatcher as any)._dependentOrderHashes;
-            expect(dependentOrderHashes[signedOrder.maker]).to.be.undefined();
-        });
-        it('should no-op when removing a non-existing order', async () => {
-            signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                makerToken.address,
-                takerToken.address,
-                maker,
-                taker,
-                fillableAmount,
-            );
-            const orderHash = ZeroEx.getOrderHashHex(signedOrder);
-            const nonExistentOrderHash = `0x${orderHash
-                .substr(2)
-                .split('')
-                .reverse()
-                .join('')}`;
-            zeroEx.orderStateWatcher.removeOrder(nonExistentOrderHash);
-        });
-    });
-    describe('#subscribe', async () => {
-        afterEach(async () => {
-            zeroEx.orderStateWatcher.unsubscribe();
-        });
-        it('should fail when trying to subscribe twice', async () => {
-            zeroEx.orderStateWatcher.subscribe(_.noop);
-            expect(() => zeroEx.orderStateWatcher.subscribe(_.noop)).to.throw(ZeroExError.SubscriptionAlreadyPresent);
-        });
-    });
-    describe('tests with cleanup', async () => {
-        afterEach(async () => {
-            zeroEx.orderStateWatcher.unsubscribe();
-            const orderHash = ZeroEx.getOrderHashHex(signedOrder);
-            zeroEx.orderStateWatcher.removeOrder(orderHash);
-        });
-        it('should emit orderStateInvalid when maker allowance set to 0 for watched order', (done: DoneCallback) => {
-            (async () => {
-                signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                    makerToken.address,
-                    takerToken.address,
-                    maker,
-                    taker,
-                    fillableAmount,
-                );
-                const orderHash = ZeroEx.getOrderHashHex(signedOrder);
-                zeroEx.orderStateWatcher.addOrder(signedOrder);
-                const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
-                    expect(orderState.isValid).to.be.false();
-                    const invalidOrderState = orderState as OrderStateInvalid;
-                    expect(invalidOrderState.orderHash).to.be.equal(orderHash);
-                    expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.InsufficientMakerAllowance);
-                });
-                zeroEx.orderStateWatcher.subscribe(callback);
-                await zeroEx.token.setProxyAllowanceAsync(makerToken.address, maker, new BigNumber(0));
-            })().catch(done);
-        });
-        it('should not emit an orderState event when irrelevant Transfer event received', (done: DoneCallback) => {
-            (async () => {
-                signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                    makerToken.address,
-                    takerToken.address,
-                    maker,
-                    taker,
-                    fillableAmount,
-                );
-                zeroEx.orderStateWatcher.addOrder(signedOrder);
-                const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
-                    throw new Error('OrderState callback fired for irrelevant order');
-                });
-                zeroEx.orderStateWatcher.subscribe(callback);
-                const notTheMaker = userAddresses[0];
-                const anyRecipient = taker;
-                const transferAmount = new BigNumber(2);
-                await zeroEx.token.transferAsync(makerToken.address, notTheMaker, anyRecipient, transferAmount);
-                setTimeout(() => {
-                    done();
-                }, TIMEOUT_MS);
-            })().catch(done);
-        });
-        it('should emit orderStateInvalid when maker moves balance backing watched order', (done: DoneCallback) => {
-            (async () => {
-                signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                    makerToken.address,
-                    takerToken.address,
-                    maker,
-                    taker,
-                    fillableAmount,
-                );
-                const orderHash = ZeroEx.getOrderHashHex(signedOrder);
-                zeroEx.orderStateWatcher.addOrder(signedOrder);
-                const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
-                    expect(orderState.isValid).to.be.false();
-                    const invalidOrderState = orderState as OrderStateInvalid;
-                    expect(invalidOrderState.orderHash).to.be.equal(orderHash);
-                    expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.InsufficientMakerBalance);
-                });
-                zeroEx.orderStateWatcher.subscribe(callback);
-                const anyRecipient = taker;
-                const makerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, maker);
-                await zeroEx.token.transferAsync(makerToken.address, maker, anyRecipient, makerBalance);
-            })().catch(done);
-        });
-        it('should emit orderStateInvalid when watched order fully filled', (done: DoneCallback) => {
-            (async () => {
-                signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                    makerToken.address,
-                    takerToken.address,
-                    maker,
-                    taker,
-                    fillableAmount,
-                );
-                const orderHash = ZeroEx.getOrderHashHex(signedOrder);
-                zeroEx.orderStateWatcher.addOrder(signedOrder);
+	let web3: Web3;
+	let zeroEx: ZeroEx;
+	let tokens: Token[];
+	let tokenUtils: TokenUtils;
+	let fillScenarios: FillScenarios;
+	let userAddresses: string[];
+	let zrxTokenAddress: string;
+	let exchangeContractAddress: string;
+	let makerToken: Token;
+	let takerToken: Token;
+	let maker: string;
+	let taker: string;
+	let signedOrder: SignedOrder;
+	const config = {
+		networkId: constants.TESTRPC_NETWORK_ID,
+	};
+	const decimals = constants.ZRX_DECIMALS;
+	const fillableAmount = ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals);
+	before(async () => {
+		web3 = web3Factory.create();
+		zeroEx = new ZeroEx(web3.currentProvider, config);
+		exchangeContractAddress = zeroEx.exchange.getContractAddress();
+		userAddresses = await zeroEx.getAvailableAddressesAsync();
+		[, maker, taker] = userAddresses;
+		tokens = await zeroEx.tokenRegistry.getTokensAsync();
+		tokenUtils = new TokenUtils(tokens);
+		zrxTokenAddress = tokenUtils.getProtocolTokenOrThrow().address;
+		fillScenarios = new FillScenarios(zeroEx, userAddresses, tokens, zrxTokenAddress, exchangeContractAddress);
+		await fillScenarios.initTokenBalancesAsync();
+		[makerToken, takerToken] = tokenUtils.getDummyTokens();
+	});
+	beforeEach(async () => {
+		await blockchainLifecycle.startAsync();
+	});
+	afterEach(async () => {
+		await blockchainLifecycle.revertAsync();
+	});
+	describe('#removeOrder', async () => {
+		it('should successfully remove existing order', async () => {
+			signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+				makerToken.address,
+				takerToken.address,
+				maker,
+				taker,
+				fillableAmount,
+			);
+			const orderHash = ZeroEx.getOrderHashHex(signedOrder);
+			zeroEx.orderStateWatcher.addOrder(signedOrder);
+			expect((zeroEx.orderStateWatcher as any)._orderByOrderHash).to.include({
+				[orderHash]: signedOrder,
+			});
+			let dependentOrderHashes = (zeroEx.orderStateWatcher as any)._dependentOrderHashes;
+			expect(dependentOrderHashes[signedOrder.maker][signedOrder.makerTokenAddress]).to.have.keys(orderHash);
+			zeroEx.orderStateWatcher.removeOrder(orderHash);
+			expect((zeroEx.orderStateWatcher as any)._orderByOrderHash).to.not.include({
+				[orderHash]: signedOrder,
+			});
+			dependentOrderHashes = (zeroEx.orderStateWatcher as any)._dependentOrderHashes;
+			expect(dependentOrderHashes[signedOrder.maker]).to.be.undefined();
+		});
+		it('should no-op when removing a non-existing order', async () => {
+			signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+				makerToken.address,
+				takerToken.address,
+				maker,
+				taker,
+				fillableAmount,
+			);
+			const orderHash = ZeroEx.getOrderHashHex(signedOrder);
+			const nonExistentOrderHash = `0x${orderHash
+				.substr(2)
+				.split('')
+				.reverse()
+				.join('')}`;
+			zeroEx.orderStateWatcher.removeOrder(nonExistentOrderHash);
+		});
+	});
+	describe('#subscribe', async () => {
+		afterEach(async () => {
+			zeroEx.orderStateWatcher.unsubscribe();
+		});
+		it('should fail when trying to subscribe twice', async () => {
+			zeroEx.orderStateWatcher.subscribe(_.noop);
+			expect(() => zeroEx.orderStateWatcher.subscribe(_.noop)).to.throw(ZeroExError.SubscriptionAlreadyPresent);
+		});
+	});
+	describe('tests with cleanup', async () => {
+		afterEach(async () => {
+			zeroEx.orderStateWatcher.unsubscribe();
+			const orderHash = ZeroEx.getOrderHashHex(signedOrder);
+			zeroEx.orderStateWatcher.removeOrder(orderHash);
+		});
+		it('should emit orderStateInvalid when maker allowance set to 0 for watched order', (done: DoneCallback) => {
+			(async () => {
+				signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+					makerToken.address,
+					takerToken.address,
+					maker,
+					taker,
+					fillableAmount,
+				);
+				const orderHash = ZeroEx.getOrderHashHex(signedOrder);
+				zeroEx.orderStateWatcher.addOrder(signedOrder);
+				const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
+					expect(orderState.isValid).to.be.false();
+					const invalidOrderState = orderState as OrderStateInvalid;
+					expect(invalidOrderState.orderHash).to.be.equal(orderHash);
+					expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.InsufficientMakerAllowance);
+				});
+				zeroEx.orderStateWatcher.subscribe(callback);
+				await zeroEx.token.setProxyAllowanceAsync(makerToken.address, maker, new BigNumber(0));
+			})().catch(done);
+		});
+		it('should not emit an orderState event when irrelevant Transfer event received', (done: DoneCallback) => {
+			(async () => {
+				signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+					makerToken.address,
+					takerToken.address,
+					maker,
+					taker,
+					fillableAmount,
+				);
+				zeroEx.orderStateWatcher.addOrder(signedOrder);
+				const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
+					throw new Error('OrderState callback fired for irrelevant order');
+				});
+				zeroEx.orderStateWatcher.subscribe(callback);
+				const notTheMaker = userAddresses[0];
+				const anyRecipient = taker;
+				const transferAmount = new BigNumber(2);
+				await zeroEx.token.transferAsync(makerToken.address, notTheMaker, anyRecipient, transferAmount);
+				setTimeout(() => {
+					done();
+				}, TIMEOUT_MS);
+			})().catch(done);
+		});
+		it('should emit orderStateInvalid when maker moves balance backing watched order', (done: DoneCallback) => {
+			(async () => {
+				signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+					makerToken.address,
+					takerToken.address,
+					maker,
+					taker,
+					fillableAmount,
+				);
+				const orderHash = ZeroEx.getOrderHashHex(signedOrder);
+				zeroEx.orderStateWatcher.addOrder(signedOrder);
+				const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
+					expect(orderState.isValid).to.be.false();
+					const invalidOrderState = orderState as OrderStateInvalid;
+					expect(invalidOrderState.orderHash).to.be.equal(orderHash);
+					expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.InsufficientMakerBalance);
+				});
+				zeroEx.orderStateWatcher.subscribe(callback);
+				const anyRecipient = taker;
+				const makerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, maker);
+				await zeroEx.token.transferAsync(makerToken.address, maker, anyRecipient, makerBalance);
+			})().catch(done);
+		});
+		it('should emit orderStateInvalid when watched order fully filled', (done: DoneCallback) => {
+			(async () => {
+				signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+					makerToken.address,
+					takerToken.address,
+					maker,
+					taker,
+					fillableAmount,
+				);
+				const orderHash = ZeroEx.getOrderHashHex(signedOrder);
+				zeroEx.orderStateWatcher.addOrder(signedOrder);
 
-                const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
-                    expect(orderState.isValid).to.be.false();
-                    const invalidOrderState = orderState as OrderStateInvalid;
-                    expect(invalidOrderState.orderHash).to.be.equal(orderHash);
-                    expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.OrderRemainingFillAmountZero);
-                });
-                zeroEx.orderStateWatcher.subscribe(callback);
+				const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
+					expect(orderState.isValid).to.be.false();
+					const invalidOrderState = orderState as OrderStateInvalid;
+					expect(invalidOrderState.orderHash).to.be.equal(orderHash);
+					expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.OrderRemainingFillAmountZero);
+				});
+				zeroEx.orderStateWatcher.subscribe(callback);
 
-                const shouldThrowOnInsufficientBalanceOrAllowance = true;
-                await zeroEx.exchange.fillOrderAsync(
-                    signedOrder,
-                    fillableAmount,
-                    shouldThrowOnInsufficientBalanceOrAllowance,
-                    taker,
-                );
-            })().catch(done);
-        });
-        it('should emit orderStateValid when watched order partially filled', (done: DoneCallback) => {
-            (async () => {
-                signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                    makerToken.address,
-                    takerToken.address,
-                    maker,
-                    taker,
-                    fillableAmount,
-                );
+				const shouldThrowOnInsufficientBalanceOrAllowance = true;
+				await zeroEx.exchange.fillOrderAsync(
+					signedOrder,
+					fillableAmount,
+					shouldThrowOnInsufficientBalanceOrAllowance,
+					taker,
+				);
+			})().catch(done);
+		});
+		it('should emit orderStateValid when watched order partially filled', (done: DoneCallback) => {
+			(async () => {
+				signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+					makerToken.address,
+					takerToken.address,
+					maker,
+					taker,
+					fillableAmount,
+				);
 
-                const makerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, maker);
-                const fillAmountInBaseUnits = new BigNumber(2);
-                const orderHash = ZeroEx.getOrderHashHex(signedOrder);
-                zeroEx.orderStateWatcher.addOrder(signedOrder);
+				const makerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, maker);
+				const fillAmountInBaseUnits = new BigNumber(2);
+				const orderHash = ZeroEx.getOrderHashHex(signedOrder);
+				zeroEx.orderStateWatcher.addOrder(signedOrder);
 
-                const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
-                    expect(orderState.isValid).to.be.true();
-                    const validOrderState = orderState as OrderStateValid;
-                    expect(validOrderState.orderHash).to.be.equal(orderHash);
-                    const orderRelevantState = validOrderState.orderRelevantState;
-                    const remainingMakerBalance = makerBalance.sub(fillAmountInBaseUnits);
-                    const remainingFillable = fillableAmount.minus(fillAmountInBaseUnits);
-                    expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
-                        remainingFillable,
-                    );
-                    expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal(
-                        remainingFillable,
-                    );
-                    expect(orderRelevantState.makerBalance).to.be.bignumber.equal(remainingMakerBalance);
-                });
-                zeroEx.orderStateWatcher.subscribe(callback);
-                const shouldThrowOnInsufficientBalanceOrAllowance = true;
-                await zeroEx.exchange.fillOrderAsync(
-                    signedOrder,
-                    fillAmountInBaseUnits,
-                    shouldThrowOnInsufficientBalanceOrAllowance,
-                    taker,
-                );
-            })().catch(done);
-        });
-        it('should trigger the callback when orders backing ZRX allowance changes', (done: DoneCallback) => {
-            (async () => {
-                const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(2), 18);
-                const takerFee = ZeroEx.toBaseUnitAmount(new BigNumber(0), 18);
-                signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
-                    makerToken.address,
-                    takerToken.address,
-                    makerFee,
-                    takerFee,
-                    maker,
-                    taker,
-                    fillableAmount,
-                    taker,
-                );
-                const callback = reportNodeCallbackErrors(done)();
-                zeroEx.orderStateWatcher.addOrder(signedOrder);
-                zeroEx.orderStateWatcher.subscribe(callback);
-                await zeroEx.token.setProxyAllowanceAsync(zrxTokenAddress, maker, new BigNumber(0));
-            })().catch(done);
-        });
-        describe('remainingFillable(M|T)akerTokenAmount', () => {
-            it('should calculate correct remaining fillable', (done: DoneCallback) => {
-                (async () => {
-                    const takerFillableAmount = ZeroEx.toBaseUnitAmount(new BigNumber(10), decimals);
-                    const makerFillableAmount = ZeroEx.toBaseUnitAmount(new BigNumber(20), decimals);
-                    signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
-                        makerToken.address,
-                        takerToken.address,
-                        maker,
-                        taker,
-                        makerFillableAmount,
-                        takerFillableAmount,
-                    );
-                    const fillAmountInBaseUnits = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
-                    const orderHash = ZeroEx.getOrderHashHex(signedOrder);
-                    zeroEx.orderStateWatcher.addOrder(signedOrder);
-                    const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
-                        expect(orderState.isValid).to.be.true();
-                        const validOrderState = orderState as OrderStateValid;
-                        expect(validOrderState.orderHash).to.be.equal(orderHash);
-                        const orderRelevantState = validOrderState.orderRelevantState;
-                        expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
-                            ZeroEx.toBaseUnitAmount(new BigNumber(16), decimals),
-                        );
-                        expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal(
-                            ZeroEx.toBaseUnitAmount(new BigNumber(8), decimals),
-                        );
-                    });
-                    zeroEx.orderStateWatcher.subscribe(callback);
-                    const shouldThrowOnInsufficientBalanceOrAllowance = true;
-                    await zeroEx.exchange.fillOrderAsync(
-                        signedOrder,
-                        fillAmountInBaseUnits,
-                        shouldThrowOnInsufficientBalanceOrAllowance,
-                        taker,
-                    );
-                })().catch(done);
-            });
-            it('should equal approved amount when approved amount is lowest', (done: DoneCallback) => {
-                (async () => {
-                    signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                        makerToken.address,
-                        takerToken.address,
-                        maker,
-                        taker,
-                        fillableAmount,
-                    );
+				const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
+					expect(orderState.isValid).to.be.true();
+					const validOrderState = orderState as OrderStateValid;
+					expect(validOrderState.orderHash).to.be.equal(orderHash);
+					const orderRelevantState = validOrderState.orderRelevantState;
+					const remainingMakerBalance = makerBalance.sub(fillAmountInBaseUnits);
+					const remainingFillable = fillableAmount.minus(fillAmountInBaseUnits);
+					expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
+						remainingFillable,
+					);
+					expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal(
+						remainingFillable,
+					);
+					expect(orderRelevantState.makerBalance).to.be.bignumber.equal(remainingMakerBalance);
+				});
+				zeroEx.orderStateWatcher.subscribe(callback);
+				const shouldThrowOnInsufficientBalanceOrAllowance = true;
+				await zeroEx.exchange.fillOrderAsync(
+					signedOrder,
+					fillAmountInBaseUnits,
+					shouldThrowOnInsufficientBalanceOrAllowance,
+					taker,
+				);
+			})().catch(done);
+		});
+		it('should trigger the callback when orders backing ZRX allowance changes', (done: DoneCallback) => {
+			(async () => {
+				const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(2), 18);
+				const takerFee = ZeroEx.toBaseUnitAmount(new BigNumber(0), 18);
+				signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
+					makerToken.address,
+					takerToken.address,
+					makerFee,
+					takerFee,
+					maker,
+					taker,
+					fillableAmount,
+					taker,
+				);
+				const callback = reportNodeCallbackErrors(done)();
+				zeroEx.orderStateWatcher.addOrder(signedOrder);
+				zeroEx.orderStateWatcher.subscribe(callback);
+				await zeroEx.token.setProxyAllowanceAsync(zrxTokenAddress, maker, new BigNumber(0));
+			})().catch(done);
+		});
+		describe('remainingFillable(M|T)akerTokenAmount', () => {
+			it('should calculate correct remaining fillable', (done: DoneCallback) => {
+				(async () => {
+					const takerFillableAmount = ZeroEx.toBaseUnitAmount(new BigNumber(10), decimals);
+					const makerFillableAmount = ZeroEx.toBaseUnitAmount(new BigNumber(20), decimals);
+					signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
+						makerToken.address,
+						takerToken.address,
+						maker,
+						taker,
+						makerFillableAmount,
+						takerFillableAmount,
+					);
+					const fillAmountInBaseUnits = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
+					const orderHash = ZeroEx.getOrderHashHex(signedOrder);
+					zeroEx.orderStateWatcher.addOrder(signedOrder);
+					const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
+						expect(orderState.isValid).to.be.true();
+						const validOrderState = orderState as OrderStateValid;
+						expect(validOrderState.orderHash).to.be.equal(orderHash);
+						const orderRelevantState = validOrderState.orderRelevantState;
+						expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
+							ZeroEx.toBaseUnitAmount(new BigNumber(16), decimals),
+						);
+						expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal(
+							ZeroEx.toBaseUnitAmount(new BigNumber(8), decimals),
+						);
+					});
+					zeroEx.orderStateWatcher.subscribe(callback);
+					const shouldThrowOnInsufficientBalanceOrAllowance = true;
+					await zeroEx.exchange.fillOrderAsync(
+						signedOrder,
+						fillAmountInBaseUnits,
+						shouldThrowOnInsufficientBalanceOrAllowance,
+						taker,
+					);
+				})().catch(done);
+			});
+			it('should equal approved amount when approved amount is lowest', (done: DoneCallback) => {
+				(async () => {
+					signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+						makerToken.address,
+						takerToken.address,
+						maker,
+						taker,
+						fillableAmount,
+					);
 
-                    const changedMakerApprovalAmount = ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals);
-                    zeroEx.orderStateWatcher.addOrder(signedOrder);
+					const changedMakerApprovalAmount = ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals);
+					zeroEx.orderStateWatcher.addOrder(signedOrder);
 
-                    const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
-                        const validOrderState = orderState as OrderStateValid;
-                        const orderRelevantState = validOrderState.orderRelevantState;
-                        expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
-                            changedMakerApprovalAmount,
-                        );
-                        expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal(
-                            changedMakerApprovalAmount,
-                        );
-                    });
-                    zeroEx.orderStateWatcher.subscribe(callback);
-                    await zeroEx.token.setProxyAllowanceAsync(makerToken.address, maker, changedMakerApprovalAmount);
-                })().catch(done);
-            });
-            it('should equal balance amount when balance amount is lowest', (done: DoneCallback) => {
-                (async () => {
-                    signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                        makerToken.address,
-                        takerToken.address,
-                        maker,
-                        taker,
-                        fillableAmount,
-                    );
+					const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
+						const validOrderState = orderState as OrderStateValid;
+						const orderRelevantState = validOrderState.orderRelevantState;
+						expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
+							changedMakerApprovalAmount,
+						);
+						expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal(
+							changedMakerApprovalAmount,
+						);
+					});
+					zeroEx.orderStateWatcher.subscribe(callback);
+					await zeroEx.token.setProxyAllowanceAsync(makerToken.address, maker, changedMakerApprovalAmount);
+				})().catch(done);
+			});
+			it('should equal balance amount when balance amount is lowest', (done: DoneCallback) => {
+				(async () => {
+					signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+						makerToken.address,
+						takerToken.address,
+						maker,
+						taker,
+						fillableAmount,
+					);
 
-                    const makerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, maker);
+					const makerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, maker);
 
-                    const remainingAmount = ZeroEx.toBaseUnitAmount(new BigNumber(1), decimals);
-                    const transferAmount = makerBalance.sub(remainingAmount);
-                    zeroEx.orderStateWatcher.addOrder(signedOrder);
+					const remainingAmount = ZeroEx.toBaseUnitAmount(new BigNumber(1), decimals);
+					const transferAmount = makerBalance.sub(remainingAmount);
+					zeroEx.orderStateWatcher.addOrder(signedOrder);
 
-                    const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
-                        expect(orderState.isValid).to.be.true();
-                        const validOrderState = orderState as OrderStateValid;
-                        const orderRelevantState = validOrderState.orderRelevantState;
-                        expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
-                            remainingAmount,
-                        );
-                        expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal(
-                            remainingAmount,
-                        );
-                    });
-                    zeroEx.orderStateWatcher.subscribe(callback);
-                    await zeroEx.token.transferAsync(makerToken.address, maker, ZeroEx.NULL_ADDRESS, transferAmount);
-                })().catch(done);
-            });
-            it('should equal remaining amount when partially cancelled and order has fees', (done: DoneCallback) => {
-                (async () => {
-                    const takerFee = ZeroEx.toBaseUnitAmount(new BigNumber(0), decimals);
-                    const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals);
-                    const feeRecipient = taker;
-                    signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
-                        makerToken.address,
-                        takerToken.address,
-                        makerFee,
-                        takerFee,
-                        maker,
-                        taker,
-                        fillableAmount,
-                        feeRecipient,
-                    );
+					const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
+						expect(orderState.isValid).to.be.true();
+						const validOrderState = orderState as OrderStateValid;
+						const orderRelevantState = validOrderState.orderRelevantState;
+						expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
+							remainingAmount,
+						);
+						expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal(
+							remainingAmount,
+						);
+					});
+					zeroEx.orderStateWatcher.subscribe(callback);
+					await zeroEx.token.transferAsync(makerToken.address, maker, ZeroEx.NULL_ADDRESS, transferAmount);
+				})().catch(done);
+			});
+			it('should equal remaining amount when partially cancelled and order has fees', (done: DoneCallback) => {
+				(async () => {
+					const takerFee = ZeroEx.toBaseUnitAmount(new BigNumber(0), decimals);
+					const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals);
+					const feeRecipient = taker;
+					signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
+						makerToken.address,
+						takerToken.address,
+						makerFee,
+						takerFee,
+						maker,
+						taker,
+						fillableAmount,
+						feeRecipient,
+					);
 
-                    const remainingTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(4), decimals);
-                    const transferTokenAmount = makerFee.sub(remainingTokenAmount);
-                    zeroEx.orderStateWatcher.addOrder(signedOrder);
+					const remainingTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(4), decimals);
+					const transferTokenAmount = makerFee.sub(remainingTokenAmount);
+					zeroEx.orderStateWatcher.addOrder(signedOrder);
 
-                    const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
-                        expect(orderState.isValid).to.be.true();
-                        const validOrderState = orderState as OrderStateValid;
-                        const orderRelevantState = validOrderState.orderRelevantState;
-                        expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
-                            remainingTokenAmount,
-                        );
-                    });
-                    zeroEx.orderStateWatcher.subscribe(callback);
-                    await zeroEx.exchange.cancelOrderAsync(signedOrder, transferTokenAmount);
-                })().catch(done);
-            });
-            it('should equal ratio amount when fee balance is lowered', (done: DoneCallback) => {
-                (async () => {
-                    const takerFee = ZeroEx.toBaseUnitAmount(new BigNumber(0), decimals);
-                    const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals);
-                    const feeRecipient = taker;
-                    signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
-                        makerToken.address,
-                        takerToken.address,
-                        makerFee,
-                        takerFee,
-                        maker,
-                        taker,
-                        fillableAmount,
-                        feeRecipient,
-                    );
+					const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
+						expect(orderState.isValid).to.be.true();
+						const validOrderState = orderState as OrderStateValid;
+						const orderRelevantState = validOrderState.orderRelevantState;
+						expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
+							remainingTokenAmount,
+						);
+					});
+					zeroEx.orderStateWatcher.subscribe(callback);
+					await zeroEx.exchange.cancelOrderAsync(signedOrder, transferTokenAmount);
+				})().catch(done);
+			});
+			it('should equal ratio amount when fee balance is lowered', (done: DoneCallback) => {
+				(async () => {
+					const takerFee = ZeroEx.toBaseUnitAmount(new BigNumber(0), decimals);
+					const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals);
+					const feeRecipient = taker;
+					signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
+						makerToken.address,
+						takerToken.address,
+						makerFee,
+						takerFee,
+						maker,
+						taker,
+						fillableAmount,
+						feeRecipient,
+					);
 
-                    const remainingFeeAmount = ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals);
+					const remainingFeeAmount = ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals);
 
-                    const remainingTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(4), decimals);
-                    const transferTokenAmount = makerFee.sub(remainingTokenAmount);
-                    zeroEx.orderStateWatcher.addOrder(signedOrder);
+					const remainingTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(4), decimals);
+					const transferTokenAmount = makerFee.sub(remainingTokenAmount);
+					zeroEx.orderStateWatcher.addOrder(signedOrder);
 
-                    const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
-                        const validOrderState = orderState as OrderStateValid;
-                        const orderRelevantState = validOrderState.orderRelevantState;
-                        expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
-                            remainingFeeAmount,
-                        );
-                    });
-                    zeroEx.orderStateWatcher.subscribe(callback);
-                    await zeroEx.token.setProxyAllowanceAsync(zrxTokenAddress, maker, remainingFeeAmount);
-                    await zeroEx.token.transferAsync(
-                        makerToken.address,
-                        maker,
-                        ZeroEx.NULL_ADDRESS,
-                        transferTokenAmount,
-                    );
-                })().catch(done);
-            });
-            it('should calculate full amount when all available and non-divisible', (done: DoneCallback) => {
-                (async () => {
-                    const takerFee = ZeroEx.toBaseUnitAmount(new BigNumber(0), decimals);
-                    const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
-                    const feeRecipient = taker;
-                    signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
-                        makerToken.address,
-                        takerToken.address,
-                        makerFee,
-                        takerFee,
-                        maker,
-                        taker,
-                        fillableAmount,
-                        feeRecipient,
-                    );
+					const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
+						const validOrderState = orderState as OrderStateValid;
+						const orderRelevantState = validOrderState.orderRelevantState;
+						expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
+							remainingFeeAmount,
+						);
+					});
+					zeroEx.orderStateWatcher.subscribe(callback);
+					await zeroEx.token.setProxyAllowanceAsync(zrxTokenAddress, maker, remainingFeeAmount);
+					await zeroEx.token.transferAsync(
+						makerToken.address,
+						maker,
+						ZeroEx.NULL_ADDRESS,
+						transferTokenAmount,
+					);
+				})().catch(done);
+			});
+			it('should calculate full amount when all available and non-divisible', (done: DoneCallback) => {
+				(async () => {
+					const takerFee = ZeroEx.toBaseUnitAmount(new BigNumber(0), decimals);
+					const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
+					const feeRecipient = taker;
+					signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
+						makerToken.address,
+						takerToken.address,
+						makerFee,
+						takerFee,
+						maker,
+						taker,
+						fillableAmount,
+						feeRecipient,
+					);
 
-                    zeroEx.orderStateWatcher.addOrder(signedOrder);
+					zeroEx.orderStateWatcher.addOrder(signedOrder);
 
-                    const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
-                        const validOrderState = orderState as OrderStateValid;
-                        const orderRelevantState = validOrderState.orderRelevantState;
-                        expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
-                            fillableAmount,
-                        );
-                    });
-                    zeroEx.orderStateWatcher.subscribe(callback);
-                    await zeroEx.token.setProxyAllowanceAsync(
-                        makerToken.address,
-                        maker,
-                        ZeroEx.toBaseUnitAmount(new BigNumber(100), decimals),
-                    );
-                })().catch(done);
-            });
-        });
-        it('should emit orderStateInvalid when watched order cancelled', (done: DoneCallback) => {
-            (async () => {
-                signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                    makerToken.address,
-                    takerToken.address,
-                    maker,
-                    taker,
-                    fillableAmount,
-                );
-                const orderHash = ZeroEx.getOrderHashHex(signedOrder);
-                zeroEx.orderStateWatcher.addOrder(signedOrder);
+					const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
+						const validOrderState = orderState as OrderStateValid;
+						const orderRelevantState = validOrderState.orderRelevantState;
+						expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
+							fillableAmount,
+						);
+					});
+					zeroEx.orderStateWatcher.subscribe(callback);
+					await zeroEx.token.setProxyAllowanceAsync(
+						makerToken.address,
+						maker,
+						ZeroEx.toBaseUnitAmount(new BigNumber(100), decimals),
+					);
+				})().catch(done);
+			});
+		});
+		it('should emit orderStateInvalid when watched order cancelled', (done: DoneCallback) => {
+			(async () => {
+				signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+					makerToken.address,
+					takerToken.address,
+					maker,
+					taker,
+					fillableAmount,
+				);
+				const orderHash = ZeroEx.getOrderHashHex(signedOrder);
+				zeroEx.orderStateWatcher.addOrder(signedOrder);
 
-                const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
-                    expect(orderState.isValid).to.be.false();
-                    const invalidOrderState = orderState as OrderStateInvalid;
-                    expect(invalidOrderState.orderHash).to.be.equal(orderHash);
-                    expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.OrderRemainingFillAmountZero);
-                });
-                zeroEx.orderStateWatcher.subscribe(callback);
+				const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
+					expect(orderState.isValid).to.be.false();
+					const invalidOrderState = orderState as OrderStateInvalid;
+					expect(invalidOrderState.orderHash).to.be.equal(orderHash);
+					expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.OrderRemainingFillAmountZero);
+				});
+				zeroEx.orderStateWatcher.subscribe(callback);
 
-                await zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount);
-            })().catch(done);
-        });
-        it('should emit orderStateInvalid when within rounding error range', (done: DoneCallback) => {
-            (async () => {
-                const remainingFillableAmountInBaseUnits = new BigNumber(100);
-                signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                    makerToken.address,
-                    takerToken.address,
-                    maker,
-                    taker,
-                    fillableAmount,
-                );
-                const orderHash = ZeroEx.getOrderHashHex(signedOrder);
-                zeroEx.orderStateWatcher.addOrder(signedOrder);
+				await zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount);
+			})().catch(done);
+		});
+		it('should emit orderStateInvalid when within rounding error range', (done: DoneCallback) => {
+			(async () => {
+				const remainingFillableAmountInBaseUnits = new BigNumber(100);
+				signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+					makerToken.address,
+					takerToken.address,
+					maker,
+					taker,
+					fillableAmount,
+				);
+				const orderHash = ZeroEx.getOrderHashHex(signedOrder);
+				zeroEx.orderStateWatcher.addOrder(signedOrder);
 
-                const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
-                    expect(orderState.isValid).to.be.false();
-                    const invalidOrderState = orderState as OrderStateInvalid;
-                    expect(invalidOrderState.orderHash).to.be.equal(orderHash);
-                    expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.OrderFillRoundingError);
-                });
-                zeroEx.orderStateWatcher.subscribe(callback);
-                await zeroEx.exchange.cancelOrderAsync(
-                    signedOrder,
-                    fillableAmount.minus(remainingFillableAmountInBaseUnits),
-                );
-            })().catch(done);
-        });
-        it('should emit orderStateValid when watched order partially cancelled', (done: DoneCallback) => {
-            (async () => {
-                signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                    makerToken.address,
-                    takerToken.address,
-                    maker,
-                    taker,
-                    fillableAmount,
-                );
+				const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
+					expect(orderState.isValid).to.be.false();
+					const invalidOrderState = orderState as OrderStateInvalid;
+					expect(invalidOrderState.orderHash).to.be.equal(orderHash);
+					expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.OrderFillRoundingError);
+				});
+				zeroEx.orderStateWatcher.subscribe(callback);
+				await zeroEx.exchange.cancelOrderAsync(
+					signedOrder,
+					fillableAmount.minus(remainingFillableAmountInBaseUnits),
+				);
+			})().catch(done);
+		});
+		it('should emit orderStateValid when watched order partially cancelled', (done: DoneCallback) => {
+			(async () => {
+				signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+					makerToken.address,
+					takerToken.address,
+					maker,
+					taker,
+					fillableAmount,
+				);
 
-                const cancelAmountInBaseUnits = new BigNumber(2);
-                const orderHash = ZeroEx.getOrderHashHex(signedOrder);
-                zeroEx.orderStateWatcher.addOrder(signedOrder);
+				const cancelAmountInBaseUnits = new BigNumber(2);
+				const orderHash = ZeroEx.getOrderHashHex(signedOrder);
+				zeroEx.orderStateWatcher.addOrder(signedOrder);
 
-                const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
-                    expect(orderState.isValid).to.be.true();
-                    const validOrderState = orderState as OrderStateValid;
-                    expect(validOrderState.orderHash).to.be.equal(orderHash);
-                    const orderRelevantState = validOrderState.orderRelevantState;
-                    expect(orderRelevantState.cancelledTakerTokenAmount).to.be.bignumber.equal(cancelAmountInBaseUnits);
-                });
-                zeroEx.orderStateWatcher.subscribe(callback);
-                await zeroEx.exchange.cancelOrderAsync(signedOrder, cancelAmountInBaseUnits);
-            })().catch(done);
-        });
-    });
+				const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
+					expect(orderState.isValid).to.be.true();
+					const validOrderState = orderState as OrderStateValid;
+					expect(validOrderState.orderHash).to.be.equal(orderHash);
+					const orderRelevantState = validOrderState.orderRelevantState;
+					expect(orderRelevantState.cancelledTakerTokenAmount).to.be.bignumber.equal(cancelAmountInBaseUnits);
+				});
+				zeroEx.orderStateWatcher.subscribe(callback);
+				await zeroEx.exchange.cancelOrderAsync(signedOrder, cancelAmountInBaseUnits);
+			})().catch(done);
+		});
+	});
 }); // tslint:disable:max-file-line-count
diff --git a/packages/0x.js/test/order_validation_test.ts b/packages/0x.js/test/order_validation_test.ts
index be3e0590c..4e023a9cc 100644
--- a/packages/0x.js/test/order_validation_test.ts
+++ b/packages/0x.js/test/order_validation_test.ts
@@ -20,455 +20,455 @@ const expect = chai.expect;
 const blockchainLifecycle = new BlockchainLifecycle(constants.RPC_URL);
 
 describe('OrderValidation', () => {
-    let web3: Web3;
-    let zeroEx: ZeroEx;
-    let userAddresses: string[];
-    let tokens: Token[];
-    let tokenUtils: TokenUtils;
-    let exchangeContractAddress: string;
-    let zrxTokenAddress: string;
-    let fillScenarios: FillScenarios;
-    let makerTokenAddress: string;
-    let takerTokenAddress: string;
-    let coinbase: string;
-    let makerAddress: string;
-    let takerAddress: string;
-    let feeRecipient: string;
-    const fillableAmount = new BigNumber(5);
-    const fillTakerAmount = new BigNumber(5);
-    const config = {
-        networkId: constants.TESTRPC_NETWORK_ID,
-    };
-    before(async () => {
-        web3 = web3Factory.create();
-        zeroEx = new ZeroEx(web3.currentProvider, config);
-        exchangeContractAddress = zeroEx.exchange.getContractAddress();
-        userAddresses = await zeroEx.getAvailableAddressesAsync();
-        [coinbase, makerAddress, takerAddress, feeRecipient] = userAddresses;
-        tokens = await zeroEx.tokenRegistry.getTokensAsync();
-        tokenUtils = new TokenUtils(tokens);
-        zrxTokenAddress = tokenUtils.getProtocolTokenOrThrow().address;
-        fillScenarios = new FillScenarios(zeroEx, userAddresses, tokens, zrxTokenAddress, exchangeContractAddress);
-        const [makerToken, takerToken] = tokenUtils.getDummyTokens();
-        makerTokenAddress = makerToken.address;
-        takerTokenAddress = takerToken.address;
-    });
-    beforeEach(async () => {
-        await blockchainLifecycle.startAsync();
-    });
-    afterEach(async () => {
-        await blockchainLifecycle.revertAsync();
-    });
-    describe('validateOrderFillableOrThrowAsync', () => {
-        it('should succeed if the order is fillable', async () => {
-            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                makerTokenAddress,
-                takerTokenAddress,
-                makerAddress,
-                takerAddress,
-                fillableAmount,
-            );
-            await zeroEx.exchange.validateOrderFillableOrThrowAsync(signedOrder);
-        });
-        it('should succeed if the order is asymmetric and fillable', async () => {
-            const makerFillableAmount = fillableAmount;
-            const takerFillableAmount = fillableAmount.minus(4);
-            const signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
-                makerTokenAddress,
-                takerTokenAddress,
-                makerAddress,
-                takerAddress,
-                makerFillableAmount,
-                takerFillableAmount,
-            );
-            await zeroEx.exchange.validateOrderFillableOrThrowAsync(signedOrder);
-        });
-        it('should throw when the order is fully filled or cancelled', async () => {
-            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                makerTokenAddress,
-                takerTokenAddress,
-                makerAddress,
-                takerAddress,
-                fillableAmount,
-            );
-            await zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount);
-            return expect(zeroEx.exchange.validateOrderFillableOrThrowAsync(signedOrder)).to.be.rejectedWith(
-                ExchangeContractErrs.OrderRemainingFillAmountZero,
-            );
-        });
-        it('should throw when order is expired', async () => {
-            const expirationInPast = new BigNumber(1496826058); // 7th Jun 2017
-            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                makerTokenAddress,
-                takerTokenAddress,
-                makerAddress,
-                takerAddress,
-                fillableAmount,
-                expirationInPast,
-            );
-            return expect(zeroEx.exchange.validateOrderFillableOrThrowAsync(signedOrder)).to.be.rejectedWith(
-                ExchangeContractErrs.OrderFillExpired,
-            );
-        });
-    });
-    describe('validateFillOrderAndThrowIfInvalidAsync', () => {
-        it('should throw when the fill amount is zero', async () => {
-            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                makerTokenAddress,
-                takerTokenAddress,
-                makerAddress,
-                takerAddress,
-                fillableAmount,
-            );
-            const zeroFillAmount = new BigNumber(0);
-            return expect(
-                zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(signedOrder, zeroFillAmount, takerAddress),
-            ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
-        });
-        it('should throw when the signature is invalid', async () => {
-            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                makerTokenAddress,
-                takerTokenAddress,
-                makerAddress,
-                takerAddress,
-                fillableAmount,
-            );
-            // 27 <--> 28
-            signedOrder.ecSignature.v = 28 - signedOrder.ecSignature.v + 27;
-            return expect(
-                zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(signedOrder, fillableAmount, takerAddress),
-            ).to.be.rejectedWith(ZeroExError.InvalidSignature);
-        });
-        it('should throw when the order is fully filled or cancelled', async () => {
-            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                makerTokenAddress,
-                takerTokenAddress,
-                makerAddress,
-                takerAddress,
-                fillableAmount,
-            );
-            await zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount);
-            return expect(
-                zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(signedOrder, fillableAmount, takerAddress),
-            ).to.be.rejectedWith(ExchangeContractErrs.OrderRemainingFillAmountZero);
-        });
-        it('should throw when sender is not a taker', async () => {
-            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                makerTokenAddress,
-                takerTokenAddress,
-                makerAddress,
-                takerAddress,
-                fillableAmount,
-            );
-            const nonTakerAddress = userAddresses[6];
-            return expect(
-                zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(signedOrder, fillTakerAmount, nonTakerAddress),
-            ).to.be.rejectedWith(ExchangeContractErrs.TransactionSenderIsNotFillOrderTaker);
-        });
-        it('should throw when order is expired', async () => {
-            const expirationInPast = new BigNumber(1496826058); // 7th Jun 2017
-            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                makerTokenAddress,
-                takerTokenAddress,
-                makerAddress,
-                takerAddress,
-                fillableAmount,
-                expirationInPast,
-            );
-            return expect(
-                zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(signedOrder, fillTakerAmount, takerAddress),
-            ).to.be.rejectedWith(ExchangeContractErrs.OrderFillExpired);
-        });
-        it('should throw when there a rounding error would have occurred', async () => {
-            const makerAmount = new BigNumber(3);
-            const takerAmount = new BigNumber(5);
-            const signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
-                makerTokenAddress,
-                takerTokenAddress,
-                makerAddress,
-                takerAddress,
-                makerAmount,
-                takerAmount,
-            );
-            const fillTakerAmountThatCausesRoundingError = new BigNumber(3);
-            return expect(
-                zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(
-                    signedOrder,
-                    fillTakerAmountThatCausesRoundingError,
-                    takerAddress,
-                ),
-            ).to.be.rejectedWith(ExchangeContractErrs.OrderFillRoundingError);
-        });
-    });
-    describe('#validateFillOrKillOrderAndThrowIfInvalidAsync', () => {
-        it('should throw if remaining fillAmount is less then the desired fillAmount', async () => {
-            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                makerTokenAddress,
-                takerTokenAddress,
-                makerAddress,
-                takerAddress,
-                fillableAmount,
-            );
-            const tooLargeFillAmount = new BigNumber(7);
-            const fillAmountDifference = tooLargeFillAmount.minus(fillableAmount);
-            await zeroEx.token.transferAsync(takerTokenAddress, coinbase, takerAddress, fillAmountDifference);
-            await zeroEx.token.setProxyAllowanceAsync(takerTokenAddress, takerAddress, tooLargeFillAmount);
-            await zeroEx.token.transferAsync(makerTokenAddress, coinbase, makerAddress, fillAmountDifference);
-            await zeroEx.token.setProxyAllowanceAsync(makerTokenAddress, makerAddress, tooLargeFillAmount);
+	let web3: Web3;
+	let zeroEx: ZeroEx;
+	let userAddresses: string[];
+	let tokens: Token[];
+	let tokenUtils: TokenUtils;
+	let exchangeContractAddress: string;
+	let zrxTokenAddress: string;
+	let fillScenarios: FillScenarios;
+	let makerTokenAddress: string;
+	let takerTokenAddress: string;
+	let coinbase: string;
+	let makerAddress: string;
+	let takerAddress: string;
+	let feeRecipient: string;
+	const fillableAmount = new BigNumber(5);
+	const fillTakerAmount = new BigNumber(5);
+	const config = {
+		networkId: constants.TESTRPC_NETWORK_ID,
+	};
+	before(async () => {
+		web3 = web3Factory.create();
+		zeroEx = new ZeroEx(web3.currentProvider, config);
+		exchangeContractAddress = zeroEx.exchange.getContractAddress();
+		userAddresses = await zeroEx.getAvailableAddressesAsync();
+		[coinbase, makerAddress, takerAddress, feeRecipient] = userAddresses;
+		tokens = await zeroEx.tokenRegistry.getTokensAsync();
+		tokenUtils = new TokenUtils(tokens);
+		zrxTokenAddress = tokenUtils.getProtocolTokenOrThrow().address;
+		fillScenarios = new FillScenarios(zeroEx, userAddresses, tokens, zrxTokenAddress, exchangeContractAddress);
+		const [makerToken, takerToken] = tokenUtils.getDummyTokens();
+		makerTokenAddress = makerToken.address;
+		takerTokenAddress = takerToken.address;
+	});
+	beforeEach(async () => {
+		await blockchainLifecycle.startAsync();
+	});
+	afterEach(async () => {
+		await blockchainLifecycle.revertAsync();
+	});
+	describe('validateOrderFillableOrThrowAsync', () => {
+		it('should succeed if the order is fillable', async () => {
+			const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+				makerTokenAddress,
+				takerTokenAddress,
+				makerAddress,
+				takerAddress,
+				fillableAmount,
+			);
+			await zeroEx.exchange.validateOrderFillableOrThrowAsync(signedOrder);
+		});
+		it('should succeed if the order is asymmetric and fillable', async () => {
+			const makerFillableAmount = fillableAmount;
+			const takerFillableAmount = fillableAmount.minus(4);
+			const signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
+				makerTokenAddress,
+				takerTokenAddress,
+				makerAddress,
+				takerAddress,
+				makerFillableAmount,
+				takerFillableAmount,
+			);
+			await zeroEx.exchange.validateOrderFillableOrThrowAsync(signedOrder);
+		});
+		it('should throw when the order is fully filled or cancelled', async () => {
+			const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+				makerTokenAddress,
+				takerTokenAddress,
+				makerAddress,
+				takerAddress,
+				fillableAmount,
+			);
+			await zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount);
+			return expect(zeroEx.exchange.validateOrderFillableOrThrowAsync(signedOrder)).to.be.rejectedWith(
+				ExchangeContractErrs.OrderRemainingFillAmountZero,
+			);
+		});
+		it('should throw when order is expired', async () => {
+			const expirationInPast = new BigNumber(1496826058); // 7th Jun 2017
+			const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+				makerTokenAddress,
+				takerTokenAddress,
+				makerAddress,
+				takerAddress,
+				fillableAmount,
+				expirationInPast,
+			);
+			return expect(zeroEx.exchange.validateOrderFillableOrThrowAsync(signedOrder)).to.be.rejectedWith(
+				ExchangeContractErrs.OrderFillExpired,
+			);
+		});
+	});
+	describe('validateFillOrderAndThrowIfInvalidAsync', () => {
+		it('should throw when the fill amount is zero', async () => {
+			const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+				makerTokenAddress,
+				takerTokenAddress,
+				makerAddress,
+				takerAddress,
+				fillableAmount,
+			);
+			const zeroFillAmount = new BigNumber(0);
+			return expect(
+				zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(signedOrder, zeroFillAmount, takerAddress),
+			).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
+		});
+		it('should throw when the signature is invalid', async () => {
+			const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+				makerTokenAddress,
+				takerTokenAddress,
+				makerAddress,
+				takerAddress,
+				fillableAmount,
+			);
+			// 27 <--> 28
+			signedOrder.ecSignature.v = 28 - signedOrder.ecSignature.v + 27;
+			return expect(
+				zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(signedOrder, fillableAmount, takerAddress),
+			).to.be.rejectedWith(ZeroExError.InvalidSignature);
+		});
+		it('should throw when the order is fully filled or cancelled', async () => {
+			const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+				makerTokenAddress,
+				takerTokenAddress,
+				makerAddress,
+				takerAddress,
+				fillableAmount,
+			);
+			await zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount);
+			return expect(
+				zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(signedOrder, fillableAmount, takerAddress),
+			).to.be.rejectedWith(ExchangeContractErrs.OrderRemainingFillAmountZero);
+		});
+		it('should throw when sender is not a taker', async () => {
+			const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+				makerTokenAddress,
+				takerTokenAddress,
+				makerAddress,
+				takerAddress,
+				fillableAmount,
+			);
+			const nonTakerAddress = userAddresses[6];
+			return expect(
+				zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(signedOrder, fillTakerAmount, nonTakerAddress),
+			).to.be.rejectedWith(ExchangeContractErrs.TransactionSenderIsNotFillOrderTaker);
+		});
+		it('should throw when order is expired', async () => {
+			const expirationInPast = new BigNumber(1496826058); // 7th Jun 2017
+			const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+				makerTokenAddress,
+				takerTokenAddress,
+				makerAddress,
+				takerAddress,
+				fillableAmount,
+				expirationInPast,
+			);
+			return expect(
+				zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(signedOrder, fillTakerAmount, takerAddress),
+			).to.be.rejectedWith(ExchangeContractErrs.OrderFillExpired);
+		});
+		it('should throw when there a rounding error would have occurred', async () => {
+			const makerAmount = new BigNumber(3);
+			const takerAmount = new BigNumber(5);
+			const signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
+				makerTokenAddress,
+				takerTokenAddress,
+				makerAddress,
+				takerAddress,
+				makerAmount,
+				takerAmount,
+			);
+			const fillTakerAmountThatCausesRoundingError = new BigNumber(3);
+			return expect(
+				zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(
+					signedOrder,
+					fillTakerAmountThatCausesRoundingError,
+					takerAddress,
+				),
+			).to.be.rejectedWith(ExchangeContractErrs.OrderFillRoundingError);
+		});
+	});
+	describe('#validateFillOrKillOrderAndThrowIfInvalidAsync', () => {
+		it('should throw if remaining fillAmount is less then the desired fillAmount', async () => {
+			const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+				makerTokenAddress,
+				takerTokenAddress,
+				makerAddress,
+				takerAddress,
+				fillableAmount,
+			);
+			const tooLargeFillAmount = new BigNumber(7);
+			const fillAmountDifference = tooLargeFillAmount.minus(fillableAmount);
+			await zeroEx.token.transferAsync(takerTokenAddress, coinbase, takerAddress, fillAmountDifference);
+			await zeroEx.token.setProxyAllowanceAsync(takerTokenAddress, takerAddress, tooLargeFillAmount);
+			await zeroEx.token.transferAsync(makerTokenAddress, coinbase, makerAddress, fillAmountDifference);
+			await zeroEx.token.setProxyAllowanceAsync(makerTokenAddress, makerAddress, tooLargeFillAmount);
 
-            return expect(
-                zeroEx.exchange.validateFillOrKillOrderThrowIfInvalidAsync(
-                    signedOrder,
-                    tooLargeFillAmount,
-                    takerAddress,
-                ),
-            ).to.be.rejectedWith(ExchangeContractErrs.InsufficientRemainingFillAmount);
-        });
-    });
-    describe('validateCancelOrderAndThrowIfInvalidAsync', () => {
-        let signedOrder: SignedOrder;
-        const cancelAmount = new BigNumber(3);
-        beforeEach(async () => {
-            [coinbase, makerAddress, takerAddress] = userAddresses;
-            const [makerToken, takerToken] = tokenUtils.getDummyTokens();
-            makerTokenAddress = makerToken.address;
-            takerTokenAddress = takerToken.address;
-            signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                makerTokenAddress,
-                takerTokenAddress,
-                makerAddress,
-                takerAddress,
-                fillableAmount,
-            );
-        });
-        it('should throw when cancel amount is zero', async () => {
-            const zeroCancelAmount = new BigNumber(0);
-            return expect(
-                zeroEx.exchange.validateCancelOrderThrowIfInvalidAsync(signedOrder, zeroCancelAmount),
-            ).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
-        });
-        it('should throw when order is expired', async () => {
-            const expirationInPast = new BigNumber(1496826058); // 7th Jun 2017
-            const expiredSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
-                makerTokenAddress,
-                takerTokenAddress,
-                makerAddress,
-                takerAddress,
-                fillableAmount,
-                expirationInPast,
-            );
-            return expect(
-                zeroEx.exchange.validateCancelOrderThrowIfInvalidAsync(expiredSignedOrder, cancelAmount),
-            ).to.be.rejectedWith(ExchangeContractErrs.OrderCancelExpired);
-        });
-        it('should throw when order is already cancelled or filled', async () => {
-            await zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount);
-            return expect(
-                zeroEx.exchange.validateCancelOrderThrowIfInvalidAsync(signedOrder, fillableAmount),
-            ).to.be.rejectedWith(ExchangeContractErrs.OrderAlreadyCancelledOrFilled);
-        });
-    });
-    describe('#validateFillOrderBalancesAllowancesThrowIfInvalidAsync', () => {
-        let exchangeTransferSimulator: ExchangeTransferSimulator;
-        let transferFromAsync: Sinon.SinonSpy;
-        const bigNumberMatch = (expected: BigNumber) => {
-            return Sinon.match((value: BigNumber) => value.eq(expected));
-        };
-        beforeEach('create exchangeTransferSimulator', async () => {
-            exchangeTransferSimulator = new ExchangeTransferSimulator(zeroEx.token, BlockParamLiteral.Latest);
-            transferFromAsync = Sinon.spy();
-            exchangeTransferSimulator.transferFromAsync = transferFromAsync as any;
-        });
-        it('should call exchangeTransferSimulator.transferFrom in a correct order', async () => {
-            const makerFee = new BigNumber(2);
-            const takerFee = new BigNumber(2);
-            const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
-                makerTokenAddress,
-                takerTokenAddress,
-                makerFee,
-                takerFee,
-                makerAddress,
-                takerAddress,
-                fillableAmount,
-                feeRecipient,
-            );
-            await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
-                exchangeTransferSimulator,
-                signedOrder,
-                fillableAmount,
-                takerAddress,
-                zrxTokenAddress,
-            );
-            expect(transferFromAsync.callCount).to.be.equal(4);
-            expect(
-                transferFromAsync
-                    .getCall(0)
-                    .calledWith(
-                        makerTokenAddress,
-                        makerAddress,
-                        takerAddress,
-                        bigNumberMatch(fillableAmount),
-                        TradeSide.Maker,
-                        TransferType.Trade,
-                    ),
-            ).to.be.true();
-            expect(
-                transferFromAsync
-                    .getCall(1)
-                    .calledWith(
-                        takerTokenAddress,
-                        takerAddress,
-                        makerAddress,
-                        bigNumberMatch(fillableAmount),
-                        TradeSide.Taker,
-                        TransferType.Trade,
-                    ),
-            ).to.be.true();
-            expect(
-                transferFromAsync
-                    .getCall(2)
-                    .calledWith(
-                        zrxTokenAddress,
-                        makerAddress,
-                        feeRecipient,
-                        bigNumberMatch(makerFee),
-                        TradeSide.Maker,
-                        TransferType.Fee,
-                    ),
-            ).to.be.true();
-            expect(
-                transferFromAsync
-                    .getCall(3)
-                    .calledWith(
-                        zrxTokenAddress,
-                        takerAddress,
-                        feeRecipient,
-                        bigNumberMatch(takerFee),
-                        TradeSide.Taker,
-                        TransferType.Fee,
-                    ),
-            ).to.be.true();
-        });
-        it('should call exchangeTransferSimulator.transferFrom with correct values for an open order', async () => {
-            const makerFee = new BigNumber(2);
-            const takerFee = new BigNumber(2);
-            const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
-                makerTokenAddress,
-                takerTokenAddress,
-                makerFee,
-                takerFee,
-                makerAddress,
-                ZeroEx.NULL_ADDRESS,
-                fillableAmount,
-                feeRecipient,
-            );
-            await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
-                exchangeTransferSimulator,
-                signedOrder,
-                fillableAmount,
-                takerAddress,
-                zrxTokenAddress,
-            );
-            expect(transferFromAsync.callCount).to.be.equal(4);
-            expect(
-                transferFromAsync
-                    .getCall(0)
-                    .calledWith(
-                        makerTokenAddress,
-                        makerAddress,
-                        takerAddress,
-                        bigNumberMatch(fillableAmount),
-                        TradeSide.Maker,
-                        TransferType.Trade,
-                    ),
-            ).to.be.true();
-            expect(
-                transferFromAsync
-                    .getCall(1)
-                    .calledWith(
-                        takerTokenAddress,
-                        takerAddress,
-                        makerAddress,
-                        bigNumberMatch(fillableAmount),
-                        TradeSide.Taker,
-                        TransferType.Trade,
-                    ),
-            ).to.be.true();
-            expect(
-                transferFromAsync
-                    .getCall(2)
-                    .calledWith(
-                        zrxTokenAddress,
-                        makerAddress,
-                        feeRecipient,
-                        bigNumberMatch(makerFee),
-                        TradeSide.Maker,
-                        TransferType.Fee,
-                    ),
-            ).to.be.true();
-            expect(
-                transferFromAsync
-                    .getCall(3)
-                    .calledWith(
-                        zrxTokenAddress,
-                        takerAddress,
-                        feeRecipient,
-                        bigNumberMatch(takerFee),
-                        TradeSide.Taker,
-                        TransferType.Fee,
-                    ),
-            ).to.be.true();
-        });
-        it('should correctly round the fillMakerTokenAmount', async () => {
-            const makerTokenAmount = new BigNumber(3);
-            const takerTokenAmount = new BigNumber(1);
-            const signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
-                makerTokenAddress,
-                takerTokenAddress,
-                makerAddress,
-                takerAddress,
-                makerTokenAmount,
-                takerTokenAmount,
-            );
-            await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
-                exchangeTransferSimulator,
-                signedOrder,
-                takerTokenAmount,
-                takerAddress,
-                zrxTokenAddress,
-            );
-            expect(transferFromAsync.callCount).to.be.equal(4);
-            const makerFillAmount = transferFromAsync.getCall(0).args[3];
-            expect(makerFillAmount).to.be.bignumber.equal(makerTokenAmount);
-        });
-        it('should correctly round the makerFeeAmount', async () => {
-            const makerFee = new BigNumber(2);
-            const takerFee = new BigNumber(4);
-            const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
-                makerTokenAddress,
-                takerTokenAddress,
-                makerFee,
-                takerFee,
-                makerAddress,
-                takerAddress,
-                fillableAmount,
-                ZeroEx.NULL_ADDRESS,
-            );
-            const fillTakerTokenAmount = fillableAmount.div(2).round(0);
-            await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
-                exchangeTransferSimulator,
-                signedOrder,
-                fillTakerTokenAmount,
-                takerAddress,
-                zrxTokenAddress,
-            );
-            const makerPartialFee = makerFee.div(2);
-            const takerPartialFee = takerFee.div(2);
-            expect(transferFromAsync.callCount).to.be.equal(4);
-            const partialMakerFee = transferFromAsync.getCall(2).args[3];
-            expect(partialMakerFee).to.be.bignumber.equal(makerPartialFee);
-            const partialTakerFee = transferFromAsync.getCall(3).args[3];
-            expect(partialTakerFee).to.be.bignumber.equal(takerPartialFee);
-        });
-    });
+			return expect(
+				zeroEx.exchange.validateFillOrKillOrderThrowIfInvalidAsync(
+					signedOrder,
+					tooLargeFillAmount,
+					takerAddress,
+				),
+			).to.be.rejectedWith(ExchangeContractErrs.InsufficientRemainingFillAmount);
+		});
+	});
+	describe('validateCancelOrderAndThrowIfInvalidAsync', () => {
+		let signedOrder: SignedOrder;
+		const cancelAmount = new BigNumber(3);
+		beforeEach(async () => {
+			[coinbase, makerAddress, takerAddress] = userAddresses;
+			const [makerToken, takerToken] = tokenUtils.getDummyTokens();
+			makerTokenAddress = makerToken.address;
+			takerTokenAddress = takerToken.address;
+			signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+				makerTokenAddress,
+				takerTokenAddress,
+				makerAddress,
+				takerAddress,
+				fillableAmount,
+			);
+		});
+		it('should throw when cancel amount is zero', async () => {
+			const zeroCancelAmount = new BigNumber(0);
+			return expect(
+				zeroEx.exchange.validateCancelOrderThrowIfInvalidAsync(signedOrder, zeroCancelAmount),
+			).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
+		});
+		it('should throw when order is expired', async () => {
+			const expirationInPast = new BigNumber(1496826058); // 7th Jun 2017
+			const expiredSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
+				makerTokenAddress,
+				takerTokenAddress,
+				makerAddress,
+				takerAddress,
+				fillableAmount,
+				expirationInPast,
+			);
+			return expect(
+				zeroEx.exchange.validateCancelOrderThrowIfInvalidAsync(expiredSignedOrder, cancelAmount),
+			).to.be.rejectedWith(ExchangeContractErrs.OrderCancelExpired);
+		});
+		it('should throw when order is already cancelled or filled', async () => {
+			await zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount);
+			return expect(
+				zeroEx.exchange.validateCancelOrderThrowIfInvalidAsync(signedOrder, fillableAmount),
+			).to.be.rejectedWith(ExchangeContractErrs.OrderAlreadyCancelledOrFilled);
+		});
+	});
+	describe('#validateFillOrderBalancesAllowancesThrowIfInvalidAsync', () => {
+		let exchangeTransferSimulator: ExchangeTransferSimulator;
+		let transferFromAsync: Sinon.SinonSpy;
+		const bigNumberMatch = (expected: BigNumber) => {
+			return Sinon.match((value: BigNumber) => value.eq(expected));
+		};
+		beforeEach('create exchangeTransferSimulator', async () => {
+			exchangeTransferSimulator = new ExchangeTransferSimulator(zeroEx.token, BlockParamLiteral.Latest);
+			transferFromAsync = Sinon.spy();
+			exchangeTransferSimulator.transferFromAsync = transferFromAsync as any;
+		});
+		it('should call exchangeTransferSimulator.transferFrom in a correct order', async () => {
+			const makerFee = new BigNumber(2);
+			const takerFee = new BigNumber(2);
+			const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
+				makerTokenAddress,
+				takerTokenAddress,
+				makerFee,
+				takerFee,
+				makerAddress,
+				takerAddress,
+				fillableAmount,
+				feeRecipient,
+			);
+			await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
+				exchangeTransferSimulator,
+				signedOrder,
+				fillableAmount,
+				takerAddress,
+				zrxTokenAddress,
+			);
+			expect(transferFromAsync.callCount).to.be.equal(4);
+			expect(
+				transferFromAsync
+					.getCall(0)
+					.calledWith(
+						makerTokenAddress,
+						makerAddress,
+						takerAddress,
+						bigNumberMatch(fillableAmount),
+						TradeSide.Maker,
+						TransferType.Trade,
+					),
+			).to.be.true();
+			expect(
+				transferFromAsync
+					.getCall(1)
+					.calledWith(
+						takerTokenAddress,
+						takerAddress,
+						makerAddress,
+						bigNumberMatch(fillableAmount),
+						TradeSide.Taker,
+						TransferType.Trade,
+					),
+			).to.be.true();
+			expect(
+				transferFromAsync
+					.getCall(2)
+					.calledWith(
+						zrxTokenAddress,
+						makerAddress,
+						feeRecipient,
+						bigNumberMatch(makerFee),
+						TradeSide.Maker,
+						TransferType.Fee,
+					),
+			).to.be.true();
+			expect(
+				transferFromAsync
+					.getCall(3)
+					.calledWith(
+						zrxTokenAddress,
+						takerAddress,
+						feeRecipient,
+						bigNumberMatch(takerFee),
+						TradeSide.Taker,
+						TransferType.Fee,
+					),
+			).to.be.true();
+		});
+		it('should call exchangeTransferSimulator.transferFrom with correct values for an open order', async () => {
+			const makerFee = new BigNumber(2);
+			const takerFee = new BigNumber(2);
+			const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
+				makerTokenAddress,
+				takerTokenAddress,
+				makerFee,
+				takerFee,
+				makerAddress,
+				ZeroEx.NULL_ADDRESS,
+				fillableAmount,
+				feeRecipient,
+			);
+			await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
+				exchangeTransferSimulator,
+				signedOrder,
+				fillableAmount,
+				takerAddress,
+				zrxTokenAddress,
+			);
+			expect(transferFromAsync.callCount).to.be.equal(4);
+			expect(
+				transferFromAsync
+					.getCall(0)
+					.calledWith(
+						makerTokenAddress,
+						makerAddress,
+						takerAddress,
+						bigNumberMatch(fillableAmount),
+						TradeSide.Maker,
+						TransferType.Trade,
+					),
+			).to.be.true();
+			expect(
+				transferFromAsync
+					.getCall(1)
+					.calledWith(
+						takerTokenAddress,
+						takerAddress,
+						makerAddress,
+						bigNumberMatch(fillableAmount),
+						TradeSide.Taker,
+						TransferType.Trade,
+					),
+			).to.be.true();
+			expect(
+				transferFromAsync
+					.getCall(2)
+					.calledWith(
+						zrxTokenAddress,
+						makerAddress,
+						feeRecipient,
+						bigNumberMatch(makerFee),
+						TradeSide.Maker,
+						TransferType.Fee,
+					),
+			).to.be.true();
+			expect(
+				transferFromAsync
+					.getCall(3)
+					.calledWith(
+						zrxTokenAddress,
+						takerAddress,
+						feeRecipient,
+						bigNumberMatch(takerFee),
+						TradeSide.Taker,
+						TransferType.Fee,
+					),
+			).to.be.true();
+		});
+		it('should correctly round the fillMakerTokenAmount', async () => {
+			const makerTokenAmount = new BigNumber(3);
+			const takerTokenAmount = new BigNumber(1);
+			const signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
+				makerTokenAddress,
+				takerTokenAddress,
+				makerAddress,
+				takerAddress,
+				makerTokenAmount,
+				takerTokenAmount,
+			);
+			await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
+				exchangeTransferSimulator,
+				signedOrder,
+				takerTokenAmount,
+				takerAddress,
+				zrxTokenAddress,
+			);
+			expect(transferFromAsync.callCount).to.be.equal(4);
+			const makerFillAmount = transferFromAsync.getCall(0).args[3];
+			expect(makerFillAmount).to.be.bignumber.equal(makerTokenAmount);
+		});
+		it('should correctly round the makerFeeAmount', async () => {
+			const makerFee = new BigNumber(2);
+			const takerFee = new BigNumber(4);
+			const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
+				makerTokenAddress,
+				takerTokenAddress,
+				makerFee,
+				takerFee,
+				makerAddress,
+				takerAddress,
+				fillableAmount,
+				ZeroEx.NULL_ADDRESS,
+			);
+			const fillTakerTokenAmount = fillableAmount.div(2).round(0);
+			await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
+				exchangeTransferSimulator,
+				signedOrder,
+				fillTakerTokenAmount,
+				takerAddress,
+				zrxTokenAddress,
+			);
+			const makerPartialFee = makerFee.div(2);
+			const takerPartialFee = takerFee.div(2);
+			expect(transferFromAsync.callCount).to.be.equal(4);
+			const partialMakerFee = transferFromAsync.getCall(2).args[3];
+			expect(partialMakerFee).to.be.bignumber.equal(makerPartialFee);
+			const partialTakerFee = transferFromAsync.getCall(3).args[3];
+			expect(partialTakerFee).to.be.bignumber.equal(takerPartialFee);
+		});
+	});
 });
diff --git a/packages/0x.js/test/remaining_fillable_calculator_test.ts b/packages/0x.js/test/remaining_fillable_calculator_test.ts
index 4c6b8f3ac..58e9dd93b 100644
--- a/packages/0x.js/test/remaining_fillable_calculator_test.ts
+++ b/packages/0x.js/test/remaining_fillable_calculator_test.ts
@@ -12,223 +12,223 @@ chaiSetup.configure();
 const expect = chai.expect;
 
 describe('RemainingFillableCalculator', () => {
-    let calculator: RemainingFillableCalculator;
-    let signedOrder: SignedOrder;
-    let transferrableMakerTokenAmount: BigNumber;
-    let transferrableMakerFeeTokenAmount: BigNumber;
-    let remainingMakerTokenAmount: BigNumber;
-    let makerAmount: BigNumber;
-    let takerAmount: BigNumber;
-    let makerFeeAmount: BigNumber;
-    let isMakerTokenZRX: boolean;
-    const makerToken: string = '0x1';
-    const takerToken: string = '0x2';
-    const decimals: number = 4;
-    const zero: BigNumber = new BigNumber(0);
-    const zeroAddress = '0x0';
-    const signature: ECSignature = { v: 27, r: '', s: '' };
-    beforeEach(async () => {
-        [makerAmount, takerAmount, makerFeeAmount] = [
-            ZeroEx.toBaseUnitAmount(new BigNumber(50), decimals),
-            ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals),
-            ZeroEx.toBaseUnitAmount(new BigNumber(1), decimals),
-        ];
-        [transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount] = [
-            ZeroEx.toBaseUnitAmount(new BigNumber(50), decimals),
-            ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals),
-        ];
-    });
-    function buildSignedOrder(): SignedOrder {
-        return {
-            ecSignature: signature,
-            exchangeContractAddress: zeroAddress,
-            feeRecipient: zeroAddress,
-            maker: zeroAddress,
-            taker: zeroAddress,
-            makerFee: makerFeeAmount,
-            takerFee: zero,
-            makerTokenAmount: makerAmount,
-            takerTokenAmount: takerAmount,
-            makerTokenAddress: makerToken,
-            takerTokenAddress: takerToken,
-            salt: zero,
-            expirationUnixTimestampSec: zero,
-        };
-    }
-    describe('Maker token is NOT ZRX', () => {
-        before(async () => {
-            isMakerTokenZRX = false;
-        });
-        it('calculates the correct amount when unfilled and funds available', () => {
-            signedOrder = buildSignedOrder();
-            remainingMakerTokenAmount = signedOrder.makerTokenAmount;
-            calculator = new RemainingFillableCalculator(
-                signedOrder,
-                isMakerTokenZRX,
-                transferrableMakerTokenAmount,
-                transferrableMakerFeeTokenAmount,
-                remainingMakerTokenAmount,
-            );
-            expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount);
-        });
-        it('calculates the correct amount when partially filled and funds available', () => {
-            signedOrder = buildSignedOrder();
-            remainingMakerTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(1), decimals);
-            calculator = new RemainingFillableCalculator(
-                signedOrder,
-                isMakerTokenZRX,
-                transferrableMakerTokenAmount,
-                transferrableMakerFeeTokenAmount,
-                remainingMakerTokenAmount,
-            );
-            expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount);
-        });
-        it('calculates the amount to be 0 when all fee funds are transferred', () => {
-            signedOrder = buildSignedOrder();
-            transferrableMakerFeeTokenAmount = zero;
-            remainingMakerTokenAmount = signedOrder.makerTokenAmount;
-            calculator = new RemainingFillableCalculator(
-                signedOrder,
-                isMakerTokenZRX,
-                transferrableMakerTokenAmount,
-                transferrableMakerFeeTokenAmount,
-                remainingMakerTokenAmount,
-            );
-            expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(zero);
-        });
-        it('calculates the correct amount when balance is less than remaining fillable', () => {
-            signedOrder = buildSignedOrder();
-            const partiallyFilledAmount = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
-            remainingMakerTokenAmount = signedOrder.makerTokenAmount.minus(partiallyFilledAmount);
-            transferrableMakerTokenAmount = remainingMakerTokenAmount.minus(partiallyFilledAmount);
-            calculator = new RemainingFillableCalculator(
-                signedOrder,
-                isMakerTokenZRX,
-                transferrableMakerTokenAmount,
-                transferrableMakerFeeTokenAmount,
-                remainingMakerTokenAmount,
-            );
-            expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(transferrableMakerTokenAmount);
-        });
-        describe('Order to Fee Ratio is < 1', () => {
-            beforeEach(async () => {
-                [makerAmount, takerAmount, makerFeeAmount] = [
-                    ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals),
-                    ZeroEx.toBaseUnitAmount(new BigNumber(6), decimals),
-                    ZeroEx.toBaseUnitAmount(new BigNumber(6), decimals),
-                ];
-            });
-            it('calculates the correct amount when funds unavailable', () => {
-                signedOrder = buildSignedOrder();
-                remainingMakerTokenAmount = signedOrder.makerTokenAmount;
-                const transferredAmount = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
-                transferrableMakerTokenAmount = remainingMakerTokenAmount.minus(transferredAmount);
-                calculator = new RemainingFillableCalculator(
-                    signedOrder,
-                    isMakerTokenZRX,
-                    transferrableMakerTokenAmount,
-                    transferrableMakerFeeTokenAmount,
-                    remainingMakerTokenAmount,
-                );
-                expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(transferrableMakerTokenAmount);
-            });
-        });
-        describe('Ratio is not evenly divisble', () => {
-            beforeEach(async () => {
-                [makerAmount, takerAmount, makerFeeAmount] = [
-                    ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals),
-                    ZeroEx.toBaseUnitAmount(new BigNumber(7), decimals),
-                    ZeroEx.toBaseUnitAmount(new BigNumber(7), decimals),
-                ];
-            });
-            it('calculates the correct amount when funds unavailable', () => {
-                signedOrder = buildSignedOrder();
-                remainingMakerTokenAmount = signedOrder.makerTokenAmount;
-                const transferredAmount = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
-                transferrableMakerTokenAmount = remainingMakerTokenAmount.minus(transferredAmount);
-                calculator = new RemainingFillableCalculator(
-                    signedOrder,
-                    isMakerTokenZRX,
-                    transferrableMakerTokenAmount,
-                    transferrableMakerFeeTokenAmount,
-                    remainingMakerTokenAmount,
-                );
-                const calculatedFillableAmount = calculator.computeRemainingMakerFillable();
-                expect(calculatedFillableAmount.lessThanOrEqualTo(transferrableMakerTokenAmount)).to.be.true();
-                expect(calculatedFillableAmount).to.be.bignumber.greaterThan(new BigNumber(0));
-                const orderToFeeRatio = signedOrder.makerTokenAmount.dividedBy(signedOrder.makerFee);
-                const calculatedFeeAmount = calculatedFillableAmount.dividedBy(orderToFeeRatio);
-                expect(calculatedFeeAmount).to.be.bignumber.lessThan(transferrableMakerFeeTokenAmount);
-            });
-        });
-    });
-    describe('Maker Token is ZRX', () => {
-        before(async () => {
-            isMakerTokenZRX = true;
-        });
-        it('calculates the correct amount when unfilled and funds available', () => {
-            signedOrder = buildSignedOrder();
-            transferrableMakerTokenAmount = makerAmount.plus(makerFeeAmount);
-            transferrableMakerFeeTokenAmount = transferrableMakerTokenAmount;
-            remainingMakerTokenAmount = signedOrder.makerTokenAmount;
-            calculator = new RemainingFillableCalculator(
-                signedOrder,
-                isMakerTokenZRX,
-                transferrableMakerTokenAmount,
-                transferrableMakerFeeTokenAmount,
-                remainingMakerTokenAmount,
-            );
-            expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount);
-        });
-        it('calculates the correct amount when partially filled and funds available', () => {
-            signedOrder = buildSignedOrder();
-            remainingMakerTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(1), decimals);
-            calculator = new RemainingFillableCalculator(
-                signedOrder,
-                isMakerTokenZRX,
-                transferrableMakerTokenAmount,
-                transferrableMakerFeeTokenAmount,
-                remainingMakerTokenAmount,
-            );
-            expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount);
-        });
-        it('calculates the amount to be 0 when all fee funds are transferred', () => {
-            signedOrder = buildSignedOrder();
-            transferrableMakerTokenAmount = zero;
-            transferrableMakerFeeTokenAmount = zero;
-            remainingMakerTokenAmount = signedOrder.makerTokenAmount;
-            calculator = new RemainingFillableCalculator(
-                signedOrder,
-                isMakerTokenZRX,
-                transferrableMakerTokenAmount,
-                transferrableMakerFeeTokenAmount,
-                remainingMakerTokenAmount,
-            );
-            expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(zero);
-        });
-        it('calculates the correct amount when balance is less than remaining fillable', () => {
-            signedOrder = buildSignedOrder();
-            const partiallyFilledAmount = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
-            remainingMakerTokenAmount = signedOrder.makerTokenAmount.minus(partiallyFilledAmount);
-            transferrableMakerTokenAmount = remainingMakerTokenAmount.minus(partiallyFilledAmount);
-            transferrableMakerFeeTokenAmount = transferrableMakerTokenAmount;
+	let calculator: RemainingFillableCalculator;
+	let signedOrder: SignedOrder;
+	let transferrableMakerTokenAmount: BigNumber;
+	let transferrableMakerFeeTokenAmount: BigNumber;
+	let remainingMakerTokenAmount: BigNumber;
+	let makerAmount: BigNumber;
+	let takerAmount: BigNumber;
+	let makerFeeAmount: BigNumber;
+	let isMakerTokenZRX: boolean;
+	const makerToken: string = '0x1';
+	const takerToken: string = '0x2';
+	const decimals: number = 4;
+	const zero: BigNumber = new BigNumber(0);
+	const zeroAddress = '0x0';
+	const signature: ECSignature = { v: 27, r: '', s: '' };
+	beforeEach(async () => {
+		[makerAmount, takerAmount, makerFeeAmount] = [
+			ZeroEx.toBaseUnitAmount(new BigNumber(50), decimals),
+			ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals),
+			ZeroEx.toBaseUnitAmount(new BigNumber(1), decimals),
+		];
+		[transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount] = [
+			ZeroEx.toBaseUnitAmount(new BigNumber(50), decimals),
+			ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals),
+		];
+	});
+	function buildSignedOrder(): SignedOrder {
+		return {
+			ecSignature: signature,
+			exchangeContractAddress: zeroAddress,
+			feeRecipient: zeroAddress,
+			maker: zeroAddress,
+			taker: zeroAddress,
+			makerFee: makerFeeAmount,
+			takerFee: zero,
+			makerTokenAmount: makerAmount,
+			takerTokenAmount: takerAmount,
+			makerTokenAddress: makerToken,
+			takerTokenAddress: takerToken,
+			salt: zero,
+			expirationUnixTimestampSec: zero,
+		};
+	}
+	describe('Maker token is NOT ZRX', () => {
+		before(async () => {
+			isMakerTokenZRX = false;
+		});
+		it('calculates the correct amount when unfilled and funds available', () => {
+			signedOrder = buildSignedOrder();
+			remainingMakerTokenAmount = signedOrder.makerTokenAmount;
+			calculator = new RemainingFillableCalculator(
+				signedOrder,
+				isMakerTokenZRX,
+				transferrableMakerTokenAmount,
+				transferrableMakerFeeTokenAmount,
+				remainingMakerTokenAmount,
+			);
+			expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount);
+		});
+		it('calculates the correct amount when partially filled and funds available', () => {
+			signedOrder = buildSignedOrder();
+			remainingMakerTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(1), decimals);
+			calculator = new RemainingFillableCalculator(
+				signedOrder,
+				isMakerTokenZRX,
+				transferrableMakerTokenAmount,
+				transferrableMakerFeeTokenAmount,
+				remainingMakerTokenAmount,
+			);
+			expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount);
+		});
+		it('calculates the amount to be 0 when all fee funds are transferred', () => {
+			signedOrder = buildSignedOrder();
+			transferrableMakerFeeTokenAmount = zero;
+			remainingMakerTokenAmount = signedOrder.makerTokenAmount;
+			calculator = new RemainingFillableCalculator(
+				signedOrder,
+				isMakerTokenZRX,
+				transferrableMakerTokenAmount,
+				transferrableMakerFeeTokenAmount,
+				remainingMakerTokenAmount,
+			);
+			expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(zero);
+		});
+		it('calculates the correct amount when balance is less than remaining fillable', () => {
+			signedOrder = buildSignedOrder();
+			const partiallyFilledAmount = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
+			remainingMakerTokenAmount = signedOrder.makerTokenAmount.minus(partiallyFilledAmount);
+			transferrableMakerTokenAmount = remainingMakerTokenAmount.minus(partiallyFilledAmount);
+			calculator = new RemainingFillableCalculator(
+				signedOrder,
+				isMakerTokenZRX,
+				transferrableMakerTokenAmount,
+				transferrableMakerFeeTokenAmount,
+				remainingMakerTokenAmount,
+			);
+			expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(transferrableMakerTokenAmount);
+		});
+		describe('Order to Fee Ratio is < 1', () => {
+			beforeEach(async () => {
+				[makerAmount, takerAmount, makerFeeAmount] = [
+					ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals),
+					ZeroEx.toBaseUnitAmount(new BigNumber(6), decimals),
+					ZeroEx.toBaseUnitAmount(new BigNumber(6), decimals),
+				];
+			});
+			it('calculates the correct amount when funds unavailable', () => {
+				signedOrder = buildSignedOrder();
+				remainingMakerTokenAmount = signedOrder.makerTokenAmount;
+				const transferredAmount = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
+				transferrableMakerTokenAmount = remainingMakerTokenAmount.minus(transferredAmount);
+				calculator = new RemainingFillableCalculator(
+					signedOrder,
+					isMakerTokenZRX,
+					transferrableMakerTokenAmount,
+					transferrableMakerFeeTokenAmount,
+					remainingMakerTokenAmount,
+				);
+				expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(transferrableMakerTokenAmount);
+			});
+		});
+		describe('Ratio is not evenly divisble', () => {
+			beforeEach(async () => {
+				[makerAmount, takerAmount, makerFeeAmount] = [
+					ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals),
+					ZeroEx.toBaseUnitAmount(new BigNumber(7), decimals),
+					ZeroEx.toBaseUnitAmount(new BigNumber(7), decimals),
+				];
+			});
+			it('calculates the correct amount when funds unavailable', () => {
+				signedOrder = buildSignedOrder();
+				remainingMakerTokenAmount = signedOrder.makerTokenAmount;
+				const transferredAmount = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
+				transferrableMakerTokenAmount = remainingMakerTokenAmount.minus(transferredAmount);
+				calculator = new RemainingFillableCalculator(
+					signedOrder,
+					isMakerTokenZRX,
+					transferrableMakerTokenAmount,
+					transferrableMakerFeeTokenAmount,
+					remainingMakerTokenAmount,
+				);
+				const calculatedFillableAmount = calculator.computeRemainingMakerFillable();
+				expect(calculatedFillableAmount.lessThanOrEqualTo(transferrableMakerTokenAmount)).to.be.true();
+				expect(calculatedFillableAmount).to.be.bignumber.greaterThan(new BigNumber(0));
+				const orderToFeeRatio = signedOrder.makerTokenAmount.dividedBy(signedOrder.makerFee);
+				const calculatedFeeAmount = calculatedFillableAmount.dividedBy(orderToFeeRatio);
+				expect(calculatedFeeAmount).to.be.bignumber.lessThan(transferrableMakerFeeTokenAmount);
+			});
+		});
+	});
+	describe('Maker Token is ZRX', () => {
+		before(async () => {
+			isMakerTokenZRX = true;
+		});
+		it('calculates the correct amount when unfilled and funds available', () => {
+			signedOrder = buildSignedOrder();
+			transferrableMakerTokenAmount = makerAmount.plus(makerFeeAmount);
+			transferrableMakerFeeTokenAmount = transferrableMakerTokenAmount;
+			remainingMakerTokenAmount = signedOrder.makerTokenAmount;
+			calculator = new RemainingFillableCalculator(
+				signedOrder,
+				isMakerTokenZRX,
+				transferrableMakerTokenAmount,
+				transferrableMakerFeeTokenAmount,
+				remainingMakerTokenAmount,
+			);
+			expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount);
+		});
+		it('calculates the correct amount when partially filled and funds available', () => {
+			signedOrder = buildSignedOrder();
+			remainingMakerTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(1), decimals);
+			calculator = new RemainingFillableCalculator(
+				signedOrder,
+				isMakerTokenZRX,
+				transferrableMakerTokenAmount,
+				transferrableMakerFeeTokenAmount,
+				remainingMakerTokenAmount,
+			);
+			expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount);
+		});
+		it('calculates the amount to be 0 when all fee funds are transferred', () => {
+			signedOrder = buildSignedOrder();
+			transferrableMakerTokenAmount = zero;
+			transferrableMakerFeeTokenAmount = zero;
+			remainingMakerTokenAmount = signedOrder.makerTokenAmount;
+			calculator = new RemainingFillableCalculator(
+				signedOrder,
+				isMakerTokenZRX,
+				transferrableMakerTokenAmount,
+				transferrableMakerFeeTokenAmount,
+				remainingMakerTokenAmount,
+			);
+			expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(zero);
+		});
+		it('calculates the correct amount when balance is less than remaining fillable', () => {
+			signedOrder = buildSignedOrder();
+			const partiallyFilledAmount = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
+			remainingMakerTokenAmount = signedOrder.makerTokenAmount.minus(partiallyFilledAmount);
+			transferrableMakerTokenAmount = remainingMakerTokenAmount.minus(partiallyFilledAmount);
+			transferrableMakerFeeTokenAmount = transferrableMakerTokenAmount;
 
-            const orderToFeeRatio = signedOrder.makerTokenAmount.dividedToIntegerBy(signedOrder.makerFee);
-            const expectedFillableAmount = new BigNumber(450980);
-            calculator = new RemainingFillableCalculator(
-                signedOrder,
-                isMakerTokenZRX,
-                transferrableMakerTokenAmount,
-                transferrableMakerFeeTokenAmount,
-                remainingMakerTokenAmount,
-            );
-            const calculatedFillableAmount = calculator.computeRemainingMakerFillable();
-            const numberOfFillsInRatio = calculatedFillableAmount.dividedToIntegerBy(orderToFeeRatio);
-            const calculatedFillableAmountPlusFees = calculatedFillableAmount.plus(numberOfFillsInRatio);
-            expect(calculatedFillableAmountPlusFees).to.be.bignumber.lessThan(transferrableMakerTokenAmount);
-            expect(calculatedFillableAmountPlusFees).to.be.bignumber.lessThan(remainingMakerTokenAmount);
-            expect(calculatedFillableAmount).to.be.bignumber.equal(expectedFillableAmount);
-            expect(numberOfFillsInRatio.decimalPlaces()).to.be.equal(0);
-        });
-    });
+			const orderToFeeRatio = signedOrder.makerTokenAmount.dividedToIntegerBy(signedOrder.makerFee);
+			const expectedFillableAmount = new BigNumber(450980);
+			calculator = new RemainingFillableCalculator(
+				signedOrder,
+				isMakerTokenZRX,
+				transferrableMakerTokenAmount,
+				transferrableMakerFeeTokenAmount,
+				remainingMakerTokenAmount,
+			);
+			const calculatedFillableAmount = calculator.computeRemainingMakerFillable();
+			const numberOfFillsInRatio = calculatedFillableAmount.dividedToIntegerBy(orderToFeeRatio);
+			const calculatedFillableAmountPlusFees = calculatedFillableAmount.plus(numberOfFillsInRatio);
+			expect(calculatedFillableAmountPlusFees).to.be.bignumber.lessThan(transferrableMakerTokenAmount);
+			expect(calculatedFillableAmountPlusFees).to.be.bignumber.lessThan(remainingMakerTokenAmount);
+			expect(calculatedFillableAmount).to.be.bignumber.equal(expectedFillableAmount);
+			expect(numberOfFillsInRatio.decimalPlaces()).to.be.equal(0);
+		});
+	});
 });
diff --git a/packages/0x.js/test/subscription_test.ts b/packages/0x.js/test/subscription_test.ts
index f4c6f748f..f70ecd6cd 100644
--- a/packages/0x.js/test/subscription_test.ts
+++ b/packages/0x.js/test/subscription_test.ts
@@ -17,69 +17,69 @@ chaiSetup.configure();
 const blockchainLifecycle = new BlockchainLifecycle(constants.RPC_URL);
 
 describe('SubscriptionTest', () => {
-    let web3: Web3;
-    let zeroEx: ZeroEx;
-    let userAddresses: string[];
-    let tokens: Token[];
-    let coinbase: string;
-    let addressWithoutFunds: string;
-    const config = {
-        networkId: constants.TESTRPC_NETWORK_ID,
-    };
-    before(async () => {
-        web3 = web3Factory.create();
-        zeroEx = new ZeroEx(web3.currentProvider, config);
-        userAddresses = await zeroEx.getAvailableAddressesAsync();
-        tokens = await zeroEx.tokenRegistry.getTokensAsync();
-        coinbase = userAddresses[0];
-        addressWithoutFunds = userAddresses[1];
-    });
-    beforeEach(async () => {
-        await blockchainLifecycle.startAsync();
-    });
-    afterEach(async () => {
-        await blockchainLifecycle.revertAsync();
-    });
-    describe('#subscribe', () => {
-        const indexFilterValues = {};
-        let tokenAddress: string;
-        const allowanceAmount = new BigNumber(42);
-        let stubs: Sinon.SinonStub[] = [];
-        before(() => {
-            const token = tokens[0];
-            tokenAddress = token.address;
-        });
-        afterEach(() => {
-            zeroEx.token.unsubscribeAll();
-            _.each(stubs, s => s.restore());
-            stubs = [];
-        });
-        it('Should receive the Error when an error occurs while fetching the block', (done: DoneCallback) => {
-            (async () => {
-                const errMsg = 'Error fetching block';
-                const callback = assertNodeCallbackError(done, errMsg);
-                stubs = [Sinon.stub((zeroEx as any)._web3Wrapper, 'getBlockAsync').throws(new Error(errMsg))];
-                zeroEx.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
-                await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount);
-            })().catch(done);
-        });
-        it('Should receive the Error when an error occurs while reconciling the new block', (done: DoneCallback) => {
-            (async () => {
-                const errMsg = 'Error fetching logs';
-                const callback = assertNodeCallbackError(done, errMsg);
-                stubs = [Sinon.stub((zeroEx as any)._web3Wrapper, 'getLogsAsync').throws(new Error(errMsg))];
-                zeroEx.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
-                await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount);
-            })().catch(done);
-        });
-        it('Should allow unsubscribeAll to be called successfully after an error', (done: DoneCallback) => {
-            (async () => {
-                const callback = (err: Error | null, logEvent?: DecodedLogEvent<ApprovalContractEventArgs>) => _.noop;
-                zeroEx.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
-                stubs = [Sinon.stub((zeroEx as any)._web3Wrapper, 'getBlockAsync').throws(new Error('JSON RPC error'))];
-                zeroEx.token.unsubscribeAll();
-                done();
-            })().catch(done);
-        });
-    });
+	let web3: Web3;
+	let zeroEx: ZeroEx;
+	let userAddresses: string[];
+	let tokens: Token[];
+	let coinbase: string;
+	let addressWithoutFunds: string;
+	const config = {
+		networkId: constants.TESTRPC_NETWORK_ID,
+	};
+	before(async () => {
+		web3 = web3Factory.create();
+		zeroEx = new ZeroEx(web3.currentProvider, config);
+		userAddresses = await zeroEx.getAvailableAddressesAsync();
+		tokens = await zeroEx.tokenRegistry.getTokensAsync();
+		coinbase = userAddresses[0];
+		addressWithoutFunds = userAddresses[1];
+	});
+	beforeEach(async () => {
+		await blockchainLifecycle.startAsync();
+	});
+	afterEach(async () => {
+		await blockchainLifecycle.revertAsync();
+	});
+	describe('#subscribe', () => {
+		const indexFilterValues = {};
+		let tokenAddress: string;
+		const allowanceAmount = new BigNumber(42);
+		let stubs: Sinon.SinonStub[] = [];
+		before(() => {
+			const token = tokens[0];
+			tokenAddress = token.address;
+		});
+		afterEach(() => {
+			zeroEx.token.unsubscribeAll();
+			_.each(stubs, s => s.restore());
+			stubs = [];
+		});
+		it('Should receive the Error when an error occurs while fetching the block', (done: DoneCallback) => {
+			(async () => {
+				const errMsg = 'Error fetching block';
+				const callback = assertNodeCallbackError(done, errMsg);
+				stubs = [Sinon.stub((zeroEx as any)._web3Wrapper, 'getBlockAsync').throws(new Error(errMsg))];
+				zeroEx.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
+				await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount);
+			})().catch(done);
+		});
+		it('Should receive the Error when an error occurs while reconciling the new block', (done: DoneCallback) => {
+			(async () => {
+				const errMsg = 'Error fetching logs';
+				const callback = assertNodeCallbackError(done, errMsg);
+				stubs = [Sinon.stub((zeroEx as any)._web3Wrapper, 'getLogsAsync').throws(new Error(errMsg))];
+				zeroEx.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
+				await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount);
+			})().catch(done);
+		});
+		it('Should allow unsubscribeAll to be called successfully after an error', (done: DoneCallback) => {
+			(async () => {
+				const callback = (err: Error | null, logEvent?: DecodedLogEvent<ApprovalContractEventArgs>) => _.noop;
+				zeroEx.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
+				stubs = [Sinon.stub((zeroEx as any)._web3Wrapper, 'getBlockAsync').throws(new Error('JSON RPC error'))];
+				zeroEx.token.unsubscribeAll();
+				done();
+			})().catch(done);
+		});
+	});
 });
diff --git a/packages/0x.js/test/token_registry_wrapper_test.ts b/packages/0x.js/test/token_registry_wrapper_test.ts
index 0a170db8f..c798c00d7 100644
--- a/packages/0x.js/test/token_registry_wrapper_test.ts
+++ b/packages/0x.js/test/token_registry_wrapper_test.ts
@@ -17,113 +17,113 @@ const blockchainLifecycle = new BlockchainLifecycle(constants.RPC_URL);
 const TOKEN_REGISTRY_SIZE_AFTER_MIGRATION = 7;
 
 describe('TokenRegistryWrapper', () => {
-    let zeroEx: ZeroEx;
-    let tokens: Token[];
-    const tokenAddressBySymbol: { [symbol: string]: string } = {};
-    const tokenAddressByName: { [symbol: string]: string } = {};
-    const tokenBySymbol: { [symbol: string]: Token } = {};
-    const tokenByName: { [symbol: string]: Token } = {};
-    const registeredSymbol = 'ZRX';
-    const registeredName = '0x Protocol Token';
-    const unregisteredSymbol = 'MAL';
-    const unregisteredName = 'Malicious Token';
-    const config = {
-        networkId: constants.TESTRPC_NETWORK_ID,
-    };
-    before(async () => {
-        const web3 = web3Factory.create();
-        zeroEx = new ZeroEx(web3.currentProvider, config);
-        tokens = await zeroEx.tokenRegistry.getTokensAsync();
-        _.map(tokens, token => {
-            tokenAddressBySymbol[token.symbol] = token.address;
-            tokenAddressByName[token.name] = token.address;
-            tokenBySymbol[token.symbol] = token;
-            tokenByName[token.name] = token;
-        });
-    });
-    beforeEach(async () => {
-        await blockchainLifecycle.startAsync();
-    });
-    afterEach(async () => {
-        await blockchainLifecycle.revertAsync();
-    });
-    describe('#getTokensAsync', () => {
-        it('should return all the tokens added to the tokenRegistry during the migration', async () => {
-            expect(tokens).to.have.lengthOf(TOKEN_REGISTRY_SIZE_AFTER_MIGRATION);
+	let zeroEx: ZeroEx;
+	let tokens: Token[];
+	const tokenAddressBySymbol: { [symbol: string]: string } = {};
+	const tokenAddressByName: { [symbol: string]: string } = {};
+	const tokenBySymbol: { [symbol: string]: Token } = {};
+	const tokenByName: { [symbol: string]: Token } = {};
+	const registeredSymbol = 'ZRX';
+	const registeredName = '0x Protocol Token';
+	const unregisteredSymbol = 'MAL';
+	const unregisteredName = 'Malicious Token';
+	const config = {
+		networkId: constants.TESTRPC_NETWORK_ID,
+	};
+	before(async () => {
+		const web3 = web3Factory.create();
+		zeroEx = new ZeroEx(web3.currentProvider, config);
+		tokens = await zeroEx.tokenRegistry.getTokensAsync();
+		_.map(tokens, token => {
+			tokenAddressBySymbol[token.symbol] = token.address;
+			tokenAddressByName[token.name] = token.address;
+			tokenBySymbol[token.symbol] = token;
+			tokenByName[token.name] = token;
+		});
+	});
+	beforeEach(async () => {
+		await blockchainLifecycle.startAsync();
+	});
+	afterEach(async () => {
+		await blockchainLifecycle.revertAsync();
+	});
+	describe('#getTokensAsync', () => {
+		it('should return all the tokens added to the tokenRegistry during the migration', async () => {
+			expect(tokens).to.have.lengthOf(TOKEN_REGISTRY_SIZE_AFTER_MIGRATION);
 
-            const schemaValidator = new SchemaValidator();
-            _.each(tokens, token => {
-                const validationResult = schemaValidator.validate(token, schemas.tokenSchema);
-                expect(validationResult.errors).to.have.lengthOf(0);
-            });
-        });
-    });
-    describe('#getTokenAddressesAsync', () => {
-        it('should return all the token addresses added to the tokenRegistry during the migration', async () => {
-            const tokenAddresses = await zeroEx.tokenRegistry.getTokenAddressesAsync();
-            expect(tokenAddresses).to.have.lengthOf(TOKEN_REGISTRY_SIZE_AFTER_MIGRATION);
+			const schemaValidator = new SchemaValidator();
+			_.each(tokens, token => {
+				const validationResult = schemaValidator.validate(token, schemas.tokenSchema);
+				expect(validationResult.errors).to.have.lengthOf(0);
+			});
+		});
+	});
+	describe('#getTokenAddressesAsync', () => {
+		it('should return all the token addresses added to the tokenRegistry during the migration', async () => {
+			const tokenAddresses = await zeroEx.tokenRegistry.getTokenAddressesAsync();
+			expect(tokenAddresses).to.have.lengthOf(TOKEN_REGISTRY_SIZE_AFTER_MIGRATION);
 
-            const schemaValidator = new SchemaValidator();
-            _.each(tokenAddresses, tokenAddress => {
-                const validationResult = schemaValidator.validate(tokenAddress, schemas.addressSchema);
-                expect(validationResult.errors).to.have.lengthOf(0);
-                expect(tokenAddress).to.not.be.equal(ZeroEx.NULL_ADDRESS);
-            });
-        });
-    });
-    describe('#getTokenAddressBySymbol', () => {
-        it('should return correct address for a token in the registry', async () => {
-            const tokenAddress = await zeroEx.tokenRegistry.getTokenAddressBySymbolIfExistsAsync(registeredSymbol);
-            expect(tokenAddress).to.be.equal(tokenAddressBySymbol[registeredSymbol]);
-        });
-        it('should return undefined for a token out of registry', async () => {
-            const tokenAddress = await zeroEx.tokenRegistry.getTokenAddressBySymbolIfExistsAsync(unregisteredSymbol);
-            expect(tokenAddress).to.be.undefined();
-        });
-    });
-    describe('#getTokenAddressByName', () => {
-        it('should return correct address for a token in the registry', async () => {
-            const tokenAddress = await zeroEx.tokenRegistry.getTokenAddressByNameIfExistsAsync(registeredName);
-            expect(tokenAddress).to.be.equal(tokenAddressByName[registeredName]);
-        });
-        it('should return undefined for a token out of registry', async () => {
-            const tokenAddress = await zeroEx.tokenRegistry.getTokenAddressByNameIfExistsAsync(unregisteredName);
-            expect(tokenAddress).to.be.undefined();
-        });
-    });
-    describe('#getTokenBySymbol', () => {
-        it('should return correct token for a token in the registry', async () => {
-            const token = await zeroEx.tokenRegistry.getTokenBySymbolIfExistsAsync(registeredSymbol);
-            expect(token).to.be.deep.equal(tokenBySymbol[registeredSymbol]);
-        });
-        it('should return undefined for a token out of registry', async () => {
-            const token = await zeroEx.tokenRegistry.getTokenBySymbolIfExistsAsync(unregisteredSymbol);
-            expect(token).to.be.undefined();
-        });
-    });
-    describe('#getTokenByName', () => {
-        it('should return correct token for a token in the registry', async () => {
-            const token = await zeroEx.tokenRegistry.getTokenByNameIfExistsAsync(registeredName);
-            expect(token).to.be.deep.equal(tokenByName[registeredName]);
-        });
-        it('should return undefined for a token out of registry', async () => {
-            const token = await zeroEx.tokenRegistry.getTokenByNameIfExistsAsync(unregisteredName);
-            expect(token).to.be.undefined();
-        });
-    });
-    describe('#getTokenIfExistsAsync', () => {
-        it('should return the token added to the tokenRegistry during the migration', async () => {
-            const aToken = tokens[0];
+			const schemaValidator = new SchemaValidator();
+			_.each(tokenAddresses, tokenAddress => {
+				const validationResult = schemaValidator.validate(tokenAddress, schemas.addressSchema);
+				expect(validationResult.errors).to.have.lengthOf(0);
+				expect(tokenAddress).to.not.be.equal(ZeroEx.NULL_ADDRESS);
+			});
+		});
+	});
+	describe('#getTokenAddressBySymbol', () => {
+		it('should return correct address for a token in the registry', async () => {
+			const tokenAddress = await zeroEx.tokenRegistry.getTokenAddressBySymbolIfExistsAsync(registeredSymbol);
+			expect(tokenAddress).to.be.equal(tokenAddressBySymbol[registeredSymbol]);
+		});
+		it('should return undefined for a token out of registry', async () => {
+			const tokenAddress = await zeroEx.tokenRegistry.getTokenAddressBySymbolIfExistsAsync(unregisteredSymbol);
+			expect(tokenAddress).to.be.undefined();
+		});
+	});
+	describe('#getTokenAddressByName', () => {
+		it('should return correct address for a token in the registry', async () => {
+			const tokenAddress = await zeroEx.tokenRegistry.getTokenAddressByNameIfExistsAsync(registeredName);
+			expect(tokenAddress).to.be.equal(tokenAddressByName[registeredName]);
+		});
+		it('should return undefined for a token out of registry', async () => {
+			const tokenAddress = await zeroEx.tokenRegistry.getTokenAddressByNameIfExistsAsync(unregisteredName);
+			expect(tokenAddress).to.be.undefined();
+		});
+	});
+	describe('#getTokenBySymbol', () => {
+		it('should return correct token for a token in the registry', async () => {
+			const token = await zeroEx.tokenRegistry.getTokenBySymbolIfExistsAsync(registeredSymbol);
+			expect(token).to.be.deep.equal(tokenBySymbol[registeredSymbol]);
+		});
+		it('should return undefined for a token out of registry', async () => {
+			const token = await zeroEx.tokenRegistry.getTokenBySymbolIfExistsAsync(unregisteredSymbol);
+			expect(token).to.be.undefined();
+		});
+	});
+	describe('#getTokenByName', () => {
+		it('should return correct token for a token in the registry', async () => {
+			const token = await zeroEx.tokenRegistry.getTokenByNameIfExistsAsync(registeredName);
+			expect(token).to.be.deep.equal(tokenByName[registeredName]);
+		});
+		it('should return undefined for a token out of registry', async () => {
+			const token = await zeroEx.tokenRegistry.getTokenByNameIfExistsAsync(unregisteredName);
+			expect(token).to.be.undefined();
+		});
+	});
+	describe('#getTokenIfExistsAsync', () => {
+		it('should return the token added to the tokenRegistry during the migration', async () => {
+			const aToken = tokens[0];
 
-            const token = await zeroEx.tokenRegistry.getTokenIfExistsAsync(aToken.address);
-            const schemaValidator = new SchemaValidator();
-            const validationResult = schemaValidator.validate(token, schemas.tokenSchema);
-            expect(validationResult.errors).to.have.lengthOf(0);
-        });
-        it('should return return undefined when passed a token address not in the tokenRegistry', async () => {
-            const unregisteredTokenAddress = '0x5409ed021d9299bf6814279a6a1411a7e866a631';
-            const tokenIfExists = await zeroEx.tokenRegistry.getTokenIfExistsAsync(unregisteredTokenAddress);
-            expect(tokenIfExists).to.be.undefined();
-        });
-    });
+			const token = await zeroEx.tokenRegistry.getTokenIfExistsAsync(aToken.address);
+			const schemaValidator = new SchemaValidator();
+			const validationResult = schemaValidator.validate(token, schemas.tokenSchema);
+			expect(validationResult.errors).to.have.lengthOf(0);
+		});
+		it('should return return undefined when passed a token address not in the tokenRegistry', async () => {
+			const unregisteredTokenAddress = '0x5409ed021d9299bf6814279a6a1411a7e866a631';
+			const tokenIfExists = await zeroEx.tokenRegistry.getTokenIfExistsAsync(unregisteredTokenAddress);
+			expect(tokenIfExists).to.be.undefined();
+		});
+	});
 });
diff --git a/packages/0x.js/test/token_transfer_proxy_wrapper_test.ts b/packages/0x.js/test/token_transfer_proxy_wrapper_test.ts
index 15bd7a8ba..622919be2 100644
--- a/packages/0x.js/test/token_transfer_proxy_wrapper_test.ts
+++ b/packages/0x.js/test/token_transfer_proxy_wrapper_test.ts
@@ -10,27 +10,27 @@ chaiSetup.configure();
 const expect = chai.expect;
 
 describe('TokenTransferProxyWrapper', () => {
-    let zeroEx: ZeroEx;
-    const config = {
-        networkId: constants.TESTRPC_NETWORK_ID,
-    };
-    before(async () => {
-        const web3 = web3Factory.create();
-        zeroEx = new ZeroEx(web3.currentProvider, config);
-    });
-    describe('#isAuthorizedAsync', () => {
-        it('should return false if the address is not authorized', async () => {
-            const isAuthorized = await zeroEx.proxy.isAuthorizedAsync(ZeroEx.NULL_ADDRESS);
-            expect(isAuthorized).to.be.false();
-        });
-    });
-    describe('#getAuthorizedAddressesAsync', () => {
-        it('should return the list of authorized addresses', async () => {
-            const authorizedAddresses = await zeroEx.proxy.getAuthorizedAddressesAsync();
-            for (const authorizedAddress of authorizedAddresses) {
-                const isAuthorized = await zeroEx.proxy.isAuthorizedAsync(authorizedAddress);
-                expect(isAuthorized).to.be.true();
-            }
-        });
-    });
+	let zeroEx: ZeroEx;
+	const config = {
+		networkId: constants.TESTRPC_NETWORK_ID,
+	};
+	before(async () => {
+		const web3 = web3Factory.create();
+		zeroEx = new ZeroEx(web3.currentProvider, config);
+	});
+	describe('#isAuthorizedAsync', () => {
+		it('should return false if the address is not authorized', async () => {
+			const isAuthorized = await zeroEx.proxy.isAuthorizedAsync(ZeroEx.NULL_ADDRESS);
+			expect(isAuthorized).to.be.false();
+		});
+	});
+	describe('#getAuthorizedAddressesAsync', () => {
+		it('should return the list of authorized addresses', async () => {
+			const authorizedAddresses = await zeroEx.proxy.getAuthorizedAddressesAsync();
+			for (const authorizedAddress of authorizedAddresses) {
+				const isAuthorized = await zeroEx.proxy.isAuthorizedAsync(authorizedAddress);
+				expect(isAuthorized).to.be.true();
+			}
+		});
+	});
 });
diff --git a/packages/0x.js/test/token_wrapper_test.ts b/packages/0x.js/test/token_wrapper_test.ts
index 4ba1f07c5..6919183cb 100644
--- a/packages/0x.js/test/token_wrapper_test.ts
+++ b/packages/0x.js/test/token_wrapper_test.ts
@@ -6,15 +6,15 @@ import 'mocha';
 import * as Web3 from 'web3';
 
 import {
-    ApprovalContractEventArgs,
-    BlockParamLiteral,
-    BlockRange,
-    DecodedLogEvent,
-    Token,
-    TokenEvents,
-    TransferContractEventArgs,
-    ZeroEx,
-    ZeroExError,
+	ApprovalContractEventArgs,
+	BlockParamLiteral,
+	BlockRange,
+	DecodedLogEvent,
+	Token,
+	TokenEvents,
+	TransferContractEventArgs,
+	ZeroEx,
+	ZeroExError,
 } from '../src';
 import { DoneCallback } from '../src/types';
 
@@ -29,493 +29,493 @@ const expect = chai.expect;
 const blockchainLifecycle = new BlockchainLifecycle(constants.RPC_URL);
 
 describe('TokenWrapper', () => {
-    let web3: Web3;
-    let zeroEx: ZeroEx;
-    let userAddresses: string[];
-    let tokens: Token[];
-    let tokenUtils: TokenUtils;
-    let coinbase: string;
-    let addressWithoutFunds: string;
-    let web3Wrapper: Web3Wrapper;
-    const config = {
-        networkId: constants.TESTRPC_NETWORK_ID,
-    };
-    before(async () => {
-        web3 = web3Factory.create();
-        zeroEx = new ZeroEx(web3.currentProvider, config);
-        web3Wrapper = new Web3Wrapper(web3.currentProvider);
-        userAddresses = await zeroEx.getAvailableAddressesAsync();
-        tokens = await zeroEx.tokenRegistry.getTokensAsync();
-        tokenUtils = new TokenUtils(tokens);
-        coinbase = userAddresses[0];
-        addressWithoutFunds = userAddresses[1];
-    });
-    beforeEach(async () => {
-        await blockchainLifecycle.startAsync();
-    });
-    afterEach(async () => {
-        await blockchainLifecycle.revertAsync();
-    });
-    describe('#transferAsync', () => {
-        let token: Token;
-        let transferAmount: BigNumber;
-        before(() => {
-            token = tokens[0];
-            transferAmount = new BigNumber(42);
-        });
-        it('should successfully transfer tokens', async () => {
-            const fromAddress = coinbase;
-            const toAddress = addressWithoutFunds;
-            const preBalance = await zeroEx.token.getBalanceAsync(token.address, toAddress);
-            expect(preBalance).to.be.bignumber.equal(0);
-            await zeroEx.token.transferAsync(token.address, fromAddress, toAddress, transferAmount);
-            const postBalance = await zeroEx.token.getBalanceAsync(token.address, toAddress);
-            return expect(postBalance).to.be.bignumber.equal(transferAmount);
-        });
-        it('should fail to transfer tokens if fromAddress has an insufficient balance', async () => {
-            const fromAddress = addressWithoutFunds;
-            const toAddress = coinbase;
-            return expect(
-                zeroEx.token.transferAsync(token.address, fromAddress, toAddress, transferAmount),
-            ).to.be.rejectedWith(ZeroExError.InsufficientBalanceForTransfer);
-        });
-        it('should throw a CONTRACT_DOES_NOT_EXIST error for a non-existent token contract', async () => {
-            const nonExistentTokenAddress = '0x9dd402f14d67e001d8efbe6583e51bf9706aa065';
-            const fromAddress = coinbase;
-            const toAddress = coinbase;
-            return expect(
-                zeroEx.token.transferAsync(nonExistentTokenAddress, fromAddress, toAddress, transferAmount),
-            ).to.be.rejectedWith(ZeroExError.TokenContractDoesNotExist);
-        });
-    });
-    describe('#transferFromAsync', () => {
-        let token: Token;
-        let toAddress: string;
-        let senderAddress: string;
-        before(async () => {
-            token = tokens[0];
-            toAddress = addressWithoutFunds;
-            senderAddress = userAddresses[2];
-        });
-        it('should fail to transfer tokens if fromAddress has insufficient allowance set', async () => {
-            const fromAddress = coinbase;
-            const transferAmount = new BigNumber(42);
-
-            const fromAddressBalance = await zeroEx.token.getBalanceAsync(token.address, fromAddress);
-            expect(fromAddressBalance).to.be.bignumber.greaterThan(transferAmount);
-
-            const fromAddressAllowance = await zeroEx.token.getAllowanceAsync(token.address, fromAddress, toAddress);
-            expect(fromAddressAllowance).to.be.bignumber.equal(0);
-
-            return expect(
-                zeroEx.token.transferFromAsync(token.address, fromAddress, toAddress, senderAddress, transferAmount),
-            ).to.be.rejectedWith(ZeroExError.InsufficientAllowanceForTransfer);
-        });
-        it('[regression] should fail to transfer tokens if set allowance for toAddress instead of senderAddress', async () => {
-            const fromAddress = coinbase;
-            const transferAmount = new BigNumber(42);
-
-            await zeroEx.token.setAllowanceAsync(token.address, fromAddress, toAddress, transferAmount);
-
-            return expect(
-                zeroEx.token.transferFromAsync(token.address, fromAddress, toAddress, senderAddress, transferAmount),
-            ).to.be.rejectedWith(ZeroExError.InsufficientAllowanceForTransfer);
-        });
-        it('should fail to transfer tokens if fromAddress has insufficient balance', async () => {
-            const fromAddress = addressWithoutFunds;
-            const transferAmount = new BigNumber(42);
-
-            const fromAddressBalance = await zeroEx.token.getBalanceAsync(token.address, fromAddress);
-            expect(fromAddressBalance).to.be.bignumber.equal(0);
-
-            await zeroEx.token.setAllowanceAsync(token.address, fromAddress, senderAddress, transferAmount);
-            const fromAddressAllowance = await zeroEx.token.getAllowanceAsync(
-                token.address,
-                fromAddress,
-                senderAddress,
-            );
-            expect(fromAddressAllowance).to.be.bignumber.equal(transferAmount);
-
-            return expect(
-                zeroEx.token.transferFromAsync(token.address, fromAddress, toAddress, senderAddress, transferAmount),
-            ).to.be.rejectedWith(ZeroExError.InsufficientBalanceForTransfer);
-        });
-        it('should successfully transfer tokens', async () => {
-            const fromAddress = coinbase;
-
-            const preBalance = await zeroEx.token.getBalanceAsync(token.address, toAddress);
-            expect(preBalance).to.be.bignumber.equal(0);
-
-            const transferAmount = new BigNumber(42);
-            await zeroEx.token.setAllowanceAsync(token.address, fromAddress, senderAddress, transferAmount);
-
-            await zeroEx.token.transferFromAsync(token.address, fromAddress, toAddress, senderAddress, transferAmount);
-            const postBalance = await zeroEx.token.getBalanceAsync(token.address, toAddress);
-            return expect(postBalance).to.be.bignumber.equal(transferAmount);
-        });
-        it('should throw a CONTRACT_DOES_NOT_EXIST error for a non-existent token contract', async () => {
-            const fromAddress = coinbase;
-            const nonExistentTokenAddress = '0x9dd402f14d67e001d8efbe6583e51bf9706aa065';
-            return expect(
-                zeroEx.token.transferFromAsync(
-                    nonExistentTokenAddress,
-                    fromAddress,
-                    toAddress,
-                    senderAddress,
-                    new BigNumber(42),
-                ),
-            ).to.be.rejectedWith(ZeroExError.TokenContractDoesNotExist);
-        });
-    });
-    describe('#getBalanceAsync', () => {
-        describe('With web3 provider with accounts', () => {
-            it('should return the balance for an existing ERC20 token', async () => {
-                const token = tokens[0];
-                const ownerAddress = coinbase;
-                const balance = await zeroEx.token.getBalanceAsync(token.address, ownerAddress);
-                const expectedBalance = new BigNumber('1000000000000000000000000000');
-                return expect(balance).to.be.bignumber.equal(expectedBalance);
-            });
-            it('should throw a CONTRACT_DOES_NOT_EXIST error for a non-existent token contract', async () => {
-                const nonExistentTokenAddress = '0x9dd402f14d67e001d8efbe6583e51bf9706aa065';
-                const ownerAddress = coinbase;
-                return expect(zeroEx.token.getBalanceAsync(nonExistentTokenAddress, ownerAddress)).to.be.rejectedWith(
-                    ZeroExError.TokenContractDoesNotExist,
-                );
-            });
-            it('should return a balance of 0 for a non-existent owner address', async () => {
-                const token = tokens[0];
-                const nonExistentOwner = '0x198c6ad858f213fb31b6fe809e25040e6b964593';
-                const balance = await zeroEx.token.getBalanceAsync(token.address, nonExistentOwner);
-                const expectedBalance = new BigNumber(0);
-                return expect(balance).to.be.bignumber.equal(expectedBalance);
-            });
-        });
-        describe('With web3 provider without accounts', () => {
-            let zeroExWithoutAccounts: ZeroEx;
-            before(async () => {
-                const hasAddresses = false;
-                const web3WithoutAccounts = web3Factory.create(hasAddresses);
-                zeroExWithoutAccounts = new ZeroEx(web3WithoutAccounts.currentProvider, config);
-            });
-            it('should return balance even when called with Web3 provider instance without addresses', async () => {
-                const token = tokens[0];
-                const ownerAddress = coinbase;
-                const balance = await zeroExWithoutAccounts.token.getBalanceAsync(token.address, ownerAddress);
-                const expectedBalance = new BigNumber('1000000000000000000000000000');
-                return expect(balance).to.be.bignumber.equal(expectedBalance);
-            });
-        });
-    });
-    describe('#setAllowanceAsync', () => {
-        it("should set the spender's allowance", async () => {
-            const token = tokens[0];
-            const ownerAddress = coinbase;
-            const spenderAddress = addressWithoutFunds;
-
-            const allowanceBeforeSet = await zeroEx.token.getAllowanceAsync(
-                token.address,
-                ownerAddress,
-                spenderAddress,
-            );
-            const expectedAllowanceBeforeAllowanceSet = new BigNumber(0);
-            expect(allowanceBeforeSet).to.be.bignumber.equal(expectedAllowanceBeforeAllowanceSet);
-
-            const amountInBaseUnits = new BigNumber(50);
-            await zeroEx.token.setAllowanceAsync(token.address, ownerAddress, spenderAddress, amountInBaseUnits);
-
-            const allowanceAfterSet = await zeroEx.token.getAllowanceAsync(token.address, ownerAddress, spenderAddress);
-            const expectedAllowanceAfterAllowanceSet = amountInBaseUnits;
-            return expect(allowanceAfterSet).to.be.bignumber.equal(expectedAllowanceAfterAllowanceSet);
-        });
-    });
-    describe('#setUnlimitedAllowanceAsync', () => {
-        it("should set the unlimited spender's allowance", async () => {
-            const token = tokens[0];
-            const ownerAddress = coinbase;
-            const spenderAddress = addressWithoutFunds;
-
-            await zeroEx.token.setUnlimitedAllowanceAsync(token.address, ownerAddress, spenderAddress);
-            const allowance = await zeroEx.token.getAllowanceAsync(token.address, ownerAddress, spenderAddress);
-            return expect(allowance).to.be.bignumber.equal(zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
-        });
-        it('should reduce the gas cost for transfers including tokens with unlimited allowance support', async () => {
-            const transferAmount = new BigNumber(5);
-            const zrx = tokenUtils.getProtocolTokenOrThrow();
-            const [, userWithNormalAllowance, userWithUnlimitedAllowance] = userAddresses;
-            await zeroEx.token.setAllowanceAsync(zrx.address, coinbase, userWithNormalAllowance, transferAmount);
-            await zeroEx.token.setUnlimitedAllowanceAsync(zrx.address, coinbase, userWithUnlimitedAllowance);
-
-            const initBalanceWithNormalAllowance = await web3Wrapper.getBalanceInWeiAsync(userWithNormalAllowance);
-            const initBalanceWithUnlimitedAllowance = await web3Wrapper.getBalanceInWeiAsync(
-                userWithUnlimitedAllowance,
-            );
-
-            await zeroEx.token.transferFromAsync(
-                zrx.address,
-                coinbase,
-                userWithNormalAllowance,
-                userWithNormalAllowance,
-                transferAmount,
-            );
-            await zeroEx.token.transferFromAsync(
-                zrx.address,
-                coinbase,
-                userWithUnlimitedAllowance,
-                userWithUnlimitedAllowance,
-                transferAmount,
-            );
-
-            const finalBalanceWithNormalAllowance = await web3Wrapper.getBalanceInWeiAsync(userWithNormalAllowance);
-            const finalBalanceWithUnlimitedAllowance = await web3Wrapper.getBalanceInWeiAsync(
-                userWithUnlimitedAllowance,
-            );
-
-            const normalGasCost = initBalanceWithNormalAllowance.minus(finalBalanceWithNormalAllowance);
-            const unlimitedGasCost = initBalanceWithUnlimitedAllowance.minus(finalBalanceWithUnlimitedAllowance);
-
-            // In theory the gas cost with unlimited allowance should be smaller, but with testrpc it's actually bigger.
-            // This needs to be investigated in ethereumjs-vm. This test is essentially a repro.
-            // TODO: Make this test pass with inverted assertion.
-            expect(unlimitedGasCost.toNumber()).to.be.gt(normalGasCost.toNumber());
-        });
-    });
-    describe('#getAllowanceAsync', () => {
-        describe('With web3 provider with accounts', () => {
-            it('should get the proxy allowance', async () => {
-                const token = tokens[0];
-                const ownerAddress = coinbase;
-                const spenderAddress = addressWithoutFunds;
-
-                const amountInBaseUnits = new BigNumber(50);
-                await zeroEx.token.setAllowanceAsync(token.address, ownerAddress, spenderAddress, amountInBaseUnits);
-
-                const allowance = await zeroEx.token.getAllowanceAsync(token.address, ownerAddress, spenderAddress);
-                const expectedAllowance = amountInBaseUnits;
-                return expect(allowance).to.be.bignumber.equal(expectedAllowance);
-            });
-            it('should return 0 if no allowance set yet', async () => {
-                const token = tokens[0];
-                const ownerAddress = coinbase;
-                const spenderAddress = addressWithoutFunds;
-                const allowance = await zeroEx.token.getAllowanceAsync(token.address, ownerAddress, spenderAddress);
-                const expectedAllowance = new BigNumber(0);
-                return expect(allowance).to.be.bignumber.equal(expectedAllowance);
-            });
-        });
-        describe('With web3 provider without accounts', () => {
-            let zeroExWithoutAccounts: ZeroEx;
-            before(async () => {
-                const hasAddresses = false;
-                const web3WithoutAccounts = web3Factory.create(hasAddresses);
-                zeroExWithoutAccounts = new ZeroEx(web3WithoutAccounts.currentProvider, config);
-            });
-            it('should get the proxy allowance', async () => {
-                const token = tokens[0];
-                const ownerAddress = coinbase;
-                const spenderAddress = addressWithoutFunds;
-
-                const amountInBaseUnits = new BigNumber(50);
-                await zeroEx.token.setAllowanceAsync(token.address, ownerAddress, spenderAddress, amountInBaseUnits);
-
-                const allowance = await zeroExWithoutAccounts.token.getAllowanceAsync(
-                    token.address,
-                    ownerAddress,
-                    spenderAddress,
-                );
-                const expectedAllowance = amountInBaseUnits;
-                return expect(allowance).to.be.bignumber.equal(expectedAllowance);
-            });
-        });
-    });
-    describe('#getProxyAllowanceAsync', () => {
-        it('should get the proxy allowance', async () => {
-            const token = tokens[0];
-            const ownerAddress = coinbase;
-
-            const amountInBaseUnits = new BigNumber(50);
-            await zeroEx.token.setProxyAllowanceAsync(token.address, ownerAddress, amountInBaseUnits);
-
-            const allowance = await zeroEx.token.getProxyAllowanceAsync(token.address, ownerAddress);
-            const expectedAllowance = amountInBaseUnits;
-            return expect(allowance).to.be.bignumber.equal(expectedAllowance);
-        });
-    });
-    describe('#setProxyAllowanceAsync', () => {
-        it('should set the proxy allowance', async () => {
-            const token = tokens[0];
-            const ownerAddress = coinbase;
-
-            const allowanceBeforeSet = await zeroEx.token.getProxyAllowanceAsync(token.address, ownerAddress);
-            const expectedAllowanceBeforeAllowanceSet = new BigNumber(0);
-            expect(allowanceBeforeSet).to.be.bignumber.equal(expectedAllowanceBeforeAllowanceSet);
-
-            const amountInBaseUnits = new BigNumber(50);
-            await zeroEx.token.setProxyAllowanceAsync(token.address, ownerAddress, amountInBaseUnits);
-
-            const allowanceAfterSet = await zeroEx.token.getProxyAllowanceAsync(token.address, ownerAddress);
-            const expectedAllowanceAfterAllowanceSet = amountInBaseUnits;
-            return expect(allowanceAfterSet).to.be.bignumber.equal(expectedAllowanceAfterAllowanceSet);
-        });
-    });
-    describe('#setUnlimitedProxyAllowanceAsync', () => {
-        it('should set the unlimited proxy allowance', async () => {
-            const token = tokens[0];
-            const ownerAddress = coinbase;
-
-            await zeroEx.token.setUnlimitedProxyAllowanceAsync(token.address, ownerAddress);
-            const allowance = await zeroEx.token.getProxyAllowanceAsync(token.address, ownerAddress);
-            return expect(allowance).to.be.bignumber.equal(zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
-        });
-    });
-    describe('#subscribe', () => {
-        const indexFilterValues = {};
-        let tokenAddress: string;
-        const transferAmount = new BigNumber(42);
-        const allowanceAmount = new BigNumber(42);
-        before(() => {
-            const token = tokens[0];
-            tokenAddress = token.address;
-        });
-        afterEach(() => {
-            zeroEx.token.unsubscribeAll();
-        });
-        // Hack: Mocha does not allow a test to be both async and have a `done` callback
-        // Since we need to await the receipt of the event in the `subscribe` callback,
-        // we do need both. A hack is to make the top-level a sync fn w/ a done callback and then
-        // wrap the rest of the test in an async block
-        // Source: https://github.com/mochajs/mocha/issues/2407
-        it('Should receive the Transfer event when tokens are transfered', (done: DoneCallback) => {
-            (async () => {
-                const callback = reportNodeCallbackErrors(done)(
-                    (logEvent: DecodedLogEvent<TransferContractEventArgs>) => {
-                        expect(logEvent.isRemoved).to.be.false();
-                        expect(logEvent.log.logIndex).to.be.equal(0);
-                        expect(logEvent.log.transactionIndex).to.be.equal(0);
-                        expect(logEvent.log.blockNumber).to.be.a('number');
-                        const args = logEvent.log.args;
-                        expect(args._from).to.be.equal(coinbase);
-                        expect(args._to).to.be.equal(addressWithoutFunds);
-                        expect(args._value).to.be.bignumber.equal(transferAmount);
-                    },
-                );
-                zeroEx.token.subscribe(tokenAddress, TokenEvents.Transfer, indexFilterValues, callback);
-                await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
-            })().catch(done);
-        });
-        it('Should receive the Approval event when allowance is being set', (done: DoneCallback) => {
-            (async () => {
-                const callback = reportNodeCallbackErrors(done)(
-                    (logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
-                        expect(logEvent).to.not.be.undefined();
-                        expect(logEvent.isRemoved).to.be.false();
-                        const args = logEvent.log.args;
-                        expect(args._owner).to.be.equal(coinbase);
-                        expect(args._spender).to.be.equal(addressWithoutFunds);
-                        expect(args._value).to.be.bignumber.equal(allowanceAmount);
-                    },
-                );
-                zeroEx.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
-                await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount);
-            })().catch(done);
-        });
-        it('Outstanding subscriptions are cancelled when zeroEx.setProvider called', (done: DoneCallback) => {
-            (async () => {
-                const callbackNeverToBeCalled = reportNodeCallbackErrors(done)(
-                    (logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
-                        done(new Error('Expected this subscription to have been cancelled'));
-                    },
-                );
-                zeroEx.token.subscribe(tokenAddress, TokenEvents.Transfer, indexFilterValues, callbackNeverToBeCalled);
-                const callbackToBeCalled = reportNodeCallbackErrors(done)();
-                const newProvider = web3Factory.getRpcProvider();
-                zeroEx.setProvider(newProvider, constants.TESTRPC_NETWORK_ID);
-                zeroEx.token.subscribe(tokenAddress, TokenEvents.Transfer, indexFilterValues, callbackToBeCalled);
-                await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
-            })().catch(done);
-        });
-        it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => {
-            (async () => {
-                const callbackNeverToBeCalled = reportNodeCallbackErrors(done)(
-                    (logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
-                        done(new Error('Expected this subscription to have been cancelled'));
-                    },
-                );
-                const subscriptionToken = zeroEx.token.subscribe(
-                    tokenAddress,
-                    TokenEvents.Transfer,
-                    indexFilterValues,
-                    callbackNeverToBeCalled,
-                );
-                zeroEx.token.unsubscribe(subscriptionToken);
-                await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
-                done();
-            })().catch(done);
-        });
-    });
-    describe('#getLogsAsync', () => {
-        let tokenAddress: string;
-        let tokenTransferProxyAddress: string;
-        const blockRange: BlockRange = {
-            fromBlock: 0,
-            toBlock: BlockParamLiteral.Latest,
-        };
-        let txHash: string;
-        before(() => {
-            const token = tokens[0];
-            tokenAddress = token.address;
-            tokenTransferProxyAddress = zeroEx.proxy.getContractAddress();
-        });
-        it('should get logs with decoded args emitted by Approval', async () => {
-            txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(tokenAddress, coinbase);
-            await zeroEx.awaitTransactionMinedAsync(txHash);
-            const eventName = TokenEvents.Approval;
-            const indexFilterValues = {};
-            const logs = await zeroEx.token.getLogsAsync<ApprovalContractEventArgs>(
-                tokenAddress,
-                eventName,
-                blockRange,
-                indexFilterValues,
-            );
-            expect(logs).to.have.length(1);
-            const args = logs[0].args;
-            expect(logs[0].event).to.be.equal(eventName);
-            expect(args._owner).to.be.equal(coinbase);
-            expect(args._spender).to.be.equal(tokenTransferProxyAddress);
-            expect(args._value).to.be.bignumber.equal(zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
-        });
-        it('should only get the logs with the correct event name', async () => {
-            txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(tokenAddress, coinbase);
-            await zeroEx.awaitTransactionMinedAsync(txHash);
-            const differentEventName = TokenEvents.Transfer;
-            const indexFilterValues = {};
-            const logs = await zeroEx.token.getLogsAsync(
-                tokenAddress,
-                differentEventName,
-                blockRange,
-                indexFilterValues,
-            );
-            expect(logs).to.have.length(0);
-        });
-        it('should only get the logs with the correct indexed fields', async () => {
-            txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(tokenAddress, coinbase);
-            await zeroEx.awaitTransactionMinedAsync(txHash);
-            txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(tokenAddress, addressWithoutFunds);
-            await zeroEx.awaitTransactionMinedAsync(txHash);
-            const eventName = TokenEvents.Approval;
-            const indexFilterValues = {
-                _owner: coinbase,
-            };
-            const logs = await zeroEx.token.getLogsAsync<ApprovalContractEventArgs>(
-                tokenAddress,
-                eventName,
-                blockRange,
-                indexFilterValues,
-            );
-            expect(logs).to.have.length(1);
-            const args = logs[0].args;
-            expect(args._owner).to.be.equal(coinbase);
-        });
-    });
+	let web3: Web3;
+	let zeroEx: ZeroEx;
+	let userAddresses: string[];
+	let tokens: Token[];
+	let tokenUtils: TokenUtils;
+	let coinbase: string;
+	let addressWithoutFunds: string;
+	let web3Wrapper: Web3Wrapper;
+	const config = {
+		networkId: constants.TESTRPC_NETWORK_ID,
+	};
+	before(async () => {
+		web3 = web3Factory.create();
+		zeroEx = new ZeroEx(web3.currentProvider, config);
+		web3Wrapper = new Web3Wrapper(web3.currentProvider);
+		userAddresses = await zeroEx.getAvailableAddressesAsync();
+		tokens = await zeroEx.tokenRegistry.getTokensAsync();
+		tokenUtils = new TokenUtils(tokens);
+		coinbase = userAddresses[0];
+		addressWithoutFunds = userAddresses[1];
+	});
+	beforeEach(async () => {
+		await blockchainLifecycle.startAsync();
+	});
+	afterEach(async () => {
+		await blockchainLifecycle.revertAsync();
+	});
+	describe('#transferAsync', () => {
+		let token: Token;
+		let transferAmount: BigNumber;
+		before(() => {
+			token = tokens[0];
+			transferAmount = new BigNumber(42);
+		});
+		it('should successfully transfer tokens', async () => {
+			const fromAddress = coinbase;
+			const toAddress = addressWithoutFunds;
+			const preBalance = await zeroEx.token.getBalanceAsync(token.address, toAddress);
+			expect(preBalance).to.be.bignumber.equal(0);
+			await zeroEx.token.transferAsync(token.address, fromAddress, toAddress, transferAmount);
+			const postBalance = await zeroEx.token.getBalanceAsync(token.address, toAddress);
+			return expect(postBalance).to.be.bignumber.equal(transferAmount);
+		});
+		it('should fail to transfer tokens if fromAddress has an insufficient balance', async () => {
+			const fromAddress = addressWithoutFunds;
+			const toAddress = coinbase;
+			return expect(
+				zeroEx.token.transferAsync(token.address, fromAddress, toAddress, transferAmount),
+			).to.be.rejectedWith(ZeroExError.InsufficientBalanceForTransfer);
+		});
+		it('should throw a CONTRACT_DOES_NOT_EXIST error for a non-existent token contract', async () => {
+			const nonExistentTokenAddress = '0x9dd402f14d67e001d8efbe6583e51bf9706aa065';
+			const fromAddress = coinbase;
+			const toAddress = coinbase;
+			return expect(
+				zeroEx.token.transferAsync(nonExistentTokenAddress, fromAddress, toAddress, transferAmount),
+			).to.be.rejectedWith(ZeroExError.TokenContractDoesNotExist);
+		});
+	});
+	describe('#transferFromAsync', () => {
+		let token: Token;
+		let toAddress: string;
+		let senderAddress: string;
+		before(async () => {
+			token = tokens[0];
+			toAddress = addressWithoutFunds;
+			senderAddress = userAddresses[2];
+		});
+		it('should fail to transfer tokens if fromAddress has insufficient allowance set', async () => {
+			const fromAddress = coinbase;
+			const transferAmount = new BigNumber(42);
+
+			const fromAddressBalance = await zeroEx.token.getBalanceAsync(token.address, fromAddress);
+			expect(fromAddressBalance).to.be.bignumber.greaterThan(transferAmount);
+
+			const fromAddressAllowance = await zeroEx.token.getAllowanceAsync(token.address, fromAddress, toAddress);
+			expect(fromAddressAllowance).to.be.bignumber.equal(0);
+
+			return expect(
+				zeroEx.token.transferFromAsync(token.address, fromAddress, toAddress, senderAddress, transferAmount),
+			).to.be.rejectedWith(ZeroExError.InsufficientAllowanceForTransfer);
+		});
+		it('[regression] should fail to transfer tokens if set allowance for toAddress instead of senderAddress', async () => {
+			const fromAddress = coinbase;
+			const transferAmount = new BigNumber(42);
+
+			await zeroEx.token.setAllowanceAsync(token.address, fromAddress, toAddress, transferAmount);
+
+			return expect(
+				zeroEx.token.transferFromAsync(token.address, fromAddress, toAddress, senderAddress, transferAmount),
+			).to.be.rejectedWith(ZeroExError.InsufficientAllowanceForTransfer);
+		});
+		it('should fail to transfer tokens if fromAddress has insufficient balance', async () => {
+			const fromAddress = addressWithoutFunds;
+			const transferAmount = new BigNumber(42);
+
+			const fromAddressBalance = await zeroEx.token.getBalanceAsync(token.address, fromAddress);
+			expect(fromAddressBalance).to.be.bignumber.equal(0);
+
+			await zeroEx.token.setAllowanceAsync(token.address, fromAddress, senderAddress, transferAmount);
+			const fromAddressAllowance = await zeroEx.token.getAllowanceAsync(
+				token.address,
+				fromAddress,
+				senderAddress,
+			);
+			expect(fromAddressAllowance).to.be.bignumber.equal(transferAmount);
+
+			return expect(
+				zeroEx.token.transferFromAsync(token.address, fromAddress, toAddress, senderAddress, transferAmount),
+			).to.be.rejectedWith(ZeroExError.InsufficientBalanceForTransfer);
+		});
+		it('should successfully transfer tokens', async () => {
+			const fromAddress = coinbase;
+
+			const preBalance = await zeroEx.token.getBalanceAsync(token.address, toAddress);
+			expect(preBalance).to.be.bignumber.equal(0);
+
+			const transferAmount = new BigNumber(42);
+			await zeroEx.token.setAllowanceAsync(token.address, fromAddress, senderAddress, transferAmount);
+
+			await zeroEx.token.transferFromAsync(token.address, fromAddress, toAddress, senderAddress, transferAmount);
+			const postBalance = await zeroEx.token.getBalanceAsync(token.address, toAddress);
+			return expect(postBalance).to.be.bignumber.equal(transferAmount);
+		});
+		it('should throw a CONTRACT_DOES_NOT_EXIST error for a non-existent token contract', async () => {
+			const fromAddress = coinbase;
+			const nonExistentTokenAddress = '0x9dd402f14d67e001d8efbe6583e51bf9706aa065';
+			return expect(
+				zeroEx.token.transferFromAsync(
+					nonExistentTokenAddress,
+					fromAddress,
+					toAddress,
+					senderAddress,
+					new BigNumber(42),
+				),
+			).to.be.rejectedWith(ZeroExError.TokenContractDoesNotExist);
+		});
+	});
+	describe('#getBalanceAsync', () => {
+		describe('With web3 provider with accounts', () => {
+			it('should return the balance for an existing ERC20 token', async () => {
+				const token = tokens[0];
+				const ownerAddress = coinbase;
+				const balance = await zeroEx.token.getBalanceAsync(token.address, ownerAddress);
+				const expectedBalance = new BigNumber('1000000000000000000000000000');
+				return expect(balance).to.be.bignumber.equal(expectedBalance);
+			});
+			it('should throw a CONTRACT_DOES_NOT_EXIST error for a non-existent token contract', async () => {
+				const nonExistentTokenAddress = '0x9dd402f14d67e001d8efbe6583e51bf9706aa065';
+				const ownerAddress = coinbase;
+				return expect(zeroEx.token.getBalanceAsync(nonExistentTokenAddress, ownerAddress)).to.be.rejectedWith(
+					ZeroExError.TokenContractDoesNotExist,
+				);
+			});
+			it('should return a balance of 0 for a non-existent owner address', async () => {
+				const token = tokens[0];
+				const nonExistentOwner = '0x198c6ad858f213fb31b6fe809e25040e6b964593';
+				const balance = await zeroEx.token.getBalanceAsync(token.address, nonExistentOwner);
+				const expectedBalance = new BigNumber(0);
+				return expect(balance).to.be.bignumber.equal(expectedBalance);
+			});
+		});
+		describe('With web3 provider without accounts', () => {
+			let zeroExWithoutAccounts: ZeroEx;
+			before(async () => {
+				const hasAddresses = false;
+				const web3WithoutAccounts = web3Factory.create(hasAddresses);
+				zeroExWithoutAccounts = new ZeroEx(web3WithoutAccounts.currentProvider, config);
+			});
+			it('should return balance even when called with Web3 provider instance without addresses', async () => {
+				const token = tokens[0];
+				const ownerAddress = coinbase;
+				const balance = await zeroExWithoutAccounts.token.getBalanceAsync(token.address, ownerAddress);
+				const expectedBalance = new BigNumber('1000000000000000000000000000');
+				return expect(balance).to.be.bignumber.equal(expectedBalance);
+			});
+		});
+	});
+	describe('#setAllowanceAsync', () => {
+		it("should set the spender's allowance", async () => {
+			const token = tokens[0];
+			const ownerAddress = coinbase;
+			const spenderAddress = addressWithoutFunds;
+
+			const allowanceBeforeSet = await zeroEx.token.getAllowanceAsync(
+				token.address,
+				ownerAddress,
+				spenderAddress,
+			);
+			const expectedAllowanceBeforeAllowanceSet = new BigNumber(0);
+			expect(allowanceBeforeSet).to.be.bignumber.equal(expectedAllowanceBeforeAllowanceSet);
+
+			const amountInBaseUnits = new BigNumber(50);
+			await zeroEx.token.setAllowanceAsync(token.address, ownerAddress, spenderAddress, amountInBaseUnits);
+
+			const allowanceAfterSet = await zeroEx.token.getAllowanceAsync(token.address, ownerAddress, spenderAddress);
+			const expectedAllowanceAfterAllowanceSet = amountInBaseUnits;
+			return expect(allowanceAfterSet).to.be.bignumber.equal(expectedAllowanceAfterAllowanceSet);
+		});
+	});
+	describe('#setUnlimitedAllowanceAsync', () => {
+		it("should set the unlimited spender's allowance", async () => {
+			const token = tokens[0];
+			const ownerAddress = coinbase;
+			const spenderAddress = addressWithoutFunds;
+
+			await zeroEx.token.setUnlimitedAllowanceAsync(token.address, ownerAddress, spenderAddress);
+			const allowance = await zeroEx.token.getAllowanceAsync(token.address, ownerAddress, spenderAddress);
+			return expect(allowance).to.be.bignumber.equal(zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
+		});
+		it('should reduce the gas cost for transfers including tokens with unlimited allowance support', async () => {
+			const transferAmount = new BigNumber(5);
+			const zrx = tokenUtils.getProtocolTokenOrThrow();
+			const [, userWithNormalAllowance, userWithUnlimitedAllowance] = userAddresses;
+			await zeroEx.token.setAllowanceAsync(zrx.address, coinbase, userWithNormalAllowance, transferAmount);
+			await zeroEx.token.setUnlimitedAllowanceAsync(zrx.address, coinbase, userWithUnlimitedAllowance);
+
+			const initBalanceWithNormalAllowance = await web3Wrapper.getBalanceInWeiAsync(userWithNormalAllowance);
+			const initBalanceWithUnlimitedAllowance = await web3Wrapper.getBalanceInWeiAsync(
+				userWithUnlimitedAllowance,
+			);
+
+			await zeroEx.token.transferFromAsync(
+				zrx.address,
+				coinbase,
+				userWithNormalAllowance,
+				userWithNormalAllowance,
+				transferAmount,
+			);
+			await zeroEx.token.transferFromAsync(
+				zrx.address,
+				coinbase,
+				userWithUnlimitedAllowance,
+				userWithUnlimitedAllowance,
+				transferAmount,
+			);
+
+			const finalBalanceWithNormalAllowance = await web3Wrapper.getBalanceInWeiAsync(userWithNormalAllowance);
+			const finalBalanceWithUnlimitedAllowance = await web3Wrapper.getBalanceInWeiAsync(
+				userWithUnlimitedAllowance,
+			);
+
+			const normalGasCost = initBalanceWithNormalAllowance.minus(finalBalanceWithNormalAllowance);
+			const unlimitedGasCost = initBalanceWithUnlimitedAllowance.minus(finalBalanceWithUnlimitedAllowance);
+
+			// In theory the gas cost with unlimited allowance should be smaller, but with testrpc it's actually bigger.
+			// This needs to be investigated in ethereumjs-vm. This test is essentially a repro.
+			// TODO: Make this test pass with inverted assertion.
+			expect(unlimitedGasCost.toNumber()).to.be.gt(normalGasCost.toNumber());
+		});
+	});
+	describe('#getAllowanceAsync', () => {
+		describe('With web3 provider with accounts', () => {
+			it('should get the proxy allowance', async () => {
+				const token = tokens[0];
+				const ownerAddress = coinbase;
+				const spenderAddress = addressWithoutFunds;
+
+				const amountInBaseUnits = new BigNumber(50);
+				await zeroEx.token.setAllowanceAsync(token.address, ownerAddress, spenderAddress, amountInBaseUnits);
+
+				const allowance = await zeroEx.token.getAllowanceAsync(token.address, ownerAddress, spenderAddress);
+				const expectedAllowance = amountInBaseUnits;
+				return expect(allowance).to.be.bignumber.equal(expectedAllowance);
+			});
+			it('should return 0 if no allowance set yet', async () => {
+				const token = tokens[0];
+				const ownerAddress = coinbase;
+				const spenderAddress = addressWithoutFunds;
+				const allowance = await zeroEx.token.getAllowanceAsync(token.address, ownerAddress, spenderAddress);
+				const expectedAllowance = new BigNumber(0);
+				return expect(allowance).to.be.bignumber.equal(expectedAllowance);
+			});
+		});
+		describe('With web3 provider without accounts', () => {
+			let zeroExWithoutAccounts: ZeroEx;
+			before(async () => {
+				const hasAddresses = false;
+				const web3WithoutAccounts = web3Factory.create(hasAddresses);
+				zeroExWithoutAccounts = new ZeroEx(web3WithoutAccounts.currentProvider, config);
+			});
+			it('should get the proxy allowance', async () => {
+				const token = tokens[0];
+				const ownerAddress = coinbase;
+				const spenderAddress = addressWithoutFunds;
+
+				const amountInBaseUnits = new BigNumber(50);
+				await zeroEx.token.setAllowanceAsync(token.address, ownerAddress, spenderAddress, amountInBaseUnits);
+
+				const allowance = await zeroExWithoutAccounts.token.getAllowanceAsync(
+					token.address,
+					ownerAddress,
+					spenderAddress,
+				);
+				const expectedAllowance = amountInBaseUnits;
+				return expect(allowance).to.be.bignumber.equal(expectedAllowance);
+			});
+		});
+	});
+	describe('#getProxyAllowanceAsync', () => {
+		it('should get the proxy allowance', async () => {
+			const token = tokens[0];
+			const ownerAddress = coinbase;
+
+			const amountInBaseUnits = new BigNumber(50);
+			await zeroEx.token.setProxyAllowanceAsync(token.address, ownerAddress, amountInBaseUnits);
+
+			const allowance = await zeroEx.token.getProxyAllowanceAsync(token.address, ownerAddress);
+			const expectedAllowance = amountInBaseUnits;
+			return expect(allowance).to.be.bignumber.equal(expectedAllowance);
+		});
+	});
+	describe('#setProxyAllowanceAsync', () => {
+		it('should set the proxy allowance', async () => {
+			const token = tokens[0];
+			const ownerAddress = coinbase;
+
+			const allowanceBeforeSet = await zeroEx.token.getProxyAllowanceAsync(token.address, ownerAddress);
+			const expectedAllowanceBeforeAllowanceSet = new BigNumber(0);
+			expect(allowanceBeforeSet).to.be.bignumber.equal(expectedAllowanceBeforeAllowanceSet);
+
+			const amountInBaseUnits = new BigNumber(50);
+			await zeroEx.token.setProxyAllowanceAsync(token.address, ownerAddress, amountInBaseUnits);
+
+			const allowanceAfterSet = await zeroEx.token.getProxyAllowanceAsync(token.address, ownerAddress);
+			const expectedAllowanceAfterAllowanceSet = amountInBaseUnits;
+			return expect(allowanceAfterSet).to.be.bignumber.equal(expectedAllowanceAfterAllowanceSet);
+		});
+	});
+	describe('#setUnlimitedProxyAllowanceAsync', () => {
+		it('should set the unlimited proxy allowance', async () => {
+			const token = tokens[0];
+			const ownerAddress = coinbase;
+
+			await zeroEx.token.setUnlimitedProxyAllowanceAsync(token.address, ownerAddress);
+			const allowance = await zeroEx.token.getProxyAllowanceAsync(token.address, ownerAddress);
+			return expect(allowance).to.be.bignumber.equal(zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
+		});
+	});
+	describe('#subscribe', () => {
+		const indexFilterValues = {};
+		let tokenAddress: string;
+		const transferAmount = new BigNumber(42);
+		const allowanceAmount = new BigNumber(42);
+		before(() => {
+			const token = tokens[0];
+			tokenAddress = token.address;
+		});
+		afterEach(() => {
+			zeroEx.token.unsubscribeAll();
+		});
+		// Hack: Mocha does not allow a test to be both async and have a `done` callback
+		// Since we need to await the receipt of the event in the `subscribe` callback,
+		// we do need both. A hack is to make the top-level a sync fn w/ a done callback and then
+		// wrap the rest of the test in an async block
+		// Source: https://github.com/mochajs/mocha/issues/2407
+		it('Should receive the Transfer event when tokens are transfered', (done: DoneCallback) => {
+			(async () => {
+				const callback = reportNodeCallbackErrors(done)(
+					(logEvent: DecodedLogEvent<TransferContractEventArgs>) => {
+						expect(logEvent.isRemoved).to.be.false();
+						expect(logEvent.log.logIndex).to.be.equal(0);
+						expect(logEvent.log.transactionIndex).to.be.equal(0);
+						expect(logEvent.log.blockNumber).to.be.a('number');
+						const args = logEvent.log.args;
+						expect(args._from).to.be.equal(coinbase);
+						expect(args._to).to.be.equal(addressWithoutFunds);
+						expect(args._value).to.be.bignumber.equal(transferAmount);
+					},
+				);
+				zeroEx.token.subscribe(tokenAddress, TokenEvents.Transfer, indexFilterValues, callback);
+				await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
+			})().catch(done);
+		});
+		it('Should receive the Approval event when allowance is being set', (done: DoneCallback) => {
+			(async () => {
+				const callback = reportNodeCallbackErrors(done)(
+					(logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
+						expect(logEvent).to.not.be.undefined();
+						expect(logEvent.isRemoved).to.be.false();
+						const args = logEvent.log.args;
+						expect(args._owner).to.be.equal(coinbase);
+						expect(args._spender).to.be.equal(addressWithoutFunds);
+						expect(args._value).to.be.bignumber.equal(allowanceAmount);
+					},
+				);
+				zeroEx.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
+				await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount);
+			})().catch(done);
+		});
+		it('Outstanding subscriptions are cancelled when zeroEx.setProvider called', (done: DoneCallback) => {
+			(async () => {
+				const callbackNeverToBeCalled = reportNodeCallbackErrors(done)(
+					(logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
+						done(new Error('Expected this subscription to have been cancelled'));
+					},
+				);
+				zeroEx.token.subscribe(tokenAddress, TokenEvents.Transfer, indexFilterValues, callbackNeverToBeCalled);
+				const callbackToBeCalled = reportNodeCallbackErrors(done)();
+				const newProvider = web3Factory.getRpcProvider();
+				zeroEx.setProvider(newProvider, constants.TESTRPC_NETWORK_ID);
+				zeroEx.token.subscribe(tokenAddress, TokenEvents.Transfer, indexFilterValues, callbackToBeCalled);
+				await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
+			})().catch(done);
+		});
+		it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => {
+			(async () => {
+				const callbackNeverToBeCalled = reportNodeCallbackErrors(done)(
+					(logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
+						done(new Error('Expected this subscription to have been cancelled'));
+					},
+				);
+				const subscriptionToken = zeroEx.token.subscribe(
+					tokenAddress,
+					TokenEvents.Transfer,
+					indexFilterValues,
+					callbackNeverToBeCalled,
+				);
+				zeroEx.token.unsubscribe(subscriptionToken);
+				await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
+				done();
+			})().catch(done);
+		});
+	});
+	describe('#getLogsAsync', () => {
+		let tokenAddress: string;
+		let tokenTransferProxyAddress: string;
+		const blockRange: BlockRange = {
+			fromBlock: 0,
+			toBlock: BlockParamLiteral.Latest,
+		};
+		let txHash: string;
+		before(() => {
+			const token = tokens[0];
+			tokenAddress = token.address;
+			tokenTransferProxyAddress = zeroEx.proxy.getContractAddress();
+		});
+		it('should get logs with decoded args emitted by Approval', async () => {
+			txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(tokenAddress, coinbase);
+			await zeroEx.awaitTransactionMinedAsync(txHash);
+			const eventName = TokenEvents.Approval;
+			const indexFilterValues = {};
+			const logs = await zeroEx.token.getLogsAsync<ApprovalContractEventArgs>(
+				tokenAddress,
+				eventName,
+				blockRange,
+				indexFilterValues,
+			);
+			expect(logs).to.have.length(1);
+			const args = logs[0].args;
+			expect(logs[0].event).to.be.equal(eventName);
+			expect(args._owner).to.be.equal(coinbase);
+			expect(args._spender).to.be.equal(tokenTransferProxyAddress);
+			expect(args._value).to.be.bignumber.equal(zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
+		});
+		it('should only get the logs with the correct event name', async () => {
+			txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(tokenAddress, coinbase);
+			await zeroEx.awaitTransactionMinedAsync(txHash);
+			const differentEventName = TokenEvents.Transfer;
+			const indexFilterValues = {};
+			const logs = await zeroEx.token.getLogsAsync(
+				tokenAddress,
+				differentEventName,
+				blockRange,
+				indexFilterValues,
+			);
+			expect(logs).to.have.length(0);
+		});
+		it('should only get the logs with the correct indexed fields', async () => {
+			txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(tokenAddress, coinbase);
+			await zeroEx.awaitTransactionMinedAsync(txHash);
+			txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(tokenAddress, addressWithoutFunds);
+			await zeroEx.awaitTransactionMinedAsync(txHash);
+			const eventName = TokenEvents.Approval;
+			const indexFilterValues = {
+				_owner: coinbase,
+			};
+			const logs = await zeroEx.token.getLogsAsync<ApprovalContractEventArgs>(
+				tokenAddress,
+				eventName,
+				blockRange,
+				indexFilterValues,
+			);
+			expect(logs).to.have.length(1);
+			const args = logs[0].args;
+			expect(args._owner).to.be.equal(coinbase);
+		});
+	});
 });
 // tslint:disable:max-file-line-count
diff --git a/packages/0x.js/test/utils/chai_setup.ts b/packages/0x.js/test/utils/chai_setup.ts
index 078edd309..e156b5f7c 100644
--- a/packages/0x.js/test/utils/chai_setup.ts
+++ b/packages/0x.js/test/utils/chai_setup.ts
@@ -4,10 +4,10 @@ import ChaiBigNumber = require('chai-bignumber');
 import * as dirtyChai from 'dirty-chai';
 
 export const chaiSetup = {
-    configure() {
-        chai.config.includeStack = true;
-        chai.use(ChaiBigNumber());
-        chai.use(dirtyChai);
-        chai.use(chaiAsPromised);
-    },
+	configure() {
+		chai.config.includeStack = true;
+		chai.use(ChaiBigNumber());
+		chai.use(dirtyChai);
+		chai.use(chaiAsPromised);
+	},
 };
diff --git a/packages/0x.js/test/utils/constants.ts b/packages/0x.js/test/utils/constants.ts
index a9e665c25..b7161e9ab 100644
--- a/packages/0x.js/test/utils/constants.ts
+++ b/packages/0x.js/test/utils/constants.ts
@@ -1,11 +1,11 @@
 export const constants = {
-    NULL_ADDRESS: '0x0000000000000000000000000000000000000000',
-    RPC_URL: 'http://localhost:8545',
-    ROPSTEN_NETWORK_ID: 3,
-    KOVAN_NETWORK_ID: 42,
-    TESTRPC_NETWORK_ID: 50,
-    KOVAN_RPC_URL: 'https://kovan.infura.io/',
-    ROPSTEN_RPC_URL: 'https://ropsten.infura.io/',
-    ZRX_DECIMALS: 18,
-    GAS_ESTIMATE: 500000,
+	NULL_ADDRESS: '0x0000000000000000000000000000000000000000',
+	RPC_URL: 'http://localhost:8545',
+	ROPSTEN_NETWORK_ID: 3,
+	KOVAN_NETWORK_ID: 42,
+	TESTRPC_NETWORK_ID: 50,
+	KOVAN_RPC_URL: 'https://kovan.infura.io/',
+	ROPSTEN_RPC_URL: 'https://ropsten.infura.io/',
+	ZRX_DECIMALS: 18,
+	GAS_ESTIMATE: 500000,
 };
diff --git a/packages/0x.js/test/utils/fill_scenarios.ts b/packages/0x.js/test/utils/fill_scenarios.ts
index 1a61487f4..1d4b8b6f4 100644
--- a/packages/0x.js/test/utils/fill_scenarios.ts
+++ b/packages/0x.js/test/utils/fill_scenarios.ts
@@ -11,192 +11,192 @@ import { constants } from './constants';
 const INITIAL_COINBASE_TOKEN_SUPPLY_IN_UNITS = new BigNumber(100);
 
 export class FillScenarios {
-    private _zeroEx: ZeroEx;
-    private _userAddresses: string[];
-    private _tokens: Token[];
-    private _coinbase: string;
-    private _zrxTokenAddress: string;
-    private _exchangeContractAddress: string;
-    constructor(
-        zeroEx: ZeroEx,
-        userAddresses: string[],
-        tokens: Token[],
-        zrxTokenAddress: string,
-        exchangeContractAddress: string,
-    ) {
-        this._zeroEx = zeroEx;
-        this._userAddresses = userAddresses;
-        this._tokens = tokens;
-        this._coinbase = userAddresses[0];
-        this._zrxTokenAddress = zrxTokenAddress;
-        this._exchangeContractAddress = exchangeContractAddress;
-    }
-    public async initTokenBalancesAsync() {
-        const web3Wrapper = (this._zeroEx as any)._web3Wrapper as Web3Wrapper;
-        for (const token of this._tokens) {
-            if (token.symbol !== 'ZRX' && token.symbol !== 'WETH') {
-                const contractInstance = web3Wrapper.getContractInstance(
-                    artifacts.DummyTokenArtifact.abi,
-                    token.address,
-                );
-                const defaults = {};
-                const dummyToken = new DummyTokenContract(contractInstance, defaults);
-                const tokenSupply = ZeroEx.toBaseUnitAmount(INITIAL_COINBASE_TOKEN_SUPPLY_IN_UNITS, token.decimals);
-                const txHash = await dummyToken.setBalance.sendTransactionAsync(this._coinbase, tokenSupply, {
-                    from: this._coinbase,
-                });
-                await this._zeroEx.awaitTransactionMinedAsync(txHash);
-            }
-        }
-    }
-    public async createFillableSignedOrderAsync(
-        makerTokenAddress: string,
-        takerTokenAddress: string,
-        makerAddress: string,
-        takerAddress: string,
-        fillableAmount: BigNumber,
-        expirationUnixTimestampSec?: BigNumber,
-    ): Promise<SignedOrder> {
-        return this.createAsymmetricFillableSignedOrderAsync(
-            makerTokenAddress,
-            takerTokenAddress,
-            makerAddress,
-            takerAddress,
-            fillableAmount,
-            fillableAmount,
-            expirationUnixTimestampSec,
-        );
-    }
-    public async createFillableSignedOrderWithFeesAsync(
-        makerTokenAddress: string,
-        takerTokenAddress: string,
-        makerFee: BigNumber,
-        takerFee: BigNumber,
-        makerAddress: string,
-        takerAddress: string,
-        fillableAmount: BigNumber,
-        feeRecepient: string,
-        expirationUnixTimestampSec?: BigNumber,
-    ): Promise<SignedOrder> {
-        return this._createAsymmetricFillableSignedOrderWithFeesAsync(
-            makerTokenAddress,
-            takerTokenAddress,
-            makerFee,
-            takerFee,
-            makerAddress,
-            takerAddress,
-            fillableAmount,
-            fillableAmount,
-            feeRecepient,
-            expirationUnixTimestampSec,
-        );
-    }
-    public async createAsymmetricFillableSignedOrderAsync(
-        makerTokenAddress: string,
-        takerTokenAddress: string,
-        makerAddress: string,
-        takerAddress: string,
-        makerFillableAmount: BigNumber,
-        takerFillableAmount: BigNumber,
-        expirationUnixTimestampSec?: BigNumber,
-    ): Promise<SignedOrder> {
-        const makerFee = new BigNumber(0);
-        const takerFee = new BigNumber(0);
-        const feeRecepient = constants.NULL_ADDRESS;
-        return this._createAsymmetricFillableSignedOrderWithFeesAsync(
-            makerTokenAddress,
-            takerTokenAddress,
-            makerFee,
-            takerFee,
-            makerAddress,
-            takerAddress,
-            makerFillableAmount,
-            takerFillableAmount,
-            feeRecepient,
-            expirationUnixTimestampSec,
-        );
-    }
-    public async createPartiallyFilledSignedOrderAsync(
-        makerTokenAddress: string,
-        takerTokenAddress: string,
-        takerAddress: string,
-        fillableAmount: BigNumber,
-        partialFillAmount: BigNumber,
-    ) {
-        const [makerAddress] = this._userAddresses;
-        const signedOrder = await this.createAsymmetricFillableSignedOrderAsync(
-            makerTokenAddress,
-            takerTokenAddress,
-            makerAddress,
-            takerAddress,
-            fillableAmount,
-            fillableAmount,
-        );
-        const shouldThrowOnInsufficientBalanceOrAllowance = false;
-        await this._zeroEx.exchange.fillOrderAsync(
-            signedOrder,
-            partialFillAmount,
-            shouldThrowOnInsufficientBalanceOrAllowance,
-            takerAddress,
-        );
-        return signedOrder;
-    }
-    private async _createAsymmetricFillableSignedOrderWithFeesAsync(
-        makerTokenAddress: string,
-        takerTokenAddress: string,
-        makerFee: BigNumber,
-        takerFee: BigNumber,
-        makerAddress: string,
-        takerAddress: string,
-        makerFillableAmount: BigNumber,
-        takerFillableAmount: BigNumber,
-        feeRecepient: string,
-        expirationUnixTimestampSec?: BigNumber,
-    ): Promise<SignedOrder> {
-        await Promise.all([
-            this._increaseBalanceAndAllowanceAsync(makerTokenAddress, makerAddress, makerFillableAmount),
-            this._increaseBalanceAndAllowanceAsync(takerTokenAddress, takerAddress, takerFillableAmount),
-        ]);
-        await Promise.all([
-            this._increaseBalanceAndAllowanceAsync(this._zrxTokenAddress, makerAddress, makerFee),
-            this._increaseBalanceAndAllowanceAsync(this._zrxTokenAddress, takerAddress, takerFee),
-        ]);
+	private _zeroEx: ZeroEx;
+	private _userAddresses: string[];
+	private _tokens: Token[];
+	private _coinbase: string;
+	private _zrxTokenAddress: string;
+	private _exchangeContractAddress: string;
+	constructor(
+		zeroEx: ZeroEx,
+		userAddresses: string[],
+		tokens: Token[],
+		zrxTokenAddress: string,
+		exchangeContractAddress: string,
+	) {
+		this._zeroEx = zeroEx;
+		this._userAddresses = userAddresses;
+		this._tokens = tokens;
+		this._coinbase = userAddresses[0];
+		this._zrxTokenAddress = zrxTokenAddress;
+		this._exchangeContractAddress = exchangeContractAddress;
+	}
+	public async initTokenBalancesAsync() {
+		const web3Wrapper = (this._zeroEx as any)._web3Wrapper as Web3Wrapper;
+		for (const token of this._tokens) {
+			if (token.symbol !== 'ZRX' && token.symbol !== 'WETH') {
+				const contractInstance = web3Wrapper.getContractInstance(
+					artifacts.DummyTokenArtifact.abi,
+					token.address,
+				);
+				const defaults = {};
+				const dummyToken = new DummyTokenContract(contractInstance, defaults);
+				const tokenSupply = ZeroEx.toBaseUnitAmount(INITIAL_COINBASE_TOKEN_SUPPLY_IN_UNITS, token.decimals);
+				const txHash = await dummyToken.setBalance.sendTransactionAsync(this._coinbase, tokenSupply, {
+					from: this._coinbase,
+				});
+				await this._zeroEx.awaitTransactionMinedAsync(txHash);
+			}
+		}
+	}
+	public async createFillableSignedOrderAsync(
+		makerTokenAddress: string,
+		takerTokenAddress: string,
+		makerAddress: string,
+		takerAddress: string,
+		fillableAmount: BigNumber,
+		expirationUnixTimestampSec?: BigNumber,
+	): Promise<SignedOrder> {
+		return this.createAsymmetricFillableSignedOrderAsync(
+			makerTokenAddress,
+			takerTokenAddress,
+			makerAddress,
+			takerAddress,
+			fillableAmount,
+			fillableAmount,
+			expirationUnixTimestampSec,
+		);
+	}
+	public async createFillableSignedOrderWithFeesAsync(
+		makerTokenAddress: string,
+		takerTokenAddress: string,
+		makerFee: BigNumber,
+		takerFee: BigNumber,
+		makerAddress: string,
+		takerAddress: string,
+		fillableAmount: BigNumber,
+		feeRecepient: string,
+		expirationUnixTimestampSec?: BigNumber,
+	): Promise<SignedOrder> {
+		return this._createAsymmetricFillableSignedOrderWithFeesAsync(
+			makerTokenAddress,
+			takerTokenAddress,
+			makerFee,
+			takerFee,
+			makerAddress,
+			takerAddress,
+			fillableAmount,
+			fillableAmount,
+			feeRecepient,
+			expirationUnixTimestampSec,
+		);
+	}
+	public async createAsymmetricFillableSignedOrderAsync(
+		makerTokenAddress: string,
+		takerTokenAddress: string,
+		makerAddress: string,
+		takerAddress: string,
+		makerFillableAmount: BigNumber,
+		takerFillableAmount: BigNumber,
+		expirationUnixTimestampSec?: BigNumber,
+	): Promise<SignedOrder> {
+		const makerFee = new BigNumber(0);
+		const takerFee = new BigNumber(0);
+		const feeRecepient = constants.NULL_ADDRESS;
+		return this._createAsymmetricFillableSignedOrderWithFeesAsync(
+			makerTokenAddress,
+			takerTokenAddress,
+			makerFee,
+			takerFee,
+			makerAddress,
+			takerAddress,
+			makerFillableAmount,
+			takerFillableAmount,
+			feeRecepient,
+			expirationUnixTimestampSec,
+		);
+	}
+	public async createPartiallyFilledSignedOrderAsync(
+		makerTokenAddress: string,
+		takerTokenAddress: string,
+		takerAddress: string,
+		fillableAmount: BigNumber,
+		partialFillAmount: BigNumber,
+	) {
+		const [makerAddress] = this._userAddresses;
+		const signedOrder = await this.createAsymmetricFillableSignedOrderAsync(
+			makerTokenAddress,
+			takerTokenAddress,
+			makerAddress,
+			takerAddress,
+			fillableAmount,
+			fillableAmount,
+		);
+		const shouldThrowOnInsufficientBalanceOrAllowance = false;
+		await this._zeroEx.exchange.fillOrderAsync(
+			signedOrder,
+			partialFillAmount,
+			shouldThrowOnInsufficientBalanceOrAllowance,
+			takerAddress,
+		);
+		return signedOrder;
+	}
+	private async _createAsymmetricFillableSignedOrderWithFeesAsync(
+		makerTokenAddress: string,
+		takerTokenAddress: string,
+		makerFee: BigNumber,
+		takerFee: BigNumber,
+		makerAddress: string,
+		takerAddress: string,
+		makerFillableAmount: BigNumber,
+		takerFillableAmount: BigNumber,
+		feeRecepient: string,
+		expirationUnixTimestampSec?: BigNumber,
+	): Promise<SignedOrder> {
+		await Promise.all([
+			this._increaseBalanceAndAllowanceAsync(makerTokenAddress, makerAddress, makerFillableAmount),
+			this._increaseBalanceAndAllowanceAsync(takerTokenAddress, takerAddress, takerFillableAmount),
+		]);
+		await Promise.all([
+			this._increaseBalanceAndAllowanceAsync(this._zrxTokenAddress, makerAddress, makerFee),
+			this._increaseBalanceAndAllowanceAsync(this._zrxTokenAddress, takerAddress, takerFee),
+		]);
 
-        const signedOrder = await orderFactory.createSignedOrderAsync(
-            this._zeroEx,
-            makerAddress,
-            takerAddress,
-            makerFee,
-            takerFee,
-            makerFillableAmount,
-            makerTokenAddress,
-            takerFillableAmount,
-            takerTokenAddress,
-            this._exchangeContractAddress,
-            feeRecepient,
-            expirationUnixTimestampSec,
-        );
-        return signedOrder;
-    }
-    private async _increaseBalanceAndAllowanceAsync(
-        tokenAddress: string,
-        address: string,
-        amount: BigNumber,
-    ): Promise<void> {
-        if (amount.isZero() || address === ZeroEx.NULL_ADDRESS) {
-            return; // noop
-        }
-        await Promise.all([
-            this._increaseBalanceAsync(tokenAddress, address, amount),
-            this._increaseAllowanceAsync(tokenAddress, address, amount),
-        ]);
-    }
-    private async _increaseBalanceAsync(tokenAddress: string, address: string, amount: BigNumber): Promise<void> {
-        await this._zeroEx.token.transferAsync(tokenAddress, this._coinbase, address, amount);
-    }
-    private async _increaseAllowanceAsync(tokenAddress: string, address: string, amount: BigNumber): Promise<void> {
-        const oldMakerAllowance = await this._zeroEx.token.getProxyAllowanceAsync(tokenAddress, address);
-        const newMakerAllowance = oldMakerAllowance.plus(amount);
-        await this._zeroEx.token.setProxyAllowanceAsync(tokenAddress, address, newMakerAllowance);
-    }
+		const signedOrder = await orderFactory.createSignedOrderAsync(
+			this._zeroEx,
+			makerAddress,
+			takerAddress,
+			makerFee,
+			takerFee,
+			makerFillableAmount,
+			makerTokenAddress,
+			takerFillableAmount,
+			takerTokenAddress,
+			this._exchangeContractAddress,
+			feeRecepient,
+			expirationUnixTimestampSec,
+		);
+		return signedOrder;
+	}
+	private async _increaseBalanceAndAllowanceAsync(
+		tokenAddress: string,
+		address: string,
+		amount: BigNumber,
+	): Promise<void> {
+		if (amount.isZero() || address === ZeroEx.NULL_ADDRESS) {
+			return; // noop
+		}
+		await Promise.all([
+			this._increaseBalanceAsync(tokenAddress, address, amount),
+			this._increaseAllowanceAsync(tokenAddress, address, amount),
+		]);
+	}
+	private async _increaseBalanceAsync(tokenAddress: string, address: string, amount: BigNumber): Promise<void> {
+		await this._zeroEx.token.transferAsync(tokenAddress, this._coinbase, address, amount);
+	}
+	private async _increaseAllowanceAsync(tokenAddress: string, address: string, amount: BigNumber): Promise<void> {
+		const oldMakerAllowance = await this._zeroEx.token.getProxyAllowanceAsync(tokenAddress, address);
+		const newMakerAllowance = oldMakerAllowance.plus(amount);
+		await this._zeroEx.token.setProxyAllowanceAsync(tokenAddress, address, newMakerAllowance);
+	}
 }
diff --git a/packages/0x.js/test/utils/order_factory.ts b/packages/0x.js/test/utils/order_factory.ts
index 08f2081a4..b65920e64 100644
--- a/packages/0x.js/test/utils/order_factory.ts
+++ b/packages/0x.js/test/utils/order_factory.ts
@@ -6,41 +6,41 @@ import { SignedOrder, ZeroEx } from '../../src';
 const SHOULD_ADD_PERSONAL_MESSAGE_PREFIX = false;
 
 export const orderFactory = {
-    async createSignedOrderAsync(
-        zeroEx: ZeroEx,
-        maker: string,
-        taker: string,
-        makerFee: BigNumber,
-        takerFee: BigNumber,
-        makerTokenAmount: BigNumber,
-        makerTokenAddress: string,
-        takerTokenAmount: BigNumber,
-        takerTokenAddress: string,
-        exchangeContractAddress: string,
-        feeRecipient: string,
-        expirationUnixTimestampSecIfExists?: BigNumber,
-    ): Promise<SignedOrder> {
-        const defaultExpirationUnixTimestampSec = new BigNumber(2524604400); // Close to infinite
-        const expirationUnixTimestampSec = _.isUndefined(expirationUnixTimestampSecIfExists)
-            ? defaultExpirationUnixTimestampSec
-            : expirationUnixTimestampSecIfExists;
-        const order = {
-            maker,
-            taker,
-            makerFee,
-            takerFee,
-            makerTokenAmount,
-            takerTokenAmount,
-            makerTokenAddress,
-            takerTokenAddress,
-            salt: ZeroEx.generatePseudoRandomSalt(),
-            exchangeContractAddress,
-            feeRecipient,
-            expirationUnixTimestampSec,
-        };
-        const orderHash = ZeroEx.getOrderHashHex(order);
-        const ecSignature = await zeroEx.signOrderHashAsync(orderHash, maker, SHOULD_ADD_PERSONAL_MESSAGE_PREFIX);
-        const signedOrder: SignedOrder = _.assign(order, { ecSignature });
-        return signedOrder;
-    },
+	async createSignedOrderAsync(
+		zeroEx: ZeroEx,
+		maker: string,
+		taker: string,
+		makerFee: BigNumber,
+		takerFee: BigNumber,
+		makerTokenAmount: BigNumber,
+		makerTokenAddress: string,
+		takerTokenAmount: BigNumber,
+		takerTokenAddress: string,
+		exchangeContractAddress: string,
+		feeRecipient: string,
+		expirationUnixTimestampSecIfExists?: BigNumber,
+	): Promise<SignedOrder> {
+		const defaultExpirationUnixTimestampSec = new BigNumber(2524604400); // Close to infinite
+		const expirationUnixTimestampSec = _.isUndefined(expirationUnixTimestampSecIfExists)
+			? defaultExpirationUnixTimestampSec
+			: expirationUnixTimestampSecIfExists;
+		const order = {
+			maker,
+			taker,
+			makerFee,
+			takerFee,
+			makerTokenAmount,
+			takerTokenAmount,
+			makerTokenAddress,
+			takerTokenAddress,
+			salt: ZeroEx.generatePseudoRandomSalt(),
+			exchangeContractAddress,
+			feeRecipient,
+			expirationUnixTimestampSec,
+		};
+		const orderHash = ZeroEx.getOrderHashHex(order);
+		const ecSignature = await zeroEx.signOrderHashAsync(orderHash, maker, SHOULD_ADD_PERSONAL_MESSAGE_PREFIX);
+		const signedOrder: SignedOrder = _.assign(order, { ecSignature });
+		return signedOrder;
+	},
 };
diff --git a/packages/0x.js/test/utils/report_callback_errors.ts b/packages/0x.js/test/utils/report_callback_errors.ts
index 27c9745c9..0b619f73e 100644
--- a/packages/0x.js/test/utils/report_callback_errors.ts
+++ b/packages/0x.js/test/utils/report_callback_errors.ts
@@ -6,61 +6,61 @@ import { DoneCallback } from '../../src/types';
 const expect = chai.expect;
 
 export const reportNoErrorCallbackErrors = (done: DoneCallback, expectToBeCalledOnce = true) => {
-    return <T>(f?: (value: T) => void) => {
-        const wrapped = (value: T) => {
-            if (_.isUndefined(f)) {
-                done();
-                return;
-            }
-            try {
-                f(value);
-                if (expectToBeCalledOnce) {
-                    done();
-                }
-            } catch (err) {
-                done(err);
-            }
-        };
-        return wrapped;
-    };
+	return <T>(f?: (value: T) => void) => {
+		const wrapped = (value: T) => {
+			if (_.isUndefined(f)) {
+				done();
+				return;
+			}
+			try {
+				f(value);
+				if (expectToBeCalledOnce) {
+					done();
+				}
+			} catch (err) {
+				done(err);
+			}
+		};
+		return wrapped;
+	};
 };
 
 export const reportNodeCallbackErrors = (done: DoneCallback, expectToBeCalledOnce = true) => {
-    return <T>(f?: (value: T) => void) => {
-        const wrapped = (error: Error | null, value: T | undefined) => {
-            if (!_.isNull(error)) {
-                done(error);
-            } else {
-                if (_.isUndefined(f)) {
-                    done();
-                    return;
-                }
-                try {
-                    f(value as T);
-                    if (expectToBeCalledOnce) {
-                        done();
-                    }
-                } catch (err) {
-                    done(err);
-                }
-            }
-        };
-        return wrapped;
-    };
+	return <T>(f?: (value: T) => void) => {
+		const wrapped = (error: Error | null, value: T | undefined) => {
+			if (!_.isNull(error)) {
+				done(error);
+			} else {
+				if (_.isUndefined(f)) {
+					done();
+					return;
+				}
+				try {
+					f(value as T);
+					if (expectToBeCalledOnce) {
+						done();
+					}
+				} catch (err) {
+					done(err);
+				}
+			}
+		};
+		return wrapped;
+	};
 };
 
 export const assertNodeCallbackError = (done: DoneCallback, errMsg: string) => {
-    const wrapped = <T>(error: Error | null, value: T | undefined) => {
-        if (_.isNull(error)) {
-            done(new Error('Expected callback to receive an error'));
-        } else {
-            try {
-                expect(error.message).to.be.equal(errMsg);
-                done();
-            } catch (err) {
-                done(err);
-            }
-        }
-    };
-    return wrapped;
+	const wrapped = <T>(error: Error | null, value: T | undefined) => {
+		if (_.isNull(error)) {
+			done(new Error('Expected callback to receive an error'));
+		} else {
+			try {
+				expect(error.message).to.be.equal(errMsg);
+				done();
+			} catch (err) {
+				done(err);
+			}
+		}
+	};
+	return wrapped;
 };
diff --git a/packages/0x.js/test/utils/subproviders/empty_wallet_subprovider.ts b/packages/0x.js/test/utils/subproviders/empty_wallet_subprovider.ts
index 53f2be83d..466b0f350 100644
--- a/packages/0x.js/test/utils/subproviders/empty_wallet_subprovider.ts
+++ b/packages/0x.js/test/utils/subproviders/empty_wallet_subprovider.ts
@@ -6,22 +6,22 @@ import { JSONRPCPayload } from '../../../src/types';
  * Source: https://github.com/MetaMask/provider-engine/blob/master/subproviders/subprovider.js
  */
 export class EmptyWalletSubprovider {
-    // This method needs to be here to satisfy the interface but linter wants it to be static.
-    // tslint:disable-next-line:prefer-function-over-method
-    public handleRequest(payload: JSONRPCPayload, next: () => void, end: (err: Error | null, result: any) => void) {
-        switch (payload.method) {
-            case 'eth_accounts':
-                end(null, []);
-                return;
+	// This method needs to be here to satisfy the interface but linter wants it to be static.
+	// tslint:disable-next-line:prefer-function-over-method
+	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
-    // tslint:disable-next-line:prefer-function-over-method
-    public setEngine(engine: any) {
-        // noop
-    }
+			default:
+				next();
+				return;
+		}
+	}
+	// Required to implement this method despite not needing it for this subprovider
+	// tslint:disable-next-line:prefer-function-over-method
+	public setEngine(engine: any) {
+		// noop
+	}
 }
diff --git a/packages/0x.js/test/utils/subproviders/fake_gas_estimate_subprovider.ts b/packages/0x.js/test/utils/subproviders/fake_gas_estimate_subprovider.ts
index e1113a851..307bfb188 100644
--- a/packages/0x.js/test/utils/subproviders/fake_gas_estimate_subprovider.ts
+++ b/packages/0x.js/test/utils/subproviders/fake_gas_estimate_subprovider.ts
@@ -9,26 +9,26 @@ import { JSONRPCPayload } from '../../../src/types';
  * Source: https://github.com/MetaMask/provider-engine/blob/master/subproviders/subprovider.js
  */
 export class FakeGasEstimateSubprovider {
-    private _constantGasAmount: number;
-    constructor(constantGasAmount: number) {
-        this._constantGasAmount = constantGasAmount;
-    }
-    // This method needs to be here to satisfy the interface but linter wants it to be static.
-    // tslint:disable-next-line:prefer-function-over-method
-    public handleRequest(payload: JSONRPCPayload, next: () => void, end: (err: Error | null, result: any) => void) {
-        switch (payload.method) {
-            case 'eth_estimateGas':
-                end(null, this._constantGasAmount);
-                return;
+	private _constantGasAmount: number;
+	constructor(constantGasAmount: number) {
+		this._constantGasAmount = constantGasAmount;
+	}
+	// This method needs to be here to satisfy the interface but linter wants it to be static.
+	// tslint:disable-next-line:prefer-function-over-method
+	public handleRequest(payload: JSONRPCPayload, next: () => void, end: (err: Error | null, result: any) => void) {
+		switch (payload.method) {
+			case 'eth_estimateGas':
+				end(null, this._constantGasAmount);
+				return;
 
-            default:
-                next();
-                return;
-        }
-    }
-    // Required to implement this method despite not needing it for this subprovider
-    // tslint:disable-next-line:prefer-function-over-method
-    public setEngine(engine: any) {
-        // noop
-    }
+			default:
+				next();
+				return;
+		}
+	}
+	// Required to implement this method despite not needing it for this subprovider
+	// tslint:disable-next-line:prefer-function-over-method
+	public setEngine(engine: any) {
+		// noop
+	}
 }
diff --git a/packages/0x.js/test/utils/token_utils.ts b/packages/0x.js/test/utils/token_utils.ts
index d3fc22ff4..9cbefcf8e 100644
--- a/packages/0x.js/test/utils/token_utils.ts
+++ b/packages/0x.js/test/utils/token_utils.ts
@@ -6,28 +6,28 @@ const PROTOCOL_TOKEN_SYMBOL = 'ZRX';
 const WETH_TOKEN_SYMBOL = 'WETH';
 
 export class TokenUtils {
-    private _tokens: Token[];
-    constructor(tokens: Token[]) {
-        this._tokens = tokens;
-    }
-    public getProtocolTokenOrThrow(): Token {
-        const zrxToken = _.find(this._tokens, { symbol: PROTOCOL_TOKEN_SYMBOL });
-        if (_.isUndefined(zrxToken)) {
-            throw new Error(InternalZeroExError.ZrxNotInTokenRegistry);
-        }
-        return zrxToken;
-    }
-    public getWethTokenOrThrow(): Token {
-        const wethToken = _.find(this._tokens, { symbol: WETH_TOKEN_SYMBOL });
-        if (_.isUndefined(wethToken)) {
-            throw new Error(InternalZeroExError.WethNotInTokenRegistry);
-        }
-        return wethToken;
-    }
-    public getDummyTokens(): Token[] {
-        const dummyTokens = _.filter(this._tokens, token => {
-            return !_.includes([PROTOCOL_TOKEN_SYMBOL, WETH_TOKEN_SYMBOL], token.symbol);
-        });
-        return dummyTokens;
-    }
+	private _tokens: Token[];
+	constructor(tokens: Token[]) {
+		this._tokens = tokens;
+	}
+	public getProtocolTokenOrThrow(): Token {
+		const zrxToken = _.find(this._tokens, { symbol: PROTOCOL_TOKEN_SYMBOL });
+		if (_.isUndefined(zrxToken)) {
+			throw new Error(InternalZeroExError.ZrxNotInTokenRegistry);
+		}
+		return zrxToken;
+	}
+	public getWethTokenOrThrow(): Token {
+		const wethToken = _.find(this._tokens, { symbol: WETH_TOKEN_SYMBOL });
+		if (_.isUndefined(wethToken)) {
+			throw new Error(InternalZeroExError.WethNotInTokenRegistry);
+		}
+		return wethToken;
+	}
+	public getDummyTokens(): Token[] {
+		const dummyTokens = _.filter(this._tokens, token => {
+			return !_.includes([PROTOCOL_TOKEN_SYMBOL, WETH_TOKEN_SYMBOL], token.symbol);
+		});
+		return dummyTokens;
+	}
 }
diff --git a/packages/0x.js/test/utils/web3_factory.ts b/packages/0x.js/test/utils/web3_factory.ts
index 26c26e03d..640b96256 100644
--- a/packages/0x.js/test/utils/web3_factory.ts
+++ b/packages/0x.js/test/utils/web3_factory.ts
@@ -19,24 +19,24 @@ import { constants } from './constants';
 import * as Web3 from 'web3';
 
 export const web3Factory = {
-    create(hasAddresses: boolean = true): Web3 {
-        const provider = this.getRpcProvider(hasAddresses);
-        const web3 = new Web3();
-        web3.setProvider(provider);
-        return web3;
-    },
-    getRpcProvider(hasAddresses: boolean = true): Web3.Provider {
-        const provider = new ProviderEngine();
-        if (!hasAddresses) {
-            provider.addProvider(new EmptyWalletSubprovider());
-        }
-        provider.addProvider(new FakeGasEstimateSubprovider(constants.GAS_ESTIMATE));
-        provider.addProvider(
-            new RpcSubprovider({
-                rpcUrl: constants.RPC_URL,
-            }),
-        );
-        provider.start();
-        return provider;
-    },
+	create(hasAddresses: boolean = true): Web3 {
+		const provider = this.getRpcProvider(hasAddresses);
+		const web3 = new Web3();
+		web3.setProvider(provider);
+		return web3;
+	},
+	getRpcProvider(hasAddresses: boolean = true): Web3.Provider {
+		const provider = new ProviderEngine();
+		if (!hasAddresses) {
+			provider.addProvider(new EmptyWalletSubprovider());
+		}
+		provider.addProvider(new FakeGasEstimateSubprovider(constants.GAS_ESTIMATE));
+		provider.addProvider(
+			new RpcSubprovider({
+				rpcUrl: constants.RPC_URL,
+			}),
+		);
+		provider.start();
+		return provider;
+	},
 };
diff --git a/packages/0x.js/tsconfig.json b/packages/0x.js/tsconfig.json
index 117f51e83..0666fbd82 100644
--- a/packages/0x.js/tsconfig.json
+++ b/packages/0x.js/tsconfig.json
@@ -1,16 +1,16 @@
 {
-    "extends": "../../tsconfig",
-    "compilerOptions": {
-        "outDir": "lib",
-        "noImplicitThis": false
-    },
-    "include": [
-        "./src/**/*",
-        "./test/**/*",
-        "../../node_modules/types-bn/index.d.ts",
-        "../../node_modules/types-ethereumjs-util/index.d.ts",
-        "../../node_modules/web3-typescript-typings/index.d.ts",
-        "../../node_modules/chai-typescript-typings/index.d.ts",
-        "../../node_modules/chai-as-promised-typescript-typings/index.d.ts"
-    ]
+	"extends": "../../tsconfig",
+	"compilerOptions": {
+		"outDir": "lib",
+		"noImplicitThis": false
+	},
+	"include": [
+		"./src/**/*",
+		"./test/**/*",
+		"../../node_modules/types-bn/index.d.ts",
+		"../../node_modules/types-ethereumjs-util/index.d.ts",
+		"../../node_modules/web3-typescript-typings/index.d.ts",
+		"../../node_modules/chai-typescript-typings/index.d.ts",
+		"../../node_modules/chai-as-promised-typescript-typings/index.d.ts"
+	]
 }
diff --git a/packages/0x.js/tslint.json b/packages/0x.js/tslint.json
index ffaefe83a..e63054bfc 100644
--- a/packages/0x.js/tslint.json
+++ b/packages/0x.js/tslint.json
@@ -1,3 +1,3 @@
 {
-    "extends": ["@0xproject/tslint-config"]
+	"extends": ["@0xproject/tslint-config"]
 }
diff --git a/packages/abi-gen/package.json b/packages/abi-gen/package.json
index 31a0f7f55..58ee12220 100644
--- a/packages/abi-gen/package.json
+++ b/packages/abi-gen/package.json
@@ -1,48 +1,48 @@
 {
-    "name": "@0xproject/abi-gen",
-    "version": "0.1.4",
-    "description": "Generate contract wrappers from ABI and handlebars templates",
-    "main": "lib/index.js",
-    "types": "lib/index.d.ts",
-    "scripts": {
-        "lint": "tslint --project . 'src/**/*.ts'",
-        "clean": "shx rm -rf lib",
-        "build": "tsc"
-    },
-    "bin": {
-        "abi-gen": "lib/index.js"
-    },
-    "repository": {
-        "type": "git",
-        "url": "https://github.com/0xProject/0x.js.git"
-    },
-    "license": "Apache-2.0",
-    "bugs": {
-        "url": "https://github.com/0xProject/0x.js/issues"
-    },
-    "homepage": "https://github.com/0xProject/0x.js/packages/abi-gen/README.md",
-    "dependencies": {
-        "@0xproject/utils": "^0.2.2",
-        "chalk": "^2.3.0",
-        "glob": "^7.1.2",
-        "handlebars": "^4.0.11",
-        "lodash": "^4.17.4",
-        "mkdirp": "^0.5.1",
-        "to-snake-case": "^1.0.0",
-        "web3": "^0.20.0",
-        "yargs": "^10.0.3"
-    },
-    "devDependencies": {
-        "@0xproject/tslint-config": "^0.4.4",
-        "@types/glob": "^5.0.33",
-        "@types/handlebars": "^4.0.36",
-        "@types/mkdirp": "^0.5.1",
-        "@types/node": "^8.0.53",
-        "@types/yargs": "^10.0.0",
-        "npm-run-all": "^4.1.2",
-        "shx": "^0.2.2",
-        "tslint": "5.8.0",
-        "typescript": "~2.6.1",
-        "web3-typescript-typings": "^0.9.6"
-    }
+	"name": "@0xproject/abi-gen",
+	"version": "0.1.4",
+	"description": "Generate contract wrappers from ABI and handlebars templates",
+	"main": "lib/index.js",
+	"types": "lib/index.d.ts",
+	"scripts": {
+		"lint": "tslint --project . 'src/**/*.ts'",
+		"clean": "shx rm -rf lib",
+		"build": "tsc"
+	},
+	"bin": {
+		"abi-gen": "lib/index.js"
+	},
+	"repository": {
+		"type": "git",
+		"url": "https://github.com/0xProject/0x.js.git"
+	},
+	"license": "Apache-2.0",
+	"bugs": {
+		"url": "https://github.com/0xProject/0x.js/issues"
+	},
+	"homepage": "https://github.com/0xProject/0x.js/packages/abi-gen/README.md",
+	"dependencies": {
+		"@0xproject/utils": "^0.2.2",
+		"chalk": "^2.3.0",
+		"glob": "^7.1.2",
+		"handlebars": "^4.0.11",
+		"lodash": "^4.17.4",
+		"mkdirp": "^0.5.1",
+		"to-snake-case": "^1.0.0",
+		"web3": "^0.20.0",
+		"yargs": "^10.0.3"
+	},
+	"devDependencies": {
+		"@0xproject/tslint-config": "^0.4.4",
+		"@types/glob": "^5.0.33",
+		"@types/handlebars": "^4.0.36",
+		"@types/mkdirp": "^0.5.1",
+		"@types/node": "^8.0.53",
+		"@types/yargs": "^10.0.0",
+		"npm-run-all": "^4.1.2",
+		"shx": "^0.2.2",
+		"tslint": "5.8.0",
+		"typescript": "~2.6.1",
+		"web3-typescript-typings": "^0.9.6"
+	}
 }
diff --git a/packages/abi-gen/src/globals.d.ts b/packages/abi-gen/src/globals.d.ts
index 39df3f852..0b46f2c40 100644
--- a/packages/abi-gen/src/globals.d.ts
+++ b/packages/abi-gen/src/globals.d.ts
@@ -1,4 +1,4 @@
 declare function toSnakeCase(str: string): string;
 declare module 'to-snake-case' {
-    export = toSnakeCase;
+	export = toSnakeCase;
 }
diff --git a/packages/abi-gen/src/index.ts b/packages/abi-gen/src/index.ts
index 527af32b1..15d218711 100644
--- a/packages/abi-gen/src/index.ts
+++ b/packages/abi-gen/src/index.ts
@@ -20,91 +20,91 @@ const ABI_TYPE_EVENT = 'event';
 const MAIN_TEMPLATE_NAME = 'contract.mustache';
 
 const args = yargs
-    .option('abiGlob', {
-        describe: 'Glob pattern to search for ABI JSON files',
-        type: 'string',
-        demand: true,
-    })
-    .option('templates', {
-        describe: 'Folder where to search for templates',
-        type: 'string',
-        demand: true,
-    })
-    .option('output', {
-        describe: 'Folder where to put the output files',
-        type: 'string',
-        demand: true,
-    }).argv;
+	.option('abiGlob', {
+		describe: 'Glob pattern to search for ABI JSON files',
+		type: 'string',
+		demand: true,
+	})
+	.option('templates', {
+		describe: 'Folder where to search for templates',
+		type: 'string',
+		demand: true,
+	})
+	.option('output', {
+		describe: 'Folder where to put the output files',
+		type: 'string',
+		demand: true,
+	}).argv;
 
 function writeOutputFile(name: string, renderedTsCode: string): void {
-    const fileName = toSnakeCase(name);
-    const filePath = `${args.output}/${fileName}.ts`;
-    fs.writeFileSync(filePath, renderedTsCode);
-    utils.log(`Created: ${chalk.bold(filePath)}`);
+	const fileName = toSnakeCase(name);
+	const filePath = `${args.output}/${fileName}.ts`;
+	fs.writeFileSync(filePath, renderedTsCode);
+	utils.log(`Created: ${chalk.bold(filePath)}`);
 }
 
 Handlebars.registerHelper('parameterType', utils.solTypeToTsType.bind(utils, ParamKind.Input));
 Handlebars.registerHelper('returnType', utils.solTypeToTsType.bind(utils, ParamKind.Output));
 const partialTemplateFileNames = globSync(`${args.templates}/partials/**/*.mustache`);
 for (const partialTemplateFileName of partialTemplateFileNames) {
-    const namedContent = utils.getNamedContent(partialTemplateFileName);
-    Handlebars.registerPartial(namedContent.name, namedContent.content);
+	const namedContent = utils.getNamedContent(partialTemplateFileName);
+	Handlebars.registerPartial(namedContent.name, namedContent.content);
 }
 
 const mainTemplate = utils.getNamedContent(`${args.templates}/${MAIN_TEMPLATE_NAME}`);
 const template = Handlebars.compile<ContextData>(mainTemplate.content);
 const abiFileNames = globSync(args.abiGlob);
 if (_.isEmpty(abiFileNames)) {
-    utils.log(`${chalk.red(`No ABI files found.`)}`);
-    utils.log(`Please make sure you've passed the correct folder name and that the files have
+	utils.log(`${chalk.red(`No ABI files found.`)}`);
+	utils.log(`Please make sure you've passed the correct folder name and that the files have
                ${chalk.bold('*.json')} extensions`);
-    process.exit(1);
+	process.exit(1);
 } else {
-    utils.log(`Found ${chalk.green(`${abiFileNames.length}`)} ${chalk.bold('ABI')} files`);
-    mkdirp.sync(args.output);
+	utils.log(`Found ${chalk.green(`${abiFileNames.length}`)} ${chalk.bold('ABI')} files`);
+	mkdirp.sync(args.output);
 }
 for (const abiFileName of abiFileNames) {
-    const namedContent = utils.getNamedContent(abiFileName);
-    utils.log(`Processing: ${chalk.bold(namedContent.name)}...`);
-    const parsedContent = JSON.parse(namedContent.content);
-    const ABI = _.isArray(parsedContent)
-        ? parsedContent // ABI file
-        : parsedContent.abi; // Truffle contracts file
-    if (_.isUndefined(ABI)) {
-        utils.log(`${chalk.red(`ABI not found in ${abiFileName}.`)}`);
-        utils.log(`Please make sure your ABI file is either an array with ABI entries or an object with the abi key`);
-        process.exit(1);
-    }
+	const namedContent = utils.getNamedContent(abiFileName);
+	utils.log(`Processing: ${chalk.bold(namedContent.name)}...`);
+	const parsedContent = JSON.parse(namedContent.content);
+	const ABI = _.isArray(parsedContent)
+		? parsedContent // ABI file
+		: parsedContent.abi; // Truffle contracts file
+	if (_.isUndefined(ABI)) {
+		utils.log(`${chalk.red(`ABI not found in ${abiFileName}.`)}`);
+		utils.log(`Please make sure your ABI file is either an array with ABI entries or an object with the abi key`);
+		process.exit(1);
+	}
 
-    let ctor = ABI.find((abi: Web3.AbiDefinition) => abi.type === ABI_TYPE_CONSTRUCTOR) as Web3.ConstructorAbi;
-    if (_.isUndefined(ctor)) {
-        ctor = utils.getEmptyConstructor(); // The constructor exists, but it's implicit in JSON's ABI definition
-    }
+	let ctor = ABI.find((abi: Web3.AbiDefinition) => abi.type === ABI_TYPE_CONSTRUCTOR) as Web3.ConstructorAbi;
+	if (_.isUndefined(ctor)) {
+		ctor = utils.getEmptyConstructor(); // The constructor exists, but it's implicit in JSON's ABI definition
+	}
 
-    const methodAbis = ABI.filter((abi: Web3.AbiDefinition) => abi.type === ABI_TYPE_METHOD) as Web3.MethodAbi[];
-    const methodsData = _.map(methodAbis, methodAbi => {
-        _.map(methodAbi.inputs, input => {
-            if (_.isEmpty(input.name)) {
-                // Auto-generated getters don't have parameter names
-                input.name = 'index';
-            }
-        });
-        // This will make templates simpler
-        const methodData = {
-            ...methodAbi,
-            singleReturnValue: methodAbi.outputs.length === 1,
-        };
-        return methodData;
-    });
+	const methodAbis = ABI.filter((abi: Web3.AbiDefinition) => abi.type === ABI_TYPE_METHOD) as Web3.MethodAbi[];
+	const methodsData = _.map(methodAbis, methodAbi => {
+		_.map(methodAbi.inputs, input => {
+			if (_.isEmpty(input.name)) {
+				// Auto-generated getters don't have parameter names
+				input.name = 'index';
+			}
+		});
+		// This will make templates simpler
+		const methodData = {
+			...methodAbi,
+			singleReturnValue: methodAbi.outputs.length === 1,
+		};
+		return methodData;
+	});
 
-    const eventAbis = ABI.filter((abi: Web3.AbiDefinition) => abi.type === ABI_TYPE_EVENT) as Web3.EventAbi[];
+	const eventAbis = ABI.filter((abi: Web3.AbiDefinition) => abi.type === ABI_TYPE_EVENT) as Web3.EventAbi[];
 
-    const contextData = {
-        contractName: namedContent.name,
-        ctor,
-        methods: methodsData,
-        events: eventAbis,
-    };
-    const renderedTsCode = template(contextData);
-    writeOutputFile(namedContent.name, renderedTsCode);
+	const contextData = {
+		contractName: namedContent.name,
+		ctor,
+		methods: methodsData,
+		events: eventAbis,
+	};
+	const renderedTsCode = template(contextData);
+	writeOutputFile(namedContent.name, renderedTsCode);
 }
diff --git a/packages/abi-gen/src/types.ts b/packages/abi-gen/src/types.ts
index e82ab824b..413f94467 100644
--- a/packages/abi-gen/src/types.ts
+++ b/packages/abi-gen/src/types.ts
@@ -1,23 +1,23 @@
 import * as Web3 from 'web3';
 
 export enum ParamKind {
-    Input = 'input',
-    Output = 'output',
+	Input = 'input',
+	Output = 'output',
 }
 
 export enum AbiType {
-    Function = 'function',
-    Constructor = 'constructor',
-    Event = 'event',
-    Fallback = 'fallback',
+	Function = 'function',
+	Constructor = 'constructor',
+	Event = 'event',
+	Fallback = 'fallback',
 }
 
 export interface Method extends Web3.MethodAbi {
-    singleReturnValue: boolean;
+	singleReturnValue: boolean;
 }
 
 export interface ContextData {
-    contractName: string;
-    methods: Method[];
-    events: Web3.EventAbi[];
+	contractName: string;
+	methods: Method[];
+	events: Web3.EventAbi[];
 }
diff --git a/packages/abi-gen/src/utils.ts b/packages/abi-gen/src/utils.ts
index 14255643a..4e1216a77 100644
--- a/packages/abi-gen/src/utils.ts
+++ b/packages/abi-gen/src/utils.ts
@@ -6,68 +6,68 @@ import * as Web3 from 'web3';
 import { AbiType, ParamKind } from './types';
 
 export const utils = {
-    solTypeToTsType(paramKind: ParamKind, solType: string): string {
-        const trailingArrayRegex = /\[\d*\]$/;
-        if (solType.match(trailingArrayRegex)) {
-            const arrayItemSolType = solType.replace(trailingArrayRegex, '');
-            const arrayItemTsType = utils.solTypeToTsType(paramKind, arrayItemSolType);
-            const arrayTsType = utils.isUnionType(arrayItemTsType)
-                ? `Array<${arrayItemTsType}>`
-                : `${arrayItemTsType}[]`;
-            return arrayTsType;
-        } else {
-            const solTypeRegexToTsType = [
-                { regex: '^string$', tsType: 'string' },
-                { regex: '^address$', tsType: 'string' },
-                { regex: '^bool$', tsType: 'boolean' },
-                { regex: '^u?int\\d*$', tsType: 'BigNumber' },
-                { regex: '^bytes\\d*$', tsType: 'string' },
-            ];
-            if (paramKind === ParamKind.Input) {
-                // web3 allows to pass those an non-bignumbers and that's nice
-                // but it always returns stuff as BigNumbers
-                solTypeRegexToTsType.unshift({
-                    regex: '^u?int(8|16|32)?$',
-                    tsType: 'number|BigNumber',
-                });
-            }
-            for (const regexAndTxType of solTypeRegexToTsType) {
-                const { regex, tsType } = regexAndTxType;
-                if (solType.match(regex)) {
-                    return tsType;
-                }
-            }
-            throw new Error(`Unknown Solidity type found: ${solType}`);
-        }
-    },
-    isUnionType(tsType: string): boolean {
-        return tsType === 'number|BigNumber';
-    },
-    log(...args: any[]): void {
-        console.log(...args); // tslint:disable-line:no-console
-    },
-    getPartialNameFromFileName(filename: string): string {
-        const name = path.parse(filename).name;
-        return name;
-    },
-    getNamedContent(filename: string): { name: string; content: string } {
-        const name = utils.getPartialNameFromFileName(filename);
-        try {
-            const content = fs.readFileSync(filename).toString();
-            return {
-                name,
-                content,
-            };
-        } catch (err) {
-            throw new Error(`Failed to read ${filename}: ${err}`);
-        }
-    },
-    getEmptyConstructor(): Web3.ConstructorAbi {
-        return {
-            type: AbiType.Constructor,
-            stateMutability: 'nonpayable',
-            payable: false,
-            inputs: [],
-        };
-    },
+	solTypeToTsType(paramKind: ParamKind, solType: string): string {
+		const trailingArrayRegex = /\[\d*\]$/;
+		if (solType.match(trailingArrayRegex)) {
+			const arrayItemSolType = solType.replace(trailingArrayRegex, '');
+			const arrayItemTsType = utils.solTypeToTsType(paramKind, arrayItemSolType);
+			const arrayTsType = utils.isUnionType(arrayItemTsType)
+				? `Array<${arrayItemTsType}>`
+				: `${arrayItemTsType}[]`;
+			return arrayTsType;
+		} else {
+			const solTypeRegexToTsType = [
+				{ regex: '^string$', tsType: 'string' },
+				{ regex: '^address$', tsType: 'string' },
+				{ regex: '^bool$', tsType: 'boolean' },
+				{ regex: '^u?int\\d*$', tsType: 'BigNumber' },
+				{ regex: '^bytes\\d*$', tsType: 'string' },
+			];
+			if (paramKind === ParamKind.Input) {
+				// web3 allows to pass those an non-bignumbers and that's nice
+				// but it always returns stuff as BigNumbers
+				solTypeRegexToTsType.unshift({
+					regex: '^u?int(8|16|32)?$',
+					tsType: 'number|BigNumber',
+				});
+			}
+			for (const regexAndTxType of solTypeRegexToTsType) {
+				const { regex, tsType } = regexAndTxType;
+				if (solType.match(regex)) {
+					return tsType;
+				}
+			}
+			throw new Error(`Unknown Solidity type found: ${solType}`);
+		}
+	},
+	isUnionType(tsType: string): boolean {
+		return tsType === 'number|BigNumber';
+	},
+	log(...args: any[]): void {
+		console.log(...args); // tslint:disable-line:no-console
+	},
+	getPartialNameFromFileName(filename: string): string {
+		const name = path.parse(filename).name;
+		return name;
+	},
+	getNamedContent(filename: string): { name: string; content: string } {
+		const name = utils.getPartialNameFromFileName(filename);
+		try {
+			const content = fs.readFileSync(filename).toString();
+			return {
+				name,
+				content,
+			};
+		} catch (err) {
+			throw new Error(`Failed to read ${filename}: ${err}`);
+		}
+	},
+	getEmptyConstructor(): Web3.ConstructorAbi {
+		return {
+			type: AbiType.Constructor,
+			stateMutability: 'nonpayable',
+			payable: false,
+			inputs: [],
+		};
+	},
 };
diff --git a/packages/abi-gen/tsconfig.json b/packages/abi-gen/tsconfig.json
index 5e0c7c6d3..1f89fb820 100644
--- a/packages/abi-gen/tsconfig.json
+++ b/packages/abi-gen/tsconfig.json
@@ -1,7 +1,7 @@
 {
-    "extends": "../../tsconfig",
-    "compilerOptions": {
-        "outDir": "lib"
-    },
-    "include": ["./src/**/*", "./test/**/*", "../../node_modules/web3-typescript-typings/index.d.ts"]
+	"extends": "../../tsconfig",
+	"compilerOptions": {
+		"outDir": "lib"
+	},
+	"include": ["./src/**/*", "./test/**/*", "../../node_modules/web3-typescript-typings/index.d.ts"]
 }
diff --git a/packages/abi-gen/tslint.json b/packages/abi-gen/tslint.json
index ffaefe83a..e63054bfc 100644
--- a/packages/abi-gen/tslint.json
+++ b/packages/abi-gen/tslint.json
@@ -1,3 +1,3 @@
 {
-    "extends": ["@0xproject/tslint-config"]
+	"extends": ["@0xproject/tslint-config"]
 }
diff --git a/packages/assert/package.json b/packages/assert/package.json
index a2d195728..0e10b3384 100644
--- a/packages/assert/package.json
+++ b/packages/assert/package.json
@@ -1,45 +1,45 @@
 {
-    "name": "@0xproject/assert",
-    "version": "0.0.13",
-    "description": "Provides a standard way of performing type and schema validation across 0x projects",
-    "main": "lib/src/index.js",
-    "types": "lib/src/index.d.ts",
-    "scripts": {
-        "build": "tsc",
-        "clean": "shx rm -rf _bundles lib test_temp",
-        "lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'",
-        "run_mocha": "mocha lib/test/**/*_test.js",
-        "prepublishOnly": "run-p build",
-        "test": "run-s clean build run_mocha",
-        "test:circleci": "yarn test"
-    },
-    "license": "Apache-2.0",
-    "repository": {
-        "type": "git",
-        "url": "https://github.com/0xProject/0x.js.git"
-    },
-    "bugs": {
-        "url": "https://github.com/0xProject/0x.js/issues"
-    },
-    "homepage": "https://github.com/0xProject/0x.js/packages/assert/README.md",
-    "devDependencies": {
-        "@0xproject/tslint-config": "^0.4.4",
-        "@types/lodash": "^4.14.86",
-        "@types/mocha": "^2.2.42",
-        "@types/valid-url": "^1.0.2",
-        "chai": "^4.0.1",
-        "chai-typescript-typings": "^0.0.2",
-        "dirty-chai": "^2.0.1",
-        "mocha": "^4.0.1",
-        "npm-run-all": "^4.1.2",
-        "shx": "^0.2.2",
-        "tslint": "5.8.0",
-        "typescript": "~2.6.1"
-    },
-    "dependencies": {
-        "@0xproject/json-schemas": "^0.7.5",
-        "@0xproject/utils": "^0.2.2",
-        "lodash": "^4.17.4",
-        "valid-url": "^1.0.9"
-    }
+	"name": "@0xproject/assert",
+	"version": "0.0.13",
+	"description": "Provides a standard way of performing type and schema validation across 0x projects",
+	"main": "lib/src/index.js",
+	"types": "lib/src/index.d.ts",
+	"scripts": {
+		"build": "tsc",
+		"clean": "shx rm -rf _bundles lib test_temp",
+		"lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'",
+		"run_mocha": "mocha lib/test/**/*_test.js",
+		"prepublishOnly": "run-p build",
+		"test": "run-s clean build run_mocha",
+		"test:circleci": "yarn test"
+	},
+	"license": "Apache-2.0",
+	"repository": {
+		"type": "git",
+		"url": "https://github.com/0xProject/0x.js.git"
+	},
+	"bugs": {
+		"url": "https://github.com/0xProject/0x.js/issues"
+	},
+	"homepage": "https://github.com/0xProject/0x.js/packages/assert/README.md",
+	"devDependencies": {
+		"@0xproject/tslint-config": "^0.4.4",
+		"@types/lodash": "^4.14.86",
+		"@types/mocha": "^2.2.42",
+		"@types/valid-url": "^1.0.2",
+		"chai": "^4.0.1",
+		"chai-typescript-typings": "^0.0.2",
+		"dirty-chai": "^2.0.1",
+		"mocha": "^4.0.1",
+		"npm-run-all": "^4.1.2",
+		"shx": "^0.2.2",
+		"tslint": "5.8.0",
+		"typescript": "~2.6.1"
+	},
+	"dependencies": {
+		"@0xproject/json-schemas": "^0.7.5",
+		"@0xproject/utils": "^0.2.2",
+		"lodash": "^4.17.4",
+		"valid-url": "^1.0.9"
+	}
 }
diff --git a/packages/assert/src/index.ts b/packages/assert/src/index.ts
index 7ad574ec7..0578bd303 100644
--- a/packages/assert/src/index.ts
+++ b/packages/assert/src/index.ts
@@ -6,89 +6,89 @@ import * as validUrl from 'valid-url';
 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 isNegative = value.lessThan(0);
-        this.assert(!isNegative, `${variableName} cannot be a negative number, found value: ${value.toNumber()}`);
-        const hasDecimals = value.decimalPlaces() !== 0;
-        this.assert(
-            !hasDecimals,
-            `${variableName} should be in baseUnits (no decimals), found value: ${value.toNumber()}`,
-        );
-    },
-    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 {
-        this.assert(addressUtils.isAddress(value), this.typeAssertionMessage(variableName, 'ETHAddressHex', value));
-        this.assert(
-            addressUtils.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}`,
-        );
-    },
-    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: any): void {
-        const isWeb3Provider = _.isFunction(value.send) || _.isFunction(value.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}
+	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 isNegative = value.lessThan(0);
+		this.assert(!isNegative, `${variableName} cannot be a negative number, found value: ${value.toNumber()}`);
+		const hasDecimals = value.decimalPlaces() !== 0;
+		this.assert(
+			!hasDecimals,
+			`${variableName} should be in baseUnits (no decimals), found value: ${value.toNumber()}`,
+		);
+	},
+	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 {
+		this.assert(addressUtils.isAddress(value), this.typeAssertionMessage(variableName, 'ETHAddressHex', value));
+		this.assert(
+			addressUtils.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}`,
+		);
+	},
+	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: any): void {
+		const isWeb3Provider = _.isFunction(value.send) || _.isFunction(value.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);
-    },
-    isHttpUrl(variableName: string, value: any): void {
-        const isValidUrl = !_.isUndefined(validUrl.isWebUri(value));
-        this.assert(isValidUrl, this.typeAssertionMessage(variableName, 'http url', value));
-    },
-    isUri(variableName: string, value: any): void {
-        const isValidUri = !_.isUndefined(validUrl.isUri(value));
-        this.assert(isValidUri, this.typeAssertionMessage(variableName, 'uri', value));
-    },
-    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}`;
-    },
+		this.assert(!hasValidationErrors, msg);
+	},
+	isHttpUrl(variableName: string, value: any): void {
+		const isValidUrl = !_.isUndefined(validUrl.isWebUri(value));
+		this.assert(isValidUrl, this.typeAssertionMessage(variableName, 'http url', value));
+	},
+	isUri(variableName: string, value: any): void {
+		const isValidUri = !_.isUndefined(validUrl.isUri(value));
+		this.assert(isValidUri, this.typeAssertionMessage(variableName, 'uri', value));
+	},
+	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/packages/assert/test/assert_test.ts b/packages/assert/test/assert_test.ts
index b0fa398d6..0af493bda 100644
--- a/packages/assert/test/assert_test.ts
+++ b/packages/assert/test/assert_test.ts
@@ -11,243 +11,243 @@ chai.use(dirtyChai);
 const expect = chai.expect;
 
 describe('Assertions', () => {
-    const variableName = 'variable';
-    describe('#isBigNumber', () => {
-        it('should not throw for valid input', () => {
-            const validInputs = [new BigNumber(23), new BigNumber('45')];
-            validInputs.forEach(input => expect(assert.isBigNumber.bind(assert, variableName, input)).to.not.throw());
-        });
-        it('should throw for invalid input', () => {
-            const invalidInputs = ['test', 42, false, { random: 'test' }, undefined];
-            invalidInputs.forEach(input => expect(assert.isBigNumber.bind(assert, variableName, input)).to.throw());
-        });
-    });
-    describe('#isValidBaseUnitAmount', () => {
-        it('should not throw for valid input', () => {
-            const validInputs = [new BigNumber(23), new BigNumber('45000000')];
-            validInputs.forEach(input =>
-                expect(assert.isValidBaseUnitAmount.bind(assert, variableName, input)).to.not.throw(),
-            );
-        });
-        it('should throw for invalid input', () => {
-            const invalidInputs = [0, undefined, new BigNumber(3.145), 3.145, new BigNumber(-400)];
-            invalidInputs.forEach(input =>
-                expect(assert.isValidBaseUnitAmount.bind(assert, variableName, input)).to.throw(),
-            );
-        });
-    });
-    describe('#isString', () => {
-        it('should not throw for valid input', () => {
-            const validInputs = ['hello', 'goodbye'];
-            validInputs.forEach(input => expect(assert.isString.bind(assert, variableName, input)).to.not.throw());
-        });
-        it('should throw for invalid input', () => {
-            const invalidInputs = [42, false, { random: 'test' }, undefined, new BigNumber(45)];
-            invalidInputs.forEach(input => expect(assert.isString.bind(assert, variableName, input)).to.throw());
-        });
-    });
-    describe('#isFunction', () => {
-        it('should not throw for valid input', () => {
-            const validInputs = [BigNumber, assert.isString];
-            validInputs.forEach(input => expect(assert.isFunction.bind(assert, variableName, input)).to.not.throw());
-        });
-        it('should throw for invalid input', () => {
-            const invalidInputs = [42, false, { random: 'test' }, undefined, new BigNumber(45)];
-            invalidInputs.forEach(input => expect(assert.isFunction.bind(assert, variableName, input)).to.throw());
-        });
-    });
-    describe('#isHexString', () => {
-        it('should not throw for valid input', () => {
-            const validInputs = [
-                '0x61a3ed31B43c8780e905a260a35faefEc527be7516aa11c0256729b5b351bc33',
-                '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
-            ];
-            validInputs.forEach(input => expect(assert.isHexString.bind(assert, variableName, input)).to.not.throw());
-        });
-        it('should throw for invalid input', () => {
-            const invalidInputs = [
-                42,
-                false,
-                { random: 'test' },
-                undefined,
-                new BigNumber(45),
-                '0x61a3ed31B43c8780e905a260a35faYfEc527be7516aa11c0256729b5b351bc33',
-            ];
-            invalidInputs.forEach(input => expect(assert.isHexString.bind(assert, variableName, input)).to.throw());
-        });
-    });
-    describe('#isETHAddressHex', () => {
-        it('should not throw for valid input', () => {
-            const validInputs = [
-                '0x0000000000000000000000000000000000000000',
-                '0x6fffd0ae3f7d88c9b4925323f54c6e4b2918c5fd',
-                '0x12459c951127e0c374ff9105dda097662a027093',
-            ];
-            validInputs.forEach(input =>
-                expect(assert.isETHAddressHex.bind(assert, variableName, input)).to.not.throw(),
-            );
-        });
-        it('should throw for invalid input', () => {
-            const invalidInputs = [
-                42,
-                false,
-                { random: 'test' },
-                undefined,
-                new BigNumber(45),
-                '0x6FFFd0ae3f7d88c9b4925323f54c6e4b2918c5fd',
-                '0x6FFFd0ae3f7d88c9b4925323f54c6e4',
-            ];
-            invalidInputs.forEach(input => expect(assert.isETHAddressHex.bind(assert, variableName, input)).to.throw());
-        });
-    });
-    describe('#doesBelongToStringEnum', () => {
-        enum TestEnums {
-            Test1 = 'Test1',
-            Test2 = 'Test2',
-        }
-        it('should not throw for valid input', () => {
-            const validInputs = [TestEnums.Test1, TestEnums.Test2];
-            validInputs.forEach(input =>
-                expect(assert.doesBelongToStringEnum.bind(assert, variableName, input, TestEnums)).to.not.throw(),
-            );
-        });
-        it('should throw for invalid input', () => {
-            const invalidInputs = [42, false, { random: 'test' }, undefined, new BigNumber(45)];
-            invalidInputs.forEach(input =>
-                expect(assert.doesBelongToStringEnum.bind(assert, variableName, input, TestEnums)).to.throw(),
-            );
-        });
-    });
-    describe('#hasAtMostOneUniqueValue', () => {
-        const errorMsg = 'more than one unique value';
-        it('should not throw for valid input', () => {
-            const validInputs = [['hello'], ['goodbye', 'goodbye', 'goodbye']];
-            validInputs.forEach(input =>
-                expect(assert.hasAtMostOneUniqueValue.bind(assert, input, errorMsg)).to.not.throw(),
-            );
-        });
-        it('should throw for invalid input', () => {
-            const invalidInputs = [['hello', 'goodbye'], ['goodbye', 42, false, false]];
-            invalidInputs.forEach(input =>
-                expect(assert.hasAtMostOneUniqueValue.bind(assert, input, errorMsg)).to.throw(),
-            );
-        });
-    });
-    describe('#isNumber', () => {
-        it('should not throw for valid input', () => {
-            const validInputs = [42, 0, 21e42];
-            validInputs.forEach(input => expect(assert.isNumber.bind(assert, variableName, input)).to.not.throw());
-        });
-        it('should throw for invalid input', () => {
-            const invalidInputs = [false, { random: 'test' }, undefined, new BigNumber(45)];
-            invalidInputs.forEach(input => expect(assert.isNumber.bind(assert, variableName, input)).to.throw());
-        });
-    });
-    describe('#isBoolean', () => {
-        it('should not throw for valid input', () => {
-            const validInputs = [true, false];
-            validInputs.forEach(input => expect(assert.isBoolean.bind(assert, variableName, input)).to.not.throw());
-        });
-        it('should throw for invalid input', () => {
-            const invalidInputs = [42, { random: 'test' }, undefined, new BigNumber(45)];
-            invalidInputs.forEach(input => expect(assert.isBoolean.bind(assert, variableName, input)).to.throw());
-        });
-    });
-    describe('#isWeb3Provider', () => {
-        it('should not throw for valid input', () => {
-            const validInputs = [{ send: () => 45 }, { sendAsync: () => 45 }];
-            validInputs.forEach(input =>
-                expect(assert.isWeb3Provider.bind(assert, variableName, input)).to.not.throw(),
-            );
-        });
-        it('should throw for invalid input', () => {
-            const invalidInputs = [42, { random: 'test' }, undefined, new BigNumber(45)];
-            invalidInputs.forEach(input => expect(assert.isWeb3Provider.bind(assert, variableName, input)).to.throw());
-        });
-    });
-    describe('#doesConformToSchema', () => {
-        const schema = schemas.addressSchema;
-        it('should not throw for valid input', () => {
-            const validInputs = [
-                '0x6fffd0ae3f7d88c9b4925323f54c6e4b2918c5fd',
-                '0x12459c951127e0c374ff9105dda097662a027093',
-            ];
-            validInputs.forEach(input =>
-                expect(assert.doesConformToSchema.bind(assert, variableName, input, schema)).to.not.throw(),
-            );
-        });
-        it('should throw for invalid input', () => {
-            const invalidInputs = [42, { random: 'test' }, undefined, new BigNumber(45)];
-            invalidInputs.forEach(input =>
-                expect(assert.doesConformToSchema.bind(assert, variableName, input, schema)).to.throw(),
-            );
-        });
-    });
-    describe('#isHttpUrl', () => {
-        it('should not throw for valid input', () => {
-            const validInputs = [
-                'http://www.google.com',
-                'https://api.example-relayer.net',
-                'https://api.radarrelay.com/0x/v0/',
-                'https://zeroex.beta.radarrelay.com:8000/0x/v0/',
-            ];
-            validInputs.forEach(input => expect(assert.isHttpUrl.bind(assert, variableName, input)).to.not.throw());
-        });
-        it('should throw for invalid input', () => {
-            const invalidInputs = [
-                42,
-                { random: 'test' },
-                undefined,
-                new BigNumber(45),
-                'ws://www.api.example-relayer.net',
-                'www.google.com',
-                'api.example-relayer.net',
-                'user:password@api.example-relayer.net',
-                '//api.example-relayer.net',
-            ];
-            invalidInputs.forEach(input => expect(assert.isHttpUrl.bind(assert, variableName, input)).to.throw());
-        });
-    });
-    describe('#isUri', () => {
-        it('should not throw for valid input', () => {
-            const validInputs = [
-                'http://www.google.com',
-                'https://api.example-relayer.net',
-                'https://api.radarrelay.com/0x/v0/',
-                'https://zeroex.beta.radarrelay.com:8000/0x/v0/',
-                'ws://www.api.example-relayer.net',
-                'wss://www.api.example-relayer.net',
-                'user:password@api.example-relayer.net',
-            ];
-            validInputs.forEach(input => expect(assert.isUri.bind(assert, variableName, input)).to.not.throw());
-        });
-        it('should throw for invalid input', () => {
-            const invalidInputs = [
-                42,
-                { random: 'test' },
-                undefined,
-                new BigNumber(45),
-                'www.google.com',
-                'api.example-relayer.net',
-                '//api.example-relayer.net',
-            ];
-            invalidInputs.forEach(input => expect(assert.isUri.bind(assert, variableName, input)).to.throw());
-        });
-    });
-    describe('#assert', () => {
-        const assertMessage = 'assert not satisfied';
-        it('should not throw for valid input', () => {
-            expect(assert.assert.bind(assert, true, assertMessage)).to.not.throw();
-        });
-        it('should throw for invalid input', () => {
-            expect(assert.assert.bind(assert, false, assertMessage)).to.throw();
-        });
-    });
-    describe('#typeAssertionMessage', () => {
-        it('should render correct message', () => {
-            expect(assert.typeAssertionMessage('variable', 'string', 'number')).to.equal(
-                `Expected variable to be of type string, encountered: number`,
-            );
-        });
-    });
+	const variableName = 'variable';
+	describe('#isBigNumber', () => {
+		it('should not throw for valid input', () => {
+			const validInputs = [new BigNumber(23), new BigNumber('45')];
+			validInputs.forEach(input => expect(assert.isBigNumber.bind(assert, variableName, input)).to.not.throw());
+		});
+		it('should throw for invalid input', () => {
+			const invalidInputs = ['test', 42, false, { random: 'test' }, undefined];
+			invalidInputs.forEach(input => expect(assert.isBigNumber.bind(assert, variableName, input)).to.throw());
+		});
+	});
+	describe('#isValidBaseUnitAmount', () => {
+		it('should not throw for valid input', () => {
+			const validInputs = [new BigNumber(23), new BigNumber('45000000')];
+			validInputs.forEach(input =>
+				expect(assert.isValidBaseUnitAmount.bind(assert, variableName, input)).to.not.throw(),
+			);
+		});
+		it('should throw for invalid input', () => {
+			const invalidInputs = [0, undefined, new BigNumber(3.145), 3.145, new BigNumber(-400)];
+			invalidInputs.forEach(input =>
+				expect(assert.isValidBaseUnitAmount.bind(assert, variableName, input)).to.throw(),
+			);
+		});
+	});
+	describe('#isString', () => {
+		it('should not throw for valid input', () => {
+			const validInputs = ['hello', 'goodbye'];
+			validInputs.forEach(input => expect(assert.isString.bind(assert, variableName, input)).to.not.throw());
+		});
+		it('should throw for invalid input', () => {
+			const invalidInputs = [42, false, { random: 'test' }, undefined, new BigNumber(45)];
+			invalidInputs.forEach(input => expect(assert.isString.bind(assert, variableName, input)).to.throw());
+		});
+	});
+	describe('#isFunction', () => {
+		it('should not throw for valid input', () => {
+			const validInputs = [BigNumber, assert.isString];
+			validInputs.forEach(input => expect(assert.isFunction.bind(assert, variableName, input)).to.not.throw());
+		});
+		it('should throw for invalid input', () => {
+			const invalidInputs = [42, false, { random: 'test' }, undefined, new BigNumber(45)];
+			invalidInputs.forEach(input => expect(assert.isFunction.bind(assert, variableName, input)).to.throw());
+		});
+	});
+	describe('#isHexString', () => {
+		it('should not throw for valid input', () => {
+			const validInputs = [
+				'0x61a3ed31B43c8780e905a260a35faefEc527be7516aa11c0256729b5b351bc33',
+				'0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
+			];
+			validInputs.forEach(input => expect(assert.isHexString.bind(assert, variableName, input)).to.not.throw());
+		});
+		it('should throw for invalid input', () => {
+			const invalidInputs = [
+				42,
+				false,
+				{ random: 'test' },
+				undefined,
+				new BigNumber(45),
+				'0x61a3ed31B43c8780e905a260a35faYfEc527be7516aa11c0256729b5b351bc33',
+			];
+			invalidInputs.forEach(input => expect(assert.isHexString.bind(assert, variableName, input)).to.throw());
+		});
+	});
+	describe('#isETHAddressHex', () => {
+		it('should not throw for valid input', () => {
+			const validInputs = [
+				'0x0000000000000000000000000000000000000000',
+				'0x6fffd0ae3f7d88c9b4925323f54c6e4b2918c5fd',
+				'0x12459c951127e0c374ff9105dda097662a027093',
+			];
+			validInputs.forEach(input =>
+				expect(assert.isETHAddressHex.bind(assert, variableName, input)).to.not.throw(),
+			);
+		});
+		it('should throw for invalid input', () => {
+			const invalidInputs = [
+				42,
+				false,
+				{ random: 'test' },
+				undefined,
+				new BigNumber(45),
+				'0x6FFFd0ae3f7d88c9b4925323f54c6e4b2918c5fd',
+				'0x6FFFd0ae3f7d88c9b4925323f54c6e4',
+			];
+			invalidInputs.forEach(input => expect(assert.isETHAddressHex.bind(assert, variableName, input)).to.throw());
+		});
+	});
+	describe('#doesBelongToStringEnum', () => {
+		enum TestEnums {
+			Test1 = 'Test1',
+			Test2 = 'Test2',
+		}
+		it('should not throw for valid input', () => {
+			const validInputs = [TestEnums.Test1, TestEnums.Test2];
+			validInputs.forEach(input =>
+				expect(assert.doesBelongToStringEnum.bind(assert, variableName, input, TestEnums)).to.not.throw(),
+			);
+		});
+		it('should throw for invalid input', () => {
+			const invalidInputs = [42, false, { random: 'test' }, undefined, new BigNumber(45)];
+			invalidInputs.forEach(input =>
+				expect(assert.doesBelongToStringEnum.bind(assert, variableName, input, TestEnums)).to.throw(),
+			);
+		});
+	});
+	describe('#hasAtMostOneUniqueValue', () => {
+		const errorMsg = 'more than one unique value';
+		it('should not throw for valid input', () => {
+			const validInputs = [['hello'], ['goodbye', 'goodbye', 'goodbye']];
+			validInputs.forEach(input =>
+				expect(assert.hasAtMostOneUniqueValue.bind(assert, input, errorMsg)).to.not.throw(),
+			);
+		});
+		it('should throw for invalid input', () => {
+			const invalidInputs = [['hello', 'goodbye'], ['goodbye', 42, false, false]];
+			invalidInputs.forEach(input =>
+				expect(assert.hasAtMostOneUniqueValue.bind(assert, input, errorMsg)).to.throw(),
+			);
+		});
+	});
+	describe('#isNumber', () => {
+		it('should not throw for valid input', () => {
+			const validInputs = [42, 0, 21e42];
+			validInputs.forEach(input => expect(assert.isNumber.bind(assert, variableName, input)).to.not.throw());
+		});
+		it('should throw for invalid input', () => {
+			const invalidInputs = [false, { random: 'test' }, undefined, new BigNumber(45)];
+			invalidInputs.forEach(input => expect(assert.isNumber.bind(assert, variableName, input)).to.throw());
+		});
+	});
+	describe('#isBoolean', () => {
+		it('should not throw for valid input', () => {
+			const validInputs = [true, false];
+			validInputs.forEach(input => expect(assert.isBoolean.bind(assert, variableName, input)).to.not.throw());
+		});
+		it('should throw for invalid input', () => {
+			const invalidInputs = [42, { random: 'test' }, undefined, new BigNumber(45)];
+			invalidInputs.forEach(input => expect(assert.isBoolean.bind(assert, variableName, input)).to.throw());
+		});
+	});
+	describe('#isWeb3Provider', () => {
+		it('should not throw for valid input', () => {
+			const validInputs = [{ send: () => 45 }, { sendAsync: () => 45 }];
+			validInputs.forEach(input =>
+				expect(assert.isWeb3Provider.bind(assert, variableName, input)).to.not.throw(),
+			);
+		});
+		it('should throw for invalid input', () => {
+			const invalidInputs = [42, { random: 'test' }, undefined, new BigNumber(45)];
+			invalidInputs.forEach(input => expect(assert.isWeb3Provider.bind(assert, variableName, input)).to.throw());
+		});
+	});
+	describe('#doesConformToSchema', () => {
+		const schema = schemas.addressSchema;
+		it('should not throw for valid input', () => {
+			const validInputs = [
+				'0x6fffd0ae3f7d88c9b4925323f54c6e4b2918c5fd',
+				'0x12459c951127e0c374ff9105dda097662a027093',
+			];
+			validInputs.forEach(input =>
+				expect(assert.doesConformToSchema.bind(assert, variableName, input, schema)).to.not.throw(),
+			);
+		});
+		it('should throw for invalid input', () => {
+			const invalidInputs = [42, { random: 'test' }, undefined, new BigNumber(45)];
+			invalidInputs.forEach(input =>
+				expect(assert.doesConformToSchema.bind(assert, variableName, input, schema)).to.throw(),
+			);
+		});
+	});
+	describe('#isHttpUrl', () => {
+		it('should not throw for valid input', () => {
+			const validInputs = [
+				'http://www.google.com',
+				'https://api.example-relayer.net',
+				'https://api.radarrelay.com/0x/v0/',
+				'https://zeroex.beta.radarrelay.com:8000/0x/v0/',
+			];
+			validInputs.forEach(input => expect(assert.isHttpUrl.bind(assert, variableName, input)).to.not.throw());
+		});
+		it('should throw for invalid input', () => {
+			const invalidInputs = [
+				42,
+				{ random: 'test' },
+				undefined,
+				new BigNumber(45),
+				'ws://www.api.example-relayer.net',
+				'www.google.com',
+				'api.example-relayer.net',
+				'user:password@api.example-relayer.net',
+				'//api.example-relayer.net',
+			];
+			invalidInputs.forEach(input => expect(assert.isHttpUrl.bind(assert, variableName, input)).to.throw());
+		});
+	});
+	describe('#isUri', () => {
+		it('should not throw for valid input', () => {
+			const validInputs = [
+				'http://www.google.com',
+				'https://api.example-relayer.net',
+				'https://api.radarrelay.com/0x/v0/',
+				'https://zeroex.beta.radarrelay.com:8000/0x/v0/',
+				'ws://www.api.example-relayer.net',
+				'wss://www.api.example-relayer.net',
+				'user:password@api.example-relayer.net',
+			];
+			validInputs.forEach(input => expect(assert.isUri.bind(assert, variableName, input)).to.not.throw());
+		});
+		it('should throw for invalid input', () => {
+			const invalidInputs = [
+				42,
+				{ random: 'test' },
+				undefined,
+				new BigNumber(45),
+				'www.google.com',
+				'api.example-relayer.net',
+				'//api.example-relayer.net',
+			];
+			invalidInputs.forEach(input => expect(assert.isUri.bind(assert, variableName, input)).to.throw());
+		});
+	});
+	describe('#assert', () => {
+		const assertMessage = 'assert not satisfied';
+		it('should not throw for valid input', () => {
+			expect(assert.assert.bind(assert, true, assertMessage)).to.not.throw();
+		});
+		it('should throw for invalid input', () => {
+			expect(assert.assert.bind(assert, false, assertMessage)).to.throw();
+		});
+	});
+	describe('#typeAssertionMessage', () => {
+		it('should render correct message', () => {
+			expect(assert.typeAssertionMessage('variable', 'string', 'number')).to.equal(
+				`Expected variable to be of type string, encountered: number`,
+			);
+		});
+	});
 });
diff --git a/packages/assert/tsconfig.json b/packages/assert/tsconfig.json
index 88a467ccb..8314a9459 100644
--- a/packages/assert/tsconfig.json
+++ b/packages/assert/tsconfig.json
@@ -1,7 +1,7 @@
 {
-    "extends": "../../tsconfig",
-    "compilerOptions": {
-        "outDir": "lib"
-    },
-    "include": ["./src/**/*", "./test/**/*", "../../node_modules/chai-typescript-typings/index.d.ts"]
+	"extends": "../../tsconfig",
+	"compilerOptions": {
+		"outDir": "lib"
+	},
+	"include": ["./src/**/*", "./test/**/*", "../../node_modules/chai-typescript-typings/index.d.ts"]
 }
diff --git a/packages/assert/tslint.json b/packages/assert/tslint.json
index ffaefe83a..e63054bfc 100644
--- a/packages/assert/tslint.json
+++ b/packages/assert/tslint.json
@@ -1,3 +1,3 @@
 {
-    "extends": ["@0xproject/tslint-config"]
+	"extends": ["@0xproject/tslint-config"]
 }
diff --git a/packages/chai-as-promised-typescript-typings/index.d.ts b/packages/chai-as-promised-typescript-typings/index.d.ts
index ba6dabdcc..389a076c6 100644
--- a/packages/chai-as-promised-typescript-typings/index.d.ts
+++ b/packages/chai-as-promised-typescript-typings/index.d.ts
@@ -4,265 +4,265 @@
 // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
 
 declare module 'chai-as-promised' {
-    function chaiAsPromised(chai: any, utils: any): void;
-    namespace chaiAsPromised {
+	function chaiAsPromised(chai: any, utils: any): void;
+	namespace chaiAsPromised {
 
-    }
-    export = chaiAsPromised;
+	}
+	export = chaiAsPromised;
 }
 
 // tslint:disable:no-namespace ban-types member-ordering
 declare namespace Chai {
-    // For BDD API
-    interface Assertion extends LanguageChains, NumericComparison, TypeComparison {
-        eventually: PromisedAssertion;
-        fulfilled: PromisedAssertion;
-        become(expected: any): PromisedAssertion;
-        rejected(): PromisedAssertion;
-        rejectedWith(expected: any, message?: string | RegExp): PromisedAssertion;
-        notify(fn: Function): PromisedAssertion;
-    }
-
-    // Eventually does not have .then(), but PromisedAssertion have.
-    interface Eventually extends PromisedLanguageChains, PromisedNumericComparison, PromisedTypeComparison {
-        // From chai-as-promised
-        become(expected: PromiseLike<any>): PromisedAssertion;
-        fulfilled: PromisedAssertion;
-        rejected: () => PromisedAssertion;
-        rejectedWith(expected: any, message?: string | RegExp): PromisedAssertion;
-        notify(fn: Function): PromisedAssertion;
-
-        // From chai
-        not: PromisedAssertion;
-        deep: PromisedDeep;
-        all: PromisedKeyFilter;
-        a: PromisedTypeComparison;
-        an: PromisedTypeComparison;
-        include: PromisedInclude;
-        contain: PromisedInclude;
-        ok: PromisedAssertion;
-        true: () => PromisedAssertion;
-        false: () => PromisedAssertion;
-        null: PromisedAssertion;
-        undefined: PromisedAssertion;
-        exist: PromisedAssertion;
-        empty: PromisedAssertion;
-        arguments: PromisedAssertion;
-        Arguments: PromisedAssertion;
-        equal: PromisedEqual;
-        equals: PromisedEqual;
-        eq: PromisedEqual;
-        eql: PromisedEqual;
-        eqls: PromisedEqual;
-        property: PromisedProperty;
-        ownProperty: PromisedOwnProperty;
-        haveOwnProperty: PromisedOwnProperty;
-        length: PromisedLength;
-        lengthOf: PromisedLength;
-        match(regexp: RegExp | string, message?: string): PromisedAssertion;
-        string(string: string, message?: string): PromisedAssertion;
-        keys: PromisedKeys;
-        key(string: string): PromisedAssertion;
-        throw: PromisedThrow;
-        throws: PromisedThrow;
-        Throw: PromisedThrow;
-        respondTo(method: string, message?: string): PromisedAssertion;
-        itself: PromisedAssertion;
-        satisfy(matcher: Function, message?: string): PromisedAssertion;
-        closeTo(expected: number, delta: number, message?: string): PromisedAssertion;
-        members: PromisedMembers;
-    }
-
-    interface PromisedAssertion extends Eventually, PromiseLike<any> {}
-
-    interface PromisedLanguageChains {
-        eventually: Eventually;
-
-        // From chai
-        to: PromisedAssertion;
-        be: PromisedAssertion;
-        been: PromisedAssertion;
-        is: PromisedAssertion;
-        that: PromisedAssertion;
-        which: PromisedAssertion;
-        and: PromisedAssertion;
-        has: PromisedAssertion;
-        have: PromisedAssertion;
-        with: PromisedAssertion;
-        at: PromisedAssertion;
-        of: PromisedAssertion;
-        same: PromisedAssertion;
-    }
-
-    interface PromisedNumericComparison {
-        above: PromisedNumberComparer;
-        gt: PromisedNumberComparer;
-        greaterThan: PromisedNumberComparer;
-        least: PromisedNumberComparer;
-        gte: PromisedNumberComparer;
-        below: PromisedNumberComparer;
-        lt: PromisedNumberComparer;
-        lessThan: PromisedNumberComparer;
-        most: PromisedNumberComparer;
-        lte: PromisedNumberComparer;
-        within(start: number, finish: number, message?: string): PromisedAssertion;
-    }
-
-    type PromisedNumberComparer = (value: number, message?: string) => PromisedAssertion;
-
-    interface PromisedTypeComparison {
-        (type: string, message?: string): PromisedAssertion;
-        instanceof: PromisedInstanceOf;
-        instanceOf: PromisedInstanceOf;
-    }
-
-    type PromisedInstanceOf = (constructor: Object, message?: string) => PromisedAssertion;
-
-    interface PromisedDeep {
-        equal: PromisedEqual;
-        include: PromisedInclude;
-        property: PromisedProperty;
-    }
-
-    interface PromisedKeyFilter {
-        keys: PromisedKeys;
-    }
-
-    type PromisedEqual = (value: any, message?: string) => PromisedAssertion;
-
-    type PromisedProperty = (name: string, value?: any, message?: string) => PromisedAssertion;
-
-    type PromisedOwnProperty = (name: string, message?: string) => PromisedAssertion;
-
-    interface PromisedLength extends PromisedLanguageChains, PromisedNumericComparison {
-        (length: number, message?: string): PromisedAssertion;
-    }
-
-    interface PromisedInclude {
-        (value: Object | string | number, message?: string): PromisedAssertion;
-        keys: PromisedKeys;
-        members: PromisedMembers;
-        all: PromisedKeyFilter;
-    }
-
-    interface PromisedKeys {
-        (...keys: string[]): PromisedAssertion;
-        (keys: any[]): PromisedAssertion;
-    }
-
-    interface PromisedThrow {
-        (): PromisedAssertion;
-        (expected: string | RegExp, message?: string): PromisedAssertion;
-        (constructor: Error | Function, expected?: string | RegExp, message?: string): PromisedAssertion;
-    }
-
-    type PromisedMembers = (set: any[], message?: string) => PromisedAssertion;
-
-    // For Assert API
-    interface Assert {
-        eventually: PromisedAssert;
-        isFulfilled(promise: PromiseLike<any>, message?: string): PromiseLike<void>;
-        becomes(promise: PromiseLike<any>, expected: any, message?: string): PromiseLike<void>;
-        doesNotBecome(promise: PromiseLike<any>, expected: any, message?: string): PromiseLike<void>;
-        isRejected(promise: PromiseLike<any>, message?: string): PromiseLike<void>;
-        isRejected(promise: PromiseLike<any>, expected: any | RegExp, message?: string): PromiseLike<void>;
-        notify(fn: Function): PromiseLike<void>;
-    }
-
-    export interface PromisedAssert {
-        fail(actual?: any, expected?: any, msg?: string, operator?: string): PromiseLike<void>;
-
-        ok(val: any, msg?: string): PromiseLike<void>;
-        notOk(val: any, msg?: string): PromiseLike<void>;
-
-        equal(act: any, exp: any, msg?: string): PromiseLike<void>;
-        notEqual(act: any, exp: any, msg?: string): PromiseLike<void>;
-
-        strictEqual(act: any, exp: any, msg?: string): PromiseLike<void>;
-        notStrictEqual(act: any, exp: any, msg?: string): PromiseLike<void>;
-
-        deepEqual(act: any, exp: any, msg?: string): PromiseLike<void>;
-        notDeepEqual(act: any, exp: any, msg?: string): PromiseLike<void>;
-
-        isTrue(val: any, msg?: string): PromiseLike<void>;
-        isFalse(val: any, msg?: string): PromiseLike<void>;
+	// For BDD API
+	interface Assertion extends LanguageChains, NumericComparison, TypeComparison {
+		eventually: PromisedAssertion;
+		fulfilled: PromisedAssertion;
+		become(expected: any): PromisedAssertion;
+		rejected(): PromisedAssertion;
+		rejectedWith(expected: any, message?: string | RegExp): PromisedAssertion;
+		notify(fn: Function): PromisedAssertion;
+	}
+
+	// Eventually does not have .then(), but PromisedAssertion have.
+	interface Eventually extends PromisedLanguageChains, PromisedNumericComparison, PromisedTypeComparison {
+		// From chai-as-promised
+		become(expected: PromiseLike<any>): PromisedAssertion;
+		fulfilled: PromisedAssertion;
+		rejected: () => PromisedAssertion;
+		rejectedWith(expected: any, message?: string | RegExp): PromisedAssertion;
+		notify(fn: Function): PromisedAssertion;
+
+		// From chai
+		not: PromisedAssertion;
+		deep: PromisedDeep;
+		all: PromisedKeyFilter;
+		a: PromisedTypeComparison;
+		an: PromisedTypeComparison;
+		include: PromisedInclude;
+		contain: PromisedInclude;
+		ok: PromisedAssertion;
+		true: () => PromisedAssertion;
+		false: () => PromisedAssertion;
+		null: PromisedAssertion;
+		undefined: PromisedAssertion;
+		exist: PromisedAssertion;
+		empty: PromisedAssertion;
+		arguments: PromisedAssertion;
+		Arguments: PromisedAssertion;
+		equal: PromisedEqual;
+		equals: PromisedEqual;
+		eq: PromisedEqual;
+		eql: PromisedEqual;
+		eqls: PromisedEqual;
+		property: PromisedProperty;
+		ownProperty: PromisedOwnProperty;
+		haveOwnProperty: PromisedOwnProperty;
+		length: PromisedLength;
+		lengthOf: PromisedLength;
+		match(regexp: RegExp | string, message?: string): PromisedAssertion;
+		string(string: string, message?: string): PromisedAssertion;
+		keys: PromisedKeys;
+		key(string: string): PromisedAssertion;
+		throw: PromisedThrow;
+		throws: PromisedThrow;
+		Throw: PromisedThrow;
+		respondTo(method: string, message?: string): PromisedAssertion;
+		itself: PromisedAssertion;
+		satisfy(matcher: Function, message?: string): PromisedAssertion;
+		closeTo(expected: number, delta: number, message?: string): PromisedAssertion;
+		members: PromisedMembers;
+	}
+
+	interface PromisedAssertion extends Eventually, PromiseLike<any> {}
+
+	interface PromisedLanguageChains {
+		eventually: Eventually;
+
+		// From chai
+		to: PromisedAssertion;
+		be: PromisedAssertion;
+		been: PromisedAssertion;
+		is: PromisedAssertion;
+		that: PromisedAssertion;
+		which: PromisedAssertion;
+		and: PromisedAssertion;
+		has: PromisedAssertion;
+		have: PromisedAssertion;
+		with: PromisedAssertion;
+		at: PromisedAssertion;
+		of: PromisedAssertion;
+		same: PromisedAssertion;
+	}
+
+	interface PromisedNumericComparison {
+		above: PromisedNumberComparer;
+		gt: PromisedNumberComparer;
+		greaterThan: PromisedNumberComparer;
+		least: PromisedNumberComparer;
+		gte: PromisedNumberComparer;
+		below: PromisedNumberComparer;
+		lt: PromisedNumberComparer;
+		lessThan: PromisedNumberComparer;
+		most: PromisedNumberComparer;
+		lte: PromisedNumberComparer;
+		within(start: number, finish: number, message?: string): PromisedAssertion;
+	}
+
+	type PromisedNumberComparer = (value: number, message?: string) => PromisedAssertion;
+
+	interface PromisedTypeComparison {
+		(type: string, message?: string): PromisedAssertion;
+		instanceof: PromisedInstanceOf;
+		instanceOf: PromisedInstanceOf;
+	}
+
+	type PromisedInstanceOf = (constructor: Object, message?: string) => PromisedAssertion;
+
+	interface PromisedDeep {
+		equal: PromisedEqual;
+		include: PromisedInclude;
+		property: PromisedProperty;
+	}
+
+	interface PromisedKeyFilter {
+		keys: PromisedKeys;
+	}
+
+	type PromisedEqual = (value: any, message?: string) => PromisedAssertion;
+
+	type PromisedProperty = (name: string, value?: any, message?: string) => PromisedAssertion;
+
+	type PromisedOwnProperty = (name: string, message?: string) => PromisedAssertion;
+
+	interface PromisedLength extends PromisedLanguageChains, PromisedNumericComparison {
+		(length: number, message?: string): PromisedAssertion;
+	}
+
+	interface PromisedInclude {
+		(value: Object | string | number, message?: string): PromisedAssertion;
+		keys: PromisedKeys;
+		members: PromisedMembers;
+		all: PromisedKeyFilter;
+	}
+
+	interface PromisedKeys {
+		(...keys: string[]): PromisedAssertion;
+		(keys: any[]): PromisedAssertion;
+	}
+
+	interface PromisedThrow {
+		(): PromisedAssertion;
+		(expected: string | RegExp, message?: string): PromisedAssertion;
+		(constructor: Error | Function, expected?: string | RegExp, message?: string): PromisedAssertion;
+	}
+
+	type PromisedMembers = (set: any[], message?: string) => PromisedAssertion;
+
+	// For Assert API
+	interface Assert {
+		eventually: PromisedAssert;
+		isFulfilled(promise: PromiseLike<any>, message?: string): PromiseLike<void>;
+		becomes(promise: PromiseLike<any>, expected: any, message?: string): PromiseLike<void>;
+		doesNotBecome(promise: PromiseLike<any>, expected: any, message?: string): PromiseLike<void>;
+		isRejected(promise: PromiseLike<any>, message?: string): PromiseLike<void>;
+		isRejected(promise: PromiseLike<any>, expected: any | RegExp, message?: string): PromiseLike<void>;
+		notify(fn: Function): PromiseLike<void>;
+	}
+
+	export interface PromisedAssert {
+		fail(actual?: any, expected?: any, msg?: string, operator?: string): PromiseLike<void>;
+
+		ok(val: any, msg?: string): PromiseLike<void>;
+		notOk(val: any, msg?: string): PromiseLike<void>;
+
+		equal(act: any, exp: any, msg?: string): PromiseLike<void>;
+		notEqual(act: any, exp: any, msg?: string): PromiseLike<void>;
+
+		strictEqual(act: any, exp: any, msg?: string): PromiseLike<void>;
+		notStrictEqual(act: any, exp: any, msg?: string): PromiseLike<void>;
+
+		deepEqual(act: any, exp: any, msg?: string): PromiseLike<void>;
+		notDeepEqual(act: any, exp: any, msg?: string): PromiseLike<void>;
+
+		isTrue(val: any, msg?: string): PromiseLike<void>;
+		isFalse(val: any, msg?: string): PromiseLike<void>;
 
-        isNull(val: any, msg?: string): PromiseLike<void>;
-        isNotNull(val: any, msg?: string): PromiseLike<void>;
+		isNull(val: any, msg?: string): PromiseLike<void>;
+		isNotNull(val: any, msg?: string): PromiseLike<void>;
 
-        isUndefined(val: any, msg?: string): PromiseLike<void>;
-        isDefined(val: any, msg?: string): PromiseLike<void>;
+		isUndefined(val: any, msg?: string): PromiseLike<void>;
+		isDefined(val: any, msg?: string): PromiseLike<void>;
 
-        isFunction(val: any, msg?: string): PromiseLike<void>;
-        isNotFunction(val: any, msg?: string): PromiseLike<void>;
+		isFunction(val: any, msg?: string): PromiseLike<void>;
+		isNotFunction(val: any, msg?: string): PromiseLike<void>;
 
-        isObject(val: any, msg?: string): PromiseLike<void>;
-        isNotObject(val: any, msg?: string): PromiseLike<void>;
+		isObject(val: any, msg?: string): PromiseLike<void>;
+		isNotObject(val: any, msg?: string): PromiseLike<void>;
 
-        isArray(val: any, msg?: string): PromiseLike<void>;
-        isNotArray(val: any, msg?: string): PromiseLike<void>;
+		isArray(val: any, msg?: string): PromiseLike<void>;
+		isNotArray(val: any, msg?: string): PromiseLike<void>;
 
-        isString(val: any, msg?: string): PromiseLike<void>;
-        isNotString(val: any, msg?: string): PromiseLike<void>;
+		isString(val: any, msg?: string): PromiseLike<void>;
+		isNotString(val: any, msg?: string): PromiseLike<void>;
 
-        isNumber(val: any, msg?: string): PromiseLike<void>;
-        isNotNumber(val: any, msg?: string): PromiseLike<void>;
+		isNumber(val: any, msg?: string): PromiseLike<void>;
+		isNotNumber(val: any, msg?: string): PromiseLike<void>;
 
-        isBoolean(val: any, msg?: string): PromiseLike<void>;
-        isNotBoolean(val: any, msg?: string): PromiseLike<void>;
+		isBoolean(val: any, msg?: string): PromiseLike<void>;
+		isNotBoolean(val: any, msg?: string): PromiseLike<void>;
 
-        typeOf(val: any, type: string, msg?: string): PromiseLike<void>;
-        notTypeOf(val: any, type: string, msg?: string): PromiseLike<void>;
+		typeOf(val: any, type: string, msg?: string): PromiseLike<void>;
+		notTypeOf(val: any, type: string, msg?: string): PromiseLike<void>;
 
-        instanceOf(val: any, type: Function, msg?: string): PromiseLike<void>;
-        notInstanceOf(val: any, type: Function, msg?: string): PromiseLike<void>;
+		instanceOf(val: any, type: Function, msg?: string): PromiseLike<void>;
+		notInstanceOf(val: any, type: Function, msg?: string): PromiseLike<void>;
 
-        include(exp: string | any[], inc: any, msg?: string): PromiseLike<void>;
+		include(exp: string | any[], inc: any, msg?: string): PromiseLike<void>;
 
-        notInclude(exp: string | any[], inc: any, msg?: string): PromiseLike<void>;
+		notInclude(exp: string | any[], inc: any, msg?: string): PromiseLike<void>;
 
-        match(exp: any, re: RegExp, msg?: string): PromiseLike<void>;
-        notMatch(exp: any, re: RegExp, msg?: string): PromiseLike<void>;
+		match(exp: any, re: RegExp, msg?: string): PromiseLike<void>;
+		notMatch(exp: any, re: RegExp, msg?: string): PromiseLike<void>;
 
-        property(obj: Object, prop: string, msg?: string): PromiseLike<void>;
-        notProperty(obj: Object, prop: string, msg?: string): PromiseLike<void>;
-        deepProperty(obj: Object, prop: string, msg?: string): PromiseLike<void>;
-        notDeepProperty(obj: Object, prop: string, msg?: string): PromiseLike<void>;
+		property(obj: Object, prop: string, msg?: string): PromiseLike<void>;
+		notProperty(obj: Object, prop: string, msg?: string): PromiseLike<void>;
+		deepProperty(obj: Object, prop: string, msg?: string): PromiseLike<void>;
+		notDeepProperty(obj: Object, prop: string, msg?: string): PromiseLike<void>;
 
-        propertyVal(obj: Object, prop: string, val: any, msg?: string): PromiseLike<void>;
-        propertyNotVal(obj: Object, prop: string, val: any, msg?: string): PromiseLike<void>;
+		propertyVal(obj: Object, prop: string, val: any, msg?: string): PromiseLike<void>;
+		propertyNotVal(obj: Object, prop: string, val: any, msg?: string): PromiseLike<void>;
 
-        deepPropertyVal(obj: Object, prop: string, val: any, msg?: string): PromiseLike<void>;
-        deepPropertyNotVal(obj: Object, prop: string, val: any, msg?: string): PromiseLike<void>;
+		deepPropertyVal(obj: Object, prop: string, val: any, msg?: string): PromiseLike<void>;
+		deepPropertyNotVal(obj: Object, prop: string, val: any, msg?: string): PromiseLike<void>;
 
-        lengthOf(exp: any, len: number, msg?: string): PromiseLike<void>;
-        // alias frenzy
-        throw(fn: Function, msg?: string): PromiseLike<void>;
-        throw(fn: Function, regExp: RegExp): PromiseLike<void>;
-        throw(fn: Function, errType: Function, msg?: string): PromiseLike<void>;
-        throw(fn: Function, errType: Function, regExp: RegExp): PromiseLike<void>;
+		lengthOf(exp: any, len: number, msg?: string): PromiseLike<void>;
+		// alias frenzy
+		throw(fn: Function, msg?: string): PromiseLike<void>;
+		throw(fn: Function, regExp: RegExp): PromiseLike<void>;
+		throw(fn: Function, errType: Function, msg?: string): PromiseLike<void>;
+		throw(fn: Function, errType: Function, regExp: RegExp): PromiseLike<void>;
 
-        throws(fn: Function, msg?: string): PromiseLike<void>;
-        throws(fn: Function, regExp: RegExp): PromiseLike<void>;
-        throws(fn: Function, errType: Function, msg?: string): PromiseLike<void>;
-        throws(fn: Function, errType: Function, regExp: RegExp): PromiseLike<void>;
+		throws(fn: Function, msg?: string): PromiseLike<void>;
+		throws(fn: Function, regExp: RegExp): PromiseLike<void>;
+		throws(fn: Function, errType: Function, msg?: string): PromiseLike<void>;
+		throws(fn: Function, errType: Function, regExp: RegExp): PromiseLike<void>;
 
-        Throw(fn: Function, msg?: string): PromiseLike<void>;
-        Throw(fn: Function, regExp: RegExp): PromiseLike<void>;
-        Throw(fn: Function, errType: Function, msg?: string): PromiseLike<void>;
-        Throw(fn: Function, errType: Function, regExp: RegExp): PromiseLike<void>;
+		Throw(fn: Function, msg?: string): PromiseLike<void>;
+		Throw(fn: Function, regExp: RegExp): PromiseLike<void>;
+		Throw(fn: Function, errType: Function, msg?: string): PromiseLike<void>;
+		Throw(fn: Function, errType: Function, regExp: RegExp): PromiseLike<void>;
 
-        doesNotThrow(fn: Function, msg?: string): PromiseLike<void>;
-        doesNotThrow(fn: Function, regExp: RegExp): PromiseLike<void>;
-        doesNotThrow(fn: Function, errType: Function, msg?: string): PromiseLike<void>;
-        doesNotThrow(fn: Function, errType: Function, regExp: RegExp): PromiseLike<void>;
+		doesNotThrow(fn: Function, msg?: string): PromiseLike<void>;
+		doesNotThrow(fn: Function, regExp: RegExp): PromiseLike<void>;
+		doesNotThrow(fn: Function, errType: Function, msg?: string): PromiseLike<void>;
+		doesNotThrow(fn: Function, errType: Function, regExp: RegExp): PromiseLike<void>;
 
-        operator(val: any, operator: string, val2: any, msg?: string): PromiseLike<void>;
-        closeTo(act: number, exp: number, delta: number, msg?: string): PromiseLike<void>;
+		operator(val: any, operator: string, val2: any, msg?: string): PromiseLike<void>;
+		closeTo(act: number, exp: number, delta: number, msg?: string): PromiseLike<void>;
 
-        sameMembers(set1: any[], set2: any[], msg?: string): PromiseLike<void>;
-        includeMembers(set1: any[], set2: any[], msg?: string): PromiseLike<void>;
+		sameMembers(set1: any[], set2: any[], msg?: string): PromiseLike<void>;
+		includeMembers(set1: any[], set2: any[], msg?: string): PromiseLike<void>;
 
-        ifError(val: any, msg?: string): PromiseLike<void>;
-    }
+		ifError(val: any, msg?: string): PromiseLike<void>;
+	}
 }
diff --git a/packages/chai-as-promised-typescript-typings/package.json b/packages/chai-as-promised-typescript-typings/package.json
index bde308547..77985de05 100644
--- a/packages/chai-as-promised-typescript-typings/package.json
+++ b/packages/chai-as-promised-typescript-typings/package.json
@@ -1,23 +1,21 @@
 {
-    "name": "chai-as-promised-typescript-typings",
-    "version": "0.0.6",
-    "description": "Typescript type definitions for chai-as-promised",
-    "main": "index.d.ts",
-    "types": "index.d.ts",
-    "repository": {
-        "type": "git",
-        "url": "git+https://github.com/0xProject/0x.js.git"
-    },
-    "author": "Fabio Berger",
-    "contributors": [
-        "Leonid Logvinov <logvinov.leon@gmail.com>"
-    ],
-    "license": "Apache-2.0",
-    "bugs": {
-        "url": "https://github.com/0xProject/0x.js/issues"
-    },
-    "homepage": "https://github.com/0xProject/0x.js/packages/chai-as-promised-typescript-typings#readme",
-    "dependencies": {
-        "chai-typescript-typings": "^0.0.0"
-    }
+	"name": "chai-as-promised-typescript-typings",
+	"version": "0.0.6",
+	"description": "Typescript type definitions for chai-as-promised",
+	"main": "index.d.ts",
+	"types": "index.d.ts",
+	"repository": {
+		"type": "git",
+		"url": "git+https://github.com/0xProject/0x.js.git"
+	},
+	"author": "Fabio Berger",
+	"contributors": ["Leonid Logvinov <logvinov.leon@gmail.com>"],
+	"license": "Apache-2.0",
+	"bugs": {
+		"url": "https://github.com/0xProject/0x.js/issues"
+	},
+	"homepage": "https://github.com/0xProject/0x.js/packages/chai-as-promised-typescript-typings#readme",
+	"dependencies": {
+		"chai-typescript-typings": "^0.0.0"
+	}
 }
diff --git a/packages/chai-as-promised-typescript-typings/tslint.json b/packages/chai-as-promised-typescript-typings/tslint.json
index 9a93a1f74..ef528b22e 100644
--- a/packages/chai-as-promised-typescript-typings/tslint.json
+++ b/packages/chai-as-promised-typescript-typings/tslint.json
@@ -1,3 +1,3 @@
 {
-    "extends": ["tslint-config-0xproject"]
+	"extends": ["tslint-config-0xproject"]
 }
diff --git a/packages/chai-typescript-typings/index.d.ts b/packages/chai-typescript-typings/index.d.ts
index 8b3e4c079..73d87a887 100644
--- a/packages/chai-typescript-typings/index.d.ts
+++ b/packages/chai-typescript-typings/index.d.ts
@@ -12,1243 +12,1243 @@
 
 // tslint:disable:no-namespace member-ordering ban-types unified-signatures variable-name callable-types
 declare namespace Chai {
-    interface ChaiStatic {
-        expect: ExpectStatic;
-        should(): Should;
-        /**
-         * Provides a way to extend the internals of Chai
-         */
-        use(fn: (chai: any, utils: any) => void): ChaiStatic;
-        assert: AssertStatic;
-        config: Config;
-        AssertionError: typeof AssertionError;
-        version: string;
-    }
-
-    export interface ExpectStatic extends AssertionStatic {
-        fail(actual?: any, expected?: any, message?: string, operator?: Operator): void;
-    }
-
-    export interface AssertStatic extends Assert {}
-
-    type AssertionStatic = (target: any, message?: string) => Assertion;
-
-    export type Operator = string; // "==" | "===" | ">" | ">=" | "<" | "<=" | "!=" | "!==";
-
-    export type OperatorComparable = boolean | null | number | string | undefined | Date;
-
-    interface ShouldAssertion {
-        equal(value1: any, value2: any, message?: string): void;
-        Throw: ShouldThrow;
-        throw: ShouldThrow;
-        exist(value: any, message?: string): void;
-    }
-
-    interface Should extends ShouldAssertion {
-        not: ShouldAssertion;
-        fail(actual: any, expected: any, message?: string, operator?: Operator): void;
-    }
-
-    interface ShouldThrow {
-        (actual: Function): void;
-        (actual: Function, expected: string | RegExp, message?: string): void;
-        (actual: Function, constructor: Error | Function, expected?: string | RegExp, message?: string): void;
-    }
-
-    interface Assertion extends LanguageChains, NumericComparison, TypeComparison {
-        not: Assertion;
-        deep: Deep;
-        nested: Nested;
-        any: KeyFilter;
-        all: KeyFilter;
-        a: TypeComparison;
-        an: TypeComparison;
-        include: Include;
-        includes: Include;
-        contain: Include;
-        contains: Include;
-        ok: Assertion;
-        true: () => Assertion;
-        false: () => Assertion;
-        null: () => Assertion;
-        undefined: () => Assertion;
-        NaN: Assertion;
-        exist: Assertion;
-        empty: Assertion;
-        arguments: Assertion;
-        Arguments: Assertion;
-        equal: Equal;
-        equals: Equal;
-        eq: Equal;
-        eql: Equal;
-        eqls: Equal;
-        property: Property;
-        ownProperty: OwnProperty;
-        haveOwnProperty: OwnProperty;
-        ownPropertyDescriptor: OwnPropertyDescriptor;
-        haveOwnPropertyDescriptor: OwnPropertyDescriptor;
-        length: Length;
-        lengthOf: Length;
-        match: Match;
-        matches: Match;
-        string(string: string, message?: string): Assertion;
-        keys: Keys;
-        key(string: string): Assertion;
-        throw: (message?: string) => Assertion;
-        throws: Throw;
-        Throw: Throw;
-        respondTo: RespondTo;
-        respondsTo: RespondTo;
-        itself: Assertion;
-        satisfy: Satisfy;
-        satisfies: Satisfy;
-        closeTo: CloseTo;
-        approximately: CloseTo;
-        members: Members;
-        increase: PropertyChange;
-        increases: PropertyChange;
-        decrease: PropertyChange;
-        decreases: PropertyChange;
-        change: PropertyChange;
-        changes: PropertyChange;
-        extensible: Assertion;
-        sealed: Assertion;
-        frozen: Assertion;
-        oneOf(list: any[], message?: string): Assertion;
-    }
-
-    interface LanguageChains {
-        to: Assertion;
-        be: Assertion;
-        been: Assertion;
-        is: Assertion;
-        that: Assertion;
-        which: Assertion;
-        and: Assertion;
-        has: Assertion;
-        have: Assertion;
-        with: Assertion;
-        at: Assertion;
-        of: Assertion;
-        same: Assertion;
-    }
-
-    interface NumericComparison {
-        above: NumberComparer;
-        gt: NumberComparer;
-        greaterThan: NumberComparer;
-        least: NumberComparer;
-        gte: NumberComparer;
-        below: NumberComparer;
-        lt: NumberComparer;
-        lessThan: NumberComparer;
-        most: NumberComparer;
-        lte: NumberComparer;
-        within(start: number, finish: number, message?: string): Assertion;
-    }
-
-    interface NumberComparer {
-        (value: number, message?: string): Assertion;
-    }
-
-    interface TypeComparison {
-        (type: string, message?: string): Assertion;
-        instanceof: InstanceOf;
-        instanceOf: InstanceOf;
-    }
-
-    interface InstanceOf {
-        (constructor: Object, message?: string): Assertion;
-    }
-
-    interface CloseTo {
-        (expected: number, delta: number, message?: string): Assertion;
-    }
-
-    interface Nested {
-        include: Include;
-        property: Property;
-        members: Members;
-    }
-
-    interface Deep {
-        equal: Equal;
-        equals: Equal;
-        eq: Equal;
-        include: Include;
-        property: Property;
-        members: Members;
-    }
-
-    interface KeyFilter {
-        keys: Keys;
-    }
-
-    interface Equal {
-        (value: any, message?: string): Assertion;
-    }
-
-    interface Property {
-        (name: string, value?: any, message?: string): Assertion;
-    }
-
-    interface OwnProperty {
-        (name: string, message?: string): Assertion;
-    }
-
-    interface OwnPropertyDescriptor {
-        (name: string, descriptor: PropertyDescriptor, message?: string): Assertion;
-        (name: string, message?: string): Assertion;
-    }
-
-    interface Length extends LanguageChains, NumericComparison {
-        (length: number, message?: string): Assertion;
-    }
-
-    interface Include {
-        (value: Object | string | number, message?: string): Assertion;
-        keys: Keys;
-        members: Members;
-        any: KeyFilter;
-        all: KeyFilter;
-    }
-
-    interface Match {
-        (regexp: RegExp | string, message?: string): Assertion;
-    }
-
-    interface Keys {
-        (...keys: string[]): Assertion;
-        (keys: any[]): Assertion;
-        (keys: Object): Assertion;
-    }
-
-    interface Throw {
-        (): Assertion;
-        (expected: string, message?: string): Assertion;
-        (expected: RegExp, message?: string): Assertion;
-        (constructor: Error, expected?: string, message?: string): Assertion;
-        (constructor: Error, expected?: RegExp, message?: string): Assertion;
-        (constructor: Function, expected?: string, message?: string): Assertion;
-        (constructor: Function, expected?: RegExp, message?: string): Assertion;
-    }
-
-    interface RespondTo {
-        (method: string, message?: string): Assertion;
-    }
-
-    interface Satisfy {
-        (matcher: Function, message?: string): Assertion;
-    }
-
-    interface Members {
-        (set: any[], message?: string): Assertion;
-    }
-
-    interface PropertyChange {
-        (object: Object, property: string, message?: string): Assertion;
-    }
-
-    export interface Assert {
-        /**
-         * @param expression    Expression to test for truthiness.
-         * @param message    Message to display on error.
-         */
-        (expression: any, message?: string): void;
-
-        /**
-         * Throws a failure.
-         *
-         * @type T   Type of the objects.
-         * @param actual   Actual value.
-         * @param expected   Potential expected value.
-         * @param message    Message to display on error.
-         * @param operator   Comparison operator, if not strict equality.
-         * @remarks Node.js assert module-compatible.
-         */
-        fail<T>(actual?: T, expected?: T, message?: string, operator?: Operator): void;
-
-        /**
-         * Asserts that object is truthy.
-         *
-         * @type T   Type of object.
-         * @param object   Object to test.
-         * @param message    Message to display on error.
-         */
-        isOk<T>(value: T, message?: string): void;
-
-        /**
-         * Asserts that object is truthy.
-         *
-         * @type T   Type of object.
-         * @param object   Object to test.
-         * @param message    Message to display on error.
-         */
-        ok<T>(value: T, message?: string): void;
-
-        /**
-         * Asserts that object is falsy.
-         *
-         * @type T   Type of object.
-         * @param object   Object to test.
-         * @param message    Message to display on error.
-         */
-        isNotOk<T>(value: T, message?: string): void;
-
-        /**
-         * Asserts that object is falsy.
-         *
-         * @type T   Type of object.
-         * @param object   Object to test.
-         * @param message    Message to display on error.
-         */
-        notOk<T>(value: T, message?: string): void;
-
-        /**
-         * Asserts non-strict equality (==) of actual and expected.
-         *
-         * @type T   Type of the objects.
-         * @param actual   Actual value.
-         * @param expected   Potential expected value.
-         * @param message   Message to display on error.
-         */
-        equal<T>(actual: T, expected: T, message?: string): void;
-
-        /**
-         * Asserts non-strict inequality (==) of actual and expected.
-         *
-         * @type T   Type of the objects.
-         * @param actual   Actual value.
-         * @param expected   Potential expected value.
-         * @param message   Message to display on error.
-         */
-        notEqual<T>(actual: T, expected: T, message?: string): void;
-
-        /**
-         * Asserts strict equality (===) of actual and expected.
-         *
-         * @type T   Type of the objects.
-         * @param actual   Actual value.
-         * @param expected   Potential expected value.
-         * @param message   Message to display on error.
-         */
-        strictEqual<T>(actual: T, expected: T, message?: string): void;
-
-        /**
-         * Asserts strict inequality (==) of actual and expected.
-         *
-         * @type T   Type of the objects.
-         * @param actual   Actual value.
-         * @param expected   Potential expected value.
-         * @param message   Message to display on error.
-         */
-        notStrictEqual<T>(actual: T, expected: T, message?: string): void;
-
-        /**
-         * Asserts that actual is deeply equal to expected.
-         *
-         * @type T   Type of the objects.
-         * @param actual   Actual value.
-         * @param expected   Potential expected value.
-         * @param message   Message to display on error.
-         */
-        deepEqual<T>(actual: T, expected: T, message?: string): void;
-
-        /**
-         * Asserts that actual is not deeply equal to expected.
-         *
-         * @type T   Type of the objects.
-         * @param actual   Actual value.
-         * @param expected   Potential expected value.
-         * @param message   Message to display on error.
-         */
-        notDeepEqual<T>(actual: T, expected: T, message?: string): void;
-
-        /**
-         * Asserts valueToCheck is strictly greater than (>) valueToBeAbove.
-         *
-         * @param valueToCheck   Actual value.
-         * @param valueToBeAbove   Minimum Potential expected value.
-         * @param message   Message to display on error.
-         */
-        isAbove(valueToCheck: number, valueToBeAbove: number, message?: string): void;
-
-        /**
-         * Asserts valueToCheck is greater than or equal to (>=) valueToBeAtLeast.
-         *
-         * @param valueToCheck   Actual value.
-         * @param valueToBeAtLeast   Minimum Potential expected value.
-         * @param message   Message to display on error.
-         */
-        isAtLeast(valueToCheck: number, valueToBeAtLeast: number, message?: string): void;
-
-        /**
-         * Asserts valueToCheck is strictly less than (<) valueToBeBelow.
-         *
-         * @param valueToCheck   Actual value.
-         * @param valueToBeBelow   Minimum Potential expected value.
-         * @param message   Message to display on error.
-         */
-        isBelow(valueToCheck: number, valueToBeBelow: number, message?: string): void;
-
-        /**
-         * Asserts valueToCheck is greater than or equal to (>=) valueToBeAtMost.
-         *
-         * @param valueToCheck   Actual value.
-         * @param valueToBeAtMost   Minimum Potential expected value.
-         * @param message   Message to display on error.
-         */
-        isAtMost(valueToCheck: number, valueToBeAtMost: number, message?: string): void;
-
-        /**
-         * Asserts that value is true.
-         *
-         * @type T   Type of value.
-         * @param value   Actual value.
-         * @param message   Message to display on error.
-         */
-        isTrue<T>(value: T, message?: string): void;
-
-        /**
-         * Asserts that value is false.
-         *
-         * @type T   Type of value.
-         * @param value   Actual value.
-         * @param message   Message to display on error.
-         */
-        isFalse<T>(value: T, message?: string): void;
-
-        /**
-         * Asserts that value is not true.
-         *
-         * @type T   Type of value.
-         * @param value   Actual value.
-         * @param message   Message to display on error.
-         */
-        isNotTrue<T>(value: T, message?: string): void;
-
-        /**
-         * Asserts that value is not false.
-         *
-         * @type T   Type of value.
-         * @param value   Actual value.
-         * @param message   Message to display on error.
-         */
-        isNotFalse<T>(value: T, message?: string): void;
-
-        /**
-         * Asserts that value is null.
-         *
-         * @type T   Type of value.
-         * @param value   Actual value.
-         * @param message   Message to display on error.
-         */
-        isNull<T>(value: T, message?: string): void;
-
-        /**
-         * Asserts that value is not null.
-         *
-         * @type T   Type of value.
-         * @param value   Actual value.
-         * @param message   Message to display on error.
-         */
-        isNotNull<T>(value: T, message?: string): void;
-
-        /**
-         * Asserts that value is not null.
-         *
-         * @type T   Type of value.
-         * @param value   Actual value.
-         * @param message   Message to display on error.
-         */
-        isNaN<T>(value: T, message?: string): void;
-
-        /**
-         * Asserts that value is not null.
-         *
-         * @type T   Type of value.
-         * @param value   Actual value.
-         * @param message   Message to display on error.
-         */
-        isNotNaN<T>(value: T, message?: string): void;
-
-        /**
-         * Asserts that value is undefined.
-         *
-         * @type T   Type of value.
-         * @param value   Actual value.
-         * @param message   Message to display on error.
-         */
-        isUndefined<T>(value: T, message?: string): void;
-
-        /**
-         * Asserts that value is not undefined.
-         *
-         * @type T   Type of value.
-         * @param value   Actual value.
-         * @param message   Message to display on error.
-         */
-        isDefined<T>(value: T, message?: string): void;
-
-        /**
-         * Asserts that value is a function.
-         *
-         * @type T   Type of value.
-         * @param value   Actual value.
-         * @param message   Message to display on error.
-         */
-        isFunction<T>(value: T, message?: string): void;
-
-        /**
-         * Asserts that value is not a function.
-         *
-         * @type T   Type of value.
-         * @param value   Actual value.
-         * @param message   Message to display on error.
-         */
-        isNotFunction<T>(value: T, message?: string): void;
-
-        /**
-         * Asserts that value is an object of type 'Object'
-         * (as revealed by Object.prototype.toString).
-         *
-         * @type T   Type of value.
-         * @param value   Actual value.
-         * @param message   Message to display on error.
-         * @remarks The assertion does not match subclassed objects.
-         */
-        isObject<T>(value: T, message?: string): void;
-
-        /**
-         * Asserts that value is not an object of type 'Object'
-         * (as revealed by Object.prototype.toString).
-         *
-         * @type T   Type of value.
-         * @param value   Actual value.
-         * @param message   Message to display on error.
-         */
-        isNotObject<T>(value: T, message?: string): void;
-
-        /**
-         * Asserts that value is an array.
-         *
-         * @type T   Type of value.
-         * @param value   Actual value.
-         * @param message   Message to display on error.
-         */
-        isArray<T>(value: T, message?: string): void;
-
-        /**
-         * Asserts that value is not an array.
-         *
-         * @type T   Type of value.
-         * @param value   Actual value.
-         * @param message   Message to display on error.
-         */
-        isNotArray<T>(value: T, message?: string): void;
-
-        /**
-         * Asserts that value is a string.
-         *
-         * @type T   Type of value.
-         * @param value   Actual value.
-         * @param message   Message to display on error.
-         */
-        isString<T>(value: T, message?: string): void;
-
-        /**
-         * Asserts that value is not a string.
-         *
-         * @type T   Type of value.
-         * @param value   Actual value.
-         * @param message   Message to display on error.
-         */
-        isNotString<T>(value: T, message?: string): void;
-
-        /**
-         * Asserts that value is a number.
-         *
-         * @type T   Type of value.
-         * @param value   Actual value.
-         * @param message   Message to display on error.
-         */
-        isNumber<T>(value: T, message?: string): void;
-
-        /**
-         * Asserts that value is not a number.
-         *
-         * @type T   Type of value.
-         * @param value   Actual value.
-         * @param message   Message to display on error.
-         */
-        isNotNumber<T>(value: T, message?: string): void;
-
-        /**
-         * Asserts that value is a boolean.
-         *
-         * @type T   Type of value.
-         * @param value   Actual value.
-         * @param message   Message to display on error.
-         */
-        isBoolean<T>(value: T, message?: string): void;
-
-        /**
-         * Asserts that value is not a boolean.
-         *
-         * @type T   Type of value.
-         * @param value   Actual value.
-         * @param message   Message to display on error.
-         */
-        isNotBoolean<T>(value: T, message?: string): void;
-
-        /**
-         * Asserts that value's type is name, as determined by Object.prototype.toString.
-         *
-         * @type T   Type of value.
-         * @param value   Actual value.
-         * @param name   Potential expected type name of value.
-         * @param message   Message to display on error.
-         */
-        typeOf<T>(value: T, name: string, message?: string): void;
-
-        /**
-         * Asserts that value's type is not name, as determined by Object.prototype.toString.
-         *
-         * @type T   Type of value.
-         * @param value   Actual value.
-         * @param name   Potential expected type name of value.
-         * @param message   Message to display on error.
-         */
-        notTypeOf<T>(value: T, name: string, message?: string): void;
-
-        /**
-         * Asserts that value is an instance of constructor.
-         *
-         * @type T   Type of value.
-         * @param value   Actual value.
-         * @param constructor   Potential expected contructor of value.
-         * @param message   Message to display on error.
-         */
-        instanceOf<T>(value: T, constructor: Function, message?: string): void;
-
-        /**
-         * Asserts that value is not an instance of constructor.
-         *
-         * @type T   Type of value.
-         * @param value   Actual value.
-         * @param constructor   Potential expected contructor of value.
-         * @param message   Message to display on error.
-         */
-        notInstanceOf<T>(value: T, type: Function, message?: string): void;
-
-        /**
-         * Asserts that haystack includes needle.
-         *
-         * @param haystack   Container string.
-         * @param needle   Potential expected substring of haystack.
-         * @param message   Message to display on error.
-         */
-        include(haystack: string, needle: string, message?: string): void;
-
-        /**
-         * Asserts that haystack includes needle.
-         *
-         * @type T   Type of values in haystack.
-         * @param haystack   Container array.
-         * @param needle   Potential value contained in haystack.
-         * @param message   Message to display on error.
-         */
-        include<T>(haystack: T[], needle: T, message?: string): void;
-
-        /**
-         * Asserts that haystack does not include needle.
-         *
-         * @param haystack   Container string.
-         * @param needle   Potential expected substring of haystack.
-         * @param message   Message to display on error.
-         */
-        notInclude(haystack: string, needle: any, message?: string): void;
-
-        /**
-         * Asserts that haystack does not include needle.
-         *
-         * @type T   Type of values in haystack.
-         * @param haystack   Container array.
-         * @param needle   Potential value contained in haystack.
-         * @param message   Message to display on error.
-         */
-        notInclude(haystack: any[], needle: any, message?: string): void;
-
-        /**
-         * Asserts that value matches the regular expression regexp.
-         *
-         * @param value   Actual value.
-         * @param regexp   Potential match of value.
-         * @param message   Message to display on error.
-         */
-        match(value: string, regexp: RegExp, message?: string): void;
-
-        /**
-         * Asserts that value does not match the regular expression regexp.
-         *
-         * @param value   Actual value.
-         * @param regexp   Potential match of value.
-         * @param message   Message to display on error.
-         */
-        notMatch(expected: any, regexp: RegExp, message?: string): void;
-
-        /**
-         * Asserts that object has a property named by property.
-         *
-         * @type T   Type of object.
-         * @param object   Container object.
-         * @param property   Potential contained property of object.
-         * @param message   Message to display on error.
-         */
-        property<T>(object: T, property: string /* keyof T */, message?: string): void;
-
-        /**
-         * Asserts that object has a property named by property.
-         *
-         * @type T   Type of object.
-         * @param object   Container object.
-         * @param property   Potential contained property of object.
-         * @param message   Message to display on error.
-         */
-        notProperty<T>(object: T, property: string /* keyof T */, message?: string): void;
-
-        /**
-         * Asserts that object has a property named by property, which can be a string
-         * using dot- and bracket-notation for deep reference.
-         *
-         * @type T   Type of object.
-         * @param object   Container object.
-         * @param property   Potential contained property of object.
-         * @param message   Message to display on error.
-         */
-        deepProperty<T>(object: T, property: string, message?: string): void;
-
-        /**
-         * Asserts that object does not have a property named by property, which can be a
-         * string using dot- and bracket-notation for deep reference.
-         *
-         * @type T   Type of object.
-         * @param object   Container object.
-         * @param property   Potential contained property of object.
-         * @param message   Message to display on error.
-         */
-        notDeepProperty<T>(object: T, property: string, message?: string): void;
-
-        /**
-         * Asserts that object has a property named by property with value given by value.
-         *
-         * @type T   Type of object.
-         * @type V   Type of value.
-         * @param object   Container object.
-         * @param property   Potential contained property of object.
-         * @param value   Potential expected property value.
-         * @param message   Message to display on error.
-         */
-        propertyVal<T, V>(object: T, property: string /* keyof T */, value: V, message?: string): void;
-
-        /**
-         * Asserts that object has a property named by property with value given by value.
-         *
-         * @type T   Type of object.
-         * @type V   Type of value.
-         * @param object   Container object.
-         * @param property   Potential contained property of object.
-         * @param value   Potential expected property value.
-         * @param message   Message to display on error.
-         */
-        propertyNotVal<T, V>(object: T, property: string /* keyof T */, value: V, message?: string): void;
-
-        /**
-         * Asserts that object has a property named by property, which can be a string
-         * using dot- and bracket-notation for deep reference.
-         *
-         * @type T   Type of object.
-         * @type V   Type of value.
-         * @param object   Container object.
-         * @param property   Potential contained property of object.
-         * @param value   Potential expected property value.
-         * @param message   Message to display on error.
-         */
-        deepPropertyVal<T, V>(object: T, property: string, value: V, message?: string): void;
-
-        /**
-         * Asserts that object does not have a property named by property, which can be a
-         * string using dot- and bracket-notation for deep reference.
-         *
-         * @type T   Type of object.
-         * @type V   Type of value.
-         * @param object   Container object.
-         * @param property   Potential contained property of object.
-         * @param value   Potential expected property value.
-         * @param message   Message to display on error.
-         */
-        deepPropertyNotVal<T, V>(object: T, property: string, value: V, message?: string): void;
-
-        /**
-         * Asserts that object has a length property with the expected value.
-         *
-         * @type T   Type of object.
-         * @param object   Container object.
-         * @param length   Potential expected length of object.
-         * @param message   Message to display on error.
-         */
-        lengthOf<T extends { readonly length?: number }>(object: T, length: number, message?: string): void;
-
-        /**
-         * Asserts that fn will throw an error.
-         *
-         * @param fn   Function that may throw.
-         * @param message   Message to display on error.
-         */
-        throw(fn: Function, message?: string): void;
-
-        /**
-         * Asserts that function will throw an error with message matching regexp.
-         *
-         * @param fn   Function that may throw.
-         * @param regExp   Potential expected message match.
-         * @param message   Message to display on error.
-         */
-        throw(fn: Function, regExp: RegExp): void;
-
-        /**
-         * Asserts that function will throw an error that is an instance of constructor.
-         *
-         * @param fn   Function that may throw.
-         * @param constructor   Potential expected error constructor.
-         * @param message   Message to display on error.
-         */
-        throw(fn: Function, constructor: Function, message?: string): void;
-
-        /**
-         * Asserts that function will throw an error that is an instance of constructor
-         * and an error with message matching regexp.
-         *
-         * @param fn   Function that may throw.
-         * @param constructor   Potential expected error constructor.
-         * @param message   Message to display on error.
-         */
-        throw(fn: Function, constructor: Function, regExp: RegExp): void;
-
-        /**
-         * Asserts that fn will throw an error.
-         *
-         * @param fn   Function that may throw.
-         * @param message   Message to display on error.
-         */
-        throws(fn: Function, message?: string): void;
-
-        /**
-         * Asserts that function will throw an error with message matching regexp.
-         *
-         * @param fn   Function that may throw.
-         * @param regExp   Potential expected message match.
-         * @param message   Message to display on error.
-         */
-        throws(fn: Function, regExp: RegExp, message?: string): void;
-
-        /**
-         * Asserts that function will throw an error that is an instance of constructor.
-         *
-         * @param fn   Function that may throw.
-         * @param constructor   Potential expected error constructor.
-         * @param message   Message to display on error.
-         */
-        throws(fn: Function, errType: Function, message?: string): void;
-
-        /**
-         * Asserts that function will throw an error that is an instance of constructor
-         * and an error with message matching regexp.
-         *
-         * @param fn   Function that may throw.
-         * @param constructor   Potential expected error constructor.
-         * @param message   Message to display on error.
-         */
-        throws(fn: Function, errType: Function, regExp: RegExp): void;
-
-        /**
-         * Asserts that fn will throw an error.
-         *
-         * @param fn   Function that may throw.
-         * @param message   Message to display on error.
-         */
-        Throw(fn: Function, message?: string): void;
-
-        /**
-         * Asserts that function will throw an error with message matching regexp.
-         *
-         * @param fn   Function that may throw.
-         * @param regExp   Potential expected message match.
-         * @param message   Message to display on error.
-         */
-        Throw(fn: Function, regExp: RegExp): void;
-
-        /**
-         * Asserts that function will throw an error that is an instance of constructor.
-         *
-         * @param fn   Function that may throw.
-         * @param constructor   Potential expected error constructor.
-         * @param message   Message to display on error.
-         */
-        Throw(fn: Function, errType: Function, message?: string): void;
-
-        /**
-         * Asserts that function will throw an error that is an instance of constructor
-         * and an error with message matching regexp.
-         *
-         * @param fn   Function that may throw.
-         * @param constructor   Potential expected error constructor.
-         * @param message   Message to display on error.
-         */
-        Throw(fn: Function, errType: Function, regExp: RegExp): void;
-
-        /**
-         * Asserts that fn will not throw an error.
-         *
-         * @param fn   Function that may throw.
-         * @param message   Message to display on error.
-         */
-        doesNotThrow(fn: Function, message?: string): void;
-
-        /**
-         * Asserts that function will throw an error with message matching regexp.
-         *
-         * @param fn   Function that may throw.
-         * @param regExp   Potential expected message match.
-         * @param message   Message to display on error.
-         */
-        doesNotThrow(fn: Function, regExp: RegExp): void;
-
-        /**
-         * Asserts that function will throw an error that is an instance of constructor.
-         *
-         * @param fn   Function that may throw.
-         * @param constructor   Potential expected error constructor.
-         * @param message   Message to display on error.
-         */
-        doesNotThrow(fn: Function, errType: Function, message?: string): void;
-
-        /**
-         * Asserts that function will throw an error that is an instance of constructor
-         * and an error with message matching regexp.
-         *
-         * @param fn   Function that may throw.
-         * @param constructor   Potential expected error constructor.
-         * @param message   Message to display on error.
-         */
-        doesNotThrow(fn: Function, errType: Function, regExp: RegExp): void;
-
-        /**
-         * Compares two values using operator.
-         *
-         * @param val1   Left value during comparison.
-         * @param operator   Comparison operator.
-         * @param val2   Right value during comparison.
-         * @param message   Message to display on error.
-         */
-        operator(val1: OperatorComparable, operator: Operator, val2: OperatorComparable, message?: string): void;
-
-        /**
-         * Asserts that the target is equal to expected, to within a +/- delta range.
-         *
-         * @param actual   Actual value
-         * @param expected   Potential expected value.
-         * @param delta   Maximum differenced between values.
-         * @param message   Message to display on error.
-         */
-        closeTo(actual: number, expected: number, delta: number, message?: string): void;
-
-        /**
-         * Asserts that the target is equal to expected, to within a +/- delta range.
-         *
-         * @param actual   Actual value
-         * @param expected   Potential expected value.
-         * @param delta   Maximum differenced between values.
-         * @param message   Message to display on error.
-         */
-        approximately(act: number, exp: number, delta: number, message?: string): void;
-
-        /**
-         * Asserts that set1 and set2 have the same members. Order is not take into account.
-         *
-         * @type T   Type of set values.
-         * @param set1   Actual set of values.
-         * @param set2   Potential expected set of values.
-         * @param message   Message to display on error.
-         */
-        sameMembers<T>(set1: T[], set2: T[], message?: string): void;
-
-        /**
-         * Asserts that set1 and set2 have the same members using deep equality checking.
-         * Order is not take into account.
-         *
-         * @type T   Type of set values.
-         * @param set1   Actual set of values.
-         * @param set2   Potential expected set of values.
-         * @param message   Message to display on error.
-         */
-        sameDeepMembers<T>(set1: T[], set2: T[], message?: string): void;
-
-        /**
-         * Asserts that subset is included in superset. Order is not take into account.
-         *
-         * @type T   Type of set values.
-         * @param superset   Actual set of values.
-         * @param subset   Potential contained set of values.
-         * @param message   Message to display on error.
-         */
-        includeMembers<T>(superset: T[], subset: T[], message?: string): void;
-
-        /**
-         * Asserts that subset is included in superset using deep equality checking.
-         * Order is not take into account.
-         *
-         * @type T   Type of set values.
-         * @param superset   Actual set of values.
-         * @param subset   Potential contained set of values.
-         * @param message   Message to display on error.
-         */
-        includeDeepMembers<T>(superset: T[], subset: T[], message?: string): void;
-
-        /**
-         * Asserts that non-object, non-array value inList appears in the flat array list.
-         *
-         * @type T   Type of list values.
-         * @param inList   Value expected to be in the list.
-         * @param list   List of values.
-         * @param message   Message to display on error.
-         */
-        oneOf<T>(inList: T, list: T[], message?: string): void;
-
-        /**
-         * Asserts that a function changes the value of a property.
-         *
-         * @type T   Type of object.
-         * @param modifier   Function to run.
-         * @param object   Container object.
-         * @param property   Property of object expected to be modified.
-         * @param message   Message to display on error.
-         */
-        changes<T>(modifier: Function, object: T, property: string /* keyof T */, message?: string): void;
-
-        /**
-         * Asserts that a function does not change the value of a property.
-         *
-         * @type T   Type of object.
-         * @param modifier   Function to run.
-         * @param object   Container object.
-         * @param property   Property of object expected not to be modified.
-         * @param message   Message to display on error.
-         */
-        doesNotChange<T>(modifier: Function, object: T, property: string /* keyof T */, message?: string): void;
-
-        /**
-         * Asserts that a function increases an object property.
-         *
-         * @type T   Type of object.
-         * @param modifier   Function to run.
-         * @param object   Container object.
-         * @param property   Property of object expected to be increased.
-         * @param message   Message to display on error.
-         */
-        increases<T>(modifier: Function, object: T, property: string /* keyof T */, message?: string): void;
-
-        /**
-         * Asserts that a function does not increase an object property.
-         *
-         * @type T   Type of object.
-         * @param modifier   Function to run.
-         * @param object   Container object.
-         * @param property   Property of object expected not to be increased.
-         * @param message   Message to display on error.
-         */
-        doesNotIncrease<T>(modifier: Function, object: T, property: string /* keyof T */, message?: string): void;
-
-        /**
-         * Asserts that a function decreases an object property.
-         *
-         * @type T   Type of object.
-         * @param modifier   Function to run.
-         * @param object   Container object.
-         * @param property   Property of object expected to be decreased.
-         * @param message   Message to display on error.
-         */
-        decreases<T>(modifier: Function, object: T, property: string /* keyof T */, message?: string): void;
-
-        /**
-         * Asserts that a function does not decrease an object property.
-         *
-         * @type T   Type of object.
-         * @param modifier   Function to run.
-         * @param object   Container object.
-         * @param property   Property of object expected not to be decreased.
-         * @param message   Message to display on error.
-         */
-        doesNotDecrease<T>(modifier: Function, object: T, property: string /* keyof T */, message?: string): void;
-
-        /**
-         * Asserts if value is not a false value, and throws if it is a true value.
-         *
-         * @type T   Type of object.
-         * @param object   Actual value.
-         * @param message   Message to display on error.
-         * @remarks This is added to allow for chai to be a drop-in replacement for
-         *          Node’s assert class.
-         */
-        ifError<T>(object: T, message?: string): void;
-
-        /**
-         * Asserts that object is extensible (can have new properties added to it).
-         *
-         * @type T   Type of object
-         * @param object   Actual value.
-         * @param message   Message to display on error.
-         */
-        isExtensible<T>(object: T, message?: string): void;
-
-        /**
-         * Asserts that object is extensible (can have new properties added to it).
-         *
-         * @type T   Type of object
-         * @param object   Actual value.
-         * @param message   Message to display on error.
-         */
-        extensible<T>(object: T, message?: string): void;
-
-        /**
-         * Asserts that object is not extensible.
-         *
-         * @type T   Type of object
-         * @param object   Actual value.
-         * @param message   Message to display on error.
-         */
-        isNotExtensible<T>(object: T, message?: string): void;
-
-        /**
-         * Asserts that object is not extensible.
-         *
-         * @type T   Type of object
-         * @param object   Actual value.
-         * @param message   Message to display on error.
-         */
-        notExtensible<T>(object: T, message?: string): void;
-
-        /**
-         * Asserts that object is sealed (can have new properties added to it
-         * and its existing properties cannot be removed).
-         *
-         * @type T   Type of object
-         * @param object   Actual value.
-         * @param message   Message to display on error.
-         */
-        isSealed<T>(object: T, message?: string): void;
-
-        /**
-         * Asserts that object is sealed (can have new properties added to it
-         * and its existing properties cannot be removed).
-         *
-         * @type T   Type of object
-         * @param object   Actual value.
-         * @param message   Message to display on error.
-         */
-        sealed<T>(object: T, message?: string): void;
-
-        /**
-         * Asserts that object is not sealed.
-         *
-         * @type T   Type of object
-         * @param object   Actual value.
-         * @param message   Message to display on error.
-         */
-        isNotSealed<T>(object: T, message?: string): void;
-
-        /**
-         * Asserts that object is not sealed.
-         *
-         * @type T   Type of object
-         * @param object   Actual value.
-         * @param message   Message to display on error.
-         */
-        notSealed<T>(object: T, message?: string): void;
-
-        /**
-         * Asserts that object is frozen (cannot have new properties added to it
-         * and its existing properties cannot be removed).
-         *
-         * @type T   Type of object
-         * @param object   Actual value.
-         * @param message   Message to display on error.
-         */
-        isFrozen<T>(object: T, message?: string): void;
-
-        /**
-         * Asserts that object is frozen (cannot have new properties added to it
-         * and its existing properties cannot be removed).
-         *
-         * @type T   Type of object
-         * @param object   Actual value.
-         * @param message   Message to display on error.
-         */
-        frozen<T>(object: T, message?: string): void;
-
-        /**
-         * Asserts that object is not frozen (cannot have new properties added to it
-         * and its existing properties cannot be removed).
-         *
-         * @type T   Type of object
-         * @param object   Actual value.
-         * @param message   Message to display on error.
-         */
-        isNotFrozen<T>(object: T, message?: string): void;
-
-        /**
-         * Asserts that object is not frozen (cannot have new properties added to it
-         * and its existing properties cannot be removed).
-         *
-         * @type T   Type of object
-         * @param object   Actual value.
-         * @param message   Message to display on error.
-         */
-        notFrozen<T>(object: T, message?: string): void;
-    }
-
-    export interface Config {
-        /**
-         * Default: false
-         */
-        includeStack: boolean;
-
-        /**
-         * Default: true
-         */
-        showDiff: boolean;
-
-        /**
-         * Default: 40
-         */
-        truncateThreshold: number;
-    }
-
-    export class AssertionError {
-        constructor(message: string, _props?: any, ssf?: Function);
-        public name: string;
-        public message: string;
-        public showDiff: boolean;
-        public stack: string;
-    }
+	interface ChaiStatic {
+		expect: ExpectStatic;
+		should(): Should;
+		/**
+		 * Provides a way to extend the internals of Chai
+		 */
+		use(fn: (chai: any, utils: any) => void): ChaiStatic;
+		assert: AssertStatic;
+		config: Config;
+		AssertionError: typeof AssertionError;
+		version: string;
+	}
+
+	export interface ExpectStatic extends AssertionStatic {
+		fail(actual?: any, expected?: any, message?: string, operator?: Operator): void;
+	}
+
+	export interface AssertStatic extends Assert {}
+
+	type AssertionStatic = (target: any, message?: string) => Assertion;
+
+	export type Operator = string; // "==" | "===" | ">" | ">=" | "<" | "<=" | "!=" | "!==";
+
+	export type OperatorComparable = boolean | null | number | string | undefined | Date;
+
+	interface ShouldAssertion {
+		equal(value1: any, value2: any, message?: string): void;
+		Throw: ShouldThrow;
+		throw: ShouldThrow;
+		exist(value: any, message?: string): void;
+	}
+
+	interface Should extends ShouldAssertion {
+		not: ShouldAssertion;
+		fail(actual: any, expected: any, message?: string, operator?: Operator): void;
+	}
+
+	interface ShouldThrow {
+		(actual: Function): void;
+		(actual: Function, expected: string | RegExp, message?: string): void;
+		(actual: Function, constructor: Error | Function, expected?: string | RegExp, message?: string): void;
+	}
+
+	interface Assertion extends LanguageChains, NumericComparison, TypeComparison {
+		not: Assertion;
+		deep: Deep;
+		nested: Nested;
+		any: KeyFilter;
+		all: KeyFilter;
+		a: TypeComparison;
+		an: TypeComparison;
+		include: Include;
+		includes: Include;
+		contain: Include;
+		contains: Include;
+		ok: Assertion;
+		true: () => Assertion;
+		false: () => Assertion;
+		null: () => Assertion;
+		undefined: () => Assertion;
+		NaN: Assertion;
+		exist: Assertion;
+		empty: Assertion;
+		arguments: Assertion;
+		Arguments: Assertion;
+		equal: Equal;
+		equals: Equal;
+		eq: Equal;
+		eql: Equal;
+		eqls: Equal;
+		property: Property;
+		ownProperty: OwnProperty;
+		haveOwnProperty: OwnProperty;
+		ownPropertyDescriptor: OwnPropertyDescriptor;
+		haveOwnPropertyDescriptor: OwnPropertyDescriptor;
+		length: Length;
+		lengthOf: Length;
+		match: Match;
+		matches: Match;
+		string(string: string, message?: string): Assertion;
+		keys: Keys;
+		key(string: string): Assertion;
+		throw: (message?: string) => Assertion;
+		throws: Throw;
+		Throw: Throw;
+		respondTo: RespondTo;
+		respondsTo: RespondTo;
+		itself: Assertion;
+		satisfy: Satisfy;
+		satisfies: Satisfy;
+		closeTo: CloseTo;
+		approximately: CloseTo;
+		members: Members;
+		increase: PropertyChange;
+		increases: PropertyChange;
+		decrease: PropertyChange;
+		decreases: PropertyChange;
+		change: PropertyChange;
+		changes: PropertyChange;
+		extensible: Assertion;
+		sealed: Assertion;
+		frozen: Assertion;
+		oneOf(list: any[], message?: string): Assertion;
+	}
+
+	interface LanguageChains {
+		to: Assertion;
+		be: Assertion;
+		been: Assertion;
+		is: Assertion;
+		that: Assertion;
+		which: Assertion;
+		and: Assertion;
+		has: Assertion;
+		have: Assertion;
+		with: Assertion;
+		at: Assertion;
+		of: Assertion;
+		same: Assertion;
+	}
+
+	interface NumericComparison {
+		above: NumberComparer;
+		gt: NumberComparer;
+		greaterThan: NumberComparer;
+		least: NumberComparer;
+		gte: NumberComparer;
+		below: NumberComparer;
+		lt: NumberComparer;
+		lessThan: NumberComparer;
+		most: NumberComparer;
+		lte: NumberComparer;
+		within(start: number, finish: number, message?: string): Assertion;
+	}
+
+	interface NumberComparer {
+		(value: number, message?: string): Assertion;
+	}
+
+	interface TypeComparison {
+		(type: string, message?: string): Assertion;
+		instanceof: InstanceOf;
+		instanceOf: InstanceOf;
+	}
+
+	interface InstanceOf {
+		(constructor: Object, message?: string): Assertion;
+	}
+
+	interface CloseTo {
+		(expected: number, delta: number, message?: string): Assertion;
+	}
+
+	interface Nested {
+		include: Include;
+		property: Property;
+		members: Members;
+	}
+
+	interface Deep {
+		equal: Equal;
+		equals: Equal;
+		eq: Equal;
+		include: Include;
+		property: Property;
+		members: Members;
+	}
+
+	interface KeyFilter {
+		keys: Keys;
+	}
+
+	interface Equal {
+		(value: any, message?: string): Assertion;
+	}
+
+	interface Property {
+		(name: string, value?: any, message?: string): Assertion;
+	}
+
+	interface OwnProperty {
+		(name: string, message?: string): Assertion;
+	}
+
+	interface OwnPropertyDescriptor {
+		(name: string, descriptor: PropertyDescriptor, message?: string): Assertion;
+		(name: string, message?: string): Assertion;
+	}
+
+	interface Length extends LanguageChains, NumericComparison {
+		(length: number, message?: string): Assertion;
+	}
+
+	interface Include {
+		(value: Object | string | number, message?: string): Assertion;
+		keys: Keys;
+		members: Members;
+		any: KeyFilter;
+		all: KeyFilter;
+	}
+
+	interface Match {
+		(regexp: RegExp | string, message?: string): Assertion;
+	}
+
+	interface Keys {
+		(...keys: string[]): Assertion;
+		(keys: any[]): Assertion;
+		(keys: Object): Assertion;
+	}
+
+	interface Throw {
+		(): Assertion;
+		(expected: string, message?: string): Assertion;
+		(expected: RegExp, message?: string): Assertion;
+		(constructor: Error, expected?: string, message?: string): Assertion;
+		(constructor: Error, expected?: RegExp, message?: string): Assertion;
+		(constructor: Function, expected?: string, message?: string): Assertion;
+		(constructor: Function, expected?: RegExp, message?: string): Assertion;
+	}
+
+	interface RespondTo {
+		(method: string, message?: string): Assertion;
+	}
+
+	interface Satisfy {
+		(matcher: Function, message?: string): Assertion;
+	}
+
+	interface Members {
+		(set: any[], message?: string): Assertion;
+	}
+
+	interface PropertyChange {
+		(object: Object, property: string, message?: string): Assertion;
+	}
+
+	export interface Assert {
+		/**
+		 * @param expression    Expression to test for truthiness.
+		 * @param message    Message to display on error.
+		 */
+		(expression: any, message?: string): void;
+
+		/**
+		 * Throws a failure.
+		 *
+		 * @type T   Type of the objects.
+		 * @param actual   Actual value.
+		 * @param expected   Potential expected value.
+		 * @param message    Message to display on error.
+		 * @param operator   Comparison operator, if not strict equality.
+		 * @remarks Node.js assert module-compatible.
+		 */
+		fail<T>(actual?: T, expected?: T, message?: string, operator?: Operator): void;
+
+		/**
+		 * Asserts that object is truthy.
+		 *
+		 * @type T   Type of object.
+		 * @param object   Object to test.
+		 * @param message    Message to display on error.
+		 */
+		isOk<T>(value: T, message?: string): void;
+
+		/**
+		 * Asserts that object is truthy.
+		 *
+		 * @type T   Type of object.
+		 * @param object   Object to test.
+		 * @param message    Message to display on error.
+		 */
+		ok<T>(value: T, message?: string): void;
+
+		/**
+		 * Asserts that object is falsy.
+		 *
+		 * @type T   Type of object.
+		 * @param object   Object to test.
+		 * @param message    Message to display on error.
+		 */
+		isNotOk<T>(value: T, message?: string): void;
+
+		/**
+		 * Asserts that object is falsy.
+		 *
+		 * @type T   Type of object.
+		 * @param object   Object to test.
+		 * @param message    Message to display on error.
+		 */
+		notOk<T>(value: T, message?: string): void;
+
+		/**
+		 * Asserts non-strict equality (==) of actual and expected.
+		 *
+		 * @type T   Type of the objects.
+		 * @param actual   Actual value.
+		 * @param expected   Potential expected value.
+		 * @param message   Message to display on error.
+		 */
+		equal<T>(actual: T, expected: T, message?: string): void;
+
+		/**
+		 * Asserts non-strict inequality (==) of actual and expected.
+		 *
+		 * @type T   Type of the objects.
+		 * @param actual   Actual value.
+		 * @param expected   Potential expected value.
+		 * @param message   Message to display on error.
+		 */
+		notEqual<T>(actual: T, expected: T, message?: string): void;
+
+		/**
+		 * Asserts strict equality (===) of actual and expected.
+		 *
+		 * @type T   Type of the objects.
+		 * @param actual   Actual value.
+		 * @param expected   Potential expected value.
+		 * @param message   Message to display on error.
+		 */
+		strictEqual<T>(actual: T, expected: T, message?: string): void;
+
+		/**
+		 * Asserts strict inequality (==) of actual and expected.
+		 *
+		 * @type T   Type of the objects.
+		 * @param actual   Actual value.
+		 * @param expected   Potential expected value.
+		 * @param message   Message to display on error.
+		 */
+		notStrictEqual<T>(actual: T, expected: T, message?: string): void;
+
+		/**
+		 * Asserts that actual is deeply equal to expected.
+		 *
+		 * @type T   Type of the objects.
+		 * @param actual   Actual value.
+		 * @param expected   Potential expected value.
+		 * @param message   Message to display on error.
+		 */
+		deepEqual<T>(actual: T, expected: T, message?: string): void;
+
+		/**
+		 * Asserts that actual is not deeply equal to expected.
+		 *
+		 * @type T   Type of the objects.
+		 * @param actual   Actual value.
+		 * @param expected   Potential expected value.
+		 * @param message   Message to display on error.
+		 */
+		notDeepEqual<T>(actual: T, expected: T, message?: string): void;
+
+		/**
+		 * Asserts valueToCheck is strictly greater than (>) valueToBeAbove.
+		 *
+		 * @param valueToCheck   Actual value.
+		 * @param valueToBeAbove   Minimum Potential expected value.
+		 * @param message   Message to display on error.
+		 */
+		isAbove(valueToCheck: number, valueToBeAbove: number, message?: string): void;
+
+		/**
+		 * Asserts valueToCheck is greater than or equal to (>=) valueToBeAtLeast.
+		 *
+		 * @param valueToCheck   Actual value.
+		 * @param valueToBeAtLeast   Minimum Potential expected value.
+		 * @param message   Message to display on error.
+		 */
+		isAtLeast(valueToCheck: number, valueToBeAtLeast: number, message?: string): void;
+
+		/**
+		 * Asserts valueToCheck is strictly less than (<) valueToBeBelow.
+		 *
+		 * @param valueToCheck   Actual value.
+		 * @param valueToBeBelow   Minimum Potential expected value.
+		 * @param message   Message to display on error.
+		 */
+		isBelow(valueToCheck: number, valueToBeBelow: number, message?: string): void;
+
+		/**
+		 * Asserts valueToCheck is greater than or equal to (>=) valueToBeAtMost.
+		 *
+		 * @param valueToCheck   Actual value.
+		 * @param valueToBeAtMost   Minimum Potential expected value.
+		 * @param message   Message to display on error.
+		 */
+		isAtMost(valueToCheck: number, valueToBeAtMost: number, message?: string): void;
+
+		/**
+		 * Asserts that value is true.
+		 *
+		 * @type T   Type of value.
+		 * @param value   Actual value.
+		 * @param message   Message to display on error.
+		 */
+		isTrue<T>(value: T, message?: string): void;
+
+		/**
+		 * Asserts that value is false.
+		 *
+		 * @type T   Type of value.
+		 * @param value   Actual value.
+		 * @param message   Message to display on error.
+		 */
+		isFalse<T>(value: T, message?: string): void;
+
+		/**
+		 * Asserts that value is not true.
+		 *
+		 * @type T   Type of value.
+		 * @param value   Actual value.
+		 * @param message   Message to display on error.
+		 */
+		isNotTrue<T>(value: T, message?: string): void;
+
+		/**
+		 * Asserts that value is not false.
+		 *
+		 * @type T   Type of value.
+		 * @param value   Actual value.
+		 * @param message   Message to display on error.
+		 */
+		isNotFalse<T>(value: T, message?: string): void;
+
+		/**
+		 * Asserts that value is null.
+		 *
+		 * @type T   Type of value.
+		 * @param value   Actual value.
+		 * @param message   Message to display on error.
+		 */
+		isNull<T>(value: T, message?: string): void;
+
+		/**
+		 * Asserts that value is not null.
+		 *
+		 * @type T   Type of value.
+		 * @param value   Actual value.
+		 * @param message   Message to display on error.
+		 */
+		isNotNull<T>(value: T, message?: string): void;
+
+		/**
+		 * Asserts that value is not null.
+		 *
+		 * @type T   Type of value.
+		 * @param value   Actual value.
+		 * @param message   Message to display on error.
+		 */
+		isNaN<T>(value: T, message?: string): void;
+
+		/**
+		 * Asserts that value is not null.
+		 *
+		 * @type T   Type of value.
+		 * @param value   Actual value.
+		 * @param message   Message to display on error.
+		 */
+		isNotNaN<T>(value: T, message?: string): void;
+
+		/**
+		 * Asserts that value is undefined.
+		 *
+		 * @type T   Type of value.
+		 * @param value   Actual value.
+		 * @param message   Message to display on error.
+		 */
+		isUndefined<T>(value: T, message?: string): void;
+
+		/**
+		 * Asserts that value is not undefined.
+		 *
+		 * @type T   Type of value.
+		 * @param value   Actual value.
+		 * @param message   Message to display on error.
+		 */
+		isDefined<T>(value: T, message?: string): void;
+
+		/**
+		 * Asserts that value is a function.
+		 *
+		 * @type T   Type of value.
+		 * @param value   Actual value.
+		 * @param message   Message to display on error.
+		 */
+		isFunction<T>(value: T, message?: string): void;
+
+		/**
+		 * Asserts that value is not a function.
+		 *
+		 * @type T   Type of value.
+		 * @param value   Actual value.
+		 * @param message   Message to display on error.
+		 */
+		isNotFunction<T>(value: T, message?: string): void;
+
+		/**
+		 * Asserts that value is an object of type 'Object'
+		 * (as revealed by Object.prototype.toString).
+		 *
+		 * @type T   Type of value.
+		 * @param value   Actual value.
+		 * @param message   Message to display on error.
+		 * @remarks The assertion does not match subclassed objects.
+		 */
+		isObject<T>(value: T, message?: string): void;
+
+		/**
+		 * Asserts that value is not an object of type 'Object'
+		 * (as revealed by Object.prototype.toString).
+		 *
+		 * @type T   Type of value.
+		 * @param value   Actual value.
+		 * @param message   Message to display on error.
+		 */
+		isNotObject<T>(value: T, message?: string): void;
+
+		/**
+		 * Asserts that value is an array.
+		 *
+		 * @type T   Type of value.
+		 * @param value   Actual value.
+		 * @param message   Message to display on error.
+		 */
+		isArray<T>(value: T, message?: string): void;
+
+		/**
+		 * Asserts that value is not an array.
+		 *
+		 * @type T   Type of value.
+		 * @param value   Actual value.
+		 * @param message   Message to display on error.
+		 */
+		isNotArray<T>(value: T, message?: string): void;
+
+		/**
+		 * Asserts that value is a string.
+		 *
+		 * @type T   Type of value.
+		 * @param value   Actual value.
+		 * @param message   Message to display on error.
+		 */
+		isString<T>(value: T, message?: string): void;
+
+		/**
+		 * Asserts that value is not a string.
+		 *
+		 * @type T   Type of value.
+		 * @param value   Actual value.
+		 * @param message   Message to display on error.
+		 */
+		isNotString<T>(value: T, message?: string): void;
+
+		/**
+		 * Asserts that value is a number.
+		 *
+		 * @type T   Type of value.
+		 * @param value   Actual value.
+		 * @param message   Message to display on error.
+		 */
+		isNumber<T>(value: T, message?: string): void;
+
+		/**
+		 * Asserts that value is not a number.
+		 *
+		 * @type T   Type of value.
+		 * @param value   Actual value.
+		 * @param message   Message to display on error.
+		 */
+		isNotNumber<T>(value: T, message?: string): void;
+
+		/**
+		 * Asserts that value is a boolean.
+		 *
+		 * @type T   Type of value.
+		 * @param value   Actual value.
+		 * @param message   Message to display on error.
+		 */
+		isBoolean<T>(value: T, message?: string): void;
+
+		/**
+		 * Asserts that value is not a boolean.
+		 *
+		 * @type T   Type of value.
+		 * @param value   Actual value.
+		 * @param message   Message to display on error.
+		 */
+		isNotBoolean<T>(value: T, message?: string): void;
+
+		/**
+		 * Asserts that value's type is name, as determined by Object.prototype.toString.
+		 *
+		 * @type T   Type of value.
+		 * @param value   Actual value.
+		 * @param name   Potential expected type name of value.
+		 * @param message   Message to display on error.
+		 */
+		typeOf<T>(value: T, name: string, message?: string): void;
+
+		/**
+		 * Asserts that value's type is not name, as determined by Object.prototype.toString.
+		 *
+		 * @type T   Type of value.
+		 * @param value   Actual value.
+		 * @param name   Potential expected type name of value.
+		 * @param message   Message to display on error.
+		 */
+		notTypeOf<T>(value: T, name: string, message?: string): void;
+
+		/**
+		 * Asserts that value is an instance of constructor.
+		 *
+		 * @type T   Type of value.
+		 * @param value   Actual value.
+		 * @param constructor   Potential expected contructor of value.
+		 * @param message   Message to display on error.
+		 */
+		instanceOf<T>(value: T, constructor: Function, message?: string): void;
+
+		/**
+		 * Asserts that value is not an instance of constructor.
+		 *
+		 * @type T   Type of value.
+		 * @param value   Actual value.
+		 * @param constructor   Potential expected contructor of value.
+		 * @param message   Message to display on error.
+		 */
+		notInstanceOf<T>(value: T, type: Function, message?: string): void;
+
+		/**
+		 * Asserts that haystack includes needle.
+		 *
+		 * @param haystack   Container string.
+		 * @param needle   Potential expected substring of haystack.
+		 * @param message   Message to display on error.
+		 */
+		include(haystack: string, needle: string, message?: string): void;
+
+		/**
+		 * Asserts that haystack includes needle.
+		 *
+		 * @type T   Type of values in haystack.
+		 * @param haystack   Container array.
+		 * @param needle   Potential value contained in haystack.
+		 * @param message   Message to display on error.
+		 */
+		include<T>(haystack: T[], needle: T, message?: string): void;
+
+		/**
+		 * Asserts that haystack does not include needle.
+		 *
+		 * @param haystack   Container string.
+		 * @param needle   Potential expected substring of haystack.
+		 * @param message   Message to display on error.
+		 */
+		notInclude(haystack: string, needle: any, message?: string): void;
+
+		/**
+		 * Asserts that haystack does not include needle.
+		 *
+		 * @type T   Type of values in haystack.
+		 * @param haystack   Container array.
+		 * @param needle   Potential value contained in haystack.
+		 * @param message   Message to display on error.
+		 */
+		notInclude(haystack: any[], needle: any, message?: string): void;
+
+		/**
+		 * Asserts that value matches the regular expression regexp.
+		 *
+		 * @param value   Actual value.
+		 * @param regexp   Potential match of value.
+		 * @param message   Message to display on error.
+		 */
+		match(value: string, regexp: RegExp, message?: string): void;
+
+		/**
+		 * Asserts that value does not match the regular expression regexp.
+		 *
+		 * @param value   Actual value.
+		 * @param regexp   Potential match of value.
+		 * @param message   Message to display on error.
+		 */
+		notMatch(expected: any, regexp: RegExp, message?: string): void;
+
+		/**
+		 * Asserts that object has a property named by property.
+		 *
+		 * @type T   Type of object.
+		 * @param object   Container object.
+		 * @param property   Potential contained property of object.
+		 * @param message   Message to display on error.
+		 */
+		property<T>(object: T, property: string /* keyof T */, message?: string): void;
+
+		/**
+		 * Asserts that object has a property named by property.
+		 *
+		 * @type T   Type of object.
+		 * @param object   Container object.
+		 * @param property   Potential contained property of object.
+		 * @param message   Message to display on error.
+		 */
+		notProperty<T>(object: T, property: string /* keyof T */, message?: string): void;
+
+		/**
+		 * Asserts that object has a property named by property, which can be a string
+		 * using dot- and bracket-notation for deep reference.
+		 *
+		 * @type T   Type of object.
+		 * @param object   Container object.
+		 * @param property   Potential contained property of object.
+		 * @param message   Message to display on error.
+		 */
+		deepProperty<T>(object: T, property: string, message?: string): void;
+
+		/**
+		 * Asserts that object does not have a property named by property, which can be a
+		 * string using dot- and bracket-notation for deep reference.
+		 *
+		 * @type T   Type of object.
+		 * @param object   Container object.
+		 * @param property   Potential contained property of object.
+		 * @param message   Message to display on error.
+		 */
+		notDeepProperty<T>(object: T, property: string, message?: string): void;
+
+		/**
+		 * Asserts that object has a property named by property with value given by value.
+		 *
+		 * @type T   Type of object.
+		 * @type V   Type of value.
+		 * @param object   Container object.
+		 * @param property   Potential contained property of object.
+		 * @param value   Potential expected property value.
+		 * @param message   Message to display on error.
+		 */
+		propertyVal<T, V>(object: T, property: string /* keyof T */, value: V, message?: string): void;
+
+		/**
+		 * Asserts that object has a property named by property with value given by value.
+		 *
+		 * @type T   Type of object.
+		 * @type V   Type of value.
+		 * @param object   Container object.
+		 * @param property   Potential contained property of object.
+		 * @param value   Potential expected property value.
+		 * @param message   Message to display on error.
+		 */
+		propertyNotVal<T, V>(object: T, property: string /* keyof T */, value: V, message?: string): void;
+
+		/**
+		 * Asserts that object has a property named by property, which can be a string
+		 * using dot- and bracket-notation for deep reference.
+		 *
+		 * @type T   Type of object.
+		 * @type V   Type of value.
+		 * @param object   Container object.
+		 * @param property   Potential contained property of object.
+		 * @param value   Potential expected property value.
+		 * @param message   Message to display on error.
+		 */
+		deepPropertyVal<T, V>(object: T, property: string, value: V, message?: string): void;
+
+		/**
+		 * Asserts that object does not have a property named by property, which can be a
+		 * string using dot- and bracket-notation for deep reference.
+		 *
+		 * @type T   Type of object.
+		 * @type V   Type of value.
+		 * @param object   Container object.
+		 * @param property   Potential contained property of object.
+		 * @param value   Potential expected property value.
+		 * @param message   Message to display on error.
+		 */
+		deepPropertyNotVal<T, V>(object: T, property: string, value: V, message?: string): void;
+
+		/**
+		 * Asserts that object has a length property with the expected value.
+		 *
+		 * @type T   Type of object.
+		 * @param object   Container object.
+		 * @param length   Potential expected length of object.
+		 * @param message   Message to display on error.
+		 */
+		lengthOf<T extends { readonly length?: number }>(object: T, length: number, message?: string): void;
+
+		/**
+		 * Asserts that fn will throw an error.
+		 *
+		 * @param fn   Function that may throw.
+		 * @param message   Message to display on error.
+		 */
+		throw(fn: Function, message?: string): void;
+
+		/**
+		 * Asserts that function will throw an error with message matching regexp.
+		 *
+		 * @param fn   Function that may throw.
+		 * @param regExp   Potential expected message match.
+		 * @param message   Message to display on error.
+		 */
+		throw(fn: Function, regExp: RegExp): void;
+
+		/**
+		 * Asserts that function will throw an error that is an instance of constructor.
+		 *
+		 * @param fn   Function that may throw.
+		 * @param constructor   Potential expected error constructor.
+		 * @param message   Message to display on error.
+		 */
+		throw(fn: Function, constructor: Function, message?: string): void;
+
+		/**
+		 * Asserts that function will throw an error that is an instance of constructor
+		 * and an error with message matching regexp.
+		 *
+		 * @param fn   Function that may throw.
+		 * @param constructor   Potential expected error constructor.
+		 * @param message   Message to display on error.
+		 */
+		throw(fn: Function, constructor: Function, regExp: RegExp): void;
+
+		/**
+		 * Asserts that fn will throw an error.
+		 *
+		 * @param fn   Function that may throw.
+		 * @param message   Message to display on error.
+		 */
+		throws(fn: Function, message?: string): void;
+
+		/**
+		 * Asserts that function will throw an error with message matching regexp.
+		 *
+		 * @param fn   Function that may throw.
+		 * @param regExp   Potential expected message match.
+		 * @param message   Message to display on error.
+		 */
+		throws(fn: Function, regExp: RegExp, message?: string): void;
+
+		/**
+		 * Asserts that function will throw an error that is an instance of constructor.
+		 *
+		 * @param fn   Function that may throw.
+		 * @param constructor   Potential expected error constructor.
+		 * @param message   Message to display on error.
+		 */
+		throws(fn: Function, errType: Function, message?: string): void;
+
+		/**
+		 * Asserts that function will throw an error that is an instance of constructor
+		 * and an error with message matching regexp.
+		 *
+		 * @param fn   Function that may throw.
+		 * @param constructor   Potential expected error constructor.
+		 * @param message   Message to display on error.
+		 */
+		throws(fn: Function, errType: Function, regExp: RegExp): void;
+
+		/**
+		 * Asserts that fn will throw an error.
+		 *
+		 * @param fn   Function that may throw.
+		 * @param message   Message to display on error.
+		 */
+		Throw(fn: Function, message?: string): void;
+
+		/**
+		 * Asserts that function will throw an error with message matching regexp.
+		 *
+		 * @param fn   Function that may throw.
+		 * @param regExp   Potential expected message match.
+		 * @param message   Message to display on error.
+		 */
+		Throw(fn: Function, regExp: RegExp): void;
+
+		/**
+		 * Asserts that function will throw an error that is an instance of constructor.
+		 *
+		 * @param fn   Function that may throw.
+		 * @param constructor   Potential expected error constructor.
+		 * @param message   Message to display on error.
+		 */
+		Throw(fn: Function, errType: Function, message?: string): void;
+
+		/**
+		 * Asserts that function will throw an error that is an instance of constructor
+		 * and an error with message matching regexp.
+		 *
+		 * @param fn   Function that may throw.
+		 * @param constructor   Potential expected error constructor.
+		 * @param message   Message to display on error.
+		 */
+		Throw(fn: Function, errType: Function, regExp: RegExp): void;
+
+		/**
+		 * Asserts that fn will not throw an error.
+		 *
+		 * @param fn   Function that may throw.
+		 * @param message   Message to display on error.
+		 */
+		doesNotThrow(fn: Function, message?: string): void;
+
+		/**
+		 * Asserts that function will throw an error with message matching regexp.
+		 *
+		 * @param fn   Function that may throw.
+		 * @param regExp   Potential expected message match.
+		 * @param message   Message to display on error.
+		 */
+		doesNotThrow(fn: Function, regExp: RegExp): void;
+
+		/**
+		 * Asserts that function will throw an error that is an instance of constructor.
+		 *
+		 * @param fn   Function that may throw.
+		 * @param constructor   Potential expected error constructor.
+		 * @param message   Message to display on error.
+		 */
+		doesNotThrow(fn: Function, errType: Function, message?: string): void;
+
+		/**
+		 * Asserts that function will throw an error that is an instance of constructor
+		 * and an error with message matching regexp.
+		 *
+		 * @param fn   Function that may throw.
+		 * @param constructor   Potential expected error constructor.
+		 * @param message   Message to display on error.
+		 */
+		doesNotThrow(fn: Function, errType: Function, regExp: RegExp): void;
+
+		/**
+		 * Compares two values using operator.
+		 *
+		 * @param val1   Left value during comparison.
+		 * @param operator   Comparison operator.
+		 * @param val2   Right value during comparison.
+		 * @param message   Message to display on error.
+		 */
+		operator(val1: OperatorComparable, operator: Operator, val2: OperatorComparable, message?: string): void;
+
+		/**
+		 * Asserts that the target is equal to expected, to within a +/- delta range.
+		 *
+		 * @param actual   Actual value
+		 * @param expected   Potential expected value.
+		 * @param delta   Maximum differenced between values.
+		 * @param message   Message to display on error.
+		 */
+		closeTo(actual: number, expected: number, delta: number, message?: string): void;
+
+		/**
+		 * Asserts that the target is equal to expected, to within a +/- delta range.
+		 *
+		 * @param actual   Actual value
+		 * @param expected   Potential expected value.
+		 * @param delta   Maximum differenced between values.
+		 * @param message   Message to display on error.
+		 */
+		approximately(act: number, exp: number, delta: number, message?: string): void;
+
+		/**
+		 * Asserts that set1 and set2 have the same members. Order is not take into account.
+		 *
+		 * @type T   Type of set values.
+		 * @param set1   Actual set of values.
+		 * @param set2   Potential expected set of values.
+		 * @param message   Message to display on error.
+		 */
+		sameMembers<T>(set1: T[], set2: T[], message?: string): void;
+
+		/**
+		 * Asserts that set1 and set2 have the same members using deep equality checking.
+		 * Order is not take into account.
+		 *
+		 * @type T   Type of set values.
+		 * @param set1   Actual set of values.
+		 * @param set2   Potential expected set of values.
+		 * @param message   Message to display on error.
+		 */
+		sameDeepMembers<T>(set1: T[], set2: T[], message?: string): void;
+
+		/**
+		 * Asserts that subset is included in superset. Order is not take into account.
+		 *
+		 * @type T   Type of set values.
+		 * @param superset   Actual set of values.
+		 * @param subset   Potential contained set of values.
+		 * @param message   Message to display on error.
+		 */
+		includeMembers<T>(superset: T[], subset: T[], message?: string): void;
+
+		/**
+		 * Asserts that subset is included in superset using deep equality checking.
+		 * Order is not take into account.
+		 *
+		 * @type T   Type of set values.
+		 * @param superset   Actual set of values.
+		 * @param subset   Potential contained set of values.
+		 * @param message   Message to display on error.
+		 */
+		includeDeepMembers<T>(superset: T[], subset: T[], message?: string): void;
+
+		/**
+		 * Asserts that non-object, non-array value inList appears in the flat array list.
+		 *
+		 * @type T   Type of list values.
+		 * @param inList   Value expected to be in the list.
+		 * @param list   List of values.
+		 * @param message   Message to display on error.
+		 */
+		oneOf<T>(inList: T, list: T[], message?: string): void;
+
+		/**
+		 * Asserts that a function changes the value of a property.
+		 *
+		 * @type T   Type of object.
+		 * @param modifier   Function to run.
+		 * @param object   Container object.
+		 * @param property   Property of object expected to be modified.
+		 * @param message   Message to display on error.
+		 */
+		changes<T>(modifier: Function, object: T, property: string /* keyof T */, message?: string): void;
+
+		/**
+		 * Asserts that a function does not change the value of a property.
+		 *
+		 * @type T   Type of object.
+		 * @param modifier   Function to run.
+		 * @param object   Container object.
+		 * @param property   Property of object expected not to be modified.
+		 * @param message   Message to display on error.
+		 */
+		doesNotChange<T>(modifier: Function, object: T, property: string /* keyof T */, message?: string): void;
+
+		/**
+		 * Asserts that a function increases an object property.
+		 *
+		 * @type T   Type of object.
+		 * @param modifier   Function to run.
+		 * @param object   Container object.
+		 * @param property   Property of object expected to be increased.
+		 * @param message   Message to display on error.
+		 */
+		increases<T>(modifier: Function, object: T, property: string /* keyof T */, message?: string): void;
+
+		/**
+		 * Asserts that a function does not increase an object property.
+		 *
+		 * @type T   Type of object.
+		 * @param modifier   Function to run.
+		 * @param object   Container object.
+		 * @param property   Property of object expected not to be increased.
+		 * @param message   Message to display on error.
+		 */
+		doesNotIncrease<T>(modifier: Function, object: T, property: string /* keyof T */, message?: string): void;
+
+		/**
+		 * Asserts that a function decreases an object property.
+		 *
+		 * @type T   Type of object.
+		 * @param modifier   Function to run.
+		 * @param object   Container object.
+		 * @param property   Property of object expected to be decreased.
+		 * @param message   Message to display on error.
+		 */
+		decreases<T>(modifier: Function, object: T, property: string /* keyof T */, message?: string): void;
+
+		/**
+		 * Asserts that a function does not decrease an object property.
+		 *
+		 * @type T   Type of object.
+		 * @param modifier   Function to run.
+		 * @param object   Container object.
+		 * @param property   Property of object expected not to be decreased.
+		 * @param message   Message to display on error.
+		 */
+		doesNotDecrease<T>(modifier: Function, object: T, property: string /* keyof T */, message?: string): void;
+
+		/**
+		 * Asserts if value is not a false value, and throws if it is a true value.
+		 *
+		 * @type T   Type of object.
+		 * @param object   Actual value.
+		 * @param message   Message to display on error.
+		 * @remarks This is added to allow for chai to be a drop-in replacement for
+		 *          Node’s assert class.
+		 */
+		ifError<T>(object: T, message?: string): void;
+
+		/**
+		 * Asserts that object is extensible (can have new properties added to it).
+		 *
+		 * @type T   Type of object
+		 * @param object   Actual value.
+		 * @param message   Message to display on error.
+		 */
+		isExtensible<T>(object: T, message?: string): void;
+
+		/**
+		 * Asserts that object is extensible (can have new properties added to it).
+		 *
+		 * @type T   Type of object
+		 * @param object   Actual value.
+		 * @param message   Message to display on error.
+		 */
+		extensible<T>(object: T, message?: string): void;
+
+		/**
+		 * Asserts that object is not extensible.
+		 *
+		 * @type T   Type of object
+		 * @param object   Actual value.
+		 * @param message   Message to display on error.
+		 */
+		isNotExtensible<T>(object: T, message?: string): void;
+
+		/**
+		 * Asserts that object is not extensible.
+		 *
+		 * @type T   Type of object
+		 * @param object   Actual value.
+		 * @param message   Message to display on error.
+		 */
+		notExtensible<T>(object: T, message?: string): void;
+
+		/**
+		 * Asserts that object is sealed (can have new properties added to it
+		 * and its existing properties cannot be removed).
+		 *
+		 * @type T   Type of object
+		 * @param object   Actual value.
+		 * @param message   Message to display on error.
+		 */
+		isSealed<T>(object: T, message?: string): void;
+
+		/**
+		 * Asserts that object is sealed (can have new properties added to it
+		 * and its existing properties cannot be removed).
+		 *
+		 * @type T   Type of object
+		 * @param object   Actual value.
+		 * @param message   Message to display on error.
+		 */
+		sealed<T>(object: T, message?: string): void;
+
+		/**
+		 * Asserts that object is not sealed.
+		 *
+		 * @type T   Type of object
+		 * @param object   Actual value.
+		 * @param message   Message to display on error.
+		 */
+		isNotSealed<T>(object: T, message?: string): void;
+
+		/**
+		 * Asserts that object is not sealed.
+		 *
+		 * @type T   Type of object
+		 * @param object   Actual value.
+		 * @param message   Message to display on error.
+		 */
+		notSealed<T>(object: T, message?: string): void;
+
+		/**
+		 * Asserts that object is frozen (cannot have new properties added to it
+		 * and its existing properties cannot be removed).
+		 *
+		 * @type T   Type of object
+		 * @param object   Actual value.
+		 * @param message   Message to display on error.
+		 */
+		isFrozen<T>(object: T, message?: string): void;
+
+		/**
+		 * Asserts that object is frozen (cannot have new properties added to it
+		 * and its existing properties cannot be removed).
+		 *
+		 * @type T   Type of object
+		 * @param object   Actual value.
+		 * @param message   Message to display on error.
+		 */
+		frozen<T>(object: T, message?: string): void;
+
+		/**
+		 * Asserts that object is not frozen (cannot have new properties added to it
+		 * and its existing properties cannot be removed).
+		 *
+		 * @type T   Type of object
+		 * @param object   Actual value.
+		 * @param message   Message to display on error.
+		 */
+		isNotFrozen<T>(object: T, message?: string): void;
+
+		/**
+		 * Asserts that object is not frozen (cannot have new properties added to it
+		 * and its existing properties cannot be removed).
+		 *
+		 * @type T   Type of object
+		 * @param object   Actual value.
+		 * @param message   Message to display on error.
+		 */
+		notFrozen<T>(object: T, message?: string): void;
+	}
+
+	export interface Config {
+		/**
+		 * Default: false
+		 */
+		includeStack: boolean;
+
+		/**
+		 * Default: true
+		 */
+		showDiff: boolean;
+
+		/**
+		 * Default: 40
+		 */
+		truncateThreshold: number;
+	}
+
+	export class AssertionError {
+		constructor(message: string, _props?: any, ssf?: Function);
+		public name: string;
+		public message: string;
+		public showDiff: boolean;
+		public stack: string;
+	}
 }
 
 declare const chai: Chai.ChaiStatic;
 
 declare module 'chai' {
-    export = chai;
+	export = chai;
 }
 
 interface Object {
-    should: Chai.Assertion;
+	should: Chai.Assertion;
 }
diff --git a/packages/chai-typescript-typings/package.json b/packages/chai-typescript-typings/package.json
index db7cba863..f2136ffa4 100644
--- a/packages/chai-typescript-typings/package.json
+++ b/packages/chai-typescript-typings/package.json
@@ -1,16 +1,16 @@
 {
-    "name": "chai-typescript-typings",
-    "version": "0.0.2",
-    "description": "Typescript type definitions for chai",
-    "main": "index.d.ts",
-    "types": "index.d.ts",
-    "repository": {
-        "type": "git",
-        "url": "git+https://github.com/0xProject/0x.js.git"
-    },
-    "license": "Apache-2.0",
-    "bugs": {
-        "url": "https://github.com/0xProject/0x.js/issues"
-    },
-    "homepage": "https://github.com/0xProject/0x.js/packages/chai-typescript-typings#readme"
+	"name": "chai-typescript-typings",
+	"version": "0.0.2",
+	"description": "Typescript type definitions for chai",
+	"main": "index.d.ts",
+	"types": "index.d.ts",
+	"repository": {
+		"type": "git",
+		"url": "git+https://github.com/0xProject/0x.js.git"
+	},
+	"license": "Apache-2.0",
+	"bugs": {
+		"url": "https://github.com/0xProject/0x.js/issues"
+	},
+	"homepage": "https://github.com/0xProject/0x.js/packages/chai-typescript-typings#readme"
 }
diff --git a/packages/chai-typescript-typings/tslint.json b/packages/chai-typescript-typings/tslint.json
index 9a93a1f74..ef528b22e 100644
--- a/packages/chai-typescript-typings/tslint.json
+++ b/packages/chai-typescript-typings/tslint.json
@@ -1,3 +1,3 @@
 {
-    "extends": ["tslint-config-0xproject"]
+	"extends": ["tslint-config-0xproject"]
 }
diff --git a/packages/connect/package.json b/packages/connect/package.json
index e67947dd4..2eff3f681 100644
--- a/packages/connect/package.json
+++ b/packages/connect/package.json
@@ -1,69 +1,64 @@
 {
-    "name": "@0xproject/connect",
-    "version": "0.5.2",
-    "description": "A javascript library for interacting with the standard relayer api",
-    "keywords": [
-        "connect",
-        "0xproject",
-        "ethereum",
-        "tokens",
-        "exchange"
-    ],
-    "main": "lib/src/index.js",
-    "types": "lib/src/index.d.ts",
-    "scripts": {
-        "build": "tsc",
-        "clean": "shx rm -rf _bundles lib test_temp",
-        "docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --json $JSON_FILE_PATH $PROJECT_DIR",
-        "upload_docs_json": "aws s3 cp generated_docs/index.json $S3_URL --profile 0xproject --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --content-type application/json",
-        "copy_test_fixtures": "copyfiles -u 2 './test/fixtures/**/*.json' ./lib/test/fixtures",
-        "lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'",
-        "run_mocha": "mocha lib/test/**/*_test.js",
-        "test": "run-s clean build copy_test_fixtures run_mocha",
-        "test:circleci": "yarn test"
-    },
-    "repository": {
-        "type": "git",
-        "url": "https://github.com/0xProject/0x.js.git"
-    },
-    "author": "Brandon Millman",
-    "license": "Apache-2.0",
-    "engines": {
-        "node": ">=6.0.0"
-    },
-    "bugs": {
-        "url": "https://github.com/0xProject/0x.js/issues"
-    },
-    "homepage": "https://github.com/0xProject/0x.js/packages/connect/README.md",
-    "dependencies": {
-        "@0xproject/assert": "^0.0.13",
-        "@0xproject/json-schemas": "^0.7.5",
-        "@0xproject/utils": "^0.2.2",
-        "isomorphic-fetch": "^2.2.1",
-        "lodash": "^4.17.4",
-        "query-string": "^5.0.1",
-        "websocket": "^1.0.25"
-    },
-    "devDependencies": {
-        "@0xproject/tslint-config": "^0.4.4",
-        "@types/fetch-mock": "^5.12.1",
-        "@types/lodash": "^4.14.86",
-        "@types/mocha": "^2.2.42",
-        "@types/query-string": "^5.0.1",
-        "@types/websocket": "^0.0.34",
-        "chai": "^4.0.1",
-        "chai-as-promised": "^7.1.0",
-        "chai-as-promised-typescript-typings": "^0.0.6",
-        "chai-typescript-typings": "^0.0.2",
-        "copyfiles": "^1.2.0",
-        "dirty-chai": "^2.0.1",
-        "fetch-mock": "^5.13.1",
-        "mocha": "^4.0.1",
-        "npm-run-all": "^4.1.2",
-        "shx": "^0.2.2",
-        "tslint": "5.8.0",
-        "typedoc": "~0.8.0",
-        "typescript": "~2.6.1",
-        "web3-typescript-typings": "^0.9.6"
-    }
+	"name": "@0xproject/connect",
+	"version": "0.5.2",
+	"description": "A javascript library for interacting with the standard relayer api",
+	"keywords": ["connect", "0xproject", "ethereum", "tokens", "exchange"],
+	"main": "lib/src/index.js",
+	"types": "lib/src/index.d.ts",
+	"scripts": {
+		"build": "tsc",
+		"clean": "shx rm -rf _bundles lib test_temp",
+		"docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --json $JSON_FILE_PATH $PROJECT_DIR",
+		"upload_docs_json":
+			"aws s3 cp generated_docs/index.json $S3_URL --profile 0xproject --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --content-type application/json",
+		"copy_test_fixtures": "copyfiles -u 2 './test/fixtures/**/*.json' ./lib/test/fixtures",
+		"lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'",
+		"run_mocha": "mocha lib/test/**/*_test.js",
+		"test": "run-s clean build copy_test_fixtures run_mocha",
+		"test:circleci": "yarn test"
+	},
+	"repository": {
+		"type": "git",
+		"url": "https://github.com/0xProject/0x.js.git"
+	},
+	"author": "Brandon Millman",
+	"license": "Apache-2.0",
+	"engines": {
+		"node": ">=6.0.0"
+	},
+	"bugs": {
+		"url": "https://github.com/0xProject/0x.js/issues"
+	},
+	"homepage": "https://github.com/0xProject/0x.js/packages/connect/README.md",
+	"dependencies": {
+		"@0xproject/assert": "^0.0.13",
+		"@0xproject/json-schemas": "^0.7.5",
+		"@0xproject/utils": "^0.2.2",
+		"isomorphic-fetch": "^2.2.1",
+		"lodash": "^4.17.4",
+		"query-string": "^5.0.1",
+		"websocket": "^1.0.25"
+	},
+	"devDependencies": {
+		"@0xproject/tslint-config": "^0.4.4",
+		"@types/fetch-mock": "^5.12.1",
+		"@types/lodash": "^4.14.86",
+		"@types/mocha": "^2.2.42",
+		"@types/query-string": "^5.0.1",
+		"@types/websocket": "^0.0.34",
+		"chai": "^4.0.1",
+		"chai-as-promised": "^7.1.0",
+		"chai-as-promised-typescript-typings": "^0.0.6",
+		"chai-typescript-typings": "^0.0.2",
+		"copyfiles": "^1.2.0",
+		"dirty-chai": "^2.0.1",
+		"fetch-mock": "^5.13.1",
+		"mocha": "^4.0.1",
+		"npm-run-all": "^4.1.2",
+		"shx": "^0.2.2",
+		"tslint": "5.8.0",
+		"typedoc": "~0.8.0",
+		"typescript": "~2.6.1",
+		"web3-typescript-typings": "^0.9.6"
+	}
 }
diff --git a/packages/connect/src/globals.d.ts b/packages/connect/src/globals.d.ts
index 078e189cd..d2011026b 100644
--- a/packages/connect/src/globals.d.ts
+++ b/packages/connect/src/globals.d.ts
@@ -1,6 +1,6 @@
 declare module 'dirty-chai';
 
 declare module '*.json' {
-    const value: any;
-    export default value;
+	const value: any;
+	export default value;
 }
diff --git a/packages/connect/src/http_client.ts b/packages/connect/src/http_client.ts
index 3df77b0f0..03c0b9702 100644
--- a/packages/connect/src/http_client.ts
+++ b/packages/connect/src/http_client.ts
@@ -6,17 +6,17 @@ import * as queryString from 'query-string';
 
 import { schemas as clientSchemas } from './schemas/schemas';
 import {
-    Client,
-    FeesRequest,
-    FeesResponse,
-    HttpRequestOptions,
-    HttpRequestType,
-    OrderbookRequest,
-    OrderbookResponse,
-    OrdersRequest,
-    SignedOrder,
-    TokenPairsItem,
-    TokenPairsRequest,
+	Client,
+	FeesRequest,
+	FeesResponse,
+	HttpRequestOptions,
+	HttpRequestType,
+	OrderbookRequest,
+	OrderbookResponse,
+	OrdersRequest,
+	SignedOrder,
+	TokenPairsItem,
+	TokenPairsRequest,
 } from './types';
 import { relayerResponseJsonParsers } from './utils/relayer_response_json_parsers';
 
@@ -26,127 +26,127 @@ const TRAILING_SLASHES_REGEX = /\/+$/;
  * that implement the standard relayer API v0
  */
 export class HttpClient implements Client {
-    private _apiEndpointUrl: string;
-    /**
-     * Instantiates a new HttpClient instance
-     * @param   url    The relayer API base HTTP url you would like to interact with
-     * @return  An instance of HttpClient
-     */
-    constructor(url: string) {
-        assert.isHttpUrl('url', url);
-        this._apiEndpointUrl = url.replace(TRAILING_SLASHES_REGEX, ''); // remove trailing slashes
-    }
-    /**
-     * Retrieve token pair info from the API
-     * @param   request     A TokenPairsRequest instance describing specific token information
-     *                      to retrieve
-     * @return  The resulting TokenPairsItems that match the request
-     */
-    public async getTokenPairsAsync(request?: TokenPairsRequest): Promise<TokenPairsItem[]> {
-        if (!_.isUndefined(request)) {
-            assert.doesConformToSchema('request', request, clientSchemas.relayerTokenPairsRequestSchema);
-        }
-        const requestOpts = {
-            params: request,
-        };
-        const responseJson = await this._requestAsync('/token_pairs', HttpRequestType.Get, requestOpts);
-        const tokenPairs = relayerResponseJsonParsers.parseTokenPairsJson(responseJson);
-        return tokenPairs;
-    }
-    /**
-     * Retrieve orders from the API
-     * @param   request     An OrdersRequest instance describing specific orders to retrieve
-     * @return  The resulting SignedOrders that match the request
-     */
-    public async getOrdersAsync(request?: OrdersRequest): Promise<SignedOrder[]> {
-        if (!_.isUndefined(request)) {
-            assert.doesConformToSchema('request', request, clientSchemas.relayerOrdersRequestSchema);
-        }
-        const requestOpts = {
-            params: request,
-        };
-        const responseJson = await this._requestAsync(`/orders`, HttpRequestType.Get, requestOpts);
-        const orders = relayerResponseJsonParsers.parseOrdersJson(responseJson);
-        return orders;
-    }
-    /**
-     * Retrieve a specific order from the API
-     * @param   orderHash     An orderHash generated from the desired order
-     * @return  The SignedOrder that matches the supplied orderHash
-     */
-    public async getOrderAsync(orderHash: string): Promise<SignedOrder> {
-        assert.doesConformToSchema('orderHash', orderHash, schemas.orderHashSchema);
-        const responseJson = await this._requestAsync(`/order/${orderHash}`, HttpRequestType.Get);
-        const order = relayerResponseJsonParsers.parseOrderJson(responseJson);
-        return order;
-    }
-    /**
-     * Retrieve an orderbook from the API
-     * @param   request     An OrderbookRequest instance describing the specific orderbook to retrieve
-     * @return  The resulting OrderbookResponse that matches the request
-     */
-    public async getOrderbookAsync(request: OrderbookRequest): Promise<OrderbookResponse> {
-        assert.doesConformToSchema('request', request, clientSchemas.relayerOrderBookRequestSchema);
-        const requestOpts = {
-            params: request,
-        };
-        const responseJson = await this._requestAsync('/orderbook', HttpRequestType.Get, requestOpts);
-        const orderbook = relayerResponseJsonParsers.parseOrderbookResponseJson(responseJson);
-        return orderbook;
-    }
-    /**
-     * Retrieve fee information from the API
-     * @param   request     A FeesRequest instance describing the specific fees to retrieve
-     * @return  The resulting FeesResponse that matches the request
-     */
-    public async getFeesAsync(request: FeesRequest): Promise<FeesResponse> {
-        assert.doesConformToSchema('request', request, schemas.relayerApiFeesPayloadSchema);
-        const requestOpts = {
-            payload: request,
-        };
-        const responseJson = await this._requestAsync('/fees', HttpRequestType.Post, requestOpts);
-        const fees = relayerResponseJsonParsers.parseFeesResponseJson(responseJson);
-        return fees;
-    }
-    /**
-     * Submit a signed order to the API
-     * @param   signedOrder     A SignedOrder instance to submit
-     */
-    public async submitOrderAsync(signedOrder: SignedOrder): Promise<void> {
-        assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
-        const requestOpts = {
-            payload: signedOrder,
-        };
-        await this._requestAsync('/order', HttpRequestType.Post, requestOpts);
-    }
-    private async _requestAsync(
-        path: string,
-        requestType: HttpRequestType,
-        requestOptions?: HttpRequestOptions,
-    ): Promise<any> {
-        const params = _.get(requestOptions, 'params');
-        const payload = _.get(requestOptions, 'payload');
-        let query = '';
-        if (!_.isUndefined(params) && !_.isEmpty(params)) {
-            const stringifiedParams = queryString.stringify(params);
-            query = `?${stringifiedParams}`;
-        }
-        const url = `${this._apiEndpointUrl}${path}${query}`;
-        const headers = new Headers({
-            'content-type': 'application/json',
-        });
-        const response = await fetch(url, {
-            method: requestType,
-            body: JSON.stringify(payload),
-            headers,
-        });
-        const json = await response.json();
-        if (!response.ok) {
-            const errorString = `${response.status} - ${response.statusText}\n${requestType} ${url}\n${JSON.stringify(
-                json,
-            )}`;
-            throw Error(errorString);
-        }
-        return json;
-    }
+	private _apiEndpointUrl: string;
+	/**
+	 * Instantiates a new HttpClient instance
+	 * @param   url    The relayer API base HTTP url you would like to interact with
+	 * @return  An instance of HttpClient
+	 */
+	constructor(url: string) {
+		assert.isHttpUrl('url', url);
+		this._apiEndpointUrl = url.replace(TRAILING_SLASHES_REGEX, ''); // remove trailing slashes
+	}
+	/**
+	 * Retrieve token pair info from the API
+	 * @param   request     A TokenPairsRequest instance describing specific token information
+	 *                      to retrieve
+	 * @return  The resulting TokenPairsItems that match the request
+	 */
+	public async getTokenPairsAsync(request?: TokenPairsRequest): Promise<TokenPairsItem[]> {
+		if (!_.isUndefined(request)) {
+			assert.doesConformToSchema('request', request, clientSchemas.relayerTokenPairsRequestSchema);
+		}
+		const requestOpts = {
+			params: request,
+		};
+		const responseJson = await this._requestAsync('/token_pairs', HttpRequestType.Get, requestOpts);
+		const tokenPairs = relayerResponseJsonParsers.parseTokenPairsJson(responseJson);
+		return tokenPairs;
+	}
+	/**
+	 * Retrieve orders from the API
+	 * @param   request     An OrdersRequest instance describing specific orders to retrieve
+	 * @return  The resulting SignedOrders that match the request
+	 */
+	public async getOrdersAsync(request?: OrdersRequest): Promise<SignedOrder[]> {
+		if (!_.isUndefined(request)) {
+			assert.doesConformToSchema('request', request, clientSchemas.relayerOrdersRequestSchema);
+		}
+		const requestOpts = {
+			params: request,
+		};
+		const responseJson = await this._requestAsync(`/orders`, HttpRequestType.Get, requestOpts);
+		const orders = relayerResponseJsonParsers.parseOrdersJson(responseJson);
+		return orders;
+	}
+	/**
+	 * Retrieve a specific order from the API
+	 * @param   orderHash     An orderHash generated from the desired order
+	 * @return  The SignedOrder that matches the supplied orderHash
+	 */
+	public async getOrderAsync(orderHash: string): Promise<SignedOrder> {
+		assert.doesConformToSchema('orderHash', orderHash, schemas.orderHashSchema);
+		const responseJson = await this._requestAsync(`/order/${orderHash}`, HttpRequestType.Get);
+		const order = relayerResponseJsonParsers.parseOrderJson(responseJson);
+		return order;
+	}
+	/**
+	 * Retrieve an orderbook from the API
+	 * @param   request     An OrderbookRequest instance describing the specific orderbook to retrieve
+	 * @return  The resulting OrderbookResponse that matches the request
+	 */
+	public async getOrderbookAsync(request: OrderbookRequest): Promise<OrderbookResponse> {
+		assert.doesConformToSchema('request', request, clientSchemas.relayerOrderBookRequestSchema);
+		const requestOpts = {
+			params: request,
+		};
+		const responseJson = await this._requestAsync('/orderbook', HttpRequestType.Get, requestOpts);
+		const orderbook = relayerResponseJsonParsers.parseOrderbookResponseJson(responseJson);
+		return orderbook;
+	}
+	/**
+	 * Retrieve fee information from the API
+	 * @param   request     A FeesRequest instance describing the specific fees to retrieve
+	 * @return  The resulting FeesResponse that matches the request
+	 */
+	public async getFeesAsync(request: FeesRequest): Promise<FeesResponse> {
+		assert.doesConformToSchema('request', request, schemas.relayerApiFeesPayloadSchema);
+		const requestOpts = {
+			payload: request,
+		};
+		const responseJson = await this._requestAsync('/fees', HttpRequestType.Post, requestOpts);
+		const fees = relayerResponseJsonParsers.parseFeesResponseJson(responseJson);
+		return fees;
+	}
+	/**
+	 * Submit a signed order to the API
+	 * @param   signedOrder     A SignedOrder instance to submit
+	 */
+	public async submitOrderAsync(signedOrder: SignedOrder): Promise<void> {
+		assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
+		const requestOpts = {
+			payload: signedOrder,
+		};
+		await this._requestAsync('/order', HttpRequestType.Post, requestOpts);
+	}
+	private async _requestAsync(
+		path: string,
+		requestType: HttpRequestType,
+		requestOptions?: HttpRequestOptions,
+	): Promise<any> {
+		const params = _.get(requestOptions, 'params');
+		const payload = _.get(requestOptions, 'payload');
+		let query = '';
+		if (!_.isUndefined(params) && !_.isEmpty(params)) {
+			const stringifiedParams = queryString.stringify(params);
+			query = `?${stringifiedParams}`;
+		}
+		const url = `${this._apiEndpointUrl}${path}${query}`;
+		const headers = new Headers({
+			'content-type': 'application/json',
+		});
+		const response = await fetch(url, {
+			method: requestType,
+			body: JSON.stringify(payload),
+			headers,
+		});
+		const json = await response.json();
+		if (!response.ok) {
+			const errorString = `${response.status} - ${response.statusText}\n${requestType} ${url}\n${JSON.stringify(
+				json,
+			)}`;
+			throw Error(errorString);
+		}
+		return json;
+	}
 }
diff --git a/packages/connect/src/index.ts b/packages/connect/src/index.ts
index a492f5ae9..d0cce9935 100644
--- a/packages/connect/src/index.ts
+++ b/packages/connect/src/index.ts
@@ -1,19 +1,19 @@
 export { HttpClient } from './http_client';
 export { WebSocketOrderbookChannel } from './ws_orderbook_channel';
 export {
-    Client,
-    ECSignature,
-    FeesRequest,
-    FeesResponse,
-    Order,
-    OrderbookChannel,
-    OrderbookChannelHandler,
-    OrderbookChannelSubscriptionOpts,
-    OrderbookRequest,
-    OrderbookResponse,
-    OrdersRequest,
-    SignedOrder,
-    TokenPairsItem,
-    TokenPairsRequest,
-    TokenTradeInfo,
+	Client,
+	ECSignature,
+	FeesRequest,
+	FeesResponse,
+	Order,
+	OrderbookChannel,
+	OrderbookChannelHandler,
+	OrderbookChannelSubscriptionOpts,
+	OrderbookRequest,
+	OrderbookResponse,
+	OrdersRequest,
+	SignedOrder,
+	TokenPairsItem,
+	TokenPairsRequest,
+	TokenTradeInfo,
 } from './types';
diff --git a/packages/connect/src/schemas/relayer_fees_request_schema.ts b/packages/connect/src/schemas/relayer_fees_request_schema.ts
index f20e077ba..bd0b91fa3 100644
--- a/packages/connect/src/schemas/relayer_fees_request_schema.ts
+++ b/packages/connect/src/schemas/relayer_fees_request_schema.ts
@@ -1,8 +1,8 @@
 export const relayerOrderBookRequestSchema = {
-    id: '/RelayerOrderBookRequest',
-    type: 'object',
-    properties: {
-        baseTokenAddress: { $ref: '/Address' },
-        quoteTokenAddress: { $ref: '/Address' },
-    },
+	id: '/RelayerOrderBookRequest',
+	type: 'object',
+	properties: {
+		baseTokenAddress: { $ref: '/Address' },
+		quoteTokenAddress: { $ref: '/Address' },
+	},
 };
diff --git a/packages/connect/src/schemas/relayer_orderbook_request_schema.ts b/packages/connect/src/schemas/relayer_orderbook_request_schema.ts
index f20e077ba..bd0b91fa3 100644
--- a/packages/connect/src/schemas/relayer_orderbook_request_schema.ts
+++ b/packages/connect/src/schemas/relayer_orderbook_request_schema.ts
@@ -1,8 +1,8 @@
 export const relayerOrderBookRequestSchema = {
-    id: '/RelayerOrderBookRequest',
-    type: 'object',
-    properties: {
-        baseTokenAddress: { $ref: '/Address' },
-        quoteTokenAddress: { $ref: '/Address' },
-    },
+	id: '/RelayerOrderBookRequest',
+	type: 'object',
+	properties: {
+		baseTokenAddress: { $ref: '/Address' },
+		quoteTokenAddress: { $ref: '/Address' },
+	},
 };
diff --git a/packages/connect/src/schemas/relayer_orders_request_schema.ts b/packages/connect/src/schemas/relayer_orders_request_schema.ts
index 570238dae..0471cb104 100644
--- a/packages/connect/src/schemas/relayer_orders_request_schema.ts
+++ b/packages/connect/src/schemas/relayer_orders_request_schema.ts
@@ -1,16 +1,16 @@
 export const relayerOrdersRequestSchema = {
-    id: '/RelayerOrdersRequest',
-    type: 'object',
-    properties: {
-        exchangeContractAddress: { $ref: '/Address' },
-        tokenAddress: { $ref: '/Address' },
-        makerTokenAddress: { $ref: '/Address' },
-        takerTokenAddress: { $ref: '/Address' },
-        tokenA: { $ref: '/Address' },
-        tokenB: { $ref: '/Address' },
-        maker: { $ref: '/Address' },
-        taker: { $ref: '/Address' },
-        trader: { $ref: '/Address' },
-        feeRecipient: { $ref: '/Address' },
-    },
+	id: '/RelayerOrdersRequest',
+	type: 'object',
+	properties: {
+		exchangeContractAddress: { $ref: '/Address' },
+		tokenAddress: { $ref: '/Address' },
+		makerTokenAddress: { $ref: '/Address' },
+		takerTokenAddress: { $ref: '/Address' },
+		tokenA: { $ref: '/Address' },
+		tokenB: { $ref: '/Address' },
+		maker: { $ref: '/Address' },
+		taker: { $ref: '/Address' },
+		trader: { $ref: '/Address' },
+		feeRecipient: { $ref: '/Address' },
+	},
 };
diff --git a/packages/connect/src/schemas/relayer_token_pairs_request_schema.ts b/packages/connect/src/schemas/relayer_token_pairs_request_schema.ts
index 379232204..cb79efdb3 100644
--- a/packages/connect/src/schemas/relayer_token_pairs_request_schema.ts
+++ b/packages/connect/src/schemas/relayer_token_pairs_request_schema.ts
@@ -1,8 +1,8 @@
 export const relayerTokenPairsRequestSchema = {
-    id: '/RelayerTokenPairsRequest',
-    type: 'object',
-    properties: {
-        tokenA: { $ref: '/Address' },
-        tokenB: { $ref: '/Address' },
-    },
+	id: '/RelayerTokenPairsRequest',
+	type: 'object',
+	properties: {
+		tokenA: { $ref: '/Address' },
+		tokenB: { $ref: '/Address' },
+	},
 };
diff --git a/packages/connect/src/schemas/schemas.ts b/packages/connect/src/schemas/schemas.ts
index 288d6969d..2982d81ab 100644
--- a/packages/connect/src/schemas/schemas.ts
+++ b/packages/connect/src/schemas/schemas.ts
@@ -3,7 +3,7 @@ import { relayerOrdersRequestSchema } from './relayer_orders_request_schema';
 import { relayerTokenPairsRequestSchema } from './relayer_token_pairs_request_schema';
 
 export const schemas = {
-    relayerOrderBookRequestSchema,
-    relayerOrdersRequestSchema,
-    relayerTokenPairsRequestSchema,
+	relayerOrderBookRequestSchema,
+	relayerOrdersRequestSchema,
+	relayerTokenPairsRequestSchema,
 };
diff --git a/packages/connect/src/types.ts b/packages/connect/src/types.ts
index edb6c77a6..5f72f6e85 100644
--- a/packages/connect/src/types.ts
+++ b/packages/connect/src/types.ts
@@ -2,45 +2,45 @@ import { BigNumber } from '@0xproject/utils';
 
 // TODO: Consolidate Order, SignedOrder and ECSignature into a shared package instead of duplicating them from 0x.js
 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;
+	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;
+	ecSignature: ECSignature;
 }
 
 /**
  * Elliptic Curve signature
  */
 export interface ECSignature {
-    v: number;
-    r: string;
-    s: string;
+	v: number;
+	r: string;
+	s: string;
 }
 
 export interface Client {
-    getTokenPairsAsync: (request?: TokenPairsRequest) => Promise<TokenPairsItem[]>;
-    getOrdersAsync: (request?: OrdersRequest) => Promise<SignedOrder[]>;
-    getOrderAsync: (orderHash: string) => Promise<SignedOrder>;
-    getOrderbookAsync: (request: OrderbookRequest) => Promise<OrderbookResponse>;
-    getFeesAsync: (request: FeesRequest) => Promise<FeesResponse>;
-    submitOrderAsync: (signedOrder: SignedOrder) => Promise<void>;
+	getTokenPairsAsync: (request?: TokenPairsRequest) => Promise<TokenPairsItem[]>;
+	getOrdersAsync: (request?: OrdersRequest) => Promise<SignedOrder[]>;
+	getOrderAsync: (orderHash: string) => Promise<SignedOrder>;
+	getOrderbookAsync: (request: OrderbookRequest) => Promise<OrderbookResponse>;
+	getFeesAsync: (request: FeesRequest) => Promise<FeesResponse>;
+	submitOrderAsync: (signedOrder: SignedOrder) => Promise<void>;
 }
 
 export interface OrderbookChannel {
-    subscribe: (subscriptionOpts: OrderbookChannelSubscriptionOpts, handler: OrderbookChannelHandler) => void;
-    close: () => void;
+	subscribe: (subscriptionOpts: OrderbookChannelSubscriptionOpts, handler: OrderbookChannelHandler) => void;
+	close: () => void;
 }
 
 /*
@@ -50,129 +50,129 @@ export interface OrderbookChannel {
  * limit: Maximum number of bids and asks in orderbook snapshot
  */
 export interface OrderbookChannelSubscriptionOpts {
-    baseTokenAddress: string;
-    quoteTokenAddress: string;
-    snapshot: boolean;
-    limit: number;
+	baseTokenAddress: string;
+	quoteTokenAddress: string;
+	snapshot: boolean;
+	limit: number;
 }
 
 export interface OrderbookChannelHandler {
-    onSnapshot: (
-        channel: OrderbookChannel,
-        subscriptionOpts: OrderbookChannelSubscriptionOpts,
-        snapshot: OrderbookResponse,
-    ) => void;
-    onUpdate: (
-        channel: OrderbookChannel,
-        subscriptionOpts: OrderbookChannelSubscriptionOpts,
-        order: SignedOrder,
-    ) => void;
-    onError: (channel: OrderbookChannel, subscriptionOpts: OrderbookChannelSubscriptionOpts, err: Error) => void;
-    onClose: (channel: OrderbookChannel, subscriptionOpts: OrderbookChannelSubscriptionOpts) => void;
+	onSnapshot: (
+		channel: OrderbookChannel,
+		subscriptionOpts: OrderbookChannelSubscriptionOpts,
+		snapshot: OrderbookResponse,
+	) => void;
+	onUpdate: (
+		channel: OrderbookChannel,
+		subscriptionOpts: OrderbookChannelSubscriptionOpts,
+		order: SignedOrder,
+	) => void;
+	onError: (channel: OrderbookChannel, subscriptionOpts: OrderbookChannelSubscriptionOpts, err: Error) => void;
+	onClose: (channel: OrderbookChannel, subscriptionOpts: OrderbookChannelSubscriptionOpts) => void;
 }
 
 export type OrderbookChannelMessage =
-    | SnapshotOrderbookChannelMessage
-    | UpdateOrderbookChannelMessage
-    | UnknownOrderbookChannelMessage;
+	| SnapshotOrderbookChannelMessage
+	| UpdateOrderbookChannelMessage
+	| UnknownOrderbookChannelMessage;
 
 export enum OrderbookChannelMessageTypes {
-    Snapshot = 'snapshot',
-    Update = 'update',
-    Unknown = 'unknown',
+	Snapshot = 'snapshot',
+	Update = 'update',
+	Unknown = 'unknown',
 }
 
 export interface SnapshotOrderbookChannelMessage {
-    type: OrderbookChannelMessageTypes.Snapshot;
-    requestId: number;
-    payload: OrderbookResponse;
+	type: OrderbookChannelMessageTypes.Snapshot;
+	requestId: number;
+	payload: OrderbookResponse;
 }
 
 export interface UpdateOrderbookChannelMessage {
-    type: OrderbookChannelMessageTypes.Update;
-    requestId: number;
-    payload: SignedOrder;
+	type: OrderbookChannelMessageTypes.Update;
+	requestId: number;
+	payload: SignedOrder;
 }
 
 export interface UnknownOrderbookChannelMessage {
-    type: OrderbookChannelMessageTypes.Unknown;
-    requestId: number;
-    payload: undefined;
+	type: OrderbookChannelMessageTypes.Unknown;
+	requestId: number;
+	payload: undefined;
 }
 
 export enum WebsocketConnectionEventType {
-    Close = 'close',
-    Error = 'error',
-    Message = 'message',
+	Close = 'close',
+	Error = 'error',
+	Message = 'message',
 }
 
 export enum WebsocketClientEventType {
-    Connect = 'connect',
-    ConnectFailed = 'connectFailed',
+	Connect = 'connect',
+	ConnectFailed = 'connectFailed',
 }
 
 export interface TokenPairsRequest {
-    tokenA?: string;
-    tokenB?: string;
+	tokenA?: string;
+	tokenB?: string;
 }
 
 export interface TokenPairsItem {
-    tokenA: TokenTradeInfo;
-    tokenB: TokenTradeInfo;
+	tokenA: TokenTradeInfo;
+	tokenB: TokenTradeInfo;
 }
 
 export interface TokenTradeInfo {
-    address: string;
-    minAmount: BigNumber;
-    maxAmount: BigNumber;
-    precision: number;
+	address: string;
+	minAmount: BigNumber;
+	maxAmount: BigNumber;
+	precision: number;
 }
 
 export interface OrdersRequest {
-    exchangeContractAddress?: string;
-    tokenAddress?: string;
-    makerTokenAddress?: string;
-    takerTokenAddress?: string;
-    maker?: string;
-    taker?: string;
-    trader?: string;
-    feeRecipient?: string;
+	exchangeContractAddress?: string;
+	tokenAddress?: string;
+	makerTokenAddress?: string;
+	takerTokenAddress?: string;
+	maker?: string;
+	taker?: string;
+	trader?: string;
+	feeRecipient?: string;
 }
 
 export interface OrderbookRequest {
-    baseTokenAddress: string;
-    quoteTokenAddress: string;
+	baseTokenAddress: string;
+	quoteTokenAddress: string;
 }
 
 export interface OrderbookResponse {
-    bids: SignedOrder[];
-    asks: SignedOrder[];
+	bids: SignedOrder[];
+	asks: SignedOrder[];
 }
 
 export interface FeesRequest {
-    exchangeContractAddress: string;
-    maker: string;
-    taker: string;
-    makerTokenAddress: string;
-    takerTokenAddress: string;
-    makerTokenAmount: BigNumber;
-    takerTokenAmount: BigNumber;
-    expirationUnixTimestampSec: BigNumber;
-    salt: BigNumber;
+	exchangeContractAddress: string;
+	maker: string;
+	taker: string;
+	makerTokenAddress: string;
+	takerTokenAddress: string;
+	makerTokenAmount: BigNumber;
+	takerTokenAmount: BigNumber;
+	expirationUnixTimestampSec: BigNumber;
+	salt: BigNumber;
 }
 
 export interface FeesResponse {
-    feeRecipient: string;
-    makerFee: BigNumber;
-    takerFee: BigNumber;
+	feeRecipient: string;
+	makerFee: BigNumber;
+	takerFee: BigNumber;
 }
 
 export interface HttpRequestOptions {
-    params?: object;
-    payload?: object;
+	params?: object;
+	payload?: object;
 }
 
 export enum HttpRequestType {
-    Get = 'GET',
-    Post = 'POST',
+	Get = 'GET',
+	Post = 'POST',
 }
diff --git a/packages/connect/src/utils/orderbook_channel_message_parser.ts b/packages/connect/src/utils/orderbook_channel_message_parser.ts
index 9a9ca8901..c5dd2ee2e 100644
--- a/packages/connect/src/utils/orderbook_channel_message_parser.ts
+++ b/packages/connect/src/utils/orderbook_channel_message_parser.ts
@@ -7,31 +7,31 @@ import { OrderbookChannelMessage, OrderbookChannelMessageTypes } from '../types'
 import { relayerResponseJsonParsers } from './relayer_response_json_parsers';
 
 export const orderbookChannelMessageParser = {
-    parse(utf8Data: string): OrderbookChannelMessage {
-        const messageObj = JSON.parse(utf8Data);
-        const type: string = _.get(messageObj, 'type');
-        assert.assert(!_.isUndefined(type), `Message is missing a type parameter: ${utf8Data}`);
-        assert.isString('type', type);
-        switch (type) {
-            case OrderbookChannelMessageTypes.Snapshot: {
-                assert.doesConformToSchema('message', messageObj, schemas.relayerApiOrderbookChannelSnapshotSchema);
-                const orderbookJson = messageObj.payload;
-                const orderbook = relayerResponseJsonParsers.parseOrderbookResponseJson(orderbookJson);
-                return _.assign(messageObj, { payload: orderbook });
-            }
-            case OrderbookChannelMessageTypes.Update: {
-                assert.doesConformToSchema('message', messageObj, schemas.relayerApiOrderbookChannelUpdateSchema);
-                const orderJson = messageObj.payload;
-                const order = relayerResponseJsonParsers.parseOrderJson(orderJson);
-                return _.assign(messageObj, { payload: order });
-            }
-            default: {
-                return {
-                    type: OrderbookChannelMessageTypes.Unknown,
-                    requestId: 0,
-                    payload: undefined,
-                };
-            }
-        }
-    },
+	parse(utf8Data: string): OrderbookChannelMessage {
+		const messageObj = JSON.parse(utf8Data);
+		const type: string = _.get(messageObj, 'type');
+		assert.assert(!_.isUndefined(type), `Message is missing a type parameter: ${utf8Data}`);
+		assert.isString('type', type);
+		switch (type) {
+			case OrderbookChannelMessageTypes.Snapshot: {
+				assert.doesConformToSchema('message', messageObj, schemas.relayerApiOrderbookChannelSnapshotSchema);
+				const orderbookJson = messageObj.payload;
+				const orderbook = relayerResponseJsonParsers.parseOrderbookResponseJson(orderbookJson);
+				return _.assign(messageObj, { payload: orderbook });
+			}
+			case OrderbookChannelMessageTypes.Update: {
+				assert.doesConformToSchema('message', messageObj, schemas.relayerApiOrderbookChannelUpdateSchema);
+				const orderJson = messageObj.payload;
+				const order = relayerResponseJsonParsers.parseOrderJson(orderJson);
+				return _.assign(messageObj, { payload: order });
+			}
+			default: {
+				return {
+					type: OrderbookChannelMessageTypes.Unknown,
+					requestId: 0,
+					payload: undefined,
+				};
+			}
+		}
+	},
 };
diff --git a/packages/connect/src/utils/relayer_response_json_parsers.ts b/packages/connect/src/utils/relayer_response_json_parsers.ts
index 668461bf4..b6c5decaf 100644
--- a/packages/connect/src/utils/relayer_response_json_parsers.ts
+++ b/packages/connect/src/utils/relayer_response_json_parsers.ts
@@ -7,31 +7,31 @@ import { FeesResponse, OrderbookResponse, SignedOrder, TokenPairsItem } from '..
 import { typeConverters } from './type_converters';
 
 export const relayerResponseJsonParsers = {
-    parseTokenPairsJson(json: any): TokenPairsItem[] {
-        assert.doesConformToSchema('tokenPairs', json, schemas.relayerApiTokenPairsResponseSchema);
-        return json.map((tokenPair: any) => {
-            return typeConverters.convertStringsFieldsToBigNumbers(tokenPair, [
-                'tokenA.minAmount',
-                'tokenA.maxAmount',
-                'tokenB.minAmount',
-                'tokenB.maxAmount',
-            ]);
-        });
-    },
-    parseOrdersJson(json: any): SignedOrder[] {
-        assert.doesConformToSchema('orders', json, schemas.signedOrdersSchema);
-        return json.map((order: object) => typeConverters.convertOrderStringFieldsToBigNumber(order));
-    },
-    parseOrderJson(json: any): SignedOrder {
-        assert.doesConformToSchema('order', json, schemas.signedOrderSchema);
-        return typeConverters.convertOrderStringFieldsToBigNumber(json);
-    },
-    parseOrderbookResponseJson(json: any): OrderbookResponse {
-        assert.doesConformToSchema('orderBook', json, schemas.relayerApiOrderBookResponseSchema);
-        return typeConverters.convertOrderbookStringFieldsToBigNumber(json);
-    },
-    parseFeesResponseJson(json: any): FeesResponse {
-        assert.doesConformToSchema('fees', json, schemas.relayerApiFeesResponseSchema);
-        return typeConverters.convertStringsFieldsToBigNumbers(json, ['makerFee', 'takerFee']);
-    },
+	parseTokenPairsJson(json: any): TokenPairsItem[] {
+		assert.doesConformToSchema('tokenPairs', json, schemas.relayerApiTokenPairsResponseSchema);
+		return json.map((tokenPair: any) => {
+			return typeConverters.convertStringsFieldsToBigNumbers(tokenPair, [
+				'tokenA.minAmount',
+				'tokenA.maxAmount',
+				'tokenB.minAmount',
+				'tokenB.maxAmount',
+			]);
+		});
+	},
+	parseOrdersJson(json: any): SignedOrder[] {
+		assert.doesConformToSchema('orders', json, schemas.signedOrdersSchema);
+		return json.map((order: object) => typeConverters.convertOrderStringFieldsToBigNumber(order));
+	},
+	parseOrderJson(json: any): SignedOrder {
+		assert.doesConformToSchema('order', json, schemas.signedOrderSchema);
+		return typeConverters.convertOrderStringFieldsToBigNumber(json);
+	},
+	parseOrderbookResponseJson(json: any): OrderbookResponse {
+		assert.doesConformToSchema('orderBook', json, schemas.relayerApiOrderBookResponseSchema);
+		return typeConverters.convertOrderbookStringFieldsToBigNumber(json);
+	},
+	parseFeesResponseJson(json: any): FeesResponse {
+		assert.doesConformToSchema('fees', json, schemas.relayerApiFeesResponseSchema);
+		return typeConverters.convertStringsFieldsToBigNumbers(json, ['makerFee', 'takerFee']);
+	},
 };
diff --git a/packages/connect/src/utils/type_converters.ts b/packages/connect/src/utils/type_converters.ts
index c1808ce8a..beea557c2 100644
--- a/packages/connect/src/utils/type_converters.ts
+++ b/packages/connect/src/utils/type_converters.ts
@@ -2,29 +2,29 @@ import { BigNumber } from '@0xproject/utils';
 import * as _ from 'lodash';
 
 export const typeConverters = {
-    convertOrderbookStringFieldsToBigNumber(orderbook: any): any {
-        const bids = _.get(orderbook, 'bids', []);
-        const asks = _.get(orderbook, 'asks', []);
-        return {
-            bids: bids.map((order: any) => this.convertOrderStringFieldsToBigNumber(order)),
-            asks: asks.map((order: any) => this.convertOrderStringFieldsToBigNumber(order)),
-        };
-    },
-    convertOrderStringFieldsToBigNumber(order: any): any {
-        return this.convertStringsFieldsToBigNumbers(order, [
-            'makerTokenAmount',
-            'takerTokenAmount',
-            'makerFee',
-            'takerFee',
-            'expirationUnixTimestampSec',
-            'salt',
-        ]);
-    },
-    convertStringsFieldsToBigNumbers(obj: any, fields: string[]): any {
-        const result = _.assign({}, obj);
-        _.each(fields, field => {
-            _.update(result, field, (value: string) => new BigNumber(value));
-        });
-        return result;
-    },
+	convertOrderbookStringFieldsToBigNumber(orderbook: any): any {
+		const bids = _.get(orderbook, 'bids', []);
+		const asks = _.get(orderbook, 'asks', []);
+		return {
+			bids: bids.map((order: any) => this.convertOrderStringFieldsToBigNumber(order)),
+			asks: asks.map((order: any) => this.convertOrderStringFieldsToBigNumber(order)),
+		};
+	},
+	convertOrderStringFieldsToBigNumber(order: any): any {
+		return this.convertStringsFieldsToBigNumbers(order, [
+			'makerTokenAmount',
+			'takerTokenAmount',
+			'makerFee',
+			'takerFee',
+			'expirationUnixTimestampSec',
+			'salt',
+		]);
+	},
+	convertStringsFieldsToBigNumbers(obj: any, fields: string[]): any {
+		const result = _.assign({}, obj);
+		_.each(fields, field => {
+			_.update(result, field, (value: string) => new BigNumber(value));
+		});
+		return result;
+	},
 };
diff --git a/packages/connect/src/ws_orderbook_channel.ts b/packages/connect/src/ws_orderbook_channel.ts
index 822a022f4..bbb47c649 100644
--- a/packages/connect/src/ws_orderbook_channel.ts
+++ b/packages/connect/src/ws_orderbook_channel.ts
@@ -4,12 +4,12 @@ import * as _ from 'lodash';
 import * as WebSocket from 'websocket';
 
 import {
-    OrderbookChannel,
-    OrderbookChannelHandler,
-    OrderbookChannelMessageTypes,
-    OrderbookChannelSubscriptionOpts,
-    WebsocketClientEventType,
-    WebsocketConnectionEventType,
+	OrderbookChannel,
+	OrderbookChannelHandler,
+	OrderbookChannelMessageTypes,
+	OrderbookChannelSubscriptionOpts,
+	WebsocketClientEventType,
+	WebsocketConnectionEventType,
 } from './types';
 import { orderbookChannelMessageParser } from './utils/orderbook_channel_message_parser';
 
@@ -18,117 +18,117 @@ import { orderbookChannelMessageParser } from './utils/orderbook_channel_message
  * that implements the standard relayer API v0
  */
 export class WebSocketOrderbookChannel implements OrderbookChannel {
-    private _apiEndpointUrl: string;
-    private _client: WebSocket.client;
-    private _connectionIfExists?: WebSocket.connection;
-    private _subscriptionCounter = 0;
-    /**
-     * Instantiates a new WebSocketOrderbookChannel instance
-     * @param   url                 The relayer API base WS url you would like to interact with
-     * @return  An instance of WebSocketOrderbookChannel
-     */
-    constructor(url: string) {
-        assert.isUri('url', url);
-        this._apiEndpointUrl = url;
-        this._client = new WebSocket.client();
-    }
-    /**
-     * Subscribe to orderbook snapshots and updates from the websocket
-     * @param   subscriptionOpts     An OrderbookChannelSubscriptionOpts instance describing which
-     *                               token pair to subscribe to
-     * @param   handler              An OrderbookChannelHandler instance that responds to various
-     *                               channel updates
-     */
-    public subscribe(subscriptionOpts: OrderbookChannelSubscriptionOpts, handler: OrderbookChannelHandler): void {
-        assert.doesConformToSchema(
-            'subscriptionOpts',
-            subscriptionOpts,
-            schemas.relayerApiOrderbookChannelSubscribePayload,
-        );
-        assert.isFunction('handler.onSnapshot', _.get(handler, 'onSnapshot'));
-        assert.isFunction('handler.onUpdate', _.get(handler, 'onUpdate'));
-        assert.isFunction('handler.onError', _.get(handler, 'onError'));
-        assert.isFunction('handler.onClose', _.get(handler, 'onClose'));
-        this._subscriptionCounter += 1;
-        const subscribeMessage = {
-            type: 'subscribe',
-            channel: 'orderbook',
-            requestId: this._subscriptionCounter,
-            payload: subscriptionOpts,
-        };
-        this._getConnection((error, connection) => {
-            if (!_.isUndefined(error)) {
-                handler.onError(this, subscriptionOpts, error);
-            } else if (!_.isUndefined(connection) && connection.connected) {
-                connection.on(WebsocketConnectionEventType.Error, wsError => {
-                    handler.onError(this, subscriptionOpts, wsError);
-                });
-                connection.on(WebsocketConnectionEventType.Close, () => {
-                    handler.onClose(this, subscriptionOpts);
-                });
-                connection.on(WebsocketConnectionEventType.Message, message => {
-                    this._handleWebSocketMessage(subscribeMessage.requestId, subscriptionOpts, message, handler);
-                });
-                connection.sendUTF(JSON.stringify(subscribeMessage));
-            }
-        });
-    }
-    /**
-     * Close the websocket and stop receiving updates
-     */
-    public close() {
-        if (!_.isUndefined(this._connectionIfExists)) {
-            this._connectionIfExists.close();
-        }
-    }
-    private _getConnection(callback: (error?: Error, connection?: WebSocket.connection) => void) {
-        if (!_.isUndefined(this._connectionIfExists) && this._connectionIfExists.connected) {
-            callback(undefined, this._connectionIfExists);
-        } else {
-            this._client.on(WebsocketClientEventType.Connect, connection => {
-                this._connectionIfExists = connection;
-                callback(undefined, this._connectionIfExists);
-            });
-            this._client.on(WebsocketClientEventType.ConnectFailed, error => {
-                callback(error, undefined);
-            });
-            this._client.connect(this._apiEndpointUrl);
-        }
-    }
-    private _handleWebSocketMessage(
-        requestId: number,
-        subscriptionOpts: OrderbookChannelSubscriptionOpts,
-        message: WebSocket.IMessage,
-        handler: OrderbookChannelHandler,
-    ): void {
-        if (!_.isUndefined(message.utf8Data)) {
-            try {
-                const utf8Data = message.utf8Data;
-                const parserResult = orderbookChannelMessageParser.parse(utf8Data);
-                if (parserResult.requestId === requestId) {
-                    switch (parserResult.type) {
-                        case OrderbookChannelMessageTypes.Snapshot: {
-                            handler.onSnapshot(this, subscriptionOpts, parserResult.payload);
-                            break;
-                        }
-                        case OrderbookChannelMessageTypes.Update: {
-                            handler.onUpdate(this, subscriptionOpts, parserResult.payload);
-                            break;
-                        }
-                        default: {
-                            handler.onError(
-                                this,
-                                subscriptionOpts,
-                                new Error(`Message has missing a type parameter: ${utf8Data}`),
-                            );
-                        }
-                    }
-                }
-            } catch (error) {
-                handler.onError(this, subscriptionOpts, error);
-            }
-        } else {
-            handler.onError(this, subscriptionOpts, new Error(`Message does not contain utf8Data`));
-        }
-    }
+	private _apiEndpointUrl: string;
+	private _client: WebSocket.client;
+	private _connectionIfExists?: WebSocket.connection;
+	private _subscriptionCounter = 0;
+	/**
+	 * Instantiates a new WebSocketOrderbookChannel instance
+	 * @param   url                 The relayer API base WS url you would like to interact with
+	 * @return  An instance of WebSocketOrderbookChannel
+	 */
+	constructor(url: string) {
+		assert.isUri('url', url);
+		this._apiEndpointUrl = url;
+		this._client = new WebSocket.client();
+	}
+	/**
+	 * Subscribe to orderbook snapshots and updates from the websocket
+	 * @param   subscriptionOpts     An OrderbookChannelSubscriptionOpts instance describing which
+	 *                               token pair to subscribe to
+	 * @param   handler              An OrderbookChannelHandler instance that responds to various
+	 *                               channel updates
+	 */
+	public subscribe(subscriptionOpts: OrderbookChannelSubscriptionOpts, handler: OrderbookChannelHandler): void {
+		assert.doesConformToSchema(
+			'subscriptionOpts',
+			subscriptionOpts,
+			schemas.relayerApiOrderbookChannelSubscribePayload,
+		);
+		assert.isFunction('handler.onSnapshot', _.get(handler, 'onSnapshot'));
+		assert.isFunction('handler.onUpdate', _.get(handler, 'onUpdate'));
+		assert.isFunction('handler.onError', _.get(handler, 'onError'));
+		assert.isFunction('handler.onClose', _.get(handler, 'onClose'));
+		this._subscriptionCounter += 1;
+		const subscribeMessage = {
+			type: 'subscribe',
+			channel: 'orderbook',
+			requestId: this._subscriptionCounter,
+			payload: subscriptionOpts,
+		};
+		this._getConnection((error, connection) => {
+			if (!_.isUndefined(error)) {
+				handler.onError(this, subscriptionOpts, error);
+			} else if (!_.isUndefined(connection) && connection.connected) {
+				connection.on(WebsocketConnectionEventType.Error, wsError => {
+					handler.onError(this, subscriptionOpts, wsError);
+				});
+				connection.on(WebsocketConnectionEventType.Close, () => {
+					handler.onClose(this, subscriptionOpts);
+				});
+				connection.on(WebsocketConnectionEventType.Message, message => {
+					this._handleWebSocketMessage(subscribeMessage.requestId, subscriptionOpts, message, handler);
+				});
+				connection.sendUTF(JSON.stringify(subscribeMessage));
+			}
+		});
+	}
+	/**
+	 * Close the websocket and stop receiving updates
+	 */
+	public close() {
+		if (!_.isUndefined(this._connectionIfExists)) {
+			this._connectionIfExists.close();
+		}
+	}
+	private _getConnection(callback: (error?: Error, connection?: WebSocket.connection) => void) {
+		if (!_.isUndefined(this._connectionIfExists) && this._connectionIfExists.connected) {
+			callback(undefined, this._connectionIfExists);
+		} else {
+			this._client.on(WebsocketClientEventType.Connect, connection => {
+				this._connectionIfExists = connection;
+				callback(undefined, this._connectionIfExists);
+			});
+			this._client.on(WebsocketClientEventType.ConnectFailed, error => {
+				callback(error, undefined);
+			});
+			this._client.connect(this._apiEndpointUrl);
+		}
+	}
+	private _handleWebSocketMessage(
+		requestId: number,
+		subscriptionOpts: OrderbookChannelSubscriptionOpts,
+		message: WebSocket.IMessage,
+		handler: OrderbookChannelHandler,
+	): void {
+		if (!_.isUndefined(message.utf8Data)) {
+			try {
+				const utf8Data = message.utf8Data;
+				const parserResult = orderbookChannelMessageParser.parse(utf8Data);
+				if (parserResult.requestId === requestId) {
+					switch (parserResult.type) {
+						case OrderbookChannelMessageTypes.Snapshot: {
+							handler.onSnapshot(this, subscriptionOpts, parserResult.payload);
+							break;
+						}
+						case OrderbookChannelMessageTypes.Update: {
+							handler.onUpdate(this, subscriptionOpts, parserResult.payload);
+							break;
+						}
+						default: {
+							handler.onError(
+								this,
+								subscriptionOpts,
+								new Error(`Message has missing a type parameter: ${utf8Data}`),
+							);
+						}
+					}
+				}
+			} catch (error) {
+				handler.onError(this, subscriptionOpts, error);
+			}
+		} else {
+			handler.onError(this, subscriptionOpts, new Error(`Message does not contain utf8Data`));
+		}
+	}
 }
diff --git a/packages/connect/test/fixtures/standard_relayer_api/fees.json b/packages/connect/test/fixtures/standard_relayer_api/fees.json
index 483a74254..9f24e93d2 100644
--- a/packages/connect/test/fixtures/standard_relayer_api/fees.json
+++ b/packages/connect/test/fixtures/standard_relayer_api/fees.json
@@ -1,5 +1,5 @@
 {
-    "feeRecipient": "0x323b5d4c32345ced77393b3530b1eed0f346429d",
-    "makerFee": "10000000000000000",
-    "takerFee": "30000000000000000"
+	"feeRecipient": "0x323b5d4c32345ced77393b3530b1eed0f346429d",
+	"makerFee": "10000000000000000",
+	"takerFee": "30000000000000000"
 }
diff --git a/packages/connect/test/fixtures/standard_relayer_api/fees.ts b/packages/connect/test/fixtures/standard_relayer_api/fees.ts
index fecbaacff..03981031a 100644
--- a/packages/connect/test/fixtures/standard_relayer_api/fees.ts
+++ b/packages/connect/test/fixtures/standard_relayer_api/fees.ts
@@ -3,7 +3,7 @@ import { BigNumber } from '@0xproject/utils';
 import { FeesResponse } from '../../../src/types';
 
 export const feesResponse: FeesResponse = {
-    feeRecipient: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-    makerFee: new BigNumber('10000000000000000'),
-    takerFee: new BigNumber('30000000000000000'),
+	feeRecipient: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+	makerFee: new BigNumber('10000000000000000'),
+	takerFee: new BigNumber('30000000000000000'),
 };
diff --git a/packages/connect/test/fixtures/standard_relayer_api/order/0xabc67323774bdbd24d94f977fa9ac94a50f016026fd13f42990861238897721f.json b/packages/connect/test/fixtures/standard_relayer_api/order/0xabc67323774bdbd24d94f977fa9ac94a50f016026fd13f42990861238897721f.json
index e84954b0d..c0423bf49 100644
--- a/packages/connect/test/fixtures/standard_relayer_api/order/0xabc67323774bdbd24d94f977fa9ac94a50f016026fd13f42990861238897721f.json
+++ b/packages/connect/test/fixtures/standard_relayer_api/order/0xabc67323774bdbd24d94f977fa9ac94a50f016026fd13f42990861238897721f.json
@@ -1,19 +1,19 @@
 {
-    "maker": "0x9e56625509c2f60af937f23b7b532600390e8c8b",
-    "taker": "0xa2b31dacf30a9c50ca473337c01d8a201ae33e32",
-    "makerFee": "100000000000000",
-    "takerFee": "200000000000000",
-    "makerTokenAmount": "10000000000000000",
-    "takerTokenAmount": "20000000000000000",
-    "makerTokenAddress": "0x323b5d4c32345ced77393b3530b1eed0f346429d",
-    "takerTokenAddress": "0xef7fff64389b814a946f3e92105513705ca6b990",
-    "salt": "256",
-    "feeRecipient": "0xb046140686d052fff581f63f8136cce132e857da",
-    "exchangeContractAddress": "0x12459c951127e0c374ff9105dda097662a027093",
-    "expirationUnixTimestampSec": "42",
-    "ecSignature": {
-        "v": 27,
-        "r": "0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33",
-        "s": "0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254"
-    }
+	"maker": "0x9e56625509c2f60af937f23b7b532600390e8c8b",
+	"taker": "0xa2b31dacf30a9c50ca473337c01d8a201ae33e32",
+	"makerFee": "100000000000000",
+	"takerFee": "200000000000000",
+	"makerTokenAmount": "10000000000000000",
+	"takerTokenAmount": "20000000000000000",
+	"makerTokenAddress": "0x323b5d4c32345ced77393b3530b1eed0f346429d",
+	"takerTokenAddress": "0xef7fff64389b814a946f3e92105513705ca6b990",
+	"salt": "256",
+	"feeRecipient": "0xb046140686d052fff581f63f8136cce132e857da",
+	"exchangeContractAddress": "0x12459c951127e0c374ff9105dda097662a027093",
+	"expirationUnixTimestampSec": "42",
+	"ecSignature": {
+		"v": 27,
+		"r": "0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33",
+		"s": "0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254"
+	}
 }
diff --git a/packages/connect/test/fixtures/standard_relayer_api/order/0xabc67323774bdbd24d94f977fa9ac94a50f016026fd13f42990861238897721f.ts b/packages/connect/test/fixtures/standard_relayer_api/order/0xabc67323774bdbd24d94f977fa9ac94a50f016026fd13f42990861238897721f.ts
index 5a03a2ff6..459a87919 100644
--- a/packages/connect/test/fixtures/standard_relayer_api/order/0xabc67323774bdbd24d94f977fa9ac94a50f016026fd13f42990861238897721f.ts
+++ b/packages/connect/test/fixtures/standard_relayer_api/order/0xabc67323774bdbd24d94f977fa9ac94a50f016026fd13f42990861238897721f.ts
@@ -1,21 +1,21 @@
 import { BigNumber } from '@0xproject/utils';
 
 export const orderResponse = {
-    maker: '0x9e56625509c2f60af937f23b7b532600390e8c8b',
-    taker: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
-    makerFee: new BigNumber('100000000000000'),
-    takerFee: new BigNumber('200000000000000'),
-    makerTokenAmount: new BigNumber('10000000000000000'),
-    takerTokenAmount: new BigNumber('20000000000000000'),
-    makerTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-    takerTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
-    salt: new BigNumber('256'),
-    feeRecipient: '0xb046140686d052fff581f63f8136cce132e857da',
-    exchangeContractAddress: '0x12459c951127e0c374ff9105dda097662a027093',
-    expirationUnixTimestampSec: new BigNumber('42'),
-    ecSignature: {
-        v: 27,
-        r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
-        s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
-    },
+	maker: '0x9e56625509c2f60af937f23b7b532600390e8c8b',
+	taker: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
+	makerFee: new BigNumber('100000000000000'),
+	takerFee: new BigNumber('200000000000000'),
+	makerTokenAmount: new BigNumber('10000000000000000'),
+	takerTokenAmount: new BigNumber('20000000000000000'),
+	makerTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+	takerTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
+	salt: new BigNumber('256'),
+	feeRecipient: '0xb046140686d052fff581f63f8136cce132e857da',
+	exchangeContractAddress: '0x12459c951127e0c374ff9105dda097662a027093',
+	expirationUnixTimestampSec: new BigNumber('42'),
+	ecSignature: {
+		v: 27,
+		r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
+		s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
+	},
 };
diff --git a/packages/connect/test/fixtures/standard_relayer_api/orderbook.json b/packages/connect/test/fixtures/standard_relayer_api/orderbook.json
index 825be34c2..569498312 100644
--- a/packages/connect/test/fixtures/standard_relayer_api/orderbook.json
+++ b/packages/connect/test/fixtures/standard_relayer_api/orderbook.json
@@ -1,44 +1,44 @@
 {
-    "bids": [
-        {
-            "maker": "0x9e56625509c2f60af937f23b7b532600390e8c8b",
-            "taker": "0xa2b31dacf30a9c50ca473337c01d8a201ae33e32",
-            "makerFee": "100000000000000",
-            "takerFee": "200000000000000",
-            "makerTokenAmount": "10000000000000000",
-            "takerTokenAmount": "20000000000000000",
-            "makerTokenAddress": "0x323b5d4c32345ced77393b3530b1eed0f346429d",
-            "takerTokenAddress": "0xef7fff64389b814a946f3e92105513705ca6b990",
-            "salt": "256",
-            "feeRecipient": "0xb046140686d052fff581f63f8136cce132e857da",
-            "exchangeContractAddress": "0x12459c951127e0c374ff9105dda097662a027093",
-            "expirationUnixTimestampSec": "42",
-            "ecSignature": {
-                "v": 27,
-                "r": "0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33",
-                "s": "0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254"
-            }
-        }
-    ],
-    "asks": [
-        {
-            "maker": "0x9e56625509c2f60af937f23b7b532600390e8c8b",
-            "taker": "0xa2b31dacf30a9c50ca473337c01d8a201ae33e32",
-            "makerFee": "100000000000000",
-            "takerFee": "200000000000000",
-            "makerTokenAmount": "10000000000000000",
-            "takerTokenAmount": "20000000000000000",
-            "makerTokenAddress": "0x323b5d4c32345ced77393b3530b1eed0f346429d",
-            "takerTokenAddress": "0xef7fff64389b814a946f3e92105513705ca6b990",
-            "salt": "256",
-            "feeRecipient": "0xb046140686d052fff581f63f8136cce132e857da",
-            "exchangeContractAddress": "0x12459c951127e0c374ff9105dda097662a027093",
-            "expirationUnixTimestampSec": "42",
-            "ecSignature": {
-                "v": 27,
-                "r": "0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33",
-                "s": "0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254"
-            }
-        }
-    ]
+	"bids": [
+		{
+			"maker": "0x9e56625509c2f60af937f23b7b532600390e8c8b",
+			"taker": "0xa2b31dacf30a9c50ca473337c01d8a201ae33e32",
+			"makerFee": "100000000000000",
+			"takerFee": "200000000000000",
+			"makerTokenAmount": "10000000000000000",
+			"takerTokenAmount": "20000000000000000",
+			"makerTokenAddress": "0x323b5d4c32345ced77393b3530b1eed0f346429d",
+			"takerTokenAddress": "0xef7fff64389b814a946f3e92105513705ca6b990",
+			"salt": "256",
+			"feeRecipient": "0xb046140686d052fff581f63f8136cce132e857da",
+			"exchangeContractAddress": "0x12459c951127e0c374ff9105dda097662a027093",
+			"expirationUnixTimestampSec": "42",
+			"ecSignature": {
+				"v": 27,
+				"r": "0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33",
+				"s": "0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254"
+			}
+		}
+	],
+	"asks": [
+		{
+			"maker": "0x9e56625509c2f60af937f23b7b532600390e8c8b",
+			"taker": "0xa2b31dacf30a9c50ca473337c01d8a201ae33e32",
+			"makerFee": "100000000000000",
+			"takerFee": "200000000000000",
+			"makerTokenAmount": "10000000000000000",
+			"takerTokenAmount": "20000000000000000",
+			"makerTokenAddress": "0x323b5d4c32345ced77393b3530b1eed0f346429d",
+			"takerTokenAddress": "0xef7fff64389b814a946f3e92105513705ca6b990",
+			"salt": "256",
+			"feeRecipient": "0xb046140686d052fff581f63f8136cce132e857da",
+			"exchangeContractAddress": "0x12459c951127e0c374ff9105dda097662a027093",
+			"expirationUnixTimestampSec": "42",
+			"ecSignature": {
+				"v": 27,
+				"r": "0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33",
+				"s": "0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254"
+			}
+		}
+	]
 }
diff --git a/packages/connect/test/fixtures/standard_relayer_api/orderbook.ts b/packages/connect/test/fixtures/standard_relayer_api/orderbook.ts
index 6684ac2e5..90d3d9220 100644
--- a/packages/connect/test/fixtures/standard_relayer_api/orderbook.ts
+++ b/packages/connect/test/fixtures/standard_relayer_api/orderbook.ts
@@ -1,46 +1,46 @@
 import { BigNumber } from '@0xproject/utils';
 
 export const orderbookResponse = {
-    bids: [
-        {
-            maker: '0x9e56625509c2f60af937f23b7b532600390e8c8b',
-            taker: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
-            makerFee: new BigNumber('100000000000000'),
-            takerFee: new BigNumber('200000000000000'),
-            makerTokenAmount: new BigNumber('10000000000000000'),
-            takerTokenAmount: new BigNumber('20000000000000000'),
-            makerTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-            takerTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
-            salt: new BigNumber('256'),
-            feeRecipient: '0xb046140686d052fff581f63f8136cce132e857da',
-            exchangeContractAddress: '0x12459c951127e0c374ff9105dda097662a027093',
-            expirationUnixTimestampSec: new BigNumber('42'),
-            ecSignature: {
-                v: 27,
-                r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
-                s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
-            },
-        },
-    ],
-    asks: [
-        {
-            maker: '0x9e56625509c2f60af937f23b7b532600390e8c8b',
-            taker: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
-            makerFee: new BigNumber('100000000000000'),
-            takerFee: new BigNumber('200000000000000'),
-            makerTokenAmount: new BigNumber('10000000000000000'),
-            takerTokenAmount: new BigNumber('20000000000000000'),
-            makerTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-            takerTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
-            salt: new BigNumber('256'),
-            feeRecipient: '0xb046140686d052fff581f63f8136cce132e857da',
-            exchangeContractAddress: '0x12459c951127e0c374ff9105dda097662a027093',
-            expirationUnixTimestampSec: new BigNumber('42'),
-            ecSignature: {
-                v: 27,
-                r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
-                s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
-            },
-        },
-    ],
+	bids: [
+		{
+			maker: '0x9e56625509c2f60af937f23b7b532600390e8c8b',
+			taker: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
+			makerFee: new BigNumber('100000000000000'),
+			takerFee: new BigNumber('200000000000000'),
+			makerTokenAmount: new BigNumber('10000000000000000'),
+			takerTokenAmount: new BigNumber('20000000000000000'),
+			makerTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+			takerTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
+			salt: new BigNumber('256'),
+			feeRecipient: '0xb046140686d052fff581f63f8136cce132e857da',
+			exchangeContractAddress: '0x12459c951127e0c374ff9105dda097662a027093',
+			expirationUnixTimestampSec: new BigNumber('42'),
+			ecSignature: {
+				v: 27,
+				r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
+				s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
+			},
+		},
+	],
+	asks: [
+		{
+			maker: '0x9e56625509c2f60af937f23b7b532600390e8c8b',
+			taker: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
+			makerFee: new BigNumber('100000000000000'),
+			takerFee: new BigNumber('200000000000000'),
+			makerTokenAmount: new BigNumber('10000000000000000'),
+			takerTokenAmount: new BigNumber('20000000000000000'),
+			makerTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+			takerTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
+			salt: new BigNumber('256'),
+			feeRecipient: '0xb046140686d052fff581f63f8136cce132e857da',
+			exchangeContractAddress: '0x12459c951127e0c374ff9105dda097662a027093',
+			expirationUnixTimestampSec: new BigNumber('42'),
+			ecSignature: {
+				v: 27,
+				r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
+				s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
+			},
+		},
+	],
 };
diff --git a/packages/connect/test/fixtures/standard_relayer_api/orders.json b/packages/connect/test/fixtures/standard_relayer_api/orders.json
index cfa780dc4..97d21abd8 100644
--- a/packages/connect/test/fixtures/standard_relayer_api/orders.json
+++ b/packages/connect/test/fixtures/standard_relayer_api/orders.json
@@ -1,21 +1,21 @@
 [
-    {
-        "maker": "0x9e56625509c2f60af937f23b7b532600390e8c8b",
-        "taker": "0xa2b31dacf30a9c50ca473337c01d8a201ae33e32",
-        "makerFee": "100000000000000",
-        "takerFee": "200000000000000",
-        "makerTokenAmount": "10000000000000000",
-        "takerTokenAmount": "20000000000000000",
-        "makerTokenAddress": "0x323b5d4c32345ced77393b3530b1eed0f346429d",
-        "takerTokenAddress": "0xef7fff64389b814a946f3e92105513705ca6b990",
-        "salt": "256",
-        "feeRecipient": "0x9e56625509c2f60af937f23b7b532600390e8c8b",
-        "exchangeContractAddress": "0x9e56625509c2f60af937f23b7b532600390e8c8b",
-        "expirationUnixTimestampSec": "42",
-        "ecSignature": {
-            "v": 27,
-            "r": "0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33",
-            "s": "0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254"
-        }
-    }
+	{
+		"maker": "0x9e56625509c2f60af937f23b7b532600390e8c8b",
+		"taker": "0xa2b31dacf30a9c50ca473337c01d8a201ae33e32",
+		"makerFee": "100000000000000",
+		"takerFee": "200000000000000",
+		"makerTokenAmount": "10000000000000000",
+		"takerTokenAmount": "20000000000000000",
+		"makerTokenAddress": "0x323b5d4c32345ced77393b3530b1eed0f346429d",
+		"takerTokenAddress": "0xef7fff64389b814a946f3e92105513705ca6b990",
+		"salt": "256",
+		"feeRecipient": "0x9e56625509c2f60af937f23b7b532600390e8c8b",
+		"exchangeContractAddress": "0x9e56625509c2f60af937f23b7b532600390e8c8b",
+		"expirationUnixTimestampSec": "42",
+		"ecSignature": {
+			"v": 27,
+			"r": "0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33",
+			"s": "0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254"
+		}
+	}
 ]
diff --git a/packages/connect/test/fixtures/standard_relayer_api/orders.ts b/packages/connect/test/fixtures/standard_relayer_api/orders.ts
index 5044777bd..701346971 100644
--- a/packages/connect/test/fixtures/standard_relayer_api/orders.ts
+++ b/packages/connect/test/fixtures/standard_relayer_api/orders.ts
@@ -1,23 +1,23 @@
 import { BigNumber } from '@0xproject/utils';
 
 export const ordersResponse = [
-    {
-        maker: '0x9e56625509c2f60af937f23b7b532600390e8c8b',
-        taker: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
-        makerFee: new BigNumber('100000000000000'),
-        takerFee: new BigNumber('200000000000000'),
-        makerTokenAmount: new BigNumber('10000000000000000'),
-        takerTokenAmount: new BigNumber('20000000000000000'),
-        makerTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-        takerTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
-        salt: new BigNumber('256'),
-        feeRecipient: '0x9e56625509c2f60af937f23b7b532600390e8c8b',
-        exchangeContractAddress: '0x9e56625509c2f60af937f23b7b532600390e8c8b',
-        expirationUnixTimestampSec: new BigNumber('42'),
-        ecSignature: {
-            v: 27,
-            r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
-            s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
-        },
-    },
+	{
+		maker: '0x9e56625509c2f60af937f23b7b532600390e8c8b',
+		taker: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
+		makerFee: new BigNumber('100000000000000'),
+		takerFee: new BigNumber('200000000000000'),
+		makerTokenAmount: new BigNumber('10000000000000000'),
+		takerTokenAmount: new BigNumber('20000000000000000'),
+		makerTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+		takerTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
+		salt: new BigNumber('256'),
+		feeRecipient: '0x9e56625509c2f60af937f23b7b532600390e8c8b',
+		exchangeContractAddress: '0x9e56625509c2f60af937f23b7b532600390e8c8b',
+		expirationUnixTimestampSec: new BigNumber('42'),
+		ecSignature: {
+			v: 27,
+			r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
+			s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
+		},
+	},
 ];
diff --git a/packages/connect/test/fixtures/standard_relayer_api/token_pairs.json b/packages/connect/test/fixtures/standard_relayer_api/token_pairs.json
index 90f57a974..8d2ea328a 100644
--- a/packages/connect/test/fixtures/standard_relayer_api/token_pairs.json
+++ b/packages/connect/test/fixtures/standard_relayer_api/token_pairs.json
@@ -1,16 +1,16 @@
 [
-    {
-        "tokenA": {
-            "address": "0x323b5d4c32345ced77393b3530b1eed0f346429d",
-            "minAmount": "0",
-            "maxAmount": "10000000000000000000",
-            "precision": 5
-        },
-        "tokenB": {
-            "address": "0xef7fff64389b814a946f3e92105513705ca6b990",
-            "minAmount": "0",
-            "maxAmount": "50000000000000000000",
-            "precision": 5
-        }
-    }
+	{
+		"tokenA": {
+			"address": "0x323b5d4c32345ced77393b3530b1eed0f346429d",
+			"minAmount": "0",
+			"maxAmount": "10000000000000000000",
+			"precision": 5
+		},
+		"tokenB": {
+			"address": "0xef7fff64389b814a946f3e92105513705ca6b990",
+			"minAmount": "0",
+			"maxAmount": "50000000000000000000",
+			"precision": 5
+		}
+	}
 ]
diff --git a/packages/connect/test/fixtures/standard_relayer_api/token_pairs.ts b/packages/connect/test/fixtures/standard_relayer_api/token_pairs.ts
index f48b1e877..80ecb8207 100644
--- a/packages/connect/test/fixtures/standard_relayer_api/token_pairs.ts
+++ b/packages/connect/test/fixtures/standard_relayer_api/token_pairs.ts
@@ -3,18 +3,18 @@ import { BigNumber } from '@0xproject/utils';
 import { TokenPairsItem } from '../../../src/types';
 
 export const tokenPairsResponse: TokenPairsItem[] = [
-    {
-        tokenA: {
-            address: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-            minAmount: new BigNumber(0),
-            maxAmount: new BigNumber('10000000000000000000'),
-            precision: 5,
-        },
-        tokenB: {
-            address: '0xef7fff64389b814a946f3e92105513705ca6b990',
-            minAmount: new BigNumber(0),
-            maxAmount: new BigNumber('50000000000000000000'),
-            precision: 5,
-        },
-    },
+	{
+		tokenA: {
+			address: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+			minAmount: new BigNumber(0),
+			maxAmount: new BigNumber('10000000000000000000'),
+			precision: 5,
+		},
+		tokenB: {
+			address: '0xef7fff64389b814a946f3e92105513705ca6b990',
+			minAmount: new BigNumber(0),
+			maxAmount: new BigNumber('50000000000000000000'),
+			precision: 5,
+		},
+	},
 ];
diff --git a/packages/connect/test/http_client_test.ts b/packages/connect/test/http_client_test.ts
index 15759d911..00bde2fc6 100644
--- a/packages/connect/test/http_client_test.ts
+++ b/packages/connect/test/http_client_test.ts
@@ -24,128 +24,128 @@ chai.use(chaiAsPromised);
 const expect = chai.expect;
 
 describe('HttpClient', () => {
-    const relayUrl = 'https://example.com';
-    const relayerClient = new HttpClient(relayUrl);
-    afterEach(() => {
-        fetchMock.restore();
-    });
-    describe('#constructor', () => {
-        it('should remove trailing slashes from api url', async () => {
-            const urlWithTrailingSlash = 'https://slash.com/';
-            const urlWithoutTrailingSlash = 'https://slash.com';
-            const client = new HttpClient(urlWithTrailingSlash);
-            const sanitizedUrl = (client as any)._apiEndpointUrl;
-            expect(sanitizedUrl).to.be.deep.equal(urlWithoutTrailingSlash);
-        });
-    });
-    describe('#getTokenPairsAsync', () => {
-        const url = `${relayUrl}/token_pairs`;
-        it('gets token pairs', async () => {
-            fetchMock.get(url, tokenPairsResponseJSON);
-            const tokenPairs = await relayerClient.getTokenPairsAsync();
-            expect(tokenPairs).to.be.deep.equal(tokenPairsResponse);
-        });
-        it('gets specific token pairs for request', async () => {
-            const tokenAddress = '0x323b5d4c32345ced77393b3530b1eed0f346429d';
-            const tokenPairsRequest = {
-                tokenA: tokenAddress,
-            };
-            const urlWithQuery = `${url}?tokenA=${tokenAddress}`;
-            fetchMock.get(urlWithQuery, tokenPairsResponseJSON);
-            const tokenPairs = await relayerClient.getTokenPairsAsync(tokenPairsRequest);
-            expect(tokenPairs).to.be.deep.equal(tokenPairsResponse);
-        });
-        it('throws an error for invalid JSON response', async () => {
-            fetchMock.get(url, { test: 'dummy' });
-            expect(relayerClient.getTokenPairsAsync()).to.be.rejected();
-        });
-    });
-    describe('#getOrdersAsync', () => {
-        const url = `${relayUrl}/orders`;
-        it('gets orders', async () => {
-            fetchMock.get(url, ordersResponseJSON);
-            const orders = await relayerClient.getOrdersAsync();
-            expect(orders).to.be.deep.equal(ordersResponse);
-        });
-        it('gets specific orders for request', async () => {
-            const tokenAddress = '0x323b5d4c32345ced77393b3530b1eed0f346429d';
-            const ordersRequest = {
-                tokenAddress,
-            };
-            const urlWithQuery = `${url}?tokenAddress=${tokenAddress}`;
-            fetchMock.get(urlWithQuery, ordersResponseJSON);
-            const orders = await relayerClient.getOrdersAsync(ordersRequest);
-            expect(orders).to.be.deep.equal(ordersResponse);
-        });
-        it('throws an error for invalid JSON response', async () => {
-            fetchMock.get(url, { test: 'dummy' });
-            expect(relayerClient.getOrdersAsync()).to.be.rejected();
-        });
-    });
-    describe('#getOrderAsync', () => {
-        const orderHash = '0xabc67323774bdbd24d94f977fa9ac94a50f016026fd13f42990861238897721f';
-        const url = `${relayUrl}/order/${orderHash}`;
-        it('gets order', async () => {
-            fetchMock.get(url, orderResponseJSON);
-            const order = await relayerClient.getOrderAsync(orderHash);
-            expect(order).to.be.deep.equal(orderResponse);
-        });
-        it('throws an error for invalid JSON response', async () => {
-            fetchMock.get(url, { test: 'dummy' });
-            expect(relayerClient.getOrderAsync(orderHash)).to.be.rejected();
-        });
-    });
-    describe('#getOrderBookAsync', () => {
-        const request = {
-            baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-            quoteTokenAddress: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
-        };
-        const url = `${relayUrl}/orderbook?baseTokenAddress=${request.baseTokenAddress}&quoteTokenAddress=${
-            request.quoteTokenAddress
-        }`;
-        it('gets order book', async () => {
-            fetchMock.get(url, orderbookJSON);
-            const orderbook = await relayerClient.getOrderbookAsync(request);
-            expect(orderbook).to.be.deep.equal(orderbookResponse);
-        });
-        it('throws an error for invalid JSON response', async () => {
-            fetchMock.get(url, { test: 'dummy' });
-            expect(relayerClient.getOrderbookAsync(request)).to.be.rejected();
-        });
-    });
-    describe('#getFeesAsync', () => {
-        const request = {
-            exchangeContractAddress: '0x12459c951127e0c374ff9105dda097662a027093',
-            maker: '0x9e56625509c2f60af937f23b7b532600390e8c8b',
-            taker: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
-            makerTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-            takerTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
-            makerTokenAmount: new BigNumber('10000000000000000000'),
-            takerTokenAmount: new BigNumber('30000000000000000000'),
-            salt: new BigNumber('256'),
-            expirationUnixTimestampSec: new BigNumber('42'),
-        };
-        const url = `${relayUrl}/fees`;
-        it('gets fees', async () => {
-            fetchMock.post(url, feesResponseJSON);
-            const fees = await relayerClient.getFeesAsync(request);
-            expect(fees).to.be.deep.equal(feesResponse);
-        });
-        it('does not mutate input', async () => {
-            fetchMock.post(url, feesResponseJSON);
-            const makerTokenAmountBefore = new BigNumber(request.makerTokenAmount);
-            const takerTokenAmountBefore = new BigNumber(request.takerTokenAmount);
-            const saltBefore = new BigNumber(request.salt);
-            const expirationUnixTimestampSecBefore = new BigNumber(request.expirationUnixTimestampSec);
-            await relayerClient.getFeesAsync(request);
-            expect(makerTokenAmountBefore).to.be.deep.equal(request.makerTokenAmount);
-            expect(takerTokenAmountBefore).to.be.deep.equal(request.takerTokenAmount);
-            expect(saltBefore).to.be.deep.equal(request.salt);
-            expect(expirationUnixTimestampSecBefore).to.be.deep.equal(request.expirationUnixTimestampSec);
-        });
-        it('throws an error for invalid JSON response', async () => {
-            fetchMock.post(url, { test: 'dummy' });
-            expect(relayerClient.getFeesAsync(request)).to.be.rejected();
-        });
-    });
+	const relayUrl = 'https://example.com';
+	const relayerClient = new HttpClient(relayUrl);
+	afterEach(() => {
+		fetchMock.restore();
+	});
+	describe('#constructor', () => {
+		it('should remove trailing slashes from api url', async () => {
+			const urlWithTrailingSlash = 'https://slash.com/';
+			const urlWithoutTrailingSlash = 'https://slash.com';
+			const client = new HttpClient(urlWithTrailingSlash);
+			const sanitizedUrl = (client as any)._apiEndpointUrl;
+			expect(sanitizedUrl).to.be.deep.equal(urlWithoutTrailingSlash);
+		});
+	});
+	describe('#getTokenPairsAsync', () => {
+		const url = `${relayUrl}/token_pairs`;
+		it('gets token pairs', async () => {
+			fetchMock.get(url, tokenPairsResponseJSON);
+			const tokenPairs = await relayerClient.getTokenPairsAsync();
+			expect(tokenPairs).to.be.deep.equal(tokenPairsResponse);
+		});
+		it('gets specific token pairs for request', async () => {
+			const tokenAddress = '0x323b5d4c32345ced77393b3530b1eed0f346429d';
+			const tokenPairsRequest = {
+				tokenA: tokenAddress,
+			};
+			const urlWithQuery = `${url}?tokenA=${tokenAddress}`;
+			fetchMock.get(urlWithQuery, tokenPairsResponseJSON);
+			const tokenPairs = await relayerClient.getTokenPairsAsync(tokenPairsRequest);
+			expect(tokenPairs).to.be.deep.equal(tokenPairsResponse);
+		});
+		it('throws an error for invalid JSON response', async () => {
+			fetchMock.get(url, { test: 'dummy' });
+			expect(relayerClient.getTokenPairsAsync()).to.be.rejected();
+		});
+	});
+	describe('#getOrdersAsync', () => {
+		const url = `${relayUrl}/orders`;
+		it('gets orders', async () => {
+			fetchMock.get(url, ordersResponseJSON);
+			const orders = await relayerClient.getOrdersAsync();
+			expect(orders).to.be.deep.equal(ordersResponse);
+		});
+		it('gets specific orders for request', async () => {
+			const tokenAddress = '0x323b5d4c32345ced77393b3530b1eed0f346429d';
+			const ordersRequest = {
+				tokenAddress,
+			};
+			const urlWithQuery = `${url}?tokenAddress=${tokenAddress}`;
+			fetchMock.get(urlWithQuery, ordersResponseJSON);
+			const orders = await relayerClient.getOrdersAsync(ordersRequest);
+			expect(orders).to.be.deep.equal(ordersResponse);
+		});
+		it('throws an error for invalid JSON response', async () => {
+			fetchMock.get(url, { test: 'dummy' });
+			expect(relayerClient.getOrdersAsync()).to.be.rejected();
+		});
+	});
+	describe('#getOrderAsync', () => {
+		const orderHash = '0xabc67323774bdbd24d94f977fa9ac94a50f016026fd13f42990861238897721f';
+		const url = `${relayUrl}/order/${orderHash}`;
+		it('gets order', async () => {
+			fetchMock.get(url, orderResponseJSON);
+			const order = await relayerClient.getOrderAsync(orderHash);
+			expect(order).to.be.deep.equal(orderResponse);
+		});
+		it('throws an error for invalid JSON response', async () => {
+			fetchMock.get(url, { test: 'dummy' });
+			expect(relayerClient.getOrderAsync(orderHash)).to.be.rejected();
+		});
+	});
+	describe('#getOrderBookAsync', () => {
+		const request = {
+			baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+			quoteTokenAddress: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
+		};
+		const url = `${relayUrl}/orderbook?baseTokenAddress=${request.baseTokenAddress}&quoteTokenAddress=${
+			request.quoteTokenAddress
+		}`;
+		it('gets order book', async () => {
+			fetchMock.get(url, orderbookJSON);
+			const orderbook = await relayerClient.getOrderbookAsync(request);
+			expect(orderbook).to.be.deep.equal(orderbookResponse);
+		});
+		it('throws an error for invalid JSON response', async () => {
+			fetchMock.get(url, { test: 'dummy' });
+			expect(relayerClient.getOrderbookAsync(request)).to.be.rejected();
+		});
+	});
+	describe('#getFeesAsync', () => {
+		const request = {
+			exchangeContractAddress: '0x12459c951127e0c374ff9105dda097662a027093',
+			maker: '0x9e56625509c2f60af937f23b7b532600390e8c8b',
+			taker: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
+			makerTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+			takerTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
+			makerTokenAmount: new BigNumber('10000000000000000000'),
+			takerTokenAmount: new BigNumber('30000000000000000000'),
+			salt: new BigNumber('256'),
+			expirationUnixTimestampSec: new BigNumber('42'),
+		};
+		const url = `${relayUrl}/fees`;
+		it('gets fees', async () => {
+			fetchMock.post(url, feesResponseJSON);
+			const fees = await relayerClient.getFeesAsync(request);
+			expect(fees).to.be.deep.equal(feesResponse);
+		});
+		it('does not mutate input', async () => {
+			fetchMock.post(url, feesResponseJSON);
+			const makerTokenAmountBefore = new BigNumber(request.makerTokenAmount);
+			const takerTokenAmountBefore = new BigNumber(request.takerTokenAmount);
+			const saltBefore = new BigNumber(request.salt);
+			const expirationUnixTimestampSecBefore = new BigNumber(request.expirationUnixTimestampSec);
+			await relayerClient.getFeesAsync(request);
+			expect(makerTokenAmountBefore).to.be.deep.equal(request.makerTokenAmount);
+			expect(takerTokenAmountBefore).to.be.deep.equal(request.takerTokenAmount);
+			expect(saltBefore).to.be.deep.equal(request.salt);
+			expect(expirationUnixTimestampSecBefore).to.be.deep.equal(request.expirationUnixTimestampSec);
+		});
+		it('throws an error for invalid JSON response', async () => {
+			fetchMock.post(url, { test: 'dummy' });
+			expect(relayerClient.getFeesAsync(request)).to.be.rejected();
+		});
+	});
 });
diff --git a/packages/connect/test/orderbook_channel_message_parsers_test.ts b/packages/connect/test/orderbook_channel_message_parsers_test.ts
index 3e1f44384..04ca157a8 100644
--- a/packages/connect/test/orderbook_channel_message_parsers_test.ts
+++ b/packages/connect/test/orderbook_channel_message_parsers_test.ts
@@ -7,13 +7,13 @@ import { orderbookChannelMessageParser } from '../src/utils/orderbook_channel_me
 import { orderResponse } from './fixtures/standard_relayer_api/order/0xabc67323774bdbd24d94f977fa9ac94a50f016026fd13f42990861238897721f';
 import { orderbookResponse } from './fixtures/standard_relayer_api/orderbook';
 import {
-    malformedSnapshotOrderbookChannelMessage,
-    snapshotOrderbookChannelMessage,
+	malformedSnapshotOrderbookChannelMessage,
+	snapshotOrderbookChannelMessage,
 } from './fixtures/standard_relayer_api/snapshot_orderbook_channel_message';
 import { unknownOrderbookChannelMessage } from './fixtures/standard_relayer_api/unknown_orderbook_channel_message';
 import {
-    malformedUpdateOrderbookChannelMessage,
-    updateOrderbookChannelMessage,
+	malformedUpdateOrderbookChannelMessage,
+	updateOrderbookChannelMessage,
 } from './fixtures/standard_relayer_api/update_orderbook_channel_message';
 
 chai.config.includeStack = true;
@@ -21,56 +21,56 @@ chai.use(dirtyChai);
 const expect = chai.expect;
 
 describe('orderbookChannelMessageParser', () => {
-    describe('#parser', () => {
-        it('parses snapshot messages', () => {
-            const snapshotMessage = orderbookChannelMessageParser.parse(snapshotOrderbookChannelMessage);
-            expect(snapshotMessage.type).to.be.equal('snapshot');
-            expect(snapshotMessage.payload).to.be.deep.equal(orderbookResponse);
-        });
-        it('parses update messages', () => {
-            const updateMessage = orderbookChannelMessageParser.parse(updateOrderbookChannelMessage);
-            expect(updateMessage.type).to.be.equal('update');
-            expect(updateMessage.payload).to.be.deep.equal(orderResponse);
-        });
-        it('returns unknown message for messages with unsupported types', () => {
-            const unknownMessage = orderbookChannelMessageParser.parse(unknownOrderbookChannelMessage);
-            expect(unknownMessage.type).to.be.equal('unknown');
-            expect(unknownMessage.payload).to.be.undefined();
-        });
-        it('throws when message does not include a type', () => {
-            const typelessMessage = `{
+	describe('#parser', () => {
+		it('parses snapshot messages', () => {
+			const snapshotMessage = orderbookChannelMessageParser.parse(snapshotOrderbookChannelMessage);
+			expect(snapshotMessage.type).to.be.equal('snapshot');
+			expect(snapshotMessage.payload).to.be.deep.equal(orderbookResponse);
+		});
+		it('parses update messages', () => {
+			const updateMessage = orderbookChannelMessageParser.parse(updateOrderbookChannelMessage);
+			expect(updateMessage.type).to.be.equal('update');
+			expect(updateMessage.payload).to.be.deep.equal(orderResponse);
+		});
+		it('returns unknown message for messages with unsupported types', () => {
+			const unknownMessage = orderbookChannelMessageParser.parse(unknownOrderbookChannelMessage);
+			expect(unknownMessage.type).to.be.equal('unknown');
+			expect(unknownMessage.payload).to.be.undefined();
+		});
+		it('throws when message does not include a type', () => {
+			const typelessMessage = `{
                 "channel": "orderbook",
                 "requestId": 1,
                 "payload": {}
             }`;
-            const badCall = () => orderbookChannelMessageParser.parse(typelessMessage);
-            expect(badCall).throws(`Message is missing a type parameter: ${typelessMessage}`);
-        });
-        it('throws when type is not a string', () => {
-            const messageWithBadType = `{
+			const badCall = () => orderbookChannelMessageParser.parse(typelessMessage);
+			expect(badCall).throws(`Message is missing a type parameter: ${typelessMessage}`);
+		});
+		it('throws when type is not a string', () => {
+			const messageWithBadType = `{
                 "type": 1,
                 "channel": "orderbook",
                 "requestId": 1,
                 "payload": {}
             }`;
-            const badCall = () => orderbookChannelMessageParser.parse(messageWithBadType);
-            expect(badCall).throws('Expected type to be of type string, encountered: 1');
-        });
-        it('throws when snapshot message has malformed payload', () => {
-            const badCall = () => orderbookChannelMessageParser.parse(malformedSnapshotOrderbookChannelMessage);
-            // tslint:disable-next-line:max-line-length
-            const errMsg =
-                'Validation errors: instance.payload requires property "bids", instance.payload requires property "asks"';
-            expect(badCall).throws(errMsg);
-        });
-        it('throws when update message has malformed payload', () => {
-            const badCall = () => orderbookChannelMessageParser.parse(malformedUpdateOrderbookChannelMessage);
-            expect(badCall).throws(/^Expected message to conform to schema/);
-        });
-        it('throws when input message is not valid JSON', () => {
-            const nonJsonString = 'h93b{sdfs9fsd f';
-            const badCall = () => orderbookChannelMessageParser.parse(nonJsonString);
-            expect(badCall).throws('Unexpected token h in JSON at position 0');
-        });
-    });
+			const badCall = () => orderbookChannelMessageParser.parse(messageWithBadType);
+			expect(badCall).throws('Expected type to be of type string, encountered: 1');
+		});
+		it('throws when snapshot message has malformed payload', () => {
+			const badCall = () => orderbookChannelMessageParser.parse(malformedSnapshotOrderbookChannelMessage);
+			// tslint:disable-next-line:max-line-length
+			const errMsg =
+				'Validation errors: instance.payload requires property "bids", instance.payload requires property "asks"';
+			expect(badCall).throws(errMsg);
+		});
+		it('throws when update message has malformed payload', () => {
+			const badCall = () => orderbookChannelMessageParser.parse(malformedUpdateOrderbookChannelMessage);
+			expect(badCall).throws(/^Expected message to conform to schema/);
+		});
+		it('throws when input message is not valid JSON', () => {
+			const nonJsonString = 'h93b{sdfs9fsd f';
+			const badCall = () => orderbookChannelMessageParser.parse(nonJsonString);
+			expect(badCall).throws('Unexpected token h in JSON at position 0');
+		});
+	});
 });
diff --git a/packages/connect/test/ws_orderbook_channel_test.ts b/packages/connect/test/ws_orderbook_channel_test.ts
index ce404d934..0cd8cd12f 100644
--- a/packages/connect/test/ws_orderbook_channel_test.ts
+++ b/packages/connect/test/ws_orderbook_channel_test.ts
@@ -10,52 +10,52 @@ chai.use(dirtyChai);
 const expect = chai.expect;
 
 describe('WebSocketOrderbookChannel', () => {
-    const websocketUrl = 'ws://localhost:8080';
-    const orderbookChannel = new WebSocketOrderbookChannel(websocketUrl);
-    const subscriptionOpts = {
-        baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-        quoteTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
-        snapshot: true,
-        limit: 100,
-    };
-    const emptyOrderbookChannelHandler = {
-        onSnapshot: () => {
-            _.noop();
-        },
-        onUpdate: () => {
-            _.noop();
-        },
-        onError: () => {
-            _.noop();
-        },
-        onClose: () => {
-            _.noop();
-        },
-    };
-    describe('#subscribe', () => {
-        it('throws when subscriptionOpts does not conform to schema', () => {
-            const badSubscribeCall = orderbookChannel.subscribe.bind(
-                orderbookChannel,
-                {},
-                emptyOrderbookChannelHandler,
-            );
-            expect(badSubscribeCall).throws(
-                'Expected subscriptionOpts to conform to schema /RelayerApiOrderbookChannelSubscribePayload\nEncountered: {}\nValidation errors: instance requires property "baseTokenAddress", instance requires property "quoteTokenAddress"',
-            );
-        });
-        it('throws when handler has the incorrect members', () => {
-            const badSubscribeCall = orderbookChannel.subscribe.bind(orderbookChannel, subscriptionOpts, {});
-            expect(badSubscribeCall).throws(
-                'Expected handler.onSnapshot to be of type function, encountered: undefined',
-            );
-        });
-        it('does not throw when inputs are of correct types', () => {
-            const goodSubscribeCall = orderbookChannel.subscribe.bind(
-                orderbookChannel,
-                subscriptionOpts,
-                emptyOrderbookChannelHandler,
-            );
-            expect(goodSubscribeCall).to.not.throw();
-        });
-    });
+	const websocketUrl = 'ws://localhost:8080';
+	const orderbookChannel = new WebSocketOrderbookChannel(websocketUrl);
+	const subscriptionOpts = {
+		baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+		quoteTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
+		snapshot: true,
+		limit: 100,
+	};
+	const emptyOrderbookChannelHandler = {
+		onSnapshot: () => {
+			_.noop();
+		},
+		onUpdate: () => {
+			_.noop();
+		},
+		onError: () => {
+			_.noop();
+		},
+		onClose: () => {
+			_.noop();
+		},
+	};
+	describe('#subscribe', () => {
+		it('throws when subscriptionOpts does not conform to schema', () => {
+			const badSubscribeCall = orderbookChannel.subscribe.bind(
+				orderbookChannel,
+				{},
+				emptyOrderbookChannelHandler,
+			);
+			expect(badSubscribeCall).throws(
+				'Expected subscriptionOpts to conform to schema /RelayerApiOrderbookChannelSubscribePayload\nEncountered: {}\nValidation errors: instance requires property "baseTokenAddress", instance requires property "quoteTokenAddress"',
+			);
+		});
+		it('throws when handler has the incorrect members', () => {
+			const badSubscribeCall = orderbookChannel.subscribe.bind(orderbookChannel, subscriptionOpts, {});
+			expect(badSubscribeCall).throws(
+				'Expected handler.onSnapshot to be of type function, encountered: undefined',
+			);
+		});
+		it('does not throw when inputs are of correct types', () => {
+			const goodSubscribeCall = orderbookChannel.subscribe.bind(
+				orderbookChannel,
+				subscriptionOpts,
+				emptyOrderbookChannelHandler,
+			);
+			expect(goodSubscribeCall).to.not.throw();
+		});
+	});
 });
diff --git a/packages/connect/tsconfig.json b/packages/connect/tsconfig.json
index 3c150236e..ed8210b04 100644
--- a/packages/connect/tsconfig.json
+++ b/packages/connect/tsconfig.json
@@ -1,12 +1,12 @@
 {
-    "extends": "../../tsconfig",
-    "compilerOptions": {
-        "outDir": "lib"
-    },
-    "include": [
-        "./src/**/*",
-        "./test/**/*",
-        "../../node_modules/chai-as-promised-typescript-typings/index.d.ts",
-        "../../node_modules/chai-typescript-typings/index.d.ts"
-    ]
+	"extends": "../../tsconfig",
+	"compilerOptions": {
+		"outDir": "lib"
+	},
+	"include": [
+		"./src/**/*",
+		"./test/**/*",
+		"../../node_modules/chai-as-promised-typescript-typings/index.d.ts",
+		"../../node_modules/chai-typescript-typings/index.d.ts"
+	]
 }
diff --git a/packages/connect/tslint.json b/packages/connect/tslint.json
index ffaefe83a..e63054bfc 100644
--- a/packages/connect/tslint.json
+++ b/packages/connect/tslint.json
@@ -1,3 +1,3 @@
 {
-    "extends": ["@0xproject/tslint-config"]
+	"extends": ["@0xproject/tslint-config"]
 }
diff --git a/packages/contracts/globals.d.ts b/packages/contracts/globals.d.ts
index 2e5827324..1f451cf5b 100644
--- a/packages/contracts/globals.d.ts
+++ b/packages/contracts/globals.d.ts
@@ -6,31 +6,31 @@ declare module 'dirty-chai';
 // disallow `namespace`, we disable tslint for the following.
 /* tslint:disable */
 declare namespace Chai {
-    interface Assertion {
-        bignumber: Assertion;
-    }
+	interface Assertion {
+		bignumber: Assertion;
+	}
 }
 /* tslint:enable */
 
 declare module '*.json' {
-    const json: any;
-    /* tslint:disable */
-    export default json;
-    /* tslint:enable */
+	const json: any;
+	/* tslint:disable */
+	export default json;
+	/* tslint:enable */
 }
 
 declare module 'solc' {
-    export function compile(sources: any, optimizerEnabled: number, findImports: (importPath: string) => any): any;
-    export function setupMethods(solcBin: any): any;
+	export function compile(sources: any, optimizerEnabled: number, findImports: (importPath: string) => any): any;
+	export function setupMethods(solcBin: any): any;
 }
 
 declare module 'web3-eth-abi' {
-    export function encodeParameters(typesArray: string[], parameters: any[]): string;
+	export function encodeParameters(typesArray: string[], parameters: any[]): string;
 }
 
 declare module 'ethereumjs-abi' {
-    const soliditySHA3: (argTypes: string[], args: any[]) => Buffer;
-    const methodID: (name: string, types: string[]) => Buffer;
+	const soliditySHA3: (argTypes: string[], args: any[]) => Buffer;
+	const methodID: (name: string, types: string[]) => Buffer;
 }
 
 // Truffle injects the following into the global scope
diff --git a/packages/contracts/globalsAugment.d.ts b/packages/contracts/globalsAugment.d.ts
index 9b16ce2ad..c81a74844 100644
--- a/packages/contracts/globalsAugment.d.ts
+++ b/packages/contracts/globalsAugment.d.ts
@@ -3,17 +3,17 @@ import { BigNumber } from '@0xproject/utils';
 // 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 */
+	// 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 */
 }
diff --git a/packages/contracts/migrations/1_initial_migration.ts b/packages/contracts/migrations/1_initial_migration.ts
index 8661ee218..73999dac5 100644
--- a/packages/contracts/migrations/1_initial_migration.ts
+++ b/packages/contracts/migrations/1_initial_migration.ts
@@ -2,5 +2,5 @@ import { Artifacts } from '../util/artifacts';
 const { Migrations } = new Artifacts(artifacts);
 
 module.exports = (deployer: any) => {
-    deployer.deploy(Migrations);
+	deployer.deploy(Migrations);
 };
diff --git a/packages/contracts/migrations/2_deploy_independent_contracts.ts b/packages/contracts/migrations/2_deploy_independent_contracts.ts
index ac1752347..07e2f600f 100644
--- a/packages/contracts/migrations/2_deploy_independent_contracts.ts
+++ b/packages/contracts/migrations/2_deploy_independent_contracts.ts
@@ -4,38 +4,38 @@ const { MultiSigWalletWithTimeLock, TokenTransferProxy, EtherToken, TokenRegistr
 
 let multiSigConfigByNetwork: MultiSigConfigByNetwork;
 try {
-    /* tslint:disable */
-    const multiSigConfig = require('./config/multisig');
-    multiSigConfigByNetwork = multiSigConfig.multiSig;
-    /* tslint:enable */
+	/* tslint:disable */
+	const multiSigConfig = require('./config/multisig');
+	multiSigConfigByNetwork = multiSigConfig.multiSig;
+	/* tslint:enable */
 } catch (e) {
-    multiSigConfigByNetwork = {};
+	multiSigConfigByNetwork = {};
 }
 
 module.exports = (deployer: any, network: string, accounts: string[]) => {
-    const defaultConfig = {
-        owners: [accounts[0], accounts[1]],
-        confirmationsRequired: 2,
-        secondsRequired: 0,
-    };
-    const config = multiSigConfigByNetwork[network] || defaultConfig;
-    if (network !== 'live') {
-        deployer
-            .deploy(MultiSigWalletWithTimeLock, config.owners, config.confirmationsRequired, config.secondsRequired)
-            .then(() => {
-                return deployer.deploy(TokenTransferProxy);
-            })
-            .then(() => {
-                return deployer.deploy(TokenRegistry);
-            })
-            .then(() => {
-                return deployer.deploy(EtherToken);
-            });
-    } else {
-        deployer.deploy([
-            [MultiSigWalletWithTimeLock, config.owners, config.confirmationsRequired, config.secondsRequired],
-            TokenTransferProxy,
-            TokenRegistry,
-        ]);
-    }
+	const defaultConfig = {
+		owners: [accounts[0], accounts[1]],
+		confirmationsRequired: 2,
+		secondsRequired: 0,
+	};
+	const config = multiSigConfigByNetwork[network] || defaultConfig;
+	if (network !== 'live') {
+		deployer
+			.deploy(MultiSigWalletWithTimeLock, config.owners, config.confirmationsRequired, config.secondsRequired)
+			.then(() => {
+				return deployer.deploy(TokenTransferProxy);
+			})
+			.then(() => {
+				return deployer.deploy(TokenRegistry);
+			})
+			.then(() => {
+				return deployer.deploy(EtherToken);
+			});
+	} else {
+		deployer.deploy([
+			[MultiSigWalletWithTimeLock, config.owners, config.confirmationsRequired, config.secondsRequired],
+			TokenTransferProxy,
+			TokenRegistry,
+		]);
+	}
 };
diff --git a/packages/contracts/migrations/3_register_tokens.ts b/packages/contracts/migrations/3_register_tokens.ts
index d5cf63f94..b36cea296 100644
--- a/packages/contracts/migrations/3_register_tokens.ts
+++ b/packages/contracts/migrations/3_register_tokens.ts
@@ -9,87 +9,87 @@ import { tokenInfo } from './config/token_info';
 const { DummyToken, EtherToken, ZRXToken, TokenRegistry } = new Artifacts(artifacts);
 
 module.exports = (deployer: any, network: string) => {
-    const tokens = network === 'live' ? tokenInfo.live : tokenInfo.development;
-    deployer
-        .then(() => {
-            return TokenRegistry.deployed();
-        })
-        .then((tokenRegistry: ContractInstance) => {
-            if (network !== 'live') {
-                const totalSupply = Math.pow(10, 18) * 1000000000;
-                return Bluebird.each(
-                    tokens.map((token: Token) => DummyToken.new(token.name, token.symbol, token.decimals, totalSupply)),
-                    _.noop,
-                ).then((dummyTokens: ContractInstance[]) => {
-                    const weth = {
-                        address: EtherToken.address,
-                        name: 'Ether Token',
-                        symbol: 'WETH',
-                        url: '',
-                        decimals: 18,
-                        ipfsHash: constants.NULL_BYTES,
-                        swarmHash: constants.NULL_BYTES,
-                    };
-                    return Bluebird.each(
-                        dummyTokens
-                            .map((tokenContract: ContractInstance, i: number) => {
-                                const token = tokens[i];
-                                return tokenRegistry.addToken(
-                                    tokenContract.address,
-                                    token.name,
-                                    token.symbol,
-                                    token.decimals,
-                                    token.ipfsHash,
-                                    token.swarmHash,
-                                );
-                            })
-                            .concat(
-                                tokenRegistry.addToken(
-                                    weth.address,
-                                    weth.name,
-                                    weth.symbol,
-                                    weth.decimals,
-                                    weth.ipfsHash,
-                                    weth.swarmHash,
-                                ),
-                            ),
-                        _.noop,
-                    );
-                });
-            } else {
-                const zrx = {
-                    address: ZRXToken.address,
-                    name: '0x Protocol Token',
-                    symbol: 'ZRX',
-                    url: 'https://www.0xproject.com/',
-                    decimals: 18,
-                    ipfsHash: constants.NULL_BYTES,
-                    swarmHash: constants.NULL_BYTES,
-                };
-                return Bluebird.each(
-                    tokens
-                        .map((token: Token) => {
-                            return tokenRegistry.addToken(
-                                token.address,
-                                token.name,
-                                token.symbol,
-                                token.decimals,
-                                token.ipfsHash,
-                                token.swarmHash,
-                            );
-                        })
-                        .concat(
-                            tokenRegistry.addToken(
-                                zrx.address,
-                                zrx.name,
-                                zrx.symbol,
-                                zrx.decimals,
-                                zrx.ipfsHash,
-                                zrx.swarmHash,
-                            ),
-                        ),
-                    _.noop,
-                );
-            }
-        });
+	const tokens = network === 'live' ? tokenInfo.live : tokenInfo.development;
+	deployer
+		.then(() => {
+			return TokenRegistry.deployed();
+		})
+		.then((tokenRegistry: ContractInstance) => {
+			if (network !== 'live') {
+				const totalSupply = Math.pow(10, 18) * 1000000000;
+				return Bluebird.each(
+					tokens.map((token: Token) => DummyToken.new(token.name, token.symbol, token.decimals, totalSupply)),
+					_.noop,
+				).then((dummyTokens: ContractInstance[]) => {
+					const weth = {
+						address: EtherToken.address,
+						name: 'Ether Token',
+						symbol: 'WETH',
+						url: '',
+						decimals: 18,
+						ipfsHash: constants.NULL_BYTES,
+						swarmHash: constants.NULL_BYTES,
+					};
+					return Bluebird.each(
+						dummyTokens
+							.map((tokenContract: ContractInstance, i: number) => {
+								const token = tokens[i];
+								return tokenRegistry.addToken(
+									tokenContract.address,
+									token.name,
+									token.symbol,
+									token.decimals,
+									token.ipfsHash,
+									token.swarmHash,
+								);
+							})
+							.concat(
+								tokenRegistry.addToken(
+									weth.address,
+									weth.name,
+									weth.symbol,
+									weth.decimals,
+									weth.ipfsHash,
+									weth.swarmHash,
+								),
+							),
+						_.noop,
+					);
+				});
+			} else {
+				const zrx = {
+					address: ZRXToken.address,
+					name: '0x Protocol Token',
+					symbol: 'ZRX',
+					url: 'https://www.0xproject.com/',
+					decimals: 18,
+					ipfsHash: constants.NULL_BYTES,
+					swarmHash: constants.NULL_BYTES,
+				};
+				return Bluebird.each(
+					tokens
+						.map((token: Token) => {
+							return tokenRegistry.addToken(
+								token.address,
+								token.name,
+								token.symbol,
+								token.decimals,
+								token.ipfsHash,
+								token.swarmHash,
+							);
+						})
+						.concat(
+							tokenRegistry.addToken(
+								zrx.address,
+								zrx.name,
+								zrx.symbol,
+								zrx.decimals,
+								zrx.ipfsHash,
+								zrx.swarmHash,
+							),
+						),
+					_.noop,
+				);
+			}
+		});
 };
diff --git a/packages/contracts/migrations/4_configure_proxy.ts b/packages/contracts/migrations/4_configure_proxy.ts
index ff3b844d6..ce34ddd32 100644
--- a/packages/contracts/migrations/4_configure_proxy.ts
+++ b/packages/contracts/migrations/4_configure_proxy.ts
@@ -4,19 +4,19 @@ const { TokenTransferProxy, Exchange, TokenRegistry } = new Artifacts(artifacts)
 
 let tokenTransferProxy: ContractInstance;
 module.exports = (deployer: any) => {
-    deployer
-        .then(async () => {
-            return Promise.all([TokenTransferProxy.deployed(), TokenRegistry.deployed()]);
-        })
-        .then((instances: ContractInstance[]) => {
-            let tokenRegistry: ContractInstance;
-            [tokenTransferProxy, tokenRegistry] = instances;
-            return tokenRegistry.getTokenAddressBySymbol('ZRX');
-        })
-        .then((ptAddress: string) => {
-            return deployer.deploy(Exchange, ptAddress, tokenTransferProxy.address);
-        })
-        .then(() => {
-            return tokenTransferProxy.addAuthorizedAddress(Exchange.address);
-        });
+	deployer
+		.then(async () => {
+			return Promise.all([TokenTransferProxy.deployed(), TokenRegistry.deployed()]);
+		})
+		.then((instances: ContractInstance[]) => {
+			let tokenRegistry: ContractInstance;
+			[tokenTransferProxy, tokenRegistry] = instances;
+			return tokenRegistry.getTokenAddressBySymbol('ZRX');
+		})
+		.then((ptAddress: string) => {
+			return deployer.deploy(Exchange, ptAddress, tokenTransferProxy.address);
+		})
+		.then(() => {
+			return tokenTransferProxy.addAuthorizedAddress(Exchange.address);
+		});
 };
diff --git a/packages/contracts/migrations/5_transfer_ownership.ts b/packages/contracts/migrations/5_transfer_ownership.ts
index a27801de3..08b068e18 100644
--- a/packages/contracts/migrations/5_transfer_ownership.ts
+++ b/packages/contracts/migrations/5_transfer_ownership.ts
@@ -4,17 +4,17 @@ const { TokenTransferProxy, MultiSigWalletWithTimeLock, TokenRegistry } = new Ar
 
 let tokenRegistry: ContractInstance;
 module.exports = (deployer: any, network: string) => {
-    if (network !== 'development') {
-        deployer.then(async () => {
-            return Promise.all([TokenTransferProxy.deployed(), TokenRegistry.deployed()])
-                .then((instances: ContractInstance[]) => {
-                    let tokenTransferProxy: ContractInstance;
-                    [tokenTransferProxy, tokenRegistry] = instances;
-                    return tokenTransferProxy.transferOwnership(MultiSigWalletWithTimeLock.address);
-                })
-                .then(() => {
-                    return tokenRegistry.transferOwnership(MultiSigWalletWithTimeLock.address);
-                });
-        });
-    }
+	if (network !== 'development') {
+		deployer.then(async () => {
+			return Promise.all([TokenTransferProxy.deployed(), TokenRegistry.deployed()])
+				.then((instances: ContractInstance[]) => {
+					let tokenTransferProxy: ContractInstance;
+					[tokenTransferProxy, tokenRegistry] = instances;
+					return tokenTransferProxy.transferOwnership(MultiSigWalletWithTimeLock.address);
+				})
+				.then(() => {
+					return tokenRegistry.transferOwnership(MultiSigWalletWithTimeLock.address);
+				});
+		});
+	}
 };
diff --git a/packages/contracts/migrations/config/multisig_sample.ts b/packages/contracts/migrations/config/multisig_sample.ts
index 97cdc2eae..6ff5efc1c 100644
--- a/packages/contracts/migrations/config/multisig_sample.ts
+++ b/packages/contracts/migrations/config/multisig_sample.ts
@@ -2,9 +2,9 @@ import { MultiSigConfigByNetwork } from '../../util/types';
 
 // Make a copy of this file named `multisig.js` and input custom params as needed
 export const multiSig: MultiSigConfigByNetwork = {
-    kovan: {
-        owners: [],
-        confirmationsRequired: 0,
-        secondsRequired: 0,
-    },
+	kovan: {
+		owners: [],
+		confirmationsRequired: 0,
+		secondsRequired: 0,
+	},
 };
diff --git a/packages/contracts/migrations/config/token_info.ts b/packages/contracts/migrations/config/token_info.ts
index 6ae67175e..9e211c489 100644
--- a/packages/contracts/migrations/config/token_info.ts
+++ b/packages/contracts/migrations/config/token_info.ts
@@ -2,98 +2,98 @@ import { constants } from '../../util/constants';
 import { TokenInfoByNetwork } from '../../util/types';
 
 export const tokenInfo: TokenInfoByNetwork = {
-    development: [
-        {
-            name: '0x Protocol Token',
-            symbol: 'ZRX',
-            decimals: 18,
-            ipfsHash: constants.NULL_BYTES,
-            swarmHash: constants.NULL_BYTES,
-        },
-        {
-            name: 'Augur Reputation Token',
-            symbol: 'REP',
-            decimals: 18,
-            ipfsHash: constants.NULL_BYTES,
-            swarmHash: constants.NULL_BYTES,
-        },
-        {
-            name: 'Digix DAO Token',
-            symbol: 'DGD',
-            decimals: 18,
-            ipfsHash: constants.NULL_BYTES,
-            swarmHash: constants.NULL_BYTES,
-        },
-        {
-            name: 'Golem Network Token',
-            symbol: 'GNT',
-            decimals: 18,
-            ipfsHash: constants.NULL_BYTES,
-            swarmHash: constants.NULL_BYTES,
-        },
-        {
-            name: 'MakerDAO',
-            symbol: 'MKR',
-            decimals: 18,
-            ipfsHash: constants.NULL_BYTES,
-            swarmHash: constants.NULL_BYTES,
-        },
-        {
-            name: 'Melon Token',
-            symbol: 'MLN',
-            decimals: 18,
-            ipfsHash: constants.NULL_BYTES,
-            swarmHash: constants.NULL_BYTES,
-        },
-    ],
-    live: [
-        {
-            address: '0xecf8f87f810ecf450940c9f60066b4a7a501d6a7',
-            name: 'ETH Wrapper Token',
-            symbol: 'WETH',
-            decimals: 18,
-            ipfsHash: constants.NULL_BYTES,
-            swarmHash: constants.NULL_BYTES,
-        },
-        {
-            address: '0x48c80f1f4d53d5951e5d5438b54cba84f29f32a5',
-            name: 'Augur Reputation Token',
-            symbol: 'REP',
-            decimals: 18,
-            ipfsHash: constants.NULL_BYTES,
-            swarmHash: constants.NULL_BYTES,
-        },
-        {
-            address: '0xe0b7927c4af23765cb51314a0e0521a9645f0e2a',
-            name: 'Digix DAO Token',
-            symbol: 'DGD',
-            decimals: 18,
-            ipfsHash: constants.NULL_BYTES,
-            swarmHash: constants.NULL_BYTES,
-        },
-        {
-            address: '0xa74476443119a942de498590fe1f2454d7d4ac0d',
-            name: 'Golem Network Token',
-            symbol: 'GNT',
-            decimals: 18,
-            ipfsHash: constants.NULL_BYTES,
-            swarmHash: constants.NULL_BYTES,
-        },
-        {
-            address: '0xc66ea802717bfb9833400264dd12c2bceaa34a6d',
-            name: 'MakerDAO',
-            symbol: 'MKR',
-            decimals: 18,
-            ipfsHash: constants.NULL_BYTES,
-            swarmHash: constants.NULL_BYTES,
-        },
-        {
-            address: '0xbeb9ef514a379b997e0798fdcc901ee474b6d9a1',
-            name: 'Melon Token',
-            symbol: 'MLN',
-            decimals: 18,
-            ipfsHash: constants.NULL_BYTES,
-            swarmHash: constants.NULL_BYTES,
-        },
-    ],
+	development: [
+		{
+			name: '0x Protocol Token',
+			symbol: 'ZRX',
+			decimals: 18,
+			ipfsHash: constants.NULL_BYTES,
+			swarmHash: constants.NULL_BYTES,
+		},
+		{
+			name: 'Augur Reputation Token',
+			symbol: 'REP',
+			decimals: 18,
+			ipfsHash: constants.NULL_BYTES,
+			swarmHash: constants.NULL_BYTES,
+		},
+		{
+			name: 'Digix DAO Token',
+			symbol: 'DGD',
+			decimals: 18,
+			ipfsHash: constants.NULL_BYTES,
+			swarmHash: constants.NULL_BYTES,
+		},
+		{
+			name: 'Golem Network Token',
+			symbol: 'GNT',
+			decimals: 18,
+			ipfsHash: constants.NULL_BYTES,
+			swarmHash: constants.NULL_BYTES,
+		},
+		{
+			name: 'MakerDAO',
+			symbol: 'MKR',
+			decimals: 18,
+			ipfsHash: constants.NULL_BYTES,
+			swarmHash: constants.NULL_BYTES,
+		},
+		{
+			name: 'Melon Token',
+			symbol: 'MLN',
+			decimals: 18,
+			ipfsHash: constants.NULL_BYTES,
+			swarmHash: constants.NULL_BYTES,
+		},
+	],
+	live: [
+		{
+			address: '0xecf8f87f810ecf450940c9f60066b4a7a501d6a7',
+			name: 'ETH Wrapper Token',
+			symbol: 'WETH',
+			decimals: 18,
+			ipfsHash: constants.NULL_BYTES,
+			swarmHash: constants.NULL_BYTES,
+		},
+		{
+			address: '0x48c80f1f4d53d5951e5d5438b54cba84f29f32a5',
+			name: 'Augur Reputation Token',
+			symbol: 'REP',
+			decimals: 18,
+			ipfsHash: constants.NULL_BYTES,
+			swarmHash: constants.NULL_BYTES,
+		},
+		{
+			address: '0xe0b7927c4af23765cb51314a0e0521a9645f0e2a',
+			name: 'Digix DAO Token',
+			symbol: 'DGD',
+			decimals: 18,
+			ipfsHash: constants.NULL_BYTES,
+			swarmHash: constants.NULL_BYTES,
+		},
+		{
+			address: '0xa74476443119a942de498590fe1f2454d7d4ac0d',
+			name: 'Golem Network Token',
+			symbol: 'GNT',
+			decimals: 18,
+			ipfsHash: constants.NULL_BYTES,
+			swarmHash: constants.NULL_BYTES,
+		},
+		{
+			address: '0xc66ea802717bfb9833400264dd12c2bceaa34a6d',
+			name: 'MakerDAO',
+			symbol: 'MKR',
+			decimals: 18,
+			ipfsHash: constants.NULL_BYTES,
+			swarmHash: constants.NULL_BYTES,
+		},
+		{
+			address: '0xbeb9ef514a379b997e0798fdcc901ee474b6d9a1',
+			name: 'Melon Token',
+			symbol: 'MLN',
+			decimals: 18,
+			ipfsHash: constants.NULL_BYTES,
+			swarmHash: constants.NULL_BYTES,
+		},
+	],
 };
diff --git a/packages/contracts/package.json b/packages/contracts/package.json
index b3af7c55d..b361c6622 100644
--- a/packages/contracts/package.json
+++ b/packages/contracts/package.json
@@ -1,72 +1,74 @@
 {
-    "private": true,
-    "name": "contracts",
-    "version": "2.1.6",
-    "description": "Smart contract components of 0x protocol",
-    "main": "index.js",
-    "directories": {
-        "test": "test"
-    },
-    "scripts": {
-        "build": "rm -rf ./lib; copyfiles ./build/**/* ./deploy/solc/solc_bin/* ./deploy/test/fixtures/contracts/**/* ./deploy/test/fixtures/contracts/* ./lib; tsc;",
-        "test": "npm run build; truffle test",
-        "compile:comment": "Yarn workspaces do not link binaries correctly so we need to reference them directly https://github.com/yarnpkg/yarn/issues/3846",
-        "compile": "node ../deployer/lib/src/cli.js compile",
-        "clean": "rm -rf ./lib",
-        "migrate": "node ../deployer/lib/src/cli.js migrate",
-        "lint": "tslint --project . 'migrations/**/*.ts' 'test/**/*.ts' 'util/**/*.ts' 'deploy/**/*.ts'",
-        "test:circleci": "yarn test"
-    },
-    "repository": {
-        "type": "git",
-        "url": "https://github.com/0xProject/0x.js.git"
-    },
-    "author": "Amir Bandeali",
-    "license": "Apache-2.0",
-    "bugs": {
-        "url": "https://github.com/0xProject/0x.js/issues"
-    },
-    "homepage": "https://github.com/0xProject/0x.js/packages/contracts/README.md",
-    "devDependencies": {
-        "@0xproject/dev-utils": "^0.0.7",
-        "@0xproject/tslint-config": "^0.4.4",
-        "@0xproject/types": "^0.1.6",
-        "@types/bluebird": "^3.5.3",
-        "@types/lodash": "^4.14.86",
-        "@types/node": "^8.0.53",
-        "@types/request-promise-native": "^1.0.2",
-        "@types/yargs": "^10.0.0",
-        "chai": "^4.0.1",
-        "chai-as-promised": "^7.1.0",
-        "chai-as-promised-typescript-typings": "^0.0.6",
-        "chai-bignumber": "^2.0.1",
-        "chai-typescript-typings": "^0.0.2",
-        "copyfiles": "^1.2.0",
-        "dirty-chai": "^2.0.1",
-        "mocha": "^4.0.1",
-        "solc": "^0.4.18",
-        "truffle": "^4.0.1",
-        "tslint": "5.8.0",
-        "types-bn": "^0.0.1",
-        "types-ethereumjs-util": "0xProject/types-ethereumjs-util",
-        "typescript": "~2.6.1",
-        "web3-typescript-typings": "^0.9.6",
-        "yargs": "^10.0.3"
-    },
-    "dependencies": {
-        "0x.js": "^0.30.2",
-        "@0xproject/deployer": "^0.0.3",
-        "@0xproject/json-schemas": "^0.7.5",
-        "@0xproject/utils": "^0.2.2",
-        "@0xproject/web3-wrapper": "^0.1.7",
-        "bluebird": "^3.5.0",
-        "bn.js": "^4.11.8",
-        "ethereumjs-abi": "^0.6.4",
-        "ethereumjs-util": "^5.1.1",
-        "isomorphic-fetch": "^2.2.1",
-        "lodash": "^4.17.4",
-        "request": "^2.81.0",
-        "web3": "^0.20.0",
-        "web3-eth-abi": "^1.0.0-beta.24"
-    }
+	"private": true,
+	"name": "contracts",
+	"version": "2.1.6",
+	"description": "Smart contract components of 0x protocol",
+	"main": "index.js",
+	"directories": {
+		"test": "test"
+	},
+	"scripts": {
+		"build":
+			"rm -rf ./lib; copyfiles ./build/**/* ./deploy/solc/solc_bin/* ./deploy/test/fixtures/contracts/**/* ./deploy/test/fixtures/contracts/* ./lib; tsc;",
+		"test": "npm run build; truffle test",
+		"compile:comment":
+			"Yarn workspaces do not link binaries correctly so we need to reference them directly https://github.com/yarnpkg/yarn/issues/3846",
+		"compile": "node ../deployer/lib/src/cli.js compile",
+		"clean": "rm -rf ./lib",
+		"migrate": "node ../deployer/lib/src/cli.js migrate",
+		"lint": "tslint --project . 'migrations/**/*.ts' 'test/**/*.ts' 'util/**/*.ts' 'deploy/**/*.ts'",
+		"test:circleci": "yarn test"
+	},
+	"repository": {
+		"type": "git",
+		"url": "https://github.com/0xProject/0x.js.git"
+	},
+	"author": "Amir Bandeali",
+	"license": "Apache-2.0",
+	"bugs": {
+		"url": "https://github.com/0xProject/0x.js/issues"
+	},
+	"homepage": "https://github.com/0xProject/0x.js/packages/contracts/README.md",
+	"devDependencies": {
+		"@0xproject/dev-utils": "^0.0.7",
+		"@0xproject/tslint-config": "^0.4.4",
+		"@0xproject/types": "^0.1.6",
+		"@types/bluebird": "^3.5.3",
+		"@types/lodash": "^4.14.86",
+		"@types/node": "^8.0.53",
+		"@types/request-promise-native": "^1.0.2",
+		"@types/yargs": "^10.0.0",
+		"chai": "^4.0.1",
+		"chai-as-promised": "^7.1.0",
+		"chai-as-promised-typescript-typings": "^0.0.6",
+		"chai-bignumber": "^2.0.1",
+		"chai-typescript-typings": "^0.0.2",
+		"copyfiles": "^1.2.0",
+		"dirty-chai": "^2.0.1",
+		"mocha": "^4.0.1",
+		"solc": "^0.4.18",
+		"truffle": "^4.0.1",
+		"tslint": "5.8.0",
+		"types-bn": "^0.0.1",
+		"types-ethereumjs-util": "0xProject/types-ethereumjs-util",
+		"typescript": "~2.6.1",
+		"web3-typescript-typings": "^0.9.6",
+		"yargs": "^10.0.3"
+	},
+	"dependencies": {
+		"0x.js": "^0.30.2",
+		"@0xproject/deployer": "^0.0.3",
+		"@0xproject/json-schemas": "^0.7.5",
+		"@0xproject/utils": "^0.2.2",
+		"@0xproject/web3-wrapper": "^0.1.7",
+		"bluebird": "^3.5.0",
+		"bn.js": "^4.11.8",
+		"ethereumjs-abi": "^0.6.4",
+		"ethereumjs-util": "^5.1.1",
+		"isomorphic-fetch": "^2.2.1",
+		"lodash": "^4.17.4",
+		"request": "^2.81.0",
+		"web3": "^0.20.0",
+		"web3-eth-abi": "^1.0.0-beta.24"
+	}
 }
diff --git a/packages/contracts/test/ts/ether_token.ts b/packages/contracts/test/ts/ether_token.ts
index f807cdaa3..c770b4001 100644
--- a/packages/contracts/test/ts/ether_token.ts
+++ b/packages/contracts/test/ts/ether_token.ts
@@ -18,107 +18,107 @@ const expect = chai.expect;
 const web3: Web3 = (global as any).web3;
 
 contract('EtherToken', (accounts: string[]) => {
-    const account = accounts[0];
-    const gasPrice = ZeroEx.toBaseUnitAmount(new BigNumber(20), 9);
-    let zeroEx: ZeroEx;
-    let etherTokenAddress: string;
-
-    before(async () => {
-        etherTokenAddress = EtherToken.address;
-        zeroEx = new ZeroEx(web3.currentProvider, {
-            gasPrice,
-            networkId: constants.TESTRPC_NETWORK_ID,
-        });
-    });
-
-    const sendTransactionAsync = promisify<string>(web3.eth.sendTransaction);
-    const getEthBalanceAsync = async (owner: string) => {
-        const balanceStr = await promisify<string>(web3.eth.getBalance)(owner);
-        const balance = new BigNumber(balanceStr);
-        return balance;
-    };
-
-    describe('deposit', () => {
-        it('should throw if caller attempts to deposit more Ether than caller balance', async () => {
-            const initEthBalance = await getEthBalanceAsync(account);
-            const ethToDeposit = initEthBalance.plus(1);
-
-            return expect(zeroEx.etherToken.depositAsync(etherTokenAddress, ethToDeposit, account)).to.be.rejectedWith(
-                ZeroExError.InsufficientEthBalanceForDeposit,
-            );
-        });
-
-        it('should convert deposited Ether to wrapped Ether tokens', async () => {
-            const initEthBalance = await getEthBalanceAsync(account);
-            const initEthTokenBalance = await zeroEx.token.getBalanceAsync(etherTokenAddress, account);
-
-            const ethToDeposit = new BigNumber(web3.toWei(1, 'ether'));
-
-            const txHash = await zeroEx.etherToken.depositAsync(etherTokenAddress, ethToDeposit, account);
-            const receipt = await zeroEx.awaitTransactionMinedAsync(txHash);
-
-            const ethSpentOnGas = gasPrice.times(receipt.gasUsed);
-            const finalEthBalance = await getEthBalanceAsync(account);
-            const finalEthTokenBalance = await zeroEx.token.getBalanceAsync(etherTokenAddress, account);
-
-            expect(finalEthBalance).to.be.bignumber.equal(initEthBalance.minus(ethToDeposit.plus(ethSpentOnGas)));
-            expect(finalEthTokenBalance).to.be.bignumber.equal(initEthTokenBalance.plus(ethToDeposit));
-        });
-    });
-
-    describe('withdraw', () => {
-        it('should throw if caller attempts to withdraw greater than caller balance', async () => {
-            const initEthTokenBalance = await zeroEx.token.getBalanceAsync(etherTokenAddress, account);
-            const ethTokensToWithdraw = initEthTokenBalance.plus(1);
-
-            return expect(
-                zeroEx.etherToken.withdrawAsync(etherTokenAddress, ethTokensToWithdraw, account),
-            ).to.be.rejectedWith(ZeroExError.InsufficientWEthBalanceForWithdrawal);
-        });
-
-        it('should convert ether tokens to ether with sufficient balance', async () => {
-            const initEthTokenBalance = await zeroEx.token.getBalanceAsync(etherTokenAddress, account);
-            const initEthBalance = await getEthBalanceAsync(account);
-            const ethTokensToWithdraw = initEthTokenBalance;
-            expect(ethTokensToWithdraw).to.not.be.bignumber.equal(0);
-            const txHash = await zeroEx.etherToken.withdrawAsync(etherTokenAddress, ethTokensToWithdraw, account, {
-                gasLimit: constants.MAX_ETHERTOKEN_WITHDRAW_GAS,
-            });
-            const receipt = await zeroEx.awaitTransactionMinedAsync(txHash);
-
-            const ethSpentOnGas = gasPrice.times(receipt.gasUsed);
-            const finalEthBalance = await getEthBalanceAsync(account);
-            const finalEthTokenBalance = await zeroEx.token.getBalanceAsync(etherTokenAddress, account);
-
-            expect(finalEthBalance).to.be.bignumber.equal(
-                initEthBalance.plus(ethTokensToWithdraw.minus(ethSpentOnGas)),
-            );
-            expect(finalEthTokenBalance).to.be.bignumber.equal(initEthTokenBalance.minus(ethTokensToWithdraw));
-        });
-    });
-
-    describe('fallback', () => {
-        it('should convert sent ether to ether tokens', async () => {
-            const initEthBalance = await getEthBalanceAsync(account);
-            const initEthTokenBalance = await zeroEx.token.getBalanceAsync(etherTokenAddress, account);
-
-            const ethToDeposit = ZeroEx.toBaseUnitAmount(new BigNumber(1), 18);
-
-            const txHash = await sendTransactionAsync({
-                from: account,
-                to: etherTokenAddress,
-                value: ethToDeposit,
-                gasPrice,
-            });
-
-            const receipt = await zeroEx.awaitTransactionMinedAsync(txHash);
-
-            const ethSpentOnGas = gasPrice.times(receipt.gasUsed);
-            const finalEthBalance = await getEthBalanceAsync(account);
-            const finalEthTokenBalance = await zeroEx.token.getBalanceAsync(etherTokenAddress, account);
-
-            expect(finalEthBalance).to.be.bignumber.equal(initEthBalance.minus(ethToDeposit.plus(ethSpentOnGas)));
-            expect(finalEthTokenBalance).to.be.bignumber.equal(initEthTokenBalance.plus(ethToDeposit));
-        });
-    });
+	const account = accounts[0];
+	const gasPrice = ZeroEx.toBaseUnitAmount(new BigNumber(20), 9);
+	let zeroEx: ZeroEx;
+	let etherTokenAddress: string;
+
+	before(async () => {
+		etherTokenAddress = EtherToken.address;
+		zeroEx = new ZeroEx(web3.currentProvider, {
+			gasPrice,
+			networkId: constants.TESTRPC_NETWORK_ID,
+		});
+	});
+
+	const sendTransactionAsync = promisify<string>(web3.eth.sendTransaction);
+	const getEthBalanceAsync = async (owner: string) => {
+		const balanceStr = await promisify<string>(web3.eth.getBalance)(owner);
+		const balance = new BigNumber(balanceStr);
+		return balance;
+	};
+
+	describe('deposit', () => {
+		it('should throw if caller attempts to deposit more Ether than caller balance', async () => {
+			const initEthBalance = await getEthBalanceAsync(account);
+			const ethToDeposit = initEthBalance.plus(1);
+
+			return expect(zeroEx.etherToken.depositAsync(etherTokenAddress, ethToDeposit, account)).to.be.rejectedWith(
+				ZeroExError.InsufficientEthBalanceForDeposit,
+			);
+		});
+
+		it('should convert deposited Ether to wrapped Ether tokens', async () => {
+			const initEthBalance = await getEthBalanceAsync(account);
+			const initEthTokenBalance = await zeroEx.token.getBalanceAsync(etherTokenAddress, account);
+
+			const ethToDeposit = new BigNumber(web3.toWei(1, 'ether'));
+
+			const txHash = await zeroEx.etherToken.depositAsync(etherTokenAddress, ethToDeposit, account);
+			const receipt = await zeroEx.awaitTransactionMinedAsync(txHash);
+
+			const ethSpentOnGas = gasPrice.times(receipt.gasUsed);
+			const finalEthBalance = await getEthBalanceAsync(account);
+			const finalEthTokenBalance = await zeroEx.token.getBalanceAsync(etherTokenAddress, account);
+
+			expect(finalEthBalance).to.be.bignumber.equal(initEthBalance.minus(ethToDeposit.plus(ethSpentOnGas)));
+			expect(finalEthTokenBalance).to.be.bignumber.equal(initEthTokenBalance.plus(ethToDeposit));
+		});
+	});
+
+	describe('withdraw', () => {
+		it('should throw if caller attempts to withdraw greater than caller balance', async () => {
+			const initEthTokenBalance = await zeroEx.token.getBalanceAsync(etherTokenAddress, account);
+			const ethTokensToWithdraw = initEthTokenBalance.plus(1);
+
+			return expect(
+				zeroEx.etherToken.withdrawAsync(etherTokenAddress, ethTokensToWithdraw, account),
+			).to.be.rejectedWith(ZeroExError.InsufficientWEthBalanceForWithdrawal);
+		});
+
+		it('should convert ether tokens to ether with sufficient balance', async () => {
+			const initEthTokenBalance = await zeroEx.token.getBalanceAsync(etherTokenAddress, account);
+			const initEthBalance = await getEthBalanceAsync(account);
+			const ethTokensToWithdraw = initEthTokenBalance;
+			expect(ethTokensToWithdraw).to.not.be.bignumber.equal(0);
+			const txHash = await zeroEx.etherToken.withdrawAsync(etherTokenAddress, ethTokensToWithdraw, account, {
+				gasLimit: constants.MAX_ETHERTOKEN_WITHDRAW_GAS,
+			});
+			const receipt = await zeroEx.awaitTransactionMinedAsync(txHash);
+
+			const ethSpentOnGas = gasPrice.times(receipt.gasUsed);
+			const finalEthBalance = await getEthBalanceAsync(account);
+			const finalEthTokenBalance = await zeroEx.token.getBalanceAsync(etherTokenAddress, account);
+
+			expect(finalEthBalance).to.be.bignumber.equal(
+				initEthBalance.plus(ethTokensToWithdraw.minus(ethSpentOnGas)),
+			);
+			expect(finalEthTokenBalance).to.be.bignumber.equal(initEthTokenBalance.minus(ethTokensToWithdraw));
+		});
+	});
+
+	describe('fallback', () => {
+		it('should convert sent ether to ether tokens', async () => {
+			const initEthBalance = await getEthBalanceAsync(account);
+			const initEthTokenBalance = await zeroEx.token.getBalanceAsync(etherTokenAddress, account);
+
+			const ethToDeposit = ZeroEx.toBaseUnitAmount(new BigNumber(1), 18);
+
+			const txHash = await sendTransactionAsync({
+				from: account,
+				to: etherTokenAddress,
+				value: ethToDeposit,
+				gasPrice,
+			});
+
+			const receipt = await zeroEx.awaitTransactionMinedAsync(txHash);
+
+			const ethSpentOnGas = gasPrice.times(receipt.gasUsed);
+			const finalEthBalance = await getEthBalanceAsync(account);
+			const finalEthTokenBalance = await zeroEx.token.getBalanceAsync(etherTokenAddress, account);
+
+			expect(finalEthBalance).to.be.bignumber.equal(initEthBalance.minus(ethToDeposit.plus(ethSpentOnGas)));
+			expect(finalEthTokenBalance).to.be.bignumber.equal(initEthTokenBalance.plus(ethToDeposit));
+		});
+	});
 });
diff --git a/packages/contracts/test/ts/exchange/core.ts b/packages/contracts/test/ts/exchange/core.ts
index 770ef0c43..36078aaa9 100644
--- a/packages/contracts/test/ts/exchange/core.ts
+++ b/packages/contracts/test/ts/exchange/core.ts
@@ -23,830 +23,830 @@ const { Exchange, TokenTransferProxy, DummyToken, TokenRegistry, MaliciousToken
 const web3: Web3 = (global as any).web3;
 
 contract('Exchange', (accounts: string[]) => {
-    const maker = accounts[0];
-    const tokenOwner = accounts[0];
-    const taker = accounts[1] || accounts[accounts.length - 1];
-    const feeRecipient = accounts[2] || accounts[accounts.length - 1];
-
-    const INITIAL_BALANCE = ZeroEx.toBaseUnitAmount(new BigNumber(10000), 18);
-    const INITIAL_ALLOWANCE = ZeroEx.toBaseUnitAmount(new BigNumber(10000), 18);
-
-    let rep: ContractInstance;
-    let dgd: ContractInstance;
-    let zrx: ContractInstance;
-    let exchange: ContractInstance;
-    let tokenRegistry: ContractInstance;
-
-    let order: Order;
-    let balances: BalancesByOwner;
-    let exWrapper: ExchangeWrapper;
-    let dmyBalances: Balances;
-    let orderFactory: OrderFactory;
-
-    let zeroEx: ZeroEx;
-
-    before(async () => {
-        [tokenRegistry, exchange] = await Promise.all([TokenRegistry.deployed(), Exchange.deployed()]);
-        exWrapper = new ExchangeWrapper(exchange);
-        zeroEx = new ZeroEx(web3.currentProvider, {
-            exchangeContractAddress: exchange.address,
-            networkId: constants.TESTRPC_NETWORK_ID,
-        });
-
-        const [repAddress, dgdAddress, zrxAddress] = await Promise.all([
-            tokenRegistry.getTokenAddressBySymbol('REP'),
-            tokenRegistry.getTokenAddressBySymbol('DGD'),
-            tokenRegistry.getTokenAddressBySymbol('ZRX'),
-        ]);
-
-        const defaultOrderParams = {
-            exchangeContractAddress: Exchange.address,
-            maker,
-            feeRecipient,
-            makerToken: repAddress,
-            takerToken: dgdAddress,
-            makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
-            takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18),
-            makerFee: ZeroEx.toBaseUnitAmount(new BigNumber(1), 18),
-            takerFee: ZeroEx.toBaseUnitAmount(new BigNumber(1), 18),
-        };
-        orderFactory = new OrderFactory(defaultOrderParams);
-
-        [rep, dgd, zrx] = await Promise.all([
-            DummyToken.at(repAddress),
-            DummyToken.at(dgdAddress),
-            DummyToken.at(zrxAddress),
-        ]);
-        dmyBalances = new Balances([rep, dgd, zrx], [maker, taker, feeRecipient]);
-        await Promise.all([
-            rep.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
-                from: maker,
-            }),
-            rep.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
-                from: taker,
-            }),
-            rep.setBalance(maker, INITIAL_BALANCE, { from: tokenOwner }),
-            rep.setBalance(taker, INITIAL_BALANCE, { from: tokenOwner }),
-            dgd.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
-                from: maker,
-            }),
-            dgd.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
-                from: taker,
-            }),
-            dgd.setBalance(maker, INITIAL_BALANCE, { from: tokenOwner }),
-            dgd.setBalance(taker, INITIAL_BALANCE, { from: tokenOwner }),
-            zrx.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
-                from: maker,
-            }),
-            zrx.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
-                from: taker,
-            }),
-            zrx.setBalance(maker, INITIAL_BALANCE, { from: tokenOwner }),
-            zrx.setBalance(taker, INITIAL_BALANCE, { from: tokenOwner }),
-        ]);
-    });
-
-    describe('internal functions', () => {
-        it('should include transferViaTokenTransferProxy', () => {
-            expect(exchange.transferViaTokenTransferProxy).to.be.undefined();
-        });
-
-        it('should include isTransferable', () => {
-            expect(exchange.isTransferable).to.be.undefined();
-        });
-
-        it('should include getBalance', () => {
-            expect(exchange.getBalance).to.be.undefined();
-        });
-
-        it('should include getAllowance', () => {
-            expect(exchange.getAllowance).to.be.undefined();
-        });
-    });
-
-    describe('fillOrder', () => {
-        beforeEach(async () => {
-            balances = await dmyBalances.getAsync();
-            order = await orderFactory.newSignedOrderAsync();
-        });
-
-        it('should create an unfillable order', async () => {
-            order = await orderFactory.newSignedOrderAsync({
-                makerTokenAmount: new BigNumber(1001),
-                takerTokenAmount: new BigNumber(3),
-            });
-
-            const filledTakerTokenAmountBefore = await zeroEx.exchange.getFilledTakerAmountAsync(
-                order.params.orderHashHex,
-            );
-            expect(filledTakerTokenAmountBefore).to.be.bignumber.equal(0);
-
-            const fillTakerTokenAmount1 = new BigNumber(2);
-            await exWrapper.fillOrderAsync(order, taker, {
-                fillTakerTokenAmount: fillTakerTokenAmount1,
-            });
-
-            const filledTakerTokenAmountAfter1 = await zeroEx.exchange.getFilledTakerAmountAsync(
-                order.params.orderHashHex,
-            );
-            expect(filledTakerTokenAmountAfter1).to.be.bignumber.equal(fillTakerTokenAmount1);
-
-            const fillTakerTokenAmount2 = new BigNumber(1);
-            await exWrapper.fillOrderAsync(order, taker, {
-                fillTakerTokenAmount: fillTakerTokenAmount2,
-            });
-
-            const filledTakerTokenAmountAfter2 = await zeroEx.exchange.getFilledTakerAmountAsync(
-                order.params.orderHashHex,
-            );
-            expect(filledTakerTokenAmountAfter2).to.be.bignumber.equal(filledTakerTokenAmountAfter1);
-        });
-
-        it('should transfer the correct amounts when makerTokenAmount === takerTokenAmount', async () => {
-            order = await orderFactory.newSignedOrderAsync({
-                makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
-                takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
-            });
-
-            const filledTakerTokenAmountBefore = await zeroEx.exchange.getFilledTakerAmountAsync(
-                order.params.orderHashHex,
-            );
-            expect(filledTakerTokenAmountBefore).to.be.bignumber.equal(0);
-
-            const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
-            await exWrapper.fillOrderAsync(order, taker, { fillTakerTokenAmount });
-
-            const filledTakerTokenAmountAfter = await zeroEx.exchange.getFilledTakerAmountAsync(
-                order.params.orderHashHex,
-            );
-            expect(filledTakerTokenAmountAfter).to.be.bignumber.equal(fillTakerTokenAmount);
-
-            const newBalances = await dmyBalances.getAsync();
-
-            const fillMakerTokenAmount = fillTakerTokenAmount
-                .times(order.params.makerTokenAmount)
-                .dividedToIntegerBy(order.params.takerTokenAmount);
-            const paidMakerFee = order.params.makerFee
-                .times(fillMakerTokenAmount)
-                .dividedToIntegerBy(order.params.makerTokenAmount);
-            const paidTakerFee = order.params.takerFee
-                .times(fillMakerTokenAmount)
-                .dividedToIntegerBy(order.params.makerTokenAmount);
-            expect(newBalances[maker][order.params.makerToken]).to.be.bignumber.equal(
-                balances[maker][order.params.makerToken].minus(fillMakerTokenAmount),
-            );
-            expect(newBalances[maker][order.params.takerToken]).to.be.bignumber.equal(
-                balances[maker][order.params.takerToken].add(fillTakerTokenAmount),
-            );
-            expect(newBalances[maker][zrx.address]).to.be.bignumber.equal(
-                balances[maker][zrx.address].minus(paidMakerFee),
-            );
-            expect(newBalances[taker][order.params.takerToken]).to.be.bignumber.equal(
-                balances[taker][order.params.takerToken].minus(fillTakerTokenAmount),
-            );
-            expect(newBalances[taker][order.params.makerToken]).to.be.bignumber.equal(
-                balances[taker][order.params.makerToken].add(fillMakerTokenAmount),
-            );
-            expect(newBalances[taker][zrx.address]).to.be.bignumber.equal(
-                balances[taker][zrx.address].minus(paidTakerFee),
-            );
-            expect(newBalances[feeRecipient][zrx.address]).to.be.bignumber.equal(
-                balances[feeRecipient][zrx.address].add(paidMakerFee.add(paidTakerFee)),
-            );
-        });
-
-        it('should transfer the correct amounts when makerTokenAmount > takerTokenAmount', async () => {
-            order = await orderFactory.newSignedOrderAsync({
-                makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18),
-                takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
-            });
-
-            const filledTakerTokenAmountBefore = await zeroEx.exchange.getFilledTakerAmountAsync(
-                order.params.orderHashHex,
-            );
-            expect(filledTakerTokenAmountBefore).to.be.bignumber.equal(0);
-
-            const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
-            await exWrapper.fillOrderAsync(order, taker, { fillTakerTokenAmount });
-
-            const filledTakerTokenAmountAfter = await zeroEx.exchange.getFilledTakerAmountAsync(
-                order.params.orderHashHex,
-            );
-            expect(filledTakerTokenAmountAfter).to.be.bignumber.equal(fillTakerTokenAmount);
-
-            const newBalances = await dmyBalances.getAsync();
-
-            const fillMakerTokenAmount = fillTakerTokenAmount
-                .times(order.params.makerTokenAmount)
-                .dividedToIntegerBy(order.params.takerTokenAmount);
-            const paidMakerFee = order.params.makerFee
-                .times(fillMakerTokenAmount)
-                .dividedToIntegerBy(order.params.makerTokenAmount);
-            const paidTakerFee = order.params.takerFee
-                .times(fillMakerTokenAmount)
-                .dividedToIntegerBy(order.params.makerTokenAmount);
-            expect(newBalances[maker][order.params.makerToken]).to.be.bignumber.equal(
-                balances[maker][order.params.makerToken].minus(fillMakerTokenAmount),
-            );
-            expect(newBalances[maker][order.params.takerToken]).to.be.bignumber.equal(
-                balances[maker][order.params.takerToken].add(fillTakerTokenAmount),
-            );
-            expect(newBalances[maker][zrx.address]).to.be.bignumber.equal(
-                balances[maker][zrx.address].minus(paidMakerFee),
-            );
-            expect(newBalances[taker][order.params.takerToken]).to.be.bignumber.equal(
-                balances[taker][order.params.takerToken].minus(fillTakerTokenAmount),
-            );
-            expect(newBalances[taker][order.params.makerToken]).to.be.bignumber.equal(
-                balances[taker][order.params.makerToken].add(fillMakerTokenAmount),
-            );
-            expect(newBalances[taker][zrx.address]).to.be.bignumber.equal(
-                balances[taker][zrx.address].minus(paidTakerFee),
-            );
-            expect(newBalances[feeRecipient][zrx.address]).to.be.bignumber.equal(
-                balances[feeRecipient][zrx.address].add(paidMakerFee.add(paidTakerFee)),
-            );
-        });
-
-        it('should transfer the correct amounts when makerTokenAmount < takerTokenAmount', async () => {
-            order = await orderFactory.newSignedOrderAsync({
-                makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
-                takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18),
-            });
-
-            const filledTakerTokenAmountBefore = await zeroEx.exchange.getFilledTakerAmountAsync(
-                order.params.orderHashHex,
-            );
-            expect(filledTakerTokenAmountBefore).to.be.bignumber.equal(0);
-
-            const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
-            await exWrapper.fillOrderAsync(order, taker, { fillTakerTokenAmount });
-
-            const filledTakerTokenAmountAfter = await zeroEx.exchange.getFilledTakerAmountAsync(
-                order.params.orderHashHex,
-            );
-            expect(filledTakerTokenAmountAfter).to.be.bignumber.equal(fillTakerTokenAmount);
-
-            const newBalances = await dmyBalances.getAsync();
-
-            const fillMakerTokenAmount = fillTakerTokenAmount
-                .times(order.params.makerTokenAmount)
-                .dividedToIntegerBy(order.params.takerTokenAmount);
-            const paidMakerFee = order.params.makerFee
-                .times(fillMakerTokenAmount)
-                .dividedToIntegerBy(order.params.makerTokenAmount);
-            const paidTakerFee = order.params.takerFee
-                .times(fillMakerTokenAmount)
-                .dividedToIntegerBy(order.params.makerTokenAmount);
-            expect(newBalances[maker][order.params.makerToken]).to.be.bignumber.equal(
-                balances[maker][order.params.makerToken].minus(fillMakerTokenAmount),
-            );
-            expect(newBalances[maker][order.params.takerToken]).to.be.bignumber.equal(
-                balances[maker][order.params.takerToken].add(fillTakerTokenAmount),
-            );
-            expect(newBalances[maker][zrx.address]).to.be.bignumber.equal(
-                balances[maker][zrx.address].minus(paidMakerFee),
-            );
-            expect(newBalances[taker][order.params.takerToken]).to.be.bignumber.equal(
-                balances[taker][order.params.takerToken].minus(fillTakerTokenAmount),
-            );
-            expect(newBalances[taker][order.params.makerToken]).to.be.bignumber.equal(
-                balances[taker][order.params.makerToken].add(fillMakerTokenAmount),
-            );
-            expect(newBalances[taker][zrx.address]).to.be.bignumber.equal(
-                balances[taker][zrx.address].minus(paidTakerFee),
-            );
-            expect(newBalances[feeRecipient][zrx.address]).to.be.bignumber.equal(
-                balances[feeRecipient][zrx.address].add(paidMakerFee.add(paidTakerFee)),
-            );
-        });
-
-        it('should transfer the correct amounts when taker is specified and order is claimed by taker', async () => {
-            order = await orderFactory.newSignedOrderAsync({
-                taker,
-                makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
-                takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18),
-            });
-
-            const filledTakerTokenAmountBefore = await zeroEx.exchange.getFilledTakerAmountAsync(
-                order.params.orderHashHex,
-            );
-            expect(filledTakerTokenAmountBefore).to.be.bignumber.equal(0);
-
-            const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
-            await exWrapper.fillOrderAsync(order, taker, { fillTakerTokenAmount });
-
-            const filledTakerTokenAmountAfter = await zeroEx.exchange.getFilledTakerAmountAsync(
-                order.params.orderHashHex,
-            );
-            const expectedFillAmountTAfter = fillTakerTokenAmount.add(filledTakerTokenAmountBefore);
-            expect(filledTakerTokenAmountAfter).to.be.bignumber.equal(expectedFillAmountTAfter);
-
-            const newBalances = await dmyBalances.getAsync();
-
-            const fillMakerTokenAmount = fillTakerTokenAmount
-                .times(order.params.makerTokenAmount)
-                .dividedToIntegerBy(order.params.takerTokenAmount);
-            const paidMakerFee = order.params.makerFee
-                .times(fillMakerTokenAmount)
-                .dividedToIntegerBy(order.params.makerTokenAmount);
-            const paidTakerFee = order.params.takerFee
-                .times(fillMakerTokenAmount)
-                .dividedToIntegerBy(order.params.makerTokenAmount);
-            expect(newBalances[maker][order.params.makerToken]).to.be.bignumber.equal(
-                balances[maker][order.params.makerToken].minus(fillMakerTokenAmount),
-            );
-            expect(newBalances[maker][order.params.takerToken]).to.be.bignumber.equal(
-                balances[maker][order.params.takerToken].add(fillTakerTokenAmount),
-            );
-            expect(newBalances[maker][zrx.address]).to.be.bignumber.equal(
-                balances[maker][zrx.address].minus(paidMakerFee),
-            );
-            expect(newBalances[taker][order.params.takerToken]).to.be.bignumber.equal(
-                balances[taker][order.params.takerToken].minus(fillTakerTokenAmount),
-            );
-            expect(newBalances[taker][order.params.makerToken]).to.be.bignumber.equal(
-                balances[taker][order.params.makerToken].add(fillMakerTokenAmount),
-            );
-            expect(newBalances[taker][zrx.address]).to.be.bignumber.equal(
-                balances[taker][zrx.address].minus(paidTakerFee),
-            );
-            expect(newBalances[feeRecipient][zrx.address]).to.be.bignumber.equal(
-                balances[feeRecipient][zrx.address].add(paidMakerFee.add(paidTakerFee)),
-            );
-        });
-
-        it('should fill remaining value if fillTakerTokenAmount > remaining takerTokenAmount', async () => {
-            const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
-            await exWrapper.fillOrderAsync(order, taker, { fillTakerTokenAmount });
-
-            const res = await exWrapper.fillOrderAsync(order, taker, {
-                fillTakerTokenAmount: order.params.takerTokenAmount,
-            });
-
-            expect(res.logs[0].args.filledTakerTokenAmount).to.be.bignumber.equal(
-                order.params.takerTokenAmount.minus(fillTakerTokenAmount),
-            );
-            const newBalances = await dmyBalances.getAsync();
-
-            expect(newBalances[maker][order.params.makerToken]).to.be.bignumber.equal(
-                balances[maker][order.params.makerToken].minus(order.params.makerTokenAmount),
-            );
-            expect(newBalances[maker][order.params.takerToken]).to.be.bignumber.equal(
-                balances[maker][order.params.takerToken].add(order.params.takerTokenAmount),
-            );
-            expect(newBalances[maker][zrx.address]).to.be.bignumber.equal(
-                balances[maker][zrx.address].minus(order.params.makerFee),
-            );
-            expect(newBalances[taker][order.params.takerToken]).to.be.bignumber.equal(
-                balances[taker][order.params.takerToken].minus(order.params.takerTokenAmount),
-            );
-            expect(newBalances[taker][order.params.makerToken]).to.be.bignumber.equal(
-                balances[taker][order.params.makerToken].add(order.params.makerTokenAmount),
-            );
-            expect(newBalances[taker][zrx.address]).to.be.bignumber.equal(
-                balances[taker][zrx.address].minus(order.params.takerFee),
-            );
-            expect(newBalances[feeRecipient][zrx.address]).to.be.bignumber.equal(
-                balances[feeRecipient][zrx.address].add(order.params.makerFee.add(order.params.takerFee)),
-            );
-        });
-
-        it('should log 1 event with the correct arguments when order has a feeRecipient', async () => {
-            const divisor = 2;
-            const res = await exWrapper.fillOrderAsync(order, taker, {
-                fillTakerTokenAmount: order.params.takerTokenAmount.div(divisor),
-            });
-            expect(res.logs).to.have.length(1);
-
-            const logArgs = res.logs[0].args;
-            const expectedFilledMakerTokenAmount = order.params.makerTokenAmount.div(divisor);
-            const expectedFilledTakerTokenAmount = order.params.takerTokenAmount.div(divisor);
-            const expectedFeeMPaid = order.params.makerFee.div(divisor);
-            const expectedFeeTPaid = order.params.takerFee.div(divisor);
-            const tokensHashBuff = crypto.solSHA3([order.params.makerToken, order.params.takerToken]);
-            const expectedTokens = ethUtil.bufferToHex(tokensHashBuff);
-
-            expect(order.params.maker).to.be.equal(logArgs.maker);
-            expect(taker).to.be.equal(logArgs.taker);
-            expect(order.params.feeRecipient).to.be.equal(logArgs.feeRecipient);
-            expect(order.params.makerToken).to.be.equal(logArgs.makerToken);
-            expect(order.params.takerToken).to.be.equal(logArgs.takerToken);
-            expect(expectedFilledMakerTokenAmount).to.be.bignumber.equal(logArgs.filledMakerTokenAmount);
-            expect(expectedFilledTakerTokenAmount).to.be.bignumber.equal(logArgs.filledTakerTokenAmount);
-            expect(expectedFeeMPaid).to.be.bignumber.equal(logArgs.paidMakerFee);
-            expect(expectedFeeTPaid).to.be.bignumber.equal(logArgs.paidTakerFee);
-            expect(expectedTokens).to.be.equal(logArgs.tokens);
-            expect(order.params.orderHashHex).to.be.equal(logArgs.orderHash);
-        });
-
-        it('should log 1 event with the correct arguments when order has no feeRecipient', async () => {
-            order = await orderFactory.newSignedOrderAsync({
-                feeRecipient: ZeroEx.NULL_ADDRESS,
-            });
-            const divisor = 2;
-            const res = await exWrapper.fillOrderAsync(order, taker, {
-                fillTakerTokenAmount: order.params.takerTokenAmount.div(divisor),
-            });
-            expect(res.logs).to.have.length(1);
-
-            const logArgs = res.logs[0].args;
-            const expectedFilledMakerTokenAmount = order.params.makerTokenAmount.div(divisor);
-            const expectedFilledTakerTokenAmount = order.params.takerTokenAmount.div(divisor);
-            const expectedFeeMPaid = new BigNumber(0);
-            const expectedFeeTPaid = new BigNumber(0);
-            const tokensHashBuff = crypto.solSHA3([order.params.makerToken, order.params.takerToken]);
-            const expectedTokens = ethUtil.bufferToHex(tokensHashBuff);
-
-            expect(order.params.maker).to.be.equal(logArgs.maker);
-            expect(taker).to.be.equal(logArgs.taker);
-            expect(order.params.feeRecipient).to.be.equal(logArgs.feeRecipient);
-            expect(order.params.makerToken).to.be.equal(logArgs.makerToken);
-            expect(order.params.takerToken).to.be.equal(logArgs.takerToken);
-            expect(expectedFilledMakerTokenAmount).to.be.bignumber.equal(logArgs.filledMakerTokenAmount);
-            expect(expectedFilledTakerTokenAmount).to.be.bignumber.equal(logArgs.filledTakerTokenAmount);
-            expect(expectedFeeMPaid).to.be.bignumber.equal(logArgs.paidMakerFee);
-            expect(expectedFeeTPaid).to.be.bignumber.equal(logArgs.paidTakerFee);
-            expect(expectedTokens).to.be.equal(logArgs.tokens);
-            expect(order.params.orderHashHex).to.be.equal(logArgs.orderHash);
-        });
-
-        it('should throw when taker is specified and order is claimed by other', async () => {
-            order = await orderFactory.newSignedOrderAsync({
-                taker: feeRecipient,
-                makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
-                takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18),
-            });
-
-            return expect(exWrapper.fillOrderAsync(order, taker)).to.be.rejectedWith(constants.REVERT);
-        });
-
-        it('should throw if signature is invalid', async () => {
-            order = await orderFactory.newSignedOrderAsync({
-                makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(10), 18),
-            });
-
-            order.params.r = ethUtil.bufferToHex(ethUtil.sha3('invalidR'));
-            order.params.s = ethUtil.bufferToHex(ethUtil.sha3('invalidS'));
-            return expect(exWrapper.fillOrderAsync(order, taker)).to.be.rejectedWith(constants.REVERT);
-        });
-
-        it('should throw if makerTokenAmount is 0', async () => {
-            order = await orderFactory.newSignedOrderAsync({
-                makerTokenAmount: new BigNumber(0),
-            });
-
-            return expect(exWrapper.fillOrderAsync(order, taker)).to.be.rejectedWith(constants.REVERT);
-        });
-
-        it('should throw if takerTokenAmount is 0', async () => {
-            order = await orderFactory.newSignedOrderAsync({
-                takerTokenAmount: new BigNumber(0),
-            });
-
-            return expect(exWrapper.fillOrderAsync(order, taker)).to.be.rejectedWith(constants.REVERT);
-        });
-
-        it('should throw if fillTakerTokenAmount is 0', async () => {
-            order = await orderFactory.newSignedOrderAsync();
-
-            return expect(
-                exWrapper.fillOrderAsync(order, taker, {
-                    fillTakerTokenAmount: new BigNumber(0),
-                }),
-            ).to.be.rejectedWith(constants.REVERT);
-        });
-
-        it('should not change balances if maker balances are too low to fill order and \
+	const maker = accounts[0];
+	const tokenOwner = accounts[0];
+	const taker = accounts[1] || accounts[accounts.length - 1];
+	const feeRecipient = accounts[2] || accounts[accounts.length - 1];
+
+	const INITIAL_BALANCE = ZeroEx.toBaseUnitAmount(new BigNumber(10000), 18);
+	const INITIAL_ALLOWANCE = ZeroEx.toBaseUnitAmount(new BigNumber(10000), 18);
+
+	let rep: ContractInstance;
+	let dgd: ContractInstance;
+	let zrx: ContractInstance;
+	let exchange: ContractInstance;
+	let tokenRegistry: ContractInstance;
+
+	let order: Order;
+	let balances: BalancesByOwner;
+	let exWrapper: ExchangeWrapper;
+	let dmyBalances: Balances;
+	let orderFactory: OrderFactory;
+
+	let zeroEx: ZeroEx;
+
+	before(async () => {
+		[tokenRegistry, exchange] = await Promise.all([TokenRegistry.deployed(), Exchange.deployed()]);
+		exWrapper = new ExchangeWrapper(exchange);
+		zeroEx = new ZeroEx(web3.currentProvider, {
+			exchangeContractAddress: exchange.address,
+			networkId: constants.TESTRPC_NETWORK_ID,
+		});
+
+		const [repAddress, dgdAddress, zrxAddress] = await Promise.all([
+			tokenRegistry.getTokenAddressBySymbol('REP'),
+			tokenRegistry.getTokenAddressBySymbol('DGD'),
+			tokenRegistry.getTokenAddressBySymbol('ZRX'),
+		]);
+
+		const defaultOrderParams = {
+			exchangeContractAddress: Exchange.address,
+			maker,
+			feeRecipient,
+			makerToken: repAddress,
+			takerToken: dgdAddress,
+			makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
+			takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18),
+			makerFee: ZeroEx.toBaseUnitAmount(new BigNumber(1), 18),
+			takerFee: ZeroEx.toBaseUnitAmount(new BigNumber(1), 18),
+		};
+		orderFactory = new OrderFactory(defaultOrderParams);
+
+		[rep, dgd, zrx] = await Promise.all([
+			DummyToken.at(repAddress),
+			DummyToken.at(dgdAddress),
+			DummyToken.at(zrxAddress),
+		]);
+		dmyBalances = new Balances([rep, dgd, zrx], [maker, taker, feeRecipient]);
+		await Promise.all([
+			rep.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
+				from: maker,
+			}),
+			rep.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
+				from: taker,
+			}),
+			rep.setBalance(maker, INITIAL_BALANCE, { from: tokenOwner }),
+			rep.setBalance(taker, INITIAL_BALANCE, { from: tokenOwner }),
+			dgd.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
+				from: maker,
+			}),
+			dgd.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
+				from: taker,
+			}),
+			dgd.setBalance(maker, INITIAL_BALANCE, { from: tokenOwner }),
+			dgd.setBalance(taker, INITIAL_BALANCE, { from: tokenOwner }),
+			zrx.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
+				from: maker,
+			}),
+			zrx.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
+				from: taker,
+			}),
+			zrx.setBalance(maker, INITIAL_BALANCE, { from: tokenOwner }),
+			zrx.setBalance(taker, INITIAL_BALANCE, { from: tokenOwner }),
+		]);
+	});
+
+	describe('internal functions', () => {
+		it('should include transferViaTokenTransferProxy', () => {
+			expect(exchange.transferViaTokenTransferProxy).to.be.undefined();
+		});
+
+		it('should include isTransferable', () => {
+			expect(exchange.isTransferable).to.be.undefined();
+		});
+
+		it('should include getBalance', () => {
+			expect(exchange.getBalance).to.be.undefined();
+		});
+
+		it('should include getAllowance', () => {
+			expect(exchange.getAllowance).to.be.undefined();
+		});
+	});
+
+	describe('fillOrder', () => {
+		beforeEach(async () => {
+			balances = await dmyBalances.getAsync();
+			order = await orderFactory.newSignedOrderAsync();
+		});
+
+		it('should create an unfillable order', async () => {
+			order = await orderFactory.newSignedOrderAsync({
+				makerTokenAmount: new BigNumber(1001),
+				takerTokenAmount: new BigNumber(3),
+			});
+
+			const filledTakerTokenAmountBefore = await zeroEx.exchange.getFilledTakerAmountAsync(
+				order.params.orderHashHex,
+			);
+			expect(filledTakerTokenAmountBefore).to.be.bignumber.equal(0);
+
+			const fillTakerTokenAmount1 = new BigNumber(2);
+			await exWrapper.fillOrderAsync(order, taker, {
+				fillTakerTokenAmount: fillTakerTokenAmount1,
+			});
+
+			const filledTakerTokenAmountAfter1 = await zeroEx.exchange.getFilledTakerAmountAsync(
+				order.params.orderHashHex,
+			);
+			expect(filledTakerTokenAmountAfter1).to.be.bignumber.equal(fillTakerTokenAmount1);
+
+			const fillTakerTokenAmount2 = new BigNumber(1);
+			await exWrapper.fillOrderAsync(order, taker, {
+				fillTakerTokenAmount: fillTakerTokenAmount2,
+			});
+
+			const filledTakerTokenAmountAfter2 = await zeroEx.exchange.getFilledTakerAmountAsync(
+				order.params.orderHashHex,
+			);
+			expect(filledTakerTokenAmountAfter2).to.be.bignumber.equal(filledTakerTokenAmountAfter1);
+		});
+
+		it('should transfer the correct amounts when makerTokenAmount === takerTokenAmount', async () => {
+			order = await orderFactory.newSignedOrderAsync({
+				makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
+				takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
+			});
+
+			const filledTakerTokenAmountBefore = await zeroEx.exchange.getFilledTakerAmountAsync(
+				order.params.orderHashHex,
+			);
+			expect(filledTakerTokenAmountBefore).to.be.bignumber.equal(0);
+
+			const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
+			await exWrapper.fillOrderAsync(order, taker, { fillTakerTokenAmount });
+
+			const filledTakerTokenAmountAfter = await zeroEx.exchange.getFilledTakerAmountAsync(
+				order.params.orderHashHex,
+			);
+			expect(filledTakerTokenAmountAfter).to.be.bignumber.equal(fillTakerTokenAmount);
+
+			const newBalances = await dmyBalances.getAsync();
+
+			const fillMakerTokenAmount = fillTakerTokenAmount
+				.times(order.params.makerTokenAmount)
+				.dividedToIntegerBy(order.params.takerTokenAmount);
+			const paidMakerFee = order.params.makerFee
+				.times(fillMakerTokenAmount)
+				.dividedToIntegerBy(order.params.makerTokenAmount);
+			const paidTakerFee = order.params.takerFee
+				.times(fillMakerTokenAmount)
+				.dividedToIntegerBy(order.params.makerTokenAmount);
+			expect(newBalances[maker][order.params.makerToken]).to.be.bignumber.equal(
+				balances[maker][order.params.makerToken].minus(fillMakerTokenAmount),
+			);
+			expect(newBalances[maker][order.params.takerToken]).to.be.bignumber.equal(
+				balances[maker][order.params.takerToken].add(fillTakerTokenAmount),
+			);
+			expect(newBalances[maker][zrx.address]).to.be.bignumber.equal(
+				balances[maker][zrx.address].minus(paidMakerFee),
+			);
+			expect(newBalances[taker][order.params.takerToken]).to.be.bignumber.equal(
+				balances[taker][order.params.takerToken].minus(fillTakerTokenAmount),
+			);
+			expect(newBalances[taker][order.params.makerToken]).to.be.bignumber.equal(
+				balances[taker][order.params.makerToken].add(fillMakerTokenAmount),
+			);
+			expect(newBalances[taker][zrx.address]).to.be.bignumber.equal(
+				balances[taker][zrx.address].minus(paidTakerFee),
+			);
+			expect(newBalances[feeRecipient][zrx.address]).to.be.bignumber.equal(
+				balances[feeRecipient][zrx.address].add(paidMakerFee.add(paidTakerFee)),
+			);
+		});
+
+		it('should transfer the correct amounts when makerTokenAmount > takerTokenAmount', async () => {
+			order = await orderFactory.newSignedOrderAsync({
+				makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18),
+				takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
+			});
+
+			const filledTakerTokenAmountBefore = await zeroEx.exchange.getFilledTakerAmountAsync(
+				order.params.orderHashHex,
+			);
+			expect(filledTakerTokenAmountBefore).to.be.bignumber.equal(0);
+
+			const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
+			await exWrapper.fillOrderAsync(order, taker, { fillTakerTokenAmount });
+
+			const filledTakerTokenAmountAfter = await zeroEx.exchange.getFilledTakerAmountAsync(
+				order.params.orderHashHex,
+			);
+			expect(filledTakerTokenAmountAfter).to.be.bignumber.equal(fillTakerTokenAmount);
+
+			const newBalances = await dmyBalances.getAsync();
+
+			const fillMakerTokenAmount = fillTakerTokenAmount
+				.times(order.params.makerTokenAmount)
+				.dividedToIntegerBy(order.params.takerTokenAmount);
+			const paidMakerFee = order.params.makerFee
+				.times(fillMakerTokenAmount)
+				.dividedToIntegerBy(order.params.makerTokenAmount);
+			const paidTakerFee = order.params.takerFee
+				.times(fillMakerTokenAmount)
+				.dividedToIntegerBy(order.params.makerTokenAmount);
+			expect(newBalances[maker][order.params.makerToken]).to.be.bignumber.equal(
+				balances[maker][order.params.makerToken].minus(fillMakerTokenAmount),
+			);
+			expect(newBalances[maker][order.params.takerToken]).to.be.bignumber.equal(
+				balances[maker][order.params.takerToken].add(fillTakerTokenAmount),
+			);
+			expect(newBalances[maker][zrx.address]).to.be.bignumber.equal(
+				balances[maker][zrx.address].minus(paidMakerFee),
+			);
+			expect(newBalances[taker][order.params.takerToken]).to.be.bignumber.equal(
+				balances[taker][order.params.takerToken].minus(fillTakerTokenAmount),
+			);
+			expect(newBalances[taker][order.params.makerToken]).to.be.bignumber.equal(
+				balances[taker][order.params.makerToken].add(fillMakerTokenAmount),
+			);
+			expect(newBalances[taker][zrx.address]).to.be.bignumber.equal(
+				balances[taker][zrx.address].minus(paidTakerFee),
+			);
+			expect(newBalances[feeRecipient][zrx.address]).to.be.bignumber.equal(
+				balances[feeRecipient][zrx.address].add(paidMakerFee.add(paidTakerFee)),
+			);
+		});
+
+		it('should transfer the correct amounts when makerTokenAmount < takerTokenAmount', async () => {
+			order = await orderFactory.newSignedOrderAsync({
+				makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
+				takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18),
+			});
+
+			const filledTakerTokenAmountBefore = await zeroEx.exchange.getFilledTakerAmountAsync(
+				order.params.orderHashHex,
+			);
+			expect(filledTakerTokenAmountBefore).to.be.bignumber.equal(0);
+
+			const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
+			await exWrapper.fillOrderAsync(order, taker, { fillTakerTokenAmount });
+
+			const filledTakerTokenAmountAfter = await zeroEx.exchange.getFilledTakerAmountAsync(
+				order.params.orderHashHex,
+			);
+			expect(filledTakerTokenAmountAfter).to.be.bignumber.equal(fillTakerTokenAmount);
+
+			const newBalances = await dmyBalances.getAsync();
+
+			const fillMakerTokenAmount = fillTakerTokenAmount
+				.times(order.params.makerTokenAmount)
+				.dividedToIntegerBy(order.params.takerTokenAmount);
+			const paidMakerFee = order.params.makerFee
+				.times(fillMakerTokenAmount)
+				.dividedToIntegerBy(order.params.makerTokenAmount);
+			const paidTakerFee = order.params.takerFee
+				.times(fillMakerTokenAmount)
+				.dividedToIntegerBy(order.params.makerTokenAmount);
+			expect(newBalances[maker][order.params.makerToken]).to.be.bignumber.equal(
+				balances[maker][order.params.makerToken].minus(fillMakerTokenAmount),
+			);
+			expect(newBalances[maker][order.params.takerToken]).to.be.bignumber.equal(
+				balances[maker][order.params.takerToken].add(fillTakerTokenAmount),
+			);
+			expect(newBalances[maker][zrx.address]).to.be.bignumber.equal(
+				balances[maker][zrx.address].minus(paidMakerFee),
+			);
+			expect(newBalances[taker][order.params.takerToken]).to.be.bignumber.equal(
+				balances[taker][order.params.takerToken].minus(fillTakerTokenAmount),
+			);
+			expect(newBalances[taker][order.params.makerToken]).to.be.bignumber.equal(
+				balances[taker][order.params.makerToken].add(fillMakerTokenAmount),
+			);
+			expect(newBalances[taker][zrx.address]).to.be.bignumber.equal(
+				balances[taker][zrx.address].minus(paidTakerFee),
+			);
+			expect(newBalances[feeRecipient][zrx.address]).to.be.bignumber.equal(
+				balances[feeRecipient][zrx.address].add(paidMakerFee.add(paidTakerFee)),
+			);
+		});
+
+		it('should transfer the correct amounts when taker is specified and order is claimed by taker', async () => {
+			order = await orderFactory.newSignedOrderAsync({
+				taker,
+				makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
+				takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18),
+			});
+
+			const filledTakerTokenAmountBefore = await zeroEx.exchange.getFilledTakerAmountAsync(
+				order.params.orderHashHex,
+			);
+			expect(filledTakerTokenAmountBefore).to.be.bignumber.equal(0);
+
+			const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
+			await exWrapper.fillOrderAsync(order, taker, { fillTakerTokenAmount });
+
+			const filledTakerTokenAmountAfter = await zeroEx.exchange.getFilledTakerAmountAsync(
+				order.params.orderHashHex,
+			);
+			const expectedFillAmountTAfter = fillTakerTokenAmount.add(filledTakerTokenAmountBefore);
+			expect(filledTakerTokenAmountAfter).to.be.bignumber.equal(expectedFillAmountTAfter);
+
+			const newBalances = await dmyBalances.getAsync();
+
+			const fillMakerTokenAmount = fillTakerTokenAmount
+				.times(order.params.makerTokenAmount)
+				.dividedToIntegerBy(order.params.takerTokenAmount);
+			const paidMakerFee = order.params.makerFee
+				.times(fillMakerTokenAmount)
+				.dividedToIntegerBy(order.params.makerTokenAmount);
+			const paidTakerFee = order.params.takerFee
+				.times(fillMakerTokenAmount)
+				.dividedToIntegerBy(order.params.makerTokenAmount);
+			expect(newBalances[maker][order.params.makerToken]).to.be.bignumber.equal(
+				balances[maker][order.params.makerToken].minus(fillMakerTokenAmount),
+			);
+			expect(newBalances[maker][order.params.takerToken]).to.be.bignumber.equal(
+				balances[maker][order.params.takerToken].add(fillTakerTokenAmount),
+			);
+			expect(newBalances[maker][zrx.address]).to.be.bignumber.equal(
+				balances[maker][zrx.address].minus(paidMakerFee),
+			);
+			expect(newBalances[taker][order.params.takerToken]).to.be.bignumber.equal(
+				balances[taker][order.params.takerToken].minus(fillTakerTokenAmount),
+			);
+			expect(newBalances[taker][order.params.makerToken]).to.be.bignumber.equal(
+				balances[taker][order.params.makerToken].add(fillMakerTokenAmount),
+			);
+			expect(newBalances[taker][zrx.address]).to.be.bignumber.equal(
+				balances[taker][zrx.address].minus(paidTakerFee),
+			);
+			expect(newBalances[feeRecipient][zrx.address]).to.be.bignumber.equal(
+				balances[feeRecipient][zrx.address].add(paidMakerFee.add(paidTakerFee)),
+			);
+		});
+
+		it('should fill remaining value if fillTakerTokenAmount > remaining takerTokenAmount', async () => {
+			const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
+			await exWrapper.fillOrderAsync(order, taker, { fillTakerTokenAmount });
+
+			const res = await exWrapper.fillOrderAsync(order, taker, {
+				fillTakerTokenAmount: order.params.takerTokenAmount,
+			});
+
+			expect(res.logs[0].args.filledTakerTokenAmount).to.be.bignumber.equal(
+				order.params.takerTokenAmount.minus(fillTakerTokenAmount),
+			);
+			const newBalances = await dmyBalances.getAsync();
+
+			expect(newBalances[maker][order.params.makerToken]).to.be.bignumber.equal(
+				balances[maker][order.params.makerToken].minus(order.params.makerTokenAmount),
+			);
+			expect(newBalances[maker][order.params.takerToken]).to.be.bignumber.equal(
+				balances[maker][order.params.takerToken].add(order.params.takerTokenAmount),
+			);
+			expect(newBalances[maker][zrx.address]).to.be.bignumber.equal(
+				balances[maker][zrx.address].minus(order.params.makerFee),
+			);
+			expect(newBalances[taker][order.params.takerToken]).to.be.bignumber.equal(
+				balances[taker][order.params.takerToken].minus(order.params.takerTokenAmount),
+			);
+			expect(newBalances[taker][order.params.makerToken]).to.be.bignumber.equal(
+				balances[taker][order.params.makerToken].add(order.params.makerTokenAmount),
+			);
+			expect(newBalances[taker][zrx.address]).to.be.bignumber.equal(
+				balances[taker][zrx.address].minus(order.params.takerFee),
+			);
+			expect(newBalances[feeRecipient][zrx.address]).to.be.bignumber.equal(
+				balances[feeRecipient][zrx.address].add(order.params.makerFee.add(order.params.takerFee)),
+			);
+		});
+
+		it('should log 1 event with the correct arguments when order has a feeRecipient', async () => {
+			const divisor = 2;
+			const res = await exWrapper.fillOrderAsync(order, taker, {
+				fillTakerTokenAmount: order.params.takerTokenAmount.div(divisor),
+			});
+			expect(res.logs).to.have.length(1);
+
+			const logArgs = res.logs[0].args;
+			const expectedFilledMakerTokenAmount = order.params.makerTokenAmount.div(divisor);
+			const expectedFilledTakerTokenAmount = order.params.takerTokenAmount.div(divisor);
+			const expectedFeeMPaid = order.params.makerFee.div(divisor);
+			const expectedFeeTPaid = order.params.takerFee.div(divisor);
+			const tokensHashBuff = crypto.solSHA3([order.params.makerToken, order.params.takerToken]);
+			const expectedTokens = ethUtil.bufferToHex(tokensHashBuff);
+
+			expect(order.params.maker).to.be.equal(logArgs.maker);
+			expect(taker).to.be.equal(logArgs.taker);
+			expect(order.params.feeRecipient).to.be.equal(logArgs.feeRecipient);
+			expect(order.params.makerToken).to.be.equal(logArgs.makerToken);
+			expect(order.params.takerToken).to.be.equal(logArgs.takerToken);
+			expect(expectedFilledMakerTokenAmount).to.be.bignumber.equal(logArgs.filledMakerTokenAmount);
+			expect(expectedFilledTakerTokenAmount).to.be.bignumber.equal(logArgs.filledTakerTokenAmount);
+			expect(expectedFeeMPaid).to.be.bignumber.equal(logArgs.paidMakerFee);
+			expect(expectedFeeTPaid).to.be.bignumber.equal(logArgs.paidTakerFee);
+			expect(expectedTokens).to.be.equal(logArgs.tokens);
+			expect(order.params.orderHashHex).to.be.equal(logArgs.orderHash);
+		});
+
+		it('should log 1 event with the correct arguments when order has no feeRecipient', async () => {
+			order = await orderFactory.newSignedOrderAsync({
+				feeRecipient: ZeroEx.NULL_ADDRESS,
+			});
+			const divisor = 2;
+			const res = await exWrapper.fillOrderAsync(order, taker, {
+				fillTakerTokenAmount: order.params.takerTokenAmount.div(divisor),
+			});
+			expect(res.logs).to.have.length(1);
+
+			const logArgs = res.logs[0].args;
+			const expectedFilledMakerTokenAmount = order.params.makerTokenAmount.div(divisor);
+			const expectedFilledTakerTokenAmount = order.params.takerTokenAmount.div(divisor);
+			const expectedFeeMPaid = new BigNumber(0);
+			const expectedFeeTPaid = new BigNumber(0);
+			const tokensHashBuff = crypto.solSHA3([order.params.makerToken, order.params.takerToken]);
+			const expectedTokens = ethUtil.bufferToHex(tokensHashBuff);
+
+			expect(order.params.maker).to.be.equal(logArgs.maker);
+			expect(taker).to.be.equal(logArgs.taker);
+			expect(order.params.feeRecipient).to.be.equal(logArgs.feeRecipient);
+			expect(order.params.makerToken).to.be.equal(logArgs.makerToken);
+			expect(order.params.takerToken).to.be.equal(logArgs.takerToken);
+			expect(expectedFilledMakerTokenAmount).to.be.bignumber.equal(logArgs.filledMakerTokenAmount);
+			expect(expectedFilledTakerTokenAmount).to.be.bignumber.equal(logArgs.filledTakerTokenAmount);
+			expect(expectedFeeMPaid).to.be.bignumber.equal(logArgs.paidMakerFee);
+			expect(expectedFeeTPaid).to.be.bignumber.equal(logArgs.paidTakerFee);
+			expect(expectedTokens).to.be.equal(logArgs.tokens);
+			expect(order.params.orderHashHex).to.be.equal(logArgs.orderHash);
+		});
+
+		it('should throw when taker is specified and order is claimed by other', async () => {
+			order = await orderFactory.newSignedOrderAsync({
+				taker: feeRecipient,
+				makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
+				takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18),
+			});
+
+			return expect(exWrapper.fillOrderAsync(order, taker)).to.be.rejectedWith(constants.REVERT);
+		});
+
+		it('should throw if signature is invalid', async () => {
+			order = await orderFactory.newSignedOrderAsync({
+				makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(10), 18),
+			});
+
+			order.params.r = ethUtil.bufferToHex(ethUtil.sha3('invalidR'));
+			order.params.s = ethUtil.bufferToHex(ethUtil.sha3('invalidS'));
+			return expect(exWrapper.fillOrderAsync(order, taker)).to.be.rejectedWith(constants.REVERT);
+		});
+
+		it('should throw if makerTokenAmount is 0', async () => {
+			order = await orderFactory.newSignedOrderAsync({
+				makerTokenAmount: new BigNumber(0),
+			});
+
+			return expect(exWrapper.fillOrderAsync(order, taker)).to.be.rejectedWith(constants.REVERT);
+		});
+
+		it('should throw if takerTokenAmount is 0', async () => {
+			order = await orderFactory.newSignedOrderAsync({
+				takerTokenAmount: new BigNumber(0),
+			});
+
+			return expect(exWrapper.fillOrderAsync(order, taker)).to.be.rejectedWith(constants.REVERT);
+		});
+
+		it('should throw if fillTakerTokenAmount is 0', async () => {
+			order = await orderFactory.newSignedOrderAsync();
+
+			return expect(
+				exWrapper.fillOrderAsync(order, taker, {
+					fillTakerTokenAmount: new BigNumber(0),
+				}),
+			).to.be.rejectedWith(constants.REVERT);
+		});
+
+		it('should not change balances if maker balances are too low to fill order and \
                 shouldThrowOnInsufficientBalanceOrAllowance = false', async () => {
-            order = await orderFactory.newSignedOrderAsync({
-                makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100000), 18),
-            });
+			order = await orderFactory.newSignedOrderAsync({
+				makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100000), 18),
+			});
 
-            await exWrapper.fillOrderAsync(order, taker);
-            const newBalances = await dmyBalances.getAsync();
-            expect(newBalances).to.be.deep.equal(balances);
-        });
+			await exWrapper.fillOrderAsync(order, taker);
+			const newBalances = await dmyBalances.getAsync();
+			expect(newBalances).to.be.deep.equal(balances);
+		});
 
-        it('should throw if maker balances are too low to fill order and \
+		it('should throw if maker balances are too low to fill order and \
                 shouldThrowOnInsufficientBalanceOrAllowance = true', async () => {
-            order = await orderFactory.newSignedOrderAsync({
-                makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100000), 18),
-            });
-
-            return expect(
-                exWrapper.fillOrderAsync(order, taker, {
-                    shouldThrowOnInsufficientBalanceOrAllowance: true,
-                }),
-            ).to.be.rejectedWith(constants.REVERT);
-        });
-
-        it('should not change balances if taker balances are too low to fill order and \
+			order = await orderFactory.newSignedOrderAsync({
+				makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100000), 18),
+			});
+
+			return expect(
+				exWrapper.fillOrderAsync(order, taker, {
+					shouldThrowOnInsufficientBalanceOrAllowance: true,
+				}),
+			).to.be.rejectedWith(constants.REVERT);
+		});
+
+		it('should not change balances if taker balances are too low to fill order and \
                 shouldThrowOnInsufficientBalanceOrAllowance = false', async () => {
-            order = await orderFactory.newSignedOrderAsync({
-                takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100000), 18),
-            });
+			order = await orderFactory.newSignedOrderAsync({
+				takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100000), 18),
+			});
 
-            await exWrapper.fillOrderAsync(order, taker);
-            const newBalances = await dmyBalances.getAsync();
-            expect(newBalances).to.be.deep.equal(balances);
-        });
+			await exWrapper.fillOrderAsync(order, taker);
+			const newBalances = await dmyBalances.getAsync();
+			expect(newBalances).to.be.deep.equal(balances);
+		});
 
-        it('should throw if taker balances are too low to fill order and \
+		it('should throw if taker balances are too low to fill order and \
                 shouldThrowOnInsufficientBalanceOrAllowance = true', async () => {
-            order = await orderFactory.newSignedOrderAsync({
-                takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100000), 18),
-            });
-
-            return expect(
-                exWrapper.fillOrderAsync(order, taker, {
-                    shouldThrowOnInsufficientBalanceOrAllowance: true,
-                }),
-            ).to.be.rejectedWith(constants.REVERT);
-        });
-
-        it('should not change balances if maker allowances are too low to fill order and \
+			order = await orderFactory.newSignedOrderAsync({
+				takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100000), 18),
+			});
+
+			return expect(
+				exWrapper.fillOrderAsync(order, taker, {
+					shouldThrowOnInsufficientBalanceOrAllowance: true,
+				}),
+			).to.be.rejectedWith(constants.REVERT);
+		});
+
+		it('should not change balances if maker allowances are too low to fill order and \
                 shouldThrowOnInsufficientBalanceOrAllowance = false', async () => {
-            await rep.approve(TokenTransferProxy.address, 0, { from: maker });
-            await exWrapper.fillOrderAsync(order, taker);
-            await rep.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
-                from: maker,
-            });
+			await rep.approve(TokenTransferProxy.address, 0, { from: maker });
+			await exWrapper.fillOrderAsync(order, taker);
+			await rep.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
+				from: maker,
+			});
 
-            const newBalances = await dmyBalances.getAsync();
-            expect(newBalances).to.be.deep.equal(balances);
-        });
+			const newBalances = await dmyBalances.getAsync();
+			expect(newBalances).to.be.deep.equal(balances);
+		});
 
-        it('should throw if maker allowances are too low to fill order and \
+		it('should throw if maker allowances are too low to fill order and \
                 shouldThrowOnInsufficientBalanceOrAllowance = true', async () => {
-            await rep.approve(TokenTransferProxy.address, 0, { from: maker });
-            expect(
-                exWrapper.fillOrderAsync(order, taker, {
-                    shouldThrowOnInsufficientBalanceOrAllowance: true,
-                }),
-            ).to.be.rejectedWith(constants.REVERT);
-            await rep.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
-                from: maker,
-            });
-        });
-
-        it('should not change balances if taker allowances are too low to fill order and \
+			await rep.approve(TokenTransferProxy.address, 0, { from: maker });
+			expect(
+				exWrapper.fillOrderAsync(order, taker, {
+					shouldThrowOnInsufficientBalanceOrAllowance: true,
+				}),
+			).to.be.rejectedWith(constants.REVERT);
+			await rep.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
+				from: maker,
+			});
+		});
+
+		it('should not change balances if taker allowances are too low to fill order and \
                 shouldThrowOnInsufficientBalanceOrAllowance = false', async () => {
-            await dgd.approve(TokenTransferProxy.address, 0, { from: taker });
-            await exWrapper.fillOrderAsync(order, taker);
-            await dgd.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
-                from: taker,
-            });
+			await dgd.approve(TokenTransferProxy.address, 0, { from: taker });
+			await exWrapper.fillOrderAsync(order, taker);
+			await dgd.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
+				from: taker,
+			});
 
-            const newBalances = await dmyBalances.getAsync();
-            expect(newBalances).to.be.deep.equal(balances);
-        });
+			const newBalances = await dmyBalances.getAsync();
+			expect(newBalances).to.be.deep.equal(balances);
+		});
 
-        it('should throw if taker allowances are too low to fill order and \
+		it('should throw if taker allowances are too low to fill order and \
                 shouldThrowOnInsufficientBalanceOrAllowance = true', async () => {
-            await dgd.approve(TokenTransferProxy.address, 0, { from: taker });
-            expect(
-                exWrapper.fillOrderAsync(order, taker, {
-                    shouldThrowOnInsufficientBalanceOrAllowance: true,
-                }),
-            ).to.be.rejectedWith(constants.REVERT);
-            await dgd.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
-                from: taker,
-            });
-        });
-
-        it('should not change balances if makerToken is ZRX, makerTokenAmount + makerFee > maker balance, \
+			await dgd.approve(TokenTransferProxy.address, 0, { from: taker });
+			expect(
+				exWrapper.fillOrderAsync(order, taker, {
+					shouldThrowOnInsufficientBalanceOrAllowance: true,
+				}),
+			).to.be.rejectedWith(constants.REVERT);
+			await dgd.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
+				from: taker,
+			});
+		});
+
+		it('should not change balances if makerToken is ZRX, makerTokenAmount + makerFee > maker balance, \
                 and shouldThrowOnInsufficientBalanceOrAllowance = false', async () => {
-            const makerZRXBalance = new BigNumber(balances[maker][zrx.address]);
-            order = await orderFactory.newSignedOrderAsync({
-                makerToken: zrx.address,
-                makerTokenAmount: makerZRXBalance,
-                makerFee: new BigNumber(1),
-            });
-            await exWrapper.fillOrderAsync(order, taker);
-            const newBalances = await dmyBalances.getAsync();
-            expect(newBalances).to.be.deep.equal(balances);
-        });
-
-        it('should not change balances if makerToken is ZRX, makerTokenAmount + makerFee > maker allowance, \
+			const makerZRXBalance = new BigNumber(balances[maker][zrx.address]);
+			order = await orderFactory.newSignedOrderAsync({
+				makerToken: zrx.address,
+				makerTokenAmount: makerZRXBalance,
+				makerFee: new BigNumber(1),
+			});
+			await exWrapper.fillOrderAsync(order, taker);
+			const newBalances = await dmyBalances.getAsync();
+			expect(newBalances).to.be.deep.equal(balances);
+		});
+
+		it('should not change balances if makerToken is ZRX, makerTokenAmount + makerFee > maker allowance, \
                 and shouldThrowOnInsufficientBalanceOrAllowance = false', async () => {
-            const makerZRXAllowance = await zrx.allowance(maker, TokenTransferProxy.address);
-            order = await orderFactory.newSignedOrderAsync({
-                makerToken: zrx.address,
-                makerTokenAmount: new BigNumber(makerZRXAllowance),
-                makerFee: new BigNumber(1),
-            });
-            await exWrapper.fillOrderAsync(order, taker);
-            const newBalances = await dmyBalances.getAsync();
-            expect(newBalances).to.be.deep.equal(balances);
-        });
-
-        it('should not change balances if takerToken is ZRX, takerTokenAmount + takerFee > taker balance, \
+			const makerZRXAllowance = await zrx.allowance(maker, TokenTransferProxy.address);
+			order = await orderFactory.newSignedOrderAsync({
+				makerToken: zrx.address,
+				makerTokenAmount: new BigNumber(makerZRXAllowance),
+				makerFee: new BigNumber(1),
+			});
+			await exWrapper.fillOrderAsync(order, taker);
+			const newBalances = await dmyBalances.getAsync();
+			expect(newBalances).to.be.deep.equal(balances);
+		});
+
+		it('should not change balances if takerToken is ZRX, takerTokenAmount + takerFee > taker balance, \
                 and shouldThrowOnInsufficientBalanceOrAllowance = false', async () => {
-            const takerZRXBalance = new BigNumber(balances[taker][zrx.address]);
-            order = await orderFactory.newSignedOrderAsync({
-                takerToken: zrx.address,
-                takerTokenAmount: takerZRXBalance,
-                takerFee: new BigNumber(1),
-            });
-            await exWrapper.fillOrderAsync(order, taker);
-            const newBalances = await dmyBalances.getAsync();
-            expect(newBalances).to.be.deep.equal(balances);
-        });
-
-        it('should not change balances if takerToken is ZRX, takerTokenAmount + takerFee > taker allowance, \
+			const takerZRXBalance = new BigNumber(balances[taker][zrx.address]);
+			order = await orderFactory.newSignedOrderAsync({
+				takerToken: zrx.address,
+				takerTokenAmount: takerZRXBalance,
+				takerFee: new BigNumber(1),
+			});
+			await exWrapper.fillOrderAsync(order, taker);
+			const newBalances = await dmyBalances.getAsync();
+			expect(newBalances).to.be.deep.equal(balances);
+		});
+
+		it('should not change balances if takerToken is ZRX, takerTokenAmount + takerFee > taker allowance, \
                 and shouldThrowOnInsufficientBalanceOrAllowance = false', async () => {
-            const takerZRXAllowance = await zrx.allowance(taker, TokenTransferProxy.address);
-            order = await orderFactory.newSignedOrderAsync({
-                takerToken: zrx.address,
-                takerTokenAmount: new BigNumber(takerZRXAllowance),
-                takerFee: new BigNumber(1),
-            });
-            await exWrapper.fillOrderAsync(order, taker);
-            const newBalances = await dmyBalances.getAsync();
-            expect(newBalances).to.be.deep.equal(balances);
-        });
-
-        it('should throw if getBalance or getAllowance attempts to change state and \
+			const takerZRXAllowance = await zrx.allowance(taker, TokenTransferProxy.address);
+			order = await orderFactory.newSignedOrderAsync({
+				takerToken: zrx.address,
+				takerTokenAmount: new BigNumber(takerZRXAllowance),
+				takerFee: new BigNumber(1),
+			});
+			await exWrapper.fillOrderAsync(order, taker);
+			const newBalances = await dmyBalances.getAsync();
+			expect(newBalances).to.be.deep.equal(balances);
+		});
+
+		it('should throw if getBalance or getAllowance attempts to change state and \
                 shouldThrowOnInsufficientBalanceOrAllowance = false', async () => {
-            const maliciousToken = await MaliciousToken.new();
-            await maliciousToken.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, { from: taker });
-
-            order = await orderFactory.newSignedOrderAsync({
-                takerToken: maliciousToken.address,
-            });
-
-            return expect(
-                exWrapper.fillOrderAsync(order, taker, {
-                    shouldThrowOnInsufficientBalanceOrAllowance: false,
-                }),
-            ).to.be.rejectedWith(constants.REVERT);
-        });
-
-        it('should not change balances if an order is expired', async () => {
-            order = await orderFactory.newSignedOrderAsync({
-                expirationTimestampInSec: new BigNumber(Math.floor((Date.now() - 10000) / 1000)),
-            });
-            await exWrapper.fillOrderAsync(order, taker);
-
-            const newBalances = await dmyBalances.getAsync();
-            expect(newBalances).to.be.deep.equal(balances);
-        });
-
-        it('should log an error event if an order is expired', async () => {
-            order = await orderFactory.newSignedOrderAsync({
-                expirationTimestampInSec: new BigNumber(Math.floor((Date.now() - 10000) / 1000)),
-            });
-
-            const res = await exWrapper.fillOrderAsync(order, taker);
-            expect(res.logs).to.have.length(1);
-            const errCode = res.logs[0].args.errorId.toNumber();
-            expect(errCode).to.be.equal(ExchangeContractErrs.ERROR_ORDER_EXPIRED);
-        });
-
-        it('should log an error event if no value is filled', async () => {
-            await exWrapper.fillOrderAsync(order, taker);
-
-            const res = await exWrapper.fillOrderAsync(order, taker);
-            expect(res.logs).to.have.length(1);
-            const errCode = res.logs[0].args.errorId.toNumber();
-            expect(errCode).to.be.equal(ExchangeContractErrs.ERROR_ORDER_FULLY_FILLED_OR_CANCELLED);
-        });
-    });
-
-    describe('cancelOrder', () => {
-        beforeEach(async () => {
-            balances = await dmyBalances.getAsync();
-            order = await orderFactory.newSignedOrderAsync();
-        });
-
-        it('should throw if not sent by maker', async () => {
-            return expect(exWrapper.cancelOrderAsync(order, taker)).to.be.rejectedWith(constants.REVERT);
-        });
-
-        it('should throw if makerTokenAmount is 0', async () => {
-            order = await orderFactory.newSignedOrderAsync({
-                makerTokenAmount: new BigNumber(0),
-            });
-
-            return expect(exWrapper.cancelOrderAsync(order, maker)).to.be.rejectedWith(constants.REVERT);
-        });
-
-        it('should throw if takerTokenAmount is 0', async () => {
-            order = await orderFactory.newSignedOrderAsync({
-                takerTokenAmount: new BigNumber(0),
-            });
-
-            return expect(exWrapper.cancelOrderAsync(order, maker)).to.be.rejectedWith(constants.REVERT);
-        });
-
-        it('should throw if cancelTakerTokenAmount is 0', async () => {
-            order = await orderFactory.newSignedOrderAsync();
-
-            return expect(
-                exWrapper.cancelOrderAsync(order, maker, {
-                    cancelTakerTokenAmount: new BigNumber(0),
-                }),
-            ).to.be.rejectedWith(constants.REVERT);
-        });
-
-        it('should be able to cancel a full order', async () => {
-            await exWrapper.cancelOrderAsync(order, maker);
-            await exWrapper.fillOrderAsync(order, taker, {
-                fillTakerTokenAmount: order.params.takerTokenAmount.div(2),
-            });
-
-            const newBalances = await dmyBalances.getAsync();
-            expect(newBalances).to.be.deep.equal(balances);
-        });
-
-        it('should be able to cancel part of an order', async () => {
-            const cancelTakerTokenAmount = order.params.takerTokenAmount.div(2);
-            await exWrapper.cancelOrderAsync(order, maker, {
-                cancelTakerTokenAmount,
-            });
-
-            const res = await exWrapper.fillOrderAsync(order, taker, {
-                fillTakerTokenAmount: order.params.takerTokenAmount,
-            });
-            expect(res.logs[0].args.filledTakerTokenAmount).to.be.bignumber.equal(
-                order.params.takerTokenAmount.minus(cancelTakerTokenAmount),
-            );
-
-            const newBalances = await dmyBalances.getAsync();
-            const cancelMakerTokenAmount = cancelTakerTokenAmount
-                .times(order.params.makerTokenAmount)
-                .dividedToIntegerBy(order.params.takerTokenAmount);
-            const paidMakerFee = order.params.makerFee
-                .times(cancelMakerTokenAmount)
-                .dividedToIntegerBy(order.params.makerTokenAmount);
-            const paidTakerFee = order.params.takerFee
-                .times(cancelMakerTokenAmount)
-                .dividedToIntegerBy(order.params.makerTokenAmount);
-            expect(newBalances[maker][order.params.makerToken]).to.be.bignumber.equal(
-                balances[maker][order.params.makerToken].minus(cancelMakerTokenAmount),
-            );
-            expect(newBalances[maker][order.params.takerToken]).to.be.bignumber.equal(
-                balances[maker][order.params.takerToken].add(cancelTakerTokenAmount),
-            );
-            expect(newBalances[maker][zrx.address]).to.be.bignumber.equal(
-                balances[maker][zrx.address].minus(paidMakerFee),
-            );
-            expect(newBalances[taker][order.params.takerToken]).to.be.bignumber.equal(
-                balances[taker][order.params.takerToken].minus(cancelTakerTokenAmount),
-            );
-            expect(newBalances[taker][order.params.makerToken]).to.be.bignumber.equal(
-                balances[taker][order.params.makerToken].add(cancelMakerTokenAmount),
-            );
-            expect(newBalances[taker][zrx.address]).to.be.bignumber.equal(
-                balances[taker][zrx.address].minus(paidTakerFee),
-            );
-            expect(newBalances[feeRecipient][zrx.address]).to.be.bignumber.equal(
-                balances[feeRecipient][zrx.address].add(paidMakerFee.add(paidTakerFee)),
-            );
-        });
-
-        it('should log 1 event with correct arguments', async () => {
-            const divisor = 2;
-            const res = await exWrapper.cancelOrderAsync(order, maker, {
-                cancelTakerTokenAmount: order.params.takerTokenAmount.div(divisor),
-            });
-            expect(res.logs).to.have.length(1);
-
-            const logArgs = res.logs[0].args;
-            const expectedCancelledMakerTokenAmount = order.params.makerTokenAmount.div(divisor);
-            const expectedCancelledTakerTokenAmount = order.params.takerTokenAmount.div(divisor);
-            const tokensHashBuff = crypto.solSHA3([order.params.makerToken, order.params.takerToken]);
-            const expectedTokens = ethUtil.bufferToHex(tokensHashBuff);
-
-            expect(order.params.maker).to.be.equal(logArgs.maker);
-            expect(order.params.feeRecipient).to.be.equal(logArgs.feeRecipient);
-            expect(order.params.makerToken).to.be.equal(logArgs.makerToken);
-            expect(order.params.takerToken).to.be.equal(logArgs.takerToken);
-            expect(expectedCancelledMakerTokenAmount).to.be.bignumber.equal(logArgs.cancelledMakerTokenAmount);
-            expect(expectedCancelledTakerTokenAmount).to.be.bignumber.equal(logArgs.cancelledTakerTokenAmount);
-            expect(expectedTokens).to.be.equal(logArgs.tokens);
-            expect(order.params.orderHashHex).to.be.equal(logArgs.orderHash);
-        });
-
-        it('should not log events if no value is cancelled', async () => {
-            await exWrapper.cancelOrderAsync(order, maker);
-
-            const res = await exWrapper.cancelOrderAsync(order, maker);
-            expect(res.logs).to.have.length(1);
-            const errCode = res.logs[0].args.errorId.toNumber();
-            expect(errCode).to.be.equal(ExchangeContractErrs.ERROR_ORDER_FULLY_FILLED_OR_CANCELLED);
-        });
-
-        it('should not log events if order is expired', async () => {
-            order = await orderFactory.newSignedOrderAsync({
-                expirationTimestampInSec: new BigNumber(Math.floor((Date.now() - 10000) / 1000)),
-            });
-
-            const res = await exWrapper.cancelOrderAsync(order, maker);
-            expect(res.logs).to.have.length(1);
-            const errCode = res.logs[0].args.errorId.toNumber();
-            expect(errCode).to.be.equal(ExchangeContractErrs.ERROR_ORDER_EXPIRED);
-        });
-    });
+			const maliciousToken = await MaliciousToken.new();
+			await maliciousToken.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, { from: taker });
+
+			order = await orderFactory.newSignedOrderAsync({
+				takerToken: maliciousToken.address,
+			});
+
+			return expect(
+				exWrapper.fillOrderAsync(order, taker, {
+					shouldThrowOnInsufficientBalanceOrAllowance: false,
+				}),
+			).to.be.rejectedWith(constants.REVERT);
+		});
+
+		it('should not change balances if an order is expired', async () => {
+			order = await orderFactory.newSignedOrderAsync({
+				expirationTimestampInSec: new BigNumber(Math.floor((Date.now() - 10000) / 1000)),
+			});
+			await exWrapper.fillOrderAsync(order, taker);
+
+			const newBalances = await dmyBalances.getAsync();
+			expect(newBalances).to.be.deep.equal(balances);
+		});
+
+		it('should log an error event if an order is expired', async () => {
+			order = await orderFactory.newSignedOrderAsync({
+				expirationTimestampInSec: new BigNumber(Math.floor((Date.now() - 10000) / 1000)),
+			});
+
+			const res = await exWrapper.fillOrderAsync(order, taker);
+			expect(res.logs).to.have.length(1);
+			const errCode = res.logs[0].args.errorId.toNumber();
+			expect(errCode).to.be.equal(ExchangeContractErrs.ERROR_ORDER_EXPIRED);
+		});
+
+		it('should log an error event if no value is filled', async () => {
+			await exWrapper.fillOrderAsync(order, taker);
+
+			const res = await exWrapper.fillOrderAsync(order, taker);
+			expect(res.logs).to.have.length(1);
+			const errCode = res.logs[0].args.errorId.toNumber();
+			expect(errCode).to.be.equal(ExchangeContractErrs.ERROR_ORDER_FULLY_FILLED_OR_CANCELLED);
+		});
+	});
+
+	describe('cancelOrder', () => {
+		beforeEach(async () => {
+			balances = await dmyBalances.getAsync();
+			order = await orderFactory.newSignedOrderAsync();
+		});
+
+		it('should throw if not sent by maker', async () => {
+			return expect(exWrapper.cancelOrderAsync(order, taker)).to.be.rejectedWith(constants.REVERT);
+		});
+
+		it('should throw if makerTokenAmount is 0', async () => {
+			order = await orderFactory.newSignedOrderAsync({
+				makerTokenAmount: new BigNumber(0),
+			});
+
+			return expect(exWrapper.cancelOrderAsync(order, maker)).to.be.rejectedWith(constants.REVERT);
+		});
+
+		it('should throw if takerTokenAmount is 0', async () => {
+			order = await orderFactory.newSignedOrderAsync({
+				takerTokenAmount: new BigNumber(0),
+			});
+
+			return expect(exWrapper.cancelOrderAsync(order, maker)).to.be.rejectedWith(constants.REVERT);
+		});
+
+		it('should throw if cancelTakerTokenAmount is 0', async () => {
+			order = await orderFactory.newSignedOrderAsync();
+
+			return expect(
+				exWrapper.cancelOrderAsync(order, maker, {
+					cancelTakerTokenAmount: new BigNumber(0),
+				}),
+			).to.be.rejectedWith(constants.REVERT);
+		});
+
+		it('should be able to cancel a full order', async () => {
+			await exWrapper.cancelOrderAsync(order, maker);
+			await exWrapper.fillOrderAsync(order, taker, {
+				fillTakerTokenAmount: order.params.takerTokenAmount.div(2),
+			});
+
+			const newBalances = await dmyBalances.getAsync();
+			expect(newBalances).to.be.deep.equal(balances);
+		});
+
+		it('should be able to cancel part of an order', async () => {
+			const cancelTakerTokenAmount = order.params.takerTokenAmount.div(2);
+			await exWrapper.cancelOrderAsync(order, maker, {
+				cancelTakerTokenAmount,
+			});
+
+			const res = await exWrapper.fillOrderAsync(order, taker, {
+				fillTakerTokenAmount: order.params.takerTokenAmount,
+			});
+			expect(res.logs[0].args.filledTakerTokenAmount).to.be.bignumber.equal(
+				order.params.takerTokenAmount.minus(cancelTakerTokenAmount),
+			);
+
+			const newBalances = await dmyBalances.getAsync();
+			const cancelMakerTokenAmount = cancelTakerTokenAmount
+				.times(order.params.makerTokenAmount)
+				.dividedToIntegerBy(order.params.takerTokenAmount);
+			const paidMakerFee = order.params.makerFee
+				.times(cancelMakerTokenAmount)
+				.dividedToIntegerBy(order.params.makerTokenAmount);
+			const paidTakerFee = order.params.takerFee
+				.times(cancelMakerTokenAmount)
+				.dividedToIntegerBy(order.params.makerTokenAmount);
+			expect(newBalances[maker][order.params.makerToken]).to.be.bignumber.equal(
+				balances[maker][order.params.makerToken].minus(cancelMakerTokenAmount),
+			);
+			expect(newBalances[maker][order.params.takerToken]).to.be.bignumber.equal(
+				balances[maker][order.params.takerToken].add(cancelTakerTokenAmount),
+			);
+			expect(newBalances[maker][zrx.address]).to.be.bignumber.equal(
+				balances[maker][zrx.address].minus(paidMakerFee),
+			);
+			expect(newBalances[taker][order.params.takerToken]).to.be.bignumber.equal(
+				balances[taker][order.params.takerToken].minus(cancelTakerTokenAmount),
+			);
+			expect(newBalances[taker][order.params.makerToken]).to.be.bignumber.equal(
+				balances[taker][order.params.makerToken].add(cancelMakerTokenAmount),
+			);
+			expect(newBalances[taker][zrx.address]).to.be.bignumber.equal(
+				balances[taker][zrx.address].minus(paidTakerFee),
+			);
+			expect(newBalances[feeRecipient][zrx.address]).to.be.bignumber.equal(
+				balances[feeRecipient][zrx.address].add(paidMakerFee.add(paidTakerFee)),
+			);
+		});
+
+		it('should log 1 event with correct arguments', async () => {
+			const divisor = 2;
+			const res = await exWrapper.cancelOrderAsync(order, maker, {
+				cancelTakerTokenAmount: order.params.takerTokenAmount.div(divisor),
+			});
+			expect(res.logs).to.have.length(1);
+
+			const logArgs = res.logs[0].args;
+			const expectedCancelledMakerTokenAmount = order.params.makerTokenAmount.div(divisor);
+			const expectedCancelledTakerTokenAmount = order.params.takerTokenAmount.div(divisor);
+			const tokensHashBuff = crypto.solSHA3([order.params.makerToken, order.params.takerToken]);
+			const expectedTokens = ethUtil.bufferToHex(tokensHashBuff);
+
+			expect(order.params.maker).to.be.equal(logArgs.maker);
+			expect(order.params.feeRecipient).to.be.equal(logArgs.feeRecipient);
+			expect(order.params.makerToken).to.be.equal(logArgs.makerToken);
+			expect(order.params.takerToken).to.be.equal(logArgs.takerToken);
+			expect(expectedCancelledMakerTokenAmount).to.be.bignumber.equal(logArgs.cancelledMakerTokenAmount);
+			expect(expectedCancelledTakerTokenAmount).to.be.bignumber.equal(logArgs.cancelledTakerTokenAmount);
+			expect(expectedTokens).to.be.equal(logArgs.tokens);
+			expect(order.params.orderHashHex).to.be.equal(logArgs.orderHash);
+		});
+
+		it('should not log events if no value is cancelled', async () => {
+			await exWrapper.cancelOrderAsync(order, maker);
+
+			const res = await exWrapper.cancelOrderAsync(order, maker);
+			expect(res.logs).to.have.length(1);
+			const errCode = res.logs[0].args.errorId.toNumber();
+			expect(errCode).to.be.equal(ExchangeContractErrs.ERROR_ORDER_FULLY_FILLED_OR_CANCELLED);
+		});
+
+		it('should not log events if order is expired', async () => {
+			order = await orderFactory.newSignedOrderAsync({
+				expirationTimestampInSec: new BigNumber(Math.floor((Date.now() - 10000) / 1000)),
+			});
+
+			const res = await exWrapper.cancelOrderAsync(order, maker);
+			expect(res.logs).to.have.length(1);
+			const errCode = res.logs[0].args.errorId.toNumber();
+			expect(errCode).to.be.equal(ExchangeContractErrs.ERROR_ORDER_EXPIRED);
+		});
+	});
 }); // tslint:disable-line:max-file-line-count
diff --git a/packages/contracts/test/ts/exchange/helpers.ts b/packages/contracts/test/ts/exchange/helpers.ts
index 95f68e419..993b4c7d5 100644
--- a/packages/contracts/test/ts/exchange/helpers.ts
+++ b/packages/contracts/test/ts/exchange/helpers.ts
@@ -15,153 +15,153 @@ const expect = chai.expect;
 const { Exchange, TokenRegistry } = new Artifacts(artifacts);
 
 contract('Exchange', (accounts: string[]) => {
-    const maker = accounts[0];
-    const feeRecipient = accounts[1] || accounts[accounts.length - 1];
-
-    let order: Order;
-    let exchangeWrapper: ExchangeWrapper;
-    let orderFactory: OrderFactory;
-
-    before(async () => {
-        const [tokenRegistry, exchange] = await Promise.all([TokenRegistry.deployed(), Exchange.deployed()]);
-        exchangeWrapper = new ExchangeWrapper(exchange);
-        const [repAddress, dgdAddress] = await Promise.all([
-            tokenRegistry.getTokenAddressBySymbol('REP'),
-            tokenRegistry.getTokenAddressBySymbol('DGD'),
-        ]);
-        const defaultOrderParams = {
-            exchangeContractAddress: Exchange.address,
-            maker,
-            feeRecipient,
-            makerToken: repAddress,
-            takerToken: dgdAddress,
-            makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
-            takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18),
-            makerFee: ZeroEx.toBaseUnitAmount(new BigNumber(1), 18),
-            takerFee: ZeroEx.toBaseUnitAmount(new BigNumber(1), 18),
-        };
-        orderFactory = new OrderFactory(defaultOrderParams);
-    });
-
-    beforeEach(async () => {
-        order = await orderFactory.newSignedOrderAsync();
-    });
-
-    describe('getOrderHash', () => {
-        it('should output the correct orderHash', async () => {
-            const orderHashHex = await exchangeWrapper.getOrderHashAsync(order);
-            expect(order.params.orderHashHex).to.be.equal(orderHashHex);
-        });
-    });
-
-    describe('isValidSignature', () => {
-        beforeEach(async () => {
-            order = await orderFactory.newSignedOrderAsync();
-        });
-
-        it('should return true with a valid signature', async () => {
-            const success = await exchangeWrapper.isValidSignatureAsync(order);
-            const isValidSignature = order.isValidSignature();
-            expect(isValidSignature).to.be.true();
-            expect(success).to.be.true();
-        });
-
-        it('should return false with an invalid signature', async () => {
-            order.params.r = ethUtil.bufferToHex(ethUtil.sha3('invalidR'));
-            order.params.s = ethUtil.bufferToHex(ethUtil.sha3('invalidS'));
-            const success = await exchangeWrapper.isValidSignatureAsync(order);
-            expect(order.isValidSignature()).to.be.false();
-            expect(success).to.be.false();
-        });
-    });
-
-    describe('isRoundingError', () => {
-        it('should return false if there is a rounding error of 0.1%', async () => {
-            const numerator = new BigNumber(20);
-            const denominator = new BigNumber(999);
-            const target = new BigNumber(50);
-            // rounding error = ((20*50/999) - floor(20*50/999)) / (20*50/999) = 0.1%
-            const isRoundingError = await exchangeWrapper.isRoundingErrorAsync(numerator, denominator, target);
-            expect(isRoundingError).to.be.false();
-        });
-
-        it('should return false if there is a rounding of 0.09%', async () => {
-            const numerator = new BigNumber(20);
-            const denominator = new BigNumber(9991);
-            const target = new BigNumber(500);
-            // rounding error = ((20*500/9991) - floor(20*500/9991)) / (20*500/9991) = 0.09%
-            const isRoundingError = await exchangeWrapper.isRoundingErrorAsync(numerator, denominator, target);
-            expect(isRoundingError).to.be.false();
-        });
-
-        it('should return true if there is a rounding error of 0.11%', async () => {
-            const numerator = new BigNumber(20);
-            const denominator = new BigNumber(9989);
-            const target = new BigNumber(500);
-            // rounding error = ((20*500/9989) - floor(20*500/9989)) / (20*500/9989) = 0.011%
-            const isRoundingError = await exchangeWrapper.isRoundingErrorAsync(numerator, denominator, target);
-            expect(isRoundingError).to.be.true();
-        });
-
-        it('should return true if there is a rounding error > 0.1%', async () => {
-            const numerator = new BigNumber(3);
-            const denominator = new BigNumber(7);
-            const target = new BigNumber(10);
-            // rounding error = ((3*10/7) - floor(3*10/7)) / (3*10/7) = 6.67%
-            const isRoundingError = await exchangeWrapper.isRoundingErrorAsync(numerator, denominator, target);
-            expect(isRoundingError).to.be.true();
-        });
-
-        it('should return false when there is no rounding error', async () => {
-            const numerator = new BigNumber(1);
-            const denominator = new BigNumber(2);
-            const target = new BigNumber(10);
-
-            const isRoundingError = await exchangeWrapper.isRoundingErrorAsync(numerator, denominator, target);
-            expect(isRoundingError).to.be.false();
-        });
-
-        it('should return false when there is rounding error <= 0.1%', async () => {
-            // randomly generated numbers
-            const numerator = new BigNumber(76564);
-            const denominator = new BigNumber(676373677);
-            const target = new BigNumber(105762562);
-            // rounding error = ((76564*105762562/676373677) - floor(76564*105762562/676373677)) /
-            // (76564*105762562/676373677) = 0.0007%
-            const isRoundingError = await exchangeWrapper.isRoundingErrorAsync(numerator, denominator, target);
-            expect(isRoundingError).to.be.false();
-        });
-    });
-
-    describe('getPartialAmount', () => {
-        it('should return the numerator/denominator*target', async () => {
-            const numerator = new BigNumber(1);
-            const denominator = new BigNumber(2);
-            const target = new BigNumber(10);
-
-            const partialAmount = await exchangeWrapper.getPartialAmountAsync(numerator, denominator, target);
-            const expectedPartialAmount = 5;
-            expect(partialAmount).to.be.bignumber.equal(expectedPartialAmount);
-        });
-
-        it('should round down', async () => {
-            const numerator = new BigNumber(2);
-            const denominator = new BigNumber(3);
-            const target = new BigNumber(10);
-
-            const partialAmount = await exchangeWrapper.getPartialAmountAsync(numerator, denominator, target);
-            const expectedPartialAmount = 6;
-            expect(partialAmount).to.be.bignumber.equal(expectedPartialAmount);
-        });
-
-        it('should round .5 down', async () => {
-            const numerator = new BigNumber(1);
-            const denominator = new BigNumber(20);
-            const target = new BigNumber(10);
-
-            const partialAmount = await exchangeWrapper.getPartialAmountAsync(numerator, denominator, target);
-            const expectedPartialAmount = 0;
-            expect(partialAmount).to.be.bignumber.equal(expectedPartialAmount);
-        });
-    });
+	const maker = accounts[0];
+	const feeRecipient = accounts[1] || accounts[accounts.length - 1];
+
+	let order: Order;
+	let exchangeWrapper: ExchangeWrapper;
+	let orderFactory: OrderFactory;
+
+	before(async () => {
+		const [tokenRegistry, exchange] = await Promise.all([TokenRegistry.deployed(), Exchange.deployed()]);
+		exchangeWrapper = new ExchangeWrapper(exchange);
+		const [repAddress, dgdAddress] = await Promise.all([
+			tokenRegistry.getTokenAddressBySymbol('REP'),
+			tokenRegistry.getTokenAddressBySymbol('DGD'),
+		]);
+		const defaultOrderParams = {
+			exchangeContractAddress: Exchange.address,
+			maker,
+			feeRecipient,
+			makerToken: repAddress,
+			takerToken: dgdAddress,
+			makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
+			takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18),
+			makerFee: ZeroEx.toBaseUnitAmount(new BigNumber(1), 18),
+			takerFee: ZeroEx.toBaseUnitAmount(new BigNumber(1), 18),
+		};
+		orderFactory = new OrderFactory(defaultOrderParams);
+	});
+
+	beforeEach(async () => {
+		order = await orderFactory.newSignedOrderAsync();
+	});
+
+	describe('getOrderHash', () => {
+		it('should output the correct orderHash', async () => {
+			const orderHashHex = await exchangeWrapper.getOrderHashAsync(order);
+			expect(order.params.orderHashHex).to.be.equal(orderHashHex);
+		});
+	});
+
+	describe('isValidSignature', () => {
+		beforeEach(async () => {
+			order = await orderFactory.newSignedOrderAsync();
+		});
+
+		it('should return true with a valid signature', async () => {
+			const success = await exchangeWrapper.isValidSignatureAsync(order);
+			const isValidSignature = order.isValidSignature();
+			expect(isValidSignature).to.be.true();
+			expect(success).to.be.true();
+		});
+
+		it('should return false with an invalid signature', async () => {
+			order.params.r = ethUtil.bufferToHex(ethUtil.sha3('invalidR'));
+			order.params.s = ethUtil.bufferToHex(ethUtil.sha3('invalidS'));
+			const success = await exchangeWrapper.isValidSignatureAsync(order);
+			expect(order.isValidSignature()).to.be.false();
+			expect(success).to.be.false();
+		});
+	});
+
+	describe('isRoundingError', () => {
+		it('should return false if there is a rounding error of 0.1%', async () => {
+			const numerator = new BigNumber(20);
+			const denominator = new BigNumber(999);
+			const target = new BigNumber(50);
+			// rounding error = ((20*50/999) - floor(20*50/999)) / (20*50/999) = 0.1%
+			const isRoundingError = await exchangeWrapper.isRoundingErrorAsync(numerator, denominator, target);
+			expect(isRoundingError).to.be.false();
+		});
+
+		it('should return false if there is a rounding of 0.09%', async () => {
+			const numerator = new BigNumber(20);
+			const denominator = new BigNumber(9991);
+			const target = new BigNumber(500);
+			// rounding error = ((20*500/9991) - floor(20*500/9991)) / (20*500/9991) = 0.09%
+			const isRoundingError = await exchangeWrapper.isRoundingErrorAsync(numerator, denominator, target);
+			expect(isRoundingError).to.be.false();
+		});
+
+		it('should return true if there is a rounding error of 0.11%', async () => {
+			const numerator = new BigNumber(20);
+			const denominator = new BigNumber(9989);
+			const target = new BigNumber(500);
+			// rounding error = ((20*500/9989) - floor(20*500/9989)) / (20*500/9989) = 0.011%
+			const isRoundingError = await exchangeWrapper.isRoundingErrorAsync(numerator, denominator, target);
+			expect(isRoundingError).to.be.true();
+		});
+
+		it('should return true if there is a rounding error > 0.1%', async () => {
+			const numerator = new BigNumber(3);
+			const denominator = new BigNumber(7);
+			const target = new BigNumber(10);
+			// rounding error = ((3*10/7) - floor(3*10/7)) / (3*10/7) = 6.67%
+			const isRoundingError = await exchangeWrapper.isRoundingErrorAsync(numerator, denominator, target);
+			expect(isRoundingError).to.be.true();
+		});
+
+		it('should return false when there is no rounding error', async () => {
+			const numerator = new BigNumber(1);
+			const denominator = new BigNumber(2);
+			const target = new BigNumber(10);
+
+			const isRoundingError = await exchangeWrapper.isRoundingErrorAsync(numerator, denominator, target);
+			expect(isRoundingError).to.be.false();
+		});
+
+		it('should return false when there is rounding error <= 0.1%', async () => {
+			// randomly generated numbers
+			const numerator = new BigNumber(76564);
+			const denominator = new BigNumber(676373677);
+			const target = new BigNumber(105762562);
+			// rounding error = ((76564*105762562/676373677) - floor(76564*105762562/676373677)) /
+			// (76564*105762562/676373677) = 0.0007%
+			const isRoundingError = await exchangeWrapper.isRoundingErrorAsync(numerator, denominator, target);
+			expect(isRoundingError).to.be.false();
+		});
+	});
+
+	describe('getPartialAmount', () => {
+		it('should return the numerator/denominator*target', async () => {
+			const numerator = new BigNumber(1);
+			const denominator = new BigNumber(2);
+			const target = new BigNumber(10);
+
+			const partialAmount = await exchangeWrapper.getPartialAmountAsync(numerator, denominator, target);
+			const expectedPartialAmount = 5;
+			expect(partialAmount).to.be.bignumber.equal(expectedPartialAmount);
+		});
+
+		it('should round down', async () => {
+			const numerator = new BigNumber(2);
+			const denominator = new BigNumber(3);
+			const target = new BigNumber(10);
+
+			const partialAmount = await exchangeWrapper.getPartialAmountAsync(numerator, denominator, target);
+			const expectedPartialAmount = 6;
+			expect(partialAmount).to.be.bignumber.equal(expectedPartialAmount);
+		});
+
+		it('should round .5 down', async () => {
+			const numerator = new BigNumber(1);
+			const denominator = new BigNumber(20);
+			const target = new BigNumber(10);
+
+			const partialAmount = await exchangeWrapper.getPartialAmountAsync(numerator, denominator, target);
+			const expectedPartialAmount = 0;
+			expect(partialAmount).to.be.bignumber.equal(expectedPartialAmount);
+		});
+	});
 });
diff --git a/packages/contracts/test/ts/exchange/wrapper.ts b/packages/contracts/test/ts/exchange/wrapper.ts
index e69e08bcf..e0243fc1b 100644
--- a/packages/contracts/test/ts/exchange/wrapper.ts
+++ b/packages/contracts/test/ts/exchange/wrapper.ts
@@ -17,332 +17,332 @@ const expect = chai.expect;
 const { Exchange, TokenTransferProxy, DummyToken, TokenRegistry } = new Artifacts(artifacts);
 
 contract('Exchange', (accounts: string[]) => {
-    const maker = accounts[0];
-    const tokenOwner = accounts[0];
-    const taker = accounts[1] || accounts[accounts.length - 1];
-    const feeRecipient = accounts[2] || accounts[accounts.length - 1];
-
-    const INIT_BAL = ZeroEx.toBaseUnitAmount(new BigNumber(10000), 18);
-    const INIT_ALLOW = ZeroEx.toBaseUnitAmount(new BigNumber(10000), 18);
-
-    let rep: ContractInstance;
-    let dgd: ContractInstance;
-    let zrx: ContractInstance;
-    let exchange: ContractInstance;
-    let tokenRegistry: ContractInstance;
-
-    let balances: BalancesByOwner;
-
-    let exWrapper: ExchangeWrapper;
-    let dmyBalances: Balances;
-    let orderFactory: OrderFactory;
-
-    before(async () => {
-        [tokenRegistry, exchange] = await Promise.all([TokenRegistry.deployed(), Exchange.deployed()]);
-        exWrapper = new ExchangeWrapper(exchange);
-        const [repAddress, dgdAddress, zrxAddress] = await Promise.all([
-            tokenRegistry.getTokenAddressBySymbol('REP'),
-            tokenRegistry.getTokenAddressBySymbol('DGD'),
-            tokenRegistry.getTokenAddressBySymbol('ZRX'),
-        ]);
-
-        const defaultOrderParams = {
-            exchangeContractAddress: Exchange.address,
-            maker,
-            feeRecipient,
-            makerToken: repAddress,
-            takerToken: dgdAddress,
-            makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
-            takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18),
-            makerFee: ZeroEx.toBaseUnitAmount(new BigNumber(1), 18),
-            takerFee: ZeroEx.toBaseUnitAmount(new BigNumber(1), 18),
-        };
-        orderFactory = new OrderFactory(defaultOrderParams);
-
-        [rep, dgd, zrx] = await Promise.all([
-            DummyToken.at(repAddress),
-            DummyToken.at(dgdAddress),
-            DummyToken.at(zrxAddress),
-        ]);
-        dmyBalances = new Balances([rep, dgd, zrx], [maker, taker, feeRecipient]);
-        await Promise.all([
-            rep.approve(TokenTransferProxy.address, INIT_ALLOW, { from: maker }),
-            rep.approve(TokenTransferProxy.address, INIT_ALLOW, { from: taker }),
-            rep.setBalance(maker, INIT_BAL, { from: tokenOwner }),
-            rep.setBalance(taker, INIT_BAL, { from: tokenOwner }),
-            dgd.approve(TokenTransferProxy.address, INIT_ALLOW, { from: maker }),
-            dgd.approve(TokenTransferProxy.address, INIT_ALLOW, { from: taker }),
-            dgd.setBalance(maker, INIT_BAL, { from: tokenOwner }),
-            dgd.setBalance(taker, INIT_BAL, { from: tokenOwner }),
-            zrx.approve(TokenTransferProxy.address, INIT_ALLOW, { from: maker }),
-            zrx.approve(TokenTransferProxy.address, INIT_ALLOW, { from: taker }),
-            zrx.setBalance(maker, INIT_BAL, { from: tokenOwner }),
-            zrx.setBalance(taker, INIT_BAL, { from: tokenOwner }),
-        ]);
-    });
-
-    describe('fillOrKillOrder', () => {
-        beforeEach(async () => {
-            balances = await dmyBalances.getAsync();
-        });
-
-        it('should transfer the correct amounts', async () => {
-            const order = await orderFactory.newSignedOrderAsync({
-                makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
-                takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18),
-            });
-            const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
-            await exWrapper.fillOrKillOrderAsync(order, taker, {
-                fillTakerTokenAmount,
-            });
-
-            const newBalances = await dmyBalances.getAsync();
-
-            const fillMakerTokenAmount = fillTakerTokenAmount
-                .times(order.params.makerTokenAmount)
-                .dividedToIntegerBy(order.params.takerTokenAmount);
-            const makerFee = order.params.makerFee
-                .times(fillMakerTokenAmount)
-                .dividedToIntegerBy(order.params.makerTokenAmount);
-            const takerFee = order.params.takerFee
-                .times(fillMakerTokenAmount)
-                .dividedToIntegerBy(order.params.makerTokenAmount);
-            expect(newBalances[maker][order.params.makerToken]).to.be.bignumber.equal(
-                balances[maker][order.params.makerToken].minus(fillMakerTokenAmount),
-            );
-            expect(newBalances[maker][order.params.takerToken]).to.be.bignumber.equal(
-                balances[maker][order.params.takerToken].add(fillTakerTokenAmount),
-            );
-            expect(newBalances[maker][zrx.address]).to.be.bignumber.equal(balances[maker][zrx.address].minus(makerFee));
-            expect(newBalances[taker][order.params.takerToken]).to.be.bignumber.equal(
-                balances[taker][order.params.takerToken].minus(fillTakerTokenAmount),
-            );
-            expect(newBalances[taker][order.params.makerToken]).to.be.bignumber.equal(
-                balances[taker][order.params.makerToken].add(fillMakerTokenAmount),
-            );
-            expect(newBalances[taker][zrx.address]).to.be.bignumber.equal(balances[taker][zrx.address].minus(takerFee));
-            expect(newBalances[feeRecipient][zrx.address]).to.be.bignumber.equal(
-                balances[feeRecipient][zrx.address].add(makerFee.add(takerFee)),
-            );
-        });
-
-        it('should throw if an order is expired', async () => {
-            const order = await orderFactory.newSignedOrderAsync({
-                expirationTimestampInSec: new BigNumber(Math.floor((Date.now() - 10000) / 1000)),
-            });
-
-            return expect(exWrapper.fillOrKillOrderAsync(order, taker)).to.be.rejectedWith(constants.REVERT);
-        });
-
-        it('should throw if entire fillTakerTokenAmount not filled', async () => {
-            const order = await orderFactory.newSignedOrderAsync();
-
-            const from = taker;
-            await exWrapper.fillOrderAsync(order, from, {
-                fillTakerTokenAmount: order.params.takerTokenAmount.div(2),
-            });
-
-            return expect(exWrapper.fillOrKillOrderAsync(order, taker)).to.be.rejectedWith(constants.REVERT);
-        });
-    });
-
-    describe('batch functions', () => {
-        let orders: Order[];
-        beforeEach(async () => {
-            orders = await Promise.all([
-                orderFactory.newSignedOrderAsync(),
-                orderFactory.newSignedOrderAsync(),
-                orderFactory.newSignedOrderAsync(),
-            ]);
-            balances = await dmyBalances.getAsync();
-        });
-
-        describe('batchFillOrders', () => {
-            it('should transfer the correct amounts', async () => {
-                const fillTakerTokenAmounts: BigNumber[] = [];
-                const makerToken = rep.address;
-                const takerToken = dgd.address;
-                orders.forEach(order => {
-                    const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
-                    const fillMakerTokenAmount = fillTakerTokenAmount
-                        .times(order.params.makerTokenAmount)
-                        .dividedToIntegerBy(order.params.takerTokenAmount);
-                    const makerFee = order.params.makerFee
-                        .times(fillMakerTokenAmount)
-                        .dividedToIntegerBy(order.params.makerTokenAmount);
-                    const takerFee = order.params.takerFee
-                        .times(fillMakerTokenAmount)
-                        .dividedToIntegerBy(order.params.makerTokenAmount);
-                    fillTakerTokenAmounts.push(fillTakerTokenAmount);
-                    balances[maker][makerToken] = balances[maker][makerToken].minus(fillMakerTokenAmount);
-                    balances[maker][takerToken] = balances[maker][takerToken].add(fillTakerTokenAmount);
-                    balances[maker][zrx.address] = balances[maker][zrx.address].minus(makerFee);
-                    balances[taker][makerToken] = balances[taker][makerToken].add(fillMakerTokenAmount);
-                    balances[taker][takerToken] = balances[taker][takerToken].minus(fillTakerTokenAmount);
-                    balances[taker][zrx.address] = balances[taker][zrx.address].minus(takerFee);
-                    balances[feeRecipient][zrx.address] = balances[feeRecipient][zrx.address].add(
-                        makerFee.add(takerFee),
-                    );
-                });
-
-                await exWrapper.batchFillOrdersAsync(orders, taker, {
-                    fillTakerTokenAmounts,
-                });
-
-                const newBalances = await dmyBalances.getAsync();
-                expect(newBalances).to.be.deep.equal(balances);
-            });
-        });
-
-        describe('batchFillOrKillOrders', () => {
-            it('should transfer the correct amounts', async () => {
-                const fillTakerTokenAmounts: BigNumber[] = [];
-                const makerToken = rep.address;
-                const takerToken = dgd.address;
-                orders.forEach(order => {
-                    const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
-                    const fillMakerTokenAmount = fillTakerTokenAmount
-                        .times(order.params.makerTokenAmount)
-                        .dividedToIntegerBy(order.params.takerTokenAmount);
-                    const makerFee = order.params.makerFee
-                        .times(fillMakerTokenAmount)
-                        .dividedToIntegerBy(order.params.makerTokenAmount);
-                    const takerFee = order.params.takerFee
-                        .times(fillMakerTokenAmount)
-                        .dividedToIntegerBy(order.params.makerTokenAmount);
-                    fillTakerTokenAmounts.push(fillTakerTokenAmount);
-                    balances[maker][makerToken] = balances[maker][makerToken].minus(fillMakerTokenAmount);
-                    balances[maker][takerToken] = balances[maker][takerToken].add(fillTakerTokenAmount);
-                    balances[maker][zrx.address] = balances[maker][zrx.address].minus(makerFee);
-                    balances[taker][makerToken] = balances[taker][makerToken].add(fillMakerTokenAmount);
-                    balances[taker][takerToken] = balances[taker][takerToken].minus(fillTakerTokenAmount);
-                    balances[taker][zrx.address] = balances[taker][zrx.address].minus(takerFee);
-                    balances[feeRecipient][zrx.address] = balances[feeRecipient][zrx.address].add(
-                        makerFee.add(takerFee),
-                    );
-                });
-
-                await exWrapper.batchFillOrKillOrdersAsync(orders, taker, {
-                    fillTakerTokenAmounts,
-                });
-
-                const newBalances = await dmyBalances.getAsync();
-                expect(newBalances).to.be.deep.equal(balances);
-            });
-
-            it('should throw if a single order does not fill the expected amount', async () => {
-                const fillTakerTokenAmounts: BigNumber[] = [];
-                orders.forEach(order => {
-                    const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
-                    fillTakerTokenAmounts.push(fillTakerTokenAmount);
-                });
-
-                await exWrapper.fillOrKillOrderAsync(orders[0], taker);
-
-                return expect(
-                    exWrapper.batchFillOrKillOrdersAsync(orders, taker, {
-                        fillTakerTokenAmounts,
-                    }),
-                ).to.be.rejectedWith(constants.REVERT);
-            });
-        });
-
-        describe('fillOrdersUpTo', () => {
-            it('should stop when the entire fillTakerTokenAmount is filled', async () => {
-                const fillTakerTokenAmount = orders[0].params.takerTokenAmount.plus(
-                    orders[1].params.takerTokenAmount.div(2),
-                );
-                await exWrapper.fillOrdersUpToAsync(orders, taker, {
-                    fillTakerTokenAmount,
-                });
-
-                const newBalances = await dmyBalances.getAsync();
-
-                const fillMakerTokenAmount = orders[0].params.makerTokenAmount.add(
-                    orders[1].params.makerTokenAmount.dividedToIntegerBy(2),
-                );
-                const makerFee = orders[0].params.makerFee.add(orders[1].params.makerFee.dividedToIntegerBy(2));
-                const takerFee = orders[0].params.takerFee.add(orders[1].params.takerFee.dividedToIntegerBy(2));
-                expect(newBalances[maker][orders[0].params.makerToken]).to.be.bignumber.equal(
-                    balances[maker][orders[0].params.makerToken].minus(fillMakerTokenAmount),
-                );
-                expect(newBalances[maker][orders[0].params.takerToken]).to.be.bignumber.equal(
-                    balances[maker][orders[0].params.takerToken].add(fillTakerTokenAmount),
-                );
-                expect(newBalances[maker][zrx.address]).to.be.bignumber.equal(
-                    balances[maker][zrx.address].minus(makerFee),
-                );
-                expect(newBalances[taker][orders[0].params.takerToken]).to.be.bignumber.equal(
-                    balances[taker][orders[0].params.takerToken].minus(fillTakerTokenAmount),
-                );
-                expect(newBalances[taker][orders[0].params.makerToken]).to.be.bignumber.equal(
-                    balances[taker][orders[0].params.makerToken].add(fillMakerTokenAmount),
-                );
-                expect(newBalances[taker][zrx.address]).to.be.bignumber.equal(
-                    balances[taker][zrx.address].minus(takerFee),
-                );
-                expect(newBalances[feeRecipient][zrx.address]).to.be.bignumber.equal(
-                    balances[feeRecipient][zrx.address].add(makerFee.add(takerFee)),
-                );
-            });
-
-            it('should fill all orders if cannot fill entire fillTakerTokenAmount', async () => {
-                const fillTakerTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(100000), 18);
-                orders.forEach(order => {
-                    balances[maker][order.params.makerToken] = balances[maker][order.params.makerToken].minus(
-                        order.params.makerTokenAmount,
-                    );
-                    balances[maker][order.params.takerToken] = balances[maker][order.params.takerToken].add(
-                        order.params.takerTokenAmount,
-                    );
-                    balances[maker][zrx.address] = balances[maker][zrx.address].minus(order.params.makerFee);
-                    balances[taker][order.params.makerToken] = balances[taker][order.params.makerToken].add(
-                        order.params.makerTokenAmount,
-                    );
-                    balances[taker][order.params.takerToken] = balances[taker][order.params.takerToken].minus(
-                        order.params.takerTokenAmount,
-                    );
-                    balances[taker][zrx.address] = balances[taker][zrx.address].minus(order.params.takerFee);
-                    balances[feeRecipient][zrx.address] = balances[feeRecipient][zrx.address].add(
-                        order.params.makerFee.add(order.params.takerFee),
-                    );
-                });
-                await exWrapper.fillOrdersUpToAsync(orders, taker, {
-                    fillTakerTokenAmount,
-                });
-
-                const newBalances = await dmyBalances.getAsync();
-                expect(newBalances).to.be.deep.equal(balances);
-            });
-
-            it('should throw when an order does not use the same takerToken', async () => {
-                orders = await Promise.all([
-                    orderFactory.newSignedOrderAsync(),
-                    orderFactory.newSignedOrderAsync({ takerToken: zrx.address }),
-                    orderFactory.newSignedOrderAsync(),
-                ]);
-
-                return expect(
-                    exWrapper.fillOrdersUpToAsync(orders, taker, {
-                        fillTakerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(1000), 18),
-                    }),
-                ).to.be.rejectedWith(constants.REVERT);
-            });
-        });
-
-        describe('batchCancelOrders', () => {
-            it('should be able to cancel multiple orders', async () => {
-                const cancelTakerTokenAmounts = _.map(orders, order => order.params.takerTokenAmount);
-                await exWrapper.batchCancelOrdersAsync(orders, maker, {
-                    cancelTakerTokenAmounts,
-                });
-
-                await exWrapper.batchFillOrdersAsync(orders, taker, {
-                    fillTakerTokenAmounts: cancelTakerTokenAmounts,
-                });
-                const newBalances = await dmyBalances.getAsync();
-                expect(balances).to.be.deep.equal(newBalances);
-            });
-        });
-    });
+	const maker = accounts[0];
+	const tokenOwner = accounts[0];
+	const taker = accounts[1] || accounts[accounts.length - 1];
+	const feeRecipient = accounts[2] || accounts[accounts.length - 1];
+
+	const INIT_BAL = ZeroEx.toBaseUnitAmount(new BigNumber(10000), 18);
+	const INIT_ALLOW = ZeroEx.toBaseUnitAmount(new BigNumber(10000), 18);
+
+	let rep: ContractInstance;
+	let dgd: ContractInstance;
+	let zrx: ContractInstance;
+	let exchange: ContractInstance;
+	let tokenRegistry: ContractInstance;
+
+	let balances: BalancesByOwner;
+
+	let exWrapper: ExchangeWrapper;
+	let dmyBalances: Balances;
+	let orderFactory: OrderFactory;
+
+	before(async () => {
+		[tokenRegistry, exchange] = await Promise.all([TokenRegistry.deployed(), Exchange.deployed()]);
+		exWrapper = new ExchangeWrapper(exchange);
+		const [repAddress, dgdAddress, zrxAddress] = await Promise.all([
+			tokenRegistry.getTokenAddressBySymbol('REP'),
+			tokenRegistry.getTokenAddressBySymbol('DGD'),
+			tokenRegistry.getTokenAddressBySymbol('ZRX'),
+		]);
+
+		const defaultOrderParams = {
+			exchangeContractAddress: Exchange.address,
+			maker,
+			feeRecipient,
+			makerToken: repAddress,
+			takerToken: dgdAddress,
+			makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
+			takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18),
+			makerFee: ZeroEx.toBaseUnitAmount(new BigNumber(1), 18),
+			takerFee: ZeroEx.toBaseUnitAmount(new BigNumber(1), 18),
+		};
+		orderFactory = new OrderFactory(defaultOrderParams);
+
+		[rep, dgd, zrx] = await Promise.all([
+			DummyToken.at(repAddress),
+			DummyToken.at(dgdAddress),
+			DummyToken.at(zrxAddress),
+		]);
+		dmyBalances = new Balances([rep, dgd, zrx], [maker, taker, feeRecipient]);
+		await Promise.all([
+			rep.approve(TokenTransferProxy.address, INIT_ALLOW, { from: maker }),
+			rep.approve(TokenTransferProxy.address, INIT_ALLOW, { from: taker }),
+			rep.setBalance(maker, INIT_BAL, { from: tokenOwner }),
+			rep.setBalance(taker, INIT_BAL, { from: tokenOwner }),
+			dgd.approve(TokenTransferProxy.address, INIT_ALLOW, { from: maker }),
+			dgd.approve(TokenTransferProxy.address, INIT_ALLOW, { from: taker }),
+			dgd.setBalance(maker, INIT_BAL, { from: tokenOwner }),
+			dgd.setBalance(taker, INIT_BAL, { from: tokenOwner }),
+			zrx.approve(TokenTransferProxy.address, INIT_ALLOW, { from: maker }),
+			zrx.approve(TokenTransferProxy.address, INIT_ALLOW, { from: taker }),
+			zrx.setBalance(maker, INIT_BAL, { from: tokenOwner }),
+			zrx.setBalance(taker, INIT_BAL, { from: tokenOwner }),
+		]);
+	});
+
+	describe('fillOrKillOrder', () => {
+		beforeEach(async () => {
+			balances = await dmyBalances.getAsync();
+		});
+
+		it('should transfer the correct amounts', async () => {
+			const order = await orderFactory.newSignedOrderAsync({
+				makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
+				takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18),
+			});
+			const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
+			await exWrapper.fillOrKillOrderAsync(order, taker, {
+				fillTakerTokenAmount,
+			});
+
+			const newBalances = await dmyBalances.getAsync();
+
+			const fillMakerTokenAmount = fillTakerTokenAmount
+				.times(order.params.makerTokenAmount)
+				.dividedToIntegerBy(order.params.takerTokenAmount);
+			const makerFee = order.params.makerFee
+				.times(fillMakerTokenAmount)
+				.dividedToIntegerBy(order.params.makerTokenAmount);
+			const takerFee = order.params.takerFee
+				.times(fillMakerTokenAmount)
+				.dividedToIntegerBy(order.params.makerTokenAmount);
+			expect(newBalances[maker][order.params.makerToken]).to.be.bignumber.equal(
+				balances[maker][order.params.makerToken].minus(fillMakerTokenAmount),
+			);
+			expect(newBalances[maker][order.params.takerToken]).to.be.bignumber.equal(
+				balances[maker][order.params.takerToken].add(fillTakerTokenAmount),
+			);
+			expect(newBalances[maker][zrx.address]).to.be.bignumber.equal(balances[maker][zrx.address].minus(makerFee));
+			expect(newBalances[taker][order.params.takerToken]).to.be.bignumber.equal(
+				balances[taker][order.params.takerToken].minus(fillTakerTokenAmount),
+			);
+			expect(newBalances[taker][order.params.makerToken]).to.be.bignumber.equal(
+				balances[taker][order.params.makerToken].add(fillMakerTokenAmount),
+			);
+			expect(newBalances[taker][zrx.address]).to.be.bignumber.equal(balances[taker][zrx.address].minus(takerFee));
+			expect(newBalances[feeRecipient][zrx.address]).to.be.bignumber.equal(
+				balances[feeRecipient][zrx.address].add(makerFee.add(takerFee)),
+			);
+		});
+
+		it('should throw if an order is expired', async () => {
+			const order = await orderFactory.newSignedOrderAsync({
+				expirationTimestampInSec: new BigNumber(Math.floor((Date.now() - 10000) / 1000)),
+			});
+
+			return expect(exWrapper.fillOrKillOrderAsync(order, taker)).to.be.rejectedWith(constants.REVERT);
+		});
+
+		it('should throw if entire fillTakerTokenAmount not filled', async () => {
+			const order = await orderFactory.newSignedOrderAsync();
+
+			const from = taker;
+			await exWrapper.fillOrderAsync(order, from, {
+				fillTakerTokenAmount: order.params.takerTokenAmount.div(2),
+			});
+
+			return expect(exWrapper.fillOrKillOrderAsync(order, taker)).to.be.rejectedWith(constants.REVERT);
+		});
+	});
+
+	describe('batch functions', () => {
+		let orders: Order[];
+		beforeEach(async () => {
+			orders = await Promise.all([
+				orderFactory.newSignedOrderAsync(),
+				orderFactory.newSignedOrderAsync(),
+				orderFactory.newSignedOrderAsync(),
+			]);
+			balances = await dmyBalances.getAsync();
+		});
+
+		describe('batchFillOrders', () => {
+			it('should transfer the correct amounts', async () => {
+				const fillTakerTokenAmounts: BigNumber[] = [];
+				const makerToken = rep.address;
+				const takerToken = dgd.address;
+				orders.forEach(order => {
+					const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
+					const fillMakerTokenAmount = fillTakerTokenAmount
+						.times(order.params.makerTokenAmount)
+						.dividedToIntegerBy(order.params.takerTokenAmount);
+					const makerFee = order.params.makerFee
+						.times(fillMakerTokenAmount)
+						.dividedToIntegerBy(order.params.makerTokenAmount);
+					const takerFee = order.params.takerFee
+						.times(fillMakerTokenAmount)
+						.dividedToIntegerBy(order.params.makerTokenAmount);
+					fillTakerTokenAmounts.push(fillTakerTokenAmount);
+					balances[maker][makerToken] = balances[maker][makerToken].minus(fillMakerTokenAmount);
+					balances[maker][takerToken] = balances[maker][takerToken].add(fillTakerTokenAmount);
+					balances[maker][zrx.address] = balances[maker][zrx.address].minus(makerFee);
+					balances[taker][makerToken] = balances[taker][makerToken].add(fillMakerTokenAmount);
+					balances[taker][takerToken] = balances[taker][takerToken].minus(fillTakerTokenAmount);
+					balances[taker][zrx.address] = balances[taker][zrx.address].minus(takerFee);
+					balances[feeRecipient][zrx.address] = balances[feeRecipient][zrx.address].add(
+						makerFee.add(takerFee),
+					);
+				});
+
+				await exWrapper.batchFillOrdersAsync(orders, taker, {
+					fillTakerTokenAmounts,
+				});
+
+				const newBalances = await dmyBalances.getAsync();
+				expect(newBalances).to.be.deep.equal(balances);
+			});
+		});
+
+		describe('batchFillOrKillOrders', () => {
+			it('should transfer the correct amounts', async () => {
+				const fillTakerTokenAmounts: BigNumber[] = [];
+				const makerToken = rep.address;
+				const takerToken = dgd.address;
+				orders.forEach(order => {
+					const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
+					const fillMakerTokenAmount = fillTakerTokenAmount
+						.times(order.params.makerTokenAmount)
+						.dividedToIntegerBy(order.params.takerTokenAmount);
+					const makerFee = order.params.makerFee
+						.times(fillMakerTokenAmount)
+						.dividedToIntegerBy(order.params.makerTokenAmount);
+					const takerFee = order.params.takerFee
+						.times(fillMakerTokenAmount)
+						.dividedToIntegerBy(order.params.makerTokenAmount);
+					fillTakerTokenAmounts.push(fillTakerTokenAmount);
+					balances[maker][makerToken] = balances[maker][makerToken].minus(fillMakerTokenAmount);
+					balances[maker][takerToken] = balances[maker][takerToken].add(fillTakerTokenAmount);
+					balances[maker][zrx.address] = balances[maker][zrx.address].minus(makerFee);
+					balances[taker][makerToken] = balances[taker][makerToken].add(fillMakerTokenAmount);
+					balances[taker][takerToken] = balances[taker][takerToken].minus(fillTakerTokenAmount);
+					balances[taker][zrx.address] = balances[taker][zrx.address].minus(takerFee);
+					balances[feeRecipient][zrx.address] = balances[feeRecipient][zrx.address].add(
+						makerFee.add(takerFee),
+					);
+				});
+
+				await exWrapper.batchFillOrKillOrdersAsync(orders, taker, {
+					fillTakerTokenAmounts,
+				});
+
+				const newBalances = await dmyBalances.getAsync();
+				expect(newBalances).to.be.deep.equal(balances);
+			});
+
+			it('should throw if a single order does not fill the expected amount', async () => {
+				const fillTakerTokenAmounts: BigNumber[] = [];
+				orders.forEach(order => {
+					const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
+					fillTakerTokenAmounts.push(fillTakerTokenAmount);
+				});
+
+				await exWrapper.fillOrKillOrderAsync(orders[0], taker);
+
+				return expect(
+					exWrapper.batchFillOrKillOrdersAsync(orders, taker, {
+						fillTakerTokenAmounts,
+					}),
+				).to.be.rejectedWith(constants.REVERT);
+			});
+		});
+
+		describe('fillOrdersUpTo', () => {
+			it('should stop when the entire fillTakerTokenAmount is filled', async () => {
+				const fillTakerTokenAmount = orders[0].params.takerTokenAmount.plus(
+					orders[1].params.takerTokenAmount.div(2),
+				);
+				await exWrapper.fillOrdersUpToAsync(orders, taker, {
+					fillTakerTokenAmount,
+				});
+
+				const newBalances = await dmyBalances.getAsync();
+
+				const fillMakerTokenAmount = orders[0].params.makerTokenAmount.add(
+					orders[1].params.makerTokenAmount.dividedToIntegerBy(2),
+				);
+				const makerFee = orders[0].params.makerFee.add(orders[1].params.makerFee.dividedToIntegerBy(2));
+				const takerFee = orders[0].params.takerFee.add(orders[1].params.takerFee.dividedToIntegerBy(2));
+				expect(newBalances[maker][orders[0].params.makerToken]).to.be.bignumber.equal(
+					balances[maker][orders[0].params.makerToken].minus(fillMakerTokenAmount),
+				);
+				expect(newBalances[maker][orders[0].params.takerToken]).to.be.bignumber.equal(
+					balances[maker][orders[0].params.takerToken].add(fillTakerTokenAmount),
+				);
+				expect(newBalances[maker][zrx.address]).to.be.bignumber.equal(
+					balances[maker][zrx.address].minus(makerFee),
+				);
+				expect(newBalances[taker][orders[0].params.takerToken]).to.be.bignumber.equal(
+					balances[taker][orders[0].params.takerToken].minus(fillTakerTokenAmount),
+				);
+				expect(newBalances[taker][orders[0].params.makerToken]).to.be.bignumber.equal(
+					balances[taker][orders[0].params.makerToken].add(fillMakerTokenAmount),
+				);
+				expect(newBalances[taker][zrx.address]).to.be.bignumber.equal(
+					balances[taker][zrx.address].minus(takerFee),
+				);
+				expect(newBalances[feeRecipient][zrx.address]).to.be.bignumber.equal(
+					balances[feeRecipient][zrx.address].add(makerFee.add(takerFee)),
+				);
+			});
+
+			it('should fill all orders if cannot fill entire fillTakerTokenAmount', async () => {
+				const fillTakerTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(100000), 18);
+				orders.forEach(order => {
+					balances[maker][order.params.makerToken] = balances[maker][order.params.makerToken].minus(
+						order.params.makerTokenAmount,
+					);
+					balances[maker][order.params.takerToken] = balances[maker][order.params.takerToken].add(
+						order.params.takerTokenAmount,
+					);
+					balances[maker][zrx.address] = balances[maker][zrx.address].minus(order.params.makerFee);
+					balances[taker][order.params.makerToken] = balances[taker][order.params.makerToken].add(
+						order.params.makerTokenAmount,
+					);
+					balances[taker][order.params.takerToken] = balances[taker][order.params.takerToken].minus(
+						order.params.takerTokenAmount,
+					);
+					balances[taker][zrx.address] = balances[taker][zrx.address].minus(order.params.takerFee);
+					balances[feeRecipient][zrx.address] = balances[feeRecipient][zrx.address].add(
+						order.params.makerFee.add(order.params.takerFee),
+					);
+				});
+				await exWrapper.fillOrdersUpToAsync(orders, taker, {
+					fillTakerTokenAmount,
+				});
+
+				const newBalances = await dmyBalances.getAsync();
+				expect(newBalances).to.be.deep.equal(balances);
+			});
+
+			it('should throw when an order does not use the same takerToken', async () => {
+				orders = await Promise.all([
+					orderFactory.newSignedOrderAsync(),
+					orderFactory.newSignedOrderAsync({ takerToken: zrx.address }),
+					orderFactory.newSignedOrderAsync(),
+				]);
+
+				return expect(
+					exWrapper.fillOrdersUpToAsync(orders, taker, {
+						fillTakerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(1000), 18),
+					}),
+				).to.be.rejectedWith(constants.REVERT);
+			});
+		});
+
+		describe('batchCancelOrders', () => {
+			it('should be able to cancel multiple orders', async () => {
+				const cancelTakerTokenAmounts = _.map(orders, order => order.params.takerTokenAmount);
+				await exWrapper.batchCancelOrdersAsync(orders, maker, {
+					cancelTakerTokenAmounts,
+				});
+
+				await exWrapper.batchFillOrdersAsync(orders, taker, {
+					fillTakerTokenAmounts: cancelTakerTokenAmounts,
+				});
+				const newBalances = await dmyBalances.getAsync();
+				expect(balances).to.be.deep.equal(newBalances);
+			});
+		});
+	});
 });
diff --git a/packages/contracts/test/ts/multi_sig_with_time_lock.ts b/packages/contracts/test/ts/multi_sig_with_time_lock.ts
index ea939a758..fa2028437 100644
--- a/packages/contracts/test/ts/multi_sig_with_time_lock.ts
+++ b/packages/contracts/test/ts/multi_sig_with_time_lock.ts
@@ -23,93 +23,93 @@ const expect = chai.expect;
 const web3: Web3 = (global as any).web3;
 
 contract('MultiSigWalletWithTimeLock', (accounts: string[]) => {
-    const owners = [accounts[0], accounts[1]];
-    const SECONDS_TIME_LOCKED = 10000;
-
-    let multiSig: ContractInstance;
-    let multiSigWrapper: MultiSigWrapper;
-    let txId: number;
-    let initialSecondsTimeLocked: number;
-    let rpc: RPC;
-
-    before(async () => {
-        multiSig = await MultiSigWalletWithTimeLock.deployed();
-        multiSigWrapper = new MultiSigWrapper(multiSig);
-
-        const secondsTimeLocked = await multiSig.secondsTimeLocked.call();
-        initialSecondsTimeLocked = secondsTimeLocked.toNumber();
-        const rpcUrl = `http://${truffleConf.networks.development.host}:${truffleConf.networks.development.port}`;
-        rpc = new RPC(rpcUrl);
-    });
-
-    describe('changeTimeLock', () => {
-        it('should throw when not called by wallet', async () => {
-            return expect(multiSig.changeTimeLock(SECONDS_TIME_LOCKED, { from: owners[0] })).to.be.rejectedWith(
-                constants.REVERT,
-            );
-        });
-
-        it('should throw without enough confirmations', async () => {
-            const destination = multiSig.address;
-            const from = owners[0];
-            const dataParams = {
-                name: 'changeTimeLock',
-                abi: MULTI_SIG_ABI,
-                args: [SECONDS_TIME_LOCKED],
-            };
-            const subRes = await multiSigWrapper.submitTransactionAsync(destination, from, dataParams);
-
-            txId = subRes.logs[0].args.transactionId.toNumber();
-            return expect(multiSig.executeTransaction(txId)).to.be.rejectedWith(constants.REVERT);
-        });
-
-        it('should set confirmation time with enough confirmations', async () => {
-            const res = await multiSig.confirmTransaction(txId, { from: owners[1] });
-            expect(res.logs).to.have.length(2);
-            const blockNum = await promisify<number>(web3.eth.getBlockNumber)();
-            const blockInfo = await promisify<Web3.BlockWithoutTransactionData>(web3.eth.getBlock)(blockNum);
-            const timestamp = new BigNumber(blockInfo.timestamp);
-            const confirmationTimeBigNum = new BigNumber(await multiSig.confirmationTimes.call(txId));
-
-            expect(timestamp).to.be.bignumber.equal(confirmationTimeBigNum);
-        });
-
-        it('should be executable with enough confirmations and secondsTimeLocked of 0', async () => {
-            expect(initialSecondsTimeLocked).to.be.equal(0);
-
-            const res = await multiSig.executeTransaction(txId);
-            expect(res.logs).to.have.length(2);
-
-            const secondsTimeLocked = new BigNumber(await multiSig.secondsTimeLocked.call());
-            expect(secondsTimeLocked).to.be.bignumber.equal(SECONDS_TIME_LOCKED);
-        });
-
-        const newSecondsTimeLocked = 0;
-        it('should throw if it has enough confirmations but is not past the time lock', async () => {
-            const destination = multiSig.address;
-            const from = owners[0];
-            const dataParams = {
-                name: 'changeTimeLock',
-                abi: MULTI_SIG_ABI,
-                args: [newSecondsTimeLocked],
-            };
-            const subRes = await multiSigWrapper.submitTransactionAsync(destination, from, dataParams);
-
-            txId = subRes.logs[0].args.transactionId.toNumber();
-            const confRes = await multiSig.confirmTransaction(txId, {
-                from: owners[1],
-            });
-            expect(confRes.logs).to.have.length(2);
-
-            return expect(multiSig.executeTransaction(txId)).to.be.rejectedWith(constants.REVERT);
-        });
-
-        it('should execute if it has enough confirmations and is past the time lock', async () => {
-            await rpc.increaseTimeAsync(SECONDS_TIME_LOCKED);
-            await multiSig.executeTransaction(txId);
-
-            const secondsTimeLocked = new BigNumber(await multiSig.secondsTimeLocked.call());
-            expect(secondsTimeLocked).to.be.bignumber.equal(newSecondsTimeLocked);
-        });
-    });
+	const owners = [accounts[0], accounts[1]];
+	const SECONDS_TIME_LOCKED = 10000;
+
+	let multiSig: ContractInstance;
+	let multiSigWrapper: MultiSigWrapper;
+	let txId: number;
+	let initialSecondsTimeLocked: number;
+	let rpc: RPC;
+
+	before(async () => {
+		multiSig = await MultiSigWalletWithTimeLock.deployed();
+		multiSigWrapper = new MultiSigWrapper(multiSig);
+
+		const secondsTimeLocked = await multiSig.secondsTimeLocked.call();
+		initialSecondsTimeLocked = secondsTimeLocked.toNumber();
+		const rpcUrl = `http://${truffleConf.networks.development.host}:${truffleConf.networks.development.port}`;
+		rpc = new RPC(rpcUrl);
+	});
+
+	describe('changeTimeLock', () => {
+		it('should throw when not called by wallet', async () => {
+			return expect(multiSig.changeTimeLock(SECONDS_TIME_LOCKED, { from: owners[0] })).to.be.rejectedWith(
+				constants.REVERT,
+			);
+		});
+
+		it('should throw without enough confirmations', async () => {
+			const destination = multiSig.address;
+			const from = owners[0];
+			const dataParams = {
+				name: 'changeTimeLock',
+				abi: MULTI_SIG_ABI,
+				args: [SECONDS_TIME_LOCKED],
+			};
+			const subRes = await multiSigWrapper.submitTransactionAsync(destination, from, dataParams);
+
+			txId = subRes.logs[0].args.transactionId.toNumber();
+			return expect(multiSig.executeTransaction(txId)).to.be.rejectedWith(constants.REVERT);
+		});
+
+		it('should set confirmation time with enough confirmations', async () => {
+			const res = await multiSig.confirmTransaction(txId, { from: owners[1] });
+			expect(res.logs).to.have.length(2);
+			const blockNum = await promisify<number>(web3.eth.getBlockNumber)();
+			const blockInfo = await promisify<Web3.BlockWithoutTransactionData>(web3.eth.getBlock)(blockNum);
+			const timestamp = new BigNumber(blockInfo.timestamp);
+			const confirmationTimeBigNum = new BigNumber(await multiSig.confirmationTimes.call(txId));
+
+			expect(timestamp).to.be.bignumber.equal(confirmationTimeBigNum);
+		});
+
+		it('should be executable with enough confirmations and secondsTimeLocked of 0', async () => {
+			expect(initialSecondsTimeLocked).to.be.equal(0);
+
+			const res = await multiSig.executeTransaction(txId);
+			expect(res.logs).to.have.length(2);
+
+			const secondsTimeLocked = new BigNumber(await multiSig.secondsTimeLocked.call());
+			expect(secondsTimeLocked).to.be.bignumber.equal(SECONDS_TIME_LOCKED);
+		});
+
+		const newSecondsTimeLocked = 0;
+		it('should throw if it has enough confirmations but is not past the time lock', async () => {
+			const destination = multiSig.address;
+			const from = owners[0];
+			const dataParams = {
+				name: 'changeTimeLock',
+				abi: MULTI_SIG_ABI,
+				args: [newSecondsTimeLocked],
+			};
+			const subRes = await multiSigWrapper.submitTransactionAsync(destination, from, dataParams);
+
+			txId = subRes.logs[0].args.transactionId.toNumber();
+			const confRes = await multiSig.confirmTransaction(txId, {
+				from: owners[1],
+			});
+			expect(confRes.logs).to.have.length(2);
+
+			return expect(multiSig.executeTransaction(txId)).to.be.rejectedWith(constants.REVERT);
+		});
+
+		it('should execute if it has enough confirmations and is past the time lock', async () => {
+			await rpc.increaseTimeAsync(SECONDS_TIME_LOCKED);
+			await multiSig.executeTransaction(txId);
+
+			const secondsTimeLocked = new BigNumber(await multiSig.secondsTimeLocked.call());
+			expect(secondsTimeLocked).to.be.bignumber.equal(newSecondsTimeLocked);
+		});
+	});
 });
diff --git a/packages/contracts/test/ts/multi_sig_with_time_lock_except_remove_auth_addr.ts b/packages/contracts/test/ts/multi_sig_with_time_lock_except_remove_auth_addr.ts
index 62aa625fe..9211cb1b6 100644
--- a/packages/contracts/test/ts/multi_sig_with_time_lock_except_remove_auth_addr.ts
+++ b/packages/contracts/test/ts/multi_sig_with_time_lock_except_remove_auth_addr.ts
@@ -15,136 +15,136 @@ chaiSetup.configure();
 const expect = chai.expect;
 
 contract('MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress', (accounts: string[]) => {
-    const owners = [accounts[0], accounts[1]];
-    const requiredApprovals = 2;
-    const SECONDS_TIME_LOCKED = 1000000;
-
-    // initialize fake addresses
-    const authorizedAddress = `0x${crypto
-        .solSHA3([accounts[0]])
-        .slice(0, 20)
-        .toString('hex')}`;
-    const unauthorizedAddress = `0x${crypto
-        .solSHA3([accounts[1]])
-        .slice(0, 20)
-        .toString('hex')}`;
-
-    let tokenTransferProxy: ContractInstance;
-    let multiSig: ContractInstance;
-    let multiSigWrapper: MultiSigWrapper;
-
-    let validDestination: string;
-
-    beforeEach(async () => {
-        const initialOwner = accounts[0];
-        tokenTransferProxy = await TokenTransferProxy.new({ from: initialOwner });
-        await tokenTransferProxy.addAuthorizedAddress(authorizedAddress, {
-            from: initialOwner,
-        });
-        multiSig = await MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress.new(
-            owners,
-            requiredApprovals,
-            SECONDS_TIME_LOCKED,
-            tokenTransferProxy.address,
-        );
-        await tokenTransferProxy.transferOwnership(multiSig.address, {
-            from: initialOwner,
-        });
-        multiSigWrapper = new MultiSigWrapper(multiSig);
-        validDestination = tokenTransferProxy.address;
-    });
-
-    describe('isFunctionRemoveAuthorizedAddress', () => {
-        it('should throw if data is not for removeAuthorizedAddress', async () => {
-            const data = MultiSigWrapper.encodeFnArgs('addAuthorizedAddress', PROXY_ABI, [owners[0]]);
-            return expect(multiSig.isFunctionRemoveAuthorizedAddress.call(data)).to.be.rejectedWith(constants.REVERT);
-        });
-
-        it('should return true if data is for removeAuthorizedAddress', async () => {
-            const data = MultiSigWrapper.encodeFnArgs('removeAuthorizedAddress', PROXY_ABI, [owners[0]]);
-            const isFunctionRemoveAuthorizedAddress = await multiSig.isFunctionRemoveAuthorizedAddress.call(data);
-            expect(isFunctionRemoveAuthorizedAddress).to.be.true();
-        });
-    });
-
-    describe('executeRemoveAuthorizedAddress', () => {
-        it('should throw without the required confirmations', async () => {
-            const dataParams: TransactionDataParams = {
-                name: 'removeAuthorizedAddress',
-                abi: PROXY_ABI,
-                args: [authorizedAddress],
-            };
-            const res = await multiSigWrapper.submitTransactionAsync(validDestination, owners[0], dataParams);
-            const txId = res.logs[0].args.transactionId.toString();
-
-            return expect(multiSig.executeRemoveAuthorizedAddress(txId)).to.be.rejectedWith(constants.REVERT);
-        });
-
-        it('should throw if tx destination is not the tokenTransferProxy', async () => {
-            const invalidTokenTransferProxy = await TokenTransferProxy.new();
-            const invalidDestination = invalidTokenTransferProxy.address;
-            const dataParams: TransactionDataParams = {
-                name: 'removeAuthorizedAddress',
-                abi: PROXY_ABI,
-                args: [authorizedAddress],
-            };
-            const res = await multiSigWrapper.submitTransactionAsync(invalidDestination, owners[0], dataParams);
-            const txId = res.logs[0].args.transactionId.toString();
-            await multiSig.confirmTransaction(txId, { from: owners[1] });
-            const isConfirmed = await multiSig.isConfirmed.call(txId);
-            expect(isConfirmed).to.be.true();
-
-            return expect(multiSig.executeRemoveAuthorizedAddress(txId)).to.be.rejectedWith(constants.REVERT);
-        });
-
-        it('should throw if tx data is not for removeAuthorizedAddress', async () => {
-            const dataParams: TransactionDataParams = {
-                name: 'addAuthorizedAddress',
-                abi: PROXY_ABI,
-                args: [unauthorizedAddress],
-            };
-            const res = await multiSigWrapper.submitTransactionAsync(validDestination, owners[0], dataParams);
-            const txId = res.logs[0].args.transactionId.toString();
-            await multiSig.confirmTransaction(txId, { from: owners[1] });
-            const isConfirmed = await multiSig.isConfirmed.call(txId);
-            expect(isConfirmed).to.be.true();
-
-            return expect(multiSig.executeRemoveAuthorizedAddress(txId)).to.be.rejectedWith(constants.REVERT);
-        });
-
-        it('should execute removeAuthorizedAddress for valid tokenTransferProxy if fully confirmed', async () => {
-            const dataParams: TransactionDataParams = {
-                name: 'removeAuthorizedAddress',
-                abi: PROXY_ABI,
-                args: [authorizedAddress],
-            };
-            const res = await multiSigWrapper.submitTransactionAsync(validDestination, owners[0], dataParams);
-            const txId = res.logs[0].args.transactionId.toString();
-            await multiSig.confirmTransaction(txId, { from: owners[1] });
-            const isConfirmed = await multiSig.isConfirmed.call(txId);
-            expect(isConfirmed).to.be.true();
-            await multiSig.executeRemoveAuthorizedAddress(txId);
-
-            const isAuthorized = await tokenTransferProxy.authorized.call(authorizedAddress);
-            expect(isAuthorized).to.be.false();
-        });
-
-        it('should throw if already executed', async () => {
-            const dataParams: TransactionDataParams = {
-                name: 'removeAuthorizedAddress',
-                abi: PROXY_ABI,
-                args: [authorizedAddress],
-            };
-            const res = await multiSigWrapper.submitTransactionAsync(validDestination, owners[0], dataParams);
-            const txId = res.logs[0].args.transactionId.toString();
-            await multiSig.confirmTransaction(txId, { from: owners[1] });
-            const isConfirmed = await multiSig.isConfirmed.call(txId);
-            expect(isConfirmed).to.be.true();
-            await multiSig.executeRemoveAuthorizedAddress(txId);
-            const tx = await multiSig.transactions.call(txId);
-            const isExecuted = tx[3];
-            expect(isExecuted).to.be.true();
-            return expect(multiSig.executeRemoveAuthorizedAddress(txId)).to.be.rejectedWith(constants.REVERT);
-        });
-    });
+	const owners = [accounts[0], accounts[1]];
+	const requiredApprovals = 2;
+	const SECONDS_TIME_LOCKED = 1000000;
+
+	// initialize fake addresses
+	const authorizedAddress = `0x${crypto
+		.solSHA3([accounts[0]])
+		.slice(0, 20)
+		.toString('hex')}`;
+	const unauthorizedAddress = `0x${crypto
+		.solSHA3([accounts[1]])
+		.slice(0, 20)
+		.toString('hex')}`;
+
+	let tokenTransferProxy: ContractInstance;
+	let multiSig: ContractInstance;
+	let multiSigWrapper: MultiSigWrapper;
+
+	let validDestination: string;
+
+	beforeEach(async () => {
+		const initialOwner = accounts[0];
+		tokenTransferProxy = await TokenTransferProxy.new({ from: initialOwner });
+		await tokenTransferProxy.addAuthorizedAddress(authorizedAddress, {
+			from: initialOwner,
+		});
+		multiSig = await MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress.new(
+			owners,
+			requiredApprovals,
+			SECONDS_TIME_LOCKED,
+			tokenTransferProxy.address,
+		);
+		await tokenTransferProxy.transferOwnership(multiSig.address, {
+			from: initialOwner,
+		});
+		multiSigWrapper = new MultiSigWrapper(multiSig);
+		validDestination = tokenTransferProxy.address;
+	});
+
+	describe('isFunctionRemoveAuthorizedAddress', () => {
+		it('should throw if data is not for removeAuthorizedAddress', async () => {
+			const data = MultiSigWrapper.encodeFnArgs('addAuthorizedAddress', PROXY_ABI, [owners[0]]);
+			return expect(multiSig.isFunctionRemoveAuthorizedAddress.call(data)).to.be.rejectedWith(constants.REVERT);
+		});
+
+		it('should return true if data is for removeAuthorizedAddress', async () => {
+			const data = MultiSigWrapper.encodeFnArgs('removeAuthorizedAddress', PROXY_ABI, [owners[0]]);
+			const isFunctionRemoveAuthorizedAddress = await multiSig.isFunctionRemoveAuthorizedAddress.call(data);
+			expect(isFunctionRemoveAuthorizedAddress).to.be.true();
+		});
+	});
+
+	describe('executeRemoveAuthorizedAddress', () => {
+		it('should throw without the required confirmations', async () => {
+			const dataParams: TransactionDataParams = {
+				name: 'removeAuthorizedAddress',
+				abi: PROXY_ABI,
+				args: [authorizedAddress],
+			};
+			const res = await multiSigWrapper.submitTransactionAsync(validDestination, owners[0], dataParams);
+			const txId = res.logs[0].args.transactionId.toString();
+
+			return expect(multiSig.executeRemoveAuthorizedAddress(txId)).to.be.rejectedWith(constants.REVERT);
+		});
+
+		it('should throw if tx destination is not the tokenTransferProxy', async () => {
+			const invalidTokenTransferProxy = await TokenTransferProxy.new();
+			const invalidDestination = invalidTokenTransferProxy.address;
+			const dataParams: TransactionDataParams = {
+				name: 'removeAuthorizedAddress',
+				abi: PROXY_ABI,
+				args: [authorizedAddress],
+			};
+			const res = await multiSigWrapper.submitTransactionAsync(invalidDestination, owners[0], dataParams);
+			const txId = res.logs[0].args.transactionId.toString();
+			await multiSig.confirmTransaction(txId, { from: owners[1] });
+			const isConfirmed = await multiSig.isConfirmed.call(txId);
+			expect(isConfirmed).to.be.true();
+
+			return expect(multiSig.executeRemoveAuthorizedAddress(txId)).to.be.rejectedWith(constants.REVERT);
+		});
+
+		it('should throw if tx data is not for removeAuthorizedAddress', async () => {
+			const dataParams: TransactionDataParams = {
+				name: 'addAuthorizedAddress',
+				abi: PROXY_ABI,
+				args: [unauthorizedAddress],
+			};
+			const res = await multiSigWrapper.submitTransactionAsync(validDestination, owners[0], dataParams);
+			const txId = res.logs[0].args.transactionId.toString();
+			await multiSig.confirmTransaction(txId, { from: owners[1] });
+			const isConfirmed = await multiSig.isConfirmed.call(txId);
+			expect(isConfirmed).to.be.true();
+
+			return expect(multiSig.executeRemoveAuthorizedAddress(txId)).to.be.rejectedWith(constants.REVERT);
+		});
+
+		it('should execute removeAuthorizedAddress for valid tokenTransferProxy if fully confirmed', async () => {
+			const dataParams: TransactionDataParams = {
+				name: 'removeAuthorizedAddress',
+				abi: PROXY_ABI,
+				args: [authorizedAddress],
+			};
+			const res = await multiSigWrapper.submitTransactionAsync(validDestination, owners[0], dataParams);
+			const txId = res.logs[0].args.transactionId.toString();
+			await multiSig.confirmTransaction(txId, { from: owners[1] });
+			const isConfirmed = await multiSig.isConfirmed.call(txId);
+			expect(isConfirmed).to.be.true();
+			await multiSig.executeRemoveAuthorizedAddress(txId);
+
+			const isAuthorized = await tokenTransferProxy.authorized.call(authorizedAddress);
+			expect(isAuthorized).to.be.false();
+		});
+
+		it('should throw if already executed', async () => {
+			const dataParams: TransactionDataParams = {
+				name: 'removeAuthorizedAddress',
+				abi: PROXY_ABI,
+				args: [authorizedAddress],
+			};
+			const res = await multiSigWrapper.submitTransactionAsync(validDestination, owners[0], dataParams);
+			const txId = res.logs[0].args.transactionId.toString();
+			await multiSig.confirmTransaction(txId, { from: owners[1] });
+			const isConfirmed = await multiSig.isConfirmed.call(txId);
+			expect(isConfirmed).to.be.true();
+			await multiSig.executeRemoveAuthorizedAddress(txId);
+			const tx = await multiSig.transactions.call(txId);
+			const isExecuted = tx[3];
+			expect(isExecuted).to.be.true();
+			return expect(multiSig.executeRemoveAuthorizedAddress(txId)).to.be.rejectedWith(constants.REVERT);
+		});
+	});
 });
diff --git a/packages/contracts/test/ts/token_registry.ts b/packages/contracts/test/ts/token_registry.ts
index d1c551565..fadb276da 100644
--- a/packages/contracts/test/ts/token_registry.ts
+++ b/packages/contracts/test/ts/token_registry.ts
@@ -15,220 +15,220 @@ chaiSetup.configure();
 const expect = chai.expect;
 
 contract('TokenRegistry', (accounts: string[]) => {
-    const owner = accounts[0];
-    const notOwner = accounts[1];
-
-    const tokenAddress1 = `0x${ethUtil.setLength(ethUtil.toBuffer('0x1'), 20, false).toString('hex')}`;
-    const tokenAddress2 = `0x${ethUtil.setLength(ethUtil.toBuffer('0x2'), 20, false).toString('hex')}`;
-
-    const token1 = {
-        address: tokenAddress1,
-        name: 'testToken1',
-        symbol: 'TT1',
-        decimals: 18,
-        ipfsHash: `0x${ethUtil.sha3('ipfs1').toString('hex')}`,
-        swarmHash: `0x${ethUtil.sha3('swarm1').toString('hex')}`,
-    };
-
-    const token2 = {
-        address: tokenAddress2,
-        name: 'testToken2',
-        symbol: 'TT2',
-        decimals: 18,
-        ipfsHash: `0x${ethUtil.sha3('ipfs2').toString('hex')}`,
-        swarmHash: `0x${ethUtil.sha3('swarm2').toString('hex')}`,
-    };
-
-    const nullToken = {
-        address: ZeroEx.NULL_ADDRESS,
-        name: '',
-        symbol: '',
-        decimals: 0,
-        ipfsHash: constants.NULL_BYTES,
-        swarmHash: constants.NULL_BYTES,
-    };
-
-    let tokenReg: ContractInstance;
-    let tokenRegWrapper: TokenRegWrapper;
-
-    beforeEach(async () => {
-        tokenReg = await TokenRegistry.new();
-        tokenRegWrapper = new TokenRegWrapper(tokenReg);
-    });
-
-    describe('addToken', () => {
-        it('should throw when not called by owner', async () => {
-            return expect(tokenRegWrapper.addTokenAsync(token1, notOwner)).to.be.rejectedWith(constants.REVERT);
-        });
-
-        it('should add token metadata when called by owner', async () => {
-            await tokenRegWrapper.addTokenAsync(token1, owner);
-            const tokenData = await tokenRegWrapper.getTokenMetaDataAsync(token1.address);
-            expect(tokenData).to.be.deep.equal(token1);
-        });
-
-        it('should throw if token already exists', async () => {
-            await tokenRegWrapper.addTokenAsync(token1, owner);
-
-            return expect(tokenRegWrapper.addTokenAsync(token1, owner)).to.be.rejectedWith(constants.REVERT);
-        });
-
-        it('should throw if token address is null', async () => {
-            return expect(tokenRegWrapper.addTokenAsync(nullToken, owner)).to.be.rejectedWith(constants.REVERT);
-        });
-
-        it('should throw if name already exists', async () => {
-            await tokenRegWrapper.addTokenAsync(token1, owner);
-            const duplicateNameToken = _.assign({}, token2, { name: token1.name });
-
-            return expect(tokenRegWrapper.addTokenAsync(duplicateNameToken, owner)).to.be.rejectedWith(
-                constants.REVERT,
-            );
-        });
-
-        it('should throw if symbol already exists', async () => {
-            await tokenRegWrapper.addTokenAsync(token1, owner);
-            const duplicateSymbolToken = _.assign({}, token2, {
-                symbol: token1.symbol,
-            });
-
-            return expect(tokenRegWrapper.addTokenAsync(duplicateSymbolToken, owner)).to.be.rejectedWith(
-                constants.REVERT,
-            );
-        });
-    });
-
-    describe('after addToken', () => {
-        beforeEach(async () => {
-            await tokenRegWrapper.addTokenAsync(token1, owner);
-        });
-
-        describe('getTokenByName', () => {
-            it('should return token metadata when given the token name', async () => {
-                const tokenData = await tokenRegWrapper.getTokenByNameAsync(token1.name);
-                expect(tokenData).to.be.deep.equal(token1);
-            });
-        });
-
-        describe('getTokenBySymbol', () => {
-            it('should return token metadata when given the token symbol', async () => {
-                const tokenData = await tokenRegWrapper.getTokenBySymbolAsync(token1.symbol);
-                expect(tokenData).to.be.deep.equal(token1);
-            });
-        });
-
-        describe('setTokenName', () => {
-            it('should throw when not called by owner', async () => {
-                return expect(
-                    tokenReg.setTokenName(token1.address, token2.name, { from: notOwner }),
-                ).to.be.rejectedWith(constants.REVERT);
-            });
-
-            it('should change the token name when called by owner', async () => {
-                const res = await tokenReg.setTokenName(token1.address, token2.name, {
-                    from: owner,
-                });
-                expect(res.logs).to.have.length(1);
-                const [newData, oldData] = await Promise.all([
-                    tokenRegWrapper.getTokenByNameAsync(token2.name),
-                    tokenRegWrapper.getTokenByNameAsync(token1.name),
-                ]);
-
-                const expectedNewData = _.assign({}, token1, { name: token2.name });
-                const expectedOldData = nullToken;
-                expect(newData).to.be.deep.equal(expectedNewData);
-                expect(oldData).to.be.deep.equal(expectedOldData);
-            });
-
-            it('should throw if the name already exists', async () => {
-                await tokenRegWrapper.addTokenAsync(token2, owner);
-
-                return expect(tokenReg.setTokenName(token1.address, token2.name, { from: owner })).to.be.rejectedWith(
-                    constants.REVERT,
-                );
-            });
-
-            it('should throw if token does not exist', async () => {
-                return expect(
-                    tokenReg.setTokenName(nullToken.address, token2.name, { from: owner }),
-                ).to.be.rejectedWith(constants.REVERT);
-            });
-        });
-
-        describe('setTokenSymbol', () => {
-            it('should throw when not called by owner', async () => {
-                return expect(
-                    tokenReg.setTokenSymbol(token1.address, token2.symbol, {
-                        from: notOwner,
-                    }),
-                ).to.be.rejectedWith(constants.REVERT);
-            });
-
-            it('should change the token symbol when called by owner', async () => {
-                const res = await tokenReg.setTokenSymbol(token1.address, token2.symbol, { from: owner });
-                expect(res.logs).to.have.length(1);
-                const [newData, oldData] = await Promise.all([
-                    tokenRegWrapper.getTokenBySymbolAsync(token2.symbol),
-                    tokenRegWrapper.getTokenBySymbolAsync(token1.symbol),
-                ]);
-
-                const expectedNewData = _.assign({}, token1, { symbol: token2.symbol });
-                const expectedOldData = nullToken;
-                expect(newData).to.be.deep.equal(expectedNewData);
-                expect(oldData).to.be.deep.equal(expectedOldData);
-            });
-
-            it('should throw if the symbol already exists', async () => {
-                await tokenRegWrapper.addTokenAsync(token2, owner);
-
-                return expect(
-                    tokenReg.setTokenSymbol(token1.address, token2.symbol, {
-                        from: owner,
-                    }),
-                ).to.be.rejectedWith(constants.REVERT);
-            });
-
-            it('should throw if token does not exist', async () => {
-                return expect(
-                    tokenReg.setTokenSymbol(nullToken.address, token2.symbol, {
-                        from: owner,
-                    }),
-                ).to.be.rejectedWith(constants.REVERT);
-            });
-        });
-
-        describe('removeToken', () => {
-            it('should throw if not called by owner', async () => {
-                const index = 0;
-                return expect(tokenReg.removeToken(token1.address, index, { from: notOwner })).to.be.rejectedWith(
-                    constants.REVERT,
-                );
-            });
-
-            it('should remove token metadata when called by owner', async () => {
-                const index = 0;
-                const res = await tokenReg.removeToken(token1.address, index, {
-                    from: owner,
-                });
-                expect(res.logs).to.have.length(1);
-                const tokenData = await tokenRegWrapper.getTokenMetaDataAsync(token1.address);
-                expect(tokenData).to.be.deep.equal(nullToken);
-            });
-
-            it('should throw if token does not exist', async () => {
-                const index = 0;
-                return expect(tokenReg.removeToken(nullToken.address, index, { from: owner })).to.be.rejectedWith(
-                    constants.REVERT,
-                );
-            });
-
-            it('should throw if token at given index does not match address', async () => {
-                await tokenRegWrapper.addTokenAsync(token2, owner);
-                const incorrectIndex = 0;
-                return expect(tokenReg.removeToken(token2.address, incorrectIndex, { from: owner })).to.be.rejectedWith(
-                    constants.REVERT,
-                );
-            });
-        });
-    });
+	const owner = accounts[0];
+	const notOwner = accounts[1];
+
+	const tokenAddress1 = `0x${ethUtil.setLength(ethUtil.toBuffer('0x1'), 20, false).toString('hex')}`;
+	const tokenAddress2 = `0x${ethUtil.setLength(ethUtil.toBuffer('0x2'), 20, false).toString('hex')}`;
+
+	const token1 = {
+		address: tokenAddress1,
+		name: 'testToken1',
+		symbol: 'TT1',
+		decimals: 18,
+		ipfsHash: `0x${ethUtil.sha3('ipfs1').toString('hex')}`,
+		swarmHash: `0x${ethUtil.sha3('swarm1').toString('hex')}`,
+	};
+
+	const token2 = {
+		address: tokenAddress2,
+		name: 'testToken2',
+		symbol: 'TT2',
+		decimals: 18,
+		ipfsHash: `0x${ethUtil.sha3('ipfs2').toString('hex')}`,
+		swarmHash: `0x${ethUtil.sha3('swarm2').toString('hex')}`,
+	};
+
+	const nullToken = {
+		address: ZeroEx.NULL_ADDRESS,
+		name: '',
+		symbol: '',
+		decimals: 0,
+		ipfsHash: constants.NULL_BYTES,
+		swarmHash: constants.NULL_BYTES,
+	};
+
+	let tokenReg: ContractInstance;
+	let tokenRegWrapper: TokenRegWrapper;
+
+	beforeEach(async () => {
+		tokenReg = await TokenRegistry.new();
+		tokenRegWrapper = new TokenRegWrapper(tokenReg);
+	});
+
+	describe('addToken', () => {
+		it('should throw when not called by owner', async () => {
+			return expect(tokenRegWrapper.addTokenAsync(token1, notOwner)).to.be.rejectedWith(constants.REVERT);
+		});
+
+		it('should add token metadata when called by owner', async () => {
+			await tokenRegWrapper.addTokenAsync(token1, owner);
+			const tokenData = await tokenRegWrapper.getTokenMetaDataAsync(token1.address);
+			expect(tokenData).to.be.deep.equal(token1);
+		});
+
+		it('should throw if token already exists', async () => {
+			await tokenRegWrapper.addTokenAsync(token1, owner);
+
+			return expect(tokenRegWrapper.addTokenAsync(token1, owner)).to.be.rejectedWith(constants.REVERT);
+		});
+
+		it('should throw if token address is null', async () => {
+			return expect(tokenRegWrapper.addTokenAsync(nullToken, owner)).to.be.rejectedWith(constants.REVERT);
+		});
+
+		it('should throw if name already exists', async () => {
+			await tokenRegWrapper.addTokenAsync(token1, owner);
+			const duplicateNameToken = _.assign({}, token2, { name: token1.name });
+
+			return expect(tokenRegWrapper.addTokenAsync(duplicateNameToken, owner)).to.be.rejectedWith(
+				constants.REVERT,
+			);
+		});
+
+		it('should throw if symbol already exists', async () => {
+			await tokenRegWrapper.addTokenAsync(token1, owner);
+			const duplicateSymbolToken = _.assign({}, token2, {
+				symbol: token1.symbol,
+			});
+
+			return expect(tokenRegWrapper.addTokenAsync(duplicateSymbolToken, owner)).to.be.rejectedWith(
+				constants.REVERT,
+			);
+		});
+	});
+
+	describe('after addToken', () => {
+		beforeEach(async () => {
+			await tokenRegWrapper.addTokenAsync(token1, owner);
+		});
+
+		describe('getTokenByName', () => {
+			it('should return token metadata when given the token name', async () => {
+				const tokenData = await tokenRegWrapper.getTokenByNameAsync(token1.name);
+				expect(tokenData).to.be.deep.equal(token1);
+			});
+		});
+
+		describe('getTokenBySymbol', () => {
+			it('should return token metadata when given the token symbol', async () => {
+				const tokenData = await tokenRegWrapper.getTokenBySymbolAsync(token1.symbol);
+				expect(tokenData).to.be.deep.equal(token1);
+			});
+		});
+
+		describe('setTokenName', () => {
+			it('should throw when not called by owner', async () => {
+				return expect(
+					tokenReg.setTokenName(token1.address, token2.name, { from: notOwner }),
+				).to.be.rejectedWith(constants.REVERT);
+			});
+
+			it('should change the token name when called by owner', async () => {
+				const res = await tokenReg.setTokenName(token1.address, token2.name, {
+					from: owner,
+				});
+				expect(res.logs).to.have.length(1);
+				const [newData, oldData] = await Promise.all([
+					tokenRegWrapper.getTokenByNameAsync(token2.name),
+					tokenRegWrapper.getTokenByNameAsync(token1.name),
+				]);
+
+				const expectedNewData = _.assign({}, token1, { name: token2.name });
+				const expectedOldData = nullToken;
+				expect(newData).to.be.deep.equal(expectedNewData);
+				expect(oldData).to.be.deep.equal(expectedOldData);
+			});
+
+			it('should throw if the name already exists', async () => {
+				await tokenRegWrapper.addTokenAsync(token2, owner);
+
+				return expect(tokenReg.setTokenName(token1.address, token2.name, { from: owner })).to.be.rejectedWith(
+					constants.REVERT,
+				);
+			});
+
+			it('should throw if token does not exist', async () => {
+				return expect(
+					tokenReg.setTokenName(nullToken.address, token2.name, { from: owner }),
+				).to.be.rejectedWith(constants.REVERT);
+			});
+		});
+
+		describe('setTokenSymbol', () => {
+			it('should throw when not called by owner', async () => {
+				return expect(
+					tokenReg.setTokenSymbol(token1.address, token2.symbol, {
+						from: notOwner,
+					}),
+				).to.be.rejectedWith(constants.REVERT);
+			});
+
+			it('should change the token symbol when called by owner', async () => {
+				const res = await tokenReg.setTokenSymbol(token1.address, token2.symbol, { from: owner });
+				expect(res.logs).to.have.length(1);
+				const [newData, oldData] = await Promise.all([
+					tokenRegWrapper.getTokenBySymbolAsync(token2.symbol),
+					tokenRegWrapper.getTokenBySymbolAsync(token1.symbol),
+				]);
+
+				const expectedNewData = _.assign({}, token1, { symbol: token2.symbol });
+				const expectedOldData = nullToken;
+				expect(newData).to.be.deep.equal(expectedNewData);
+				expect(oldData).to.be.deep.equal(expectedOldData);
+			});
+
+			it('should throw if the symbol already exists', async () => {
+				await tokenRegWrapper.addTokenAsync(token2, owner);
+
+				return expect(
+					tokenReg.setTokenSymbol(token1.address, token2.symbol, {
+						from: owner,
+					}),
+				).to.be.rejectedWith(constants.REVERT);
+			});
+
+			it('should throw if token does not exist', async () => {
+				return expect(
+					tokenReg.setTokenSymbol(nullToken.address, token2.symbol, {
+						from: owner,
+					}),
+				).to.be.rejectedWith(constants.REVERT);
+			});
+		});
+
+		describe('removeToken', () => {
+			it('should throw if not called by owner', async () => {
+				const index = 0;
+				return expect(tokenReg.removeToken(token1.address, index, { from: notOwner })).to.be.rejectedWith(
+					constants.REVERT,
+				);
+			});
+
+			it('should remove token metadata when called by owner', async () => {
+				const index = 0;
+				const res = await tokenReg.removeToken(token1.address, index, {
+					from: owner,
+				});
+				expect(res.logs).to.have.length(1);
+				const tokenData = await tokenRegWrapper.getTokenMetaDataAsync(token1.address);
+				expect(tokenData).to.be.deep.equal(nullToken);
+			});
+
+			it('should throw if token does not exist', async () => {
+				const index = 0;
+				return expect(tokenReg.removeToken(nullToken.address, index, { from: owner })).to.be.rejectedWith(
+					constants.REVERT,
+				);
+			});
+
+			it('should throw if token at given index does not match address', async () => {
+				await tokenRegWrapper.addTokenAsync(token2, owner);
+				const incorrectIndex = 0;
+				return expect(tokenReg.removeToken(token2.address, incorrectIndex, { from: owner })).to.be.rejectedWith(
+					constants.REVERT,
+				);
+			});
+		});
+	});
 });
diff --git a/packages/contracts/test/ts/token_transfer_proxy/auth.ts b/packages/contracts/test/ts/token_transfer_proxy/auth.ts
index 9ae0a8fc3..69a6c0ada 100644
--- a/packages/contracts/test/ts/token_transfer_proxy/auth.ts
+++ b/packages/contracts/test/ts/token_transfer_proxy/auth.ts
@@ -9,91 +9,91 @@ const expect = chai.expect;
 const TokenTransferProxy = artifacts.require('./db/TokenTransferProxy.sol');
 
 contract('TokenTransferProxy', (accounts: string[]) => {
-    const owner = accounts[0];
-    const notOwner = accounts[1];
+	const owner = accounts[0];
+	const notOwner = accounts[1];
 
-    let tokenTransferProxy: ContractInstance;
-    let authorized: string;
-    let notAuthorized = owner;
+	let tokenTransferProxy: ContractInstance;
+	let authorized: string;
+	let notAuthorized = owner;
 
-    before(async () => {
-        tokenTransferProxy = await TokenTransferProxy.deployed();
-    });
+	before(async () => {
+		tokenTransferProxy = await TokenTransferProxy.deployed();
+	});
 
-    describe('addAuthorizedAddress', () => {
-        it('should throw if not called by owner', async () => {
-            return expect(tokenTransferProxy.addAuthorizedAddress(notOwner, { from: notOwner })).to.be.rejectedWith(
-                constants.REVERT,
-            );
-        });
+	describe('addAuthorizedAddress', () => {
+		it('should throw if not called by owner', async () => {
+			return expect(tokenTransferProxy.addAuthorizedAddress(notOwner, { from: notOwner })).to.be.rejectedWith(
+				constants.REVERT,
+			);
+		});
 
-        it('should allow owner to add an authorized address', async () => {
-            await tokenTransferProxy.addAuthorizedAddress(notAuthorized, {
-                from: owner,
-            });
-            authorized = notAuthorized;
-            notAuthorized = null;
-            const isAuthorized = await tokenTransferProxy.authorized.call(authorized);
-            expect(isAuthorized).to.be.true();
-        });
+		it('should allow owner to add an authorized address', async () => {
+			await tokenTransferProxy.addAuthorizedAddress(notAuthorized, {
+				from: owner,
+			});
+			authorized = notAuthorized;
+			notAuthorized = null;
+			const isAuthorized = await tokenTransferProxy.authorized.call(authorized);
+			expect(isAuthorized).to.be.true();
+		});
 
-        it('should throw if owner attempts to authorize a duplicate address', async () => {
-            return expect(tokenTransferProxy.addAuthorizedAddress(authorized, { from: owner })).to.be.rejectedWith(
-                constants.REVERT,
-            );
-        });
-    });
+		it('should throw if owner attempts to authorize a duplicate address', async () => {
+			return expect(tokenTransferProxy.addAuthorizedAddress(authorized, { from: owner })).to.be.rejectedWith(
+				constants.REVERT,
+			);
+		});
+	});
 
-    describe('removeAuthorizedAddress', () => {
-        it('should throw if not called by owner', async () => {
-            return expect(
-                tokenTransferProxy.removeAuthorizedAddress(authorized, {
-                    from: notOwner,
-                }),
-            ).to.be.rejectedWith(constants.REVERT);
-        });
+	describe('removeAuthorizedAddress', () => {
+		it('should throw if not called by owner', async () => {
+			return expect(
+				tokenTransferProxy.removeAuthorizedAddress(authorized, {
+					from: notOwner,
+				}),
+			).to.be.rejectedWith(constants.REVERT);
+		});
 
-        it('should allow owner to remove an authorized address', async () => {
-            await tokenTransferProxy.removeAuthorizedAddress(authorized, {
-                from: owner,
-            });
-            notAuthorized = authorized;
-            authorized = null;
+		it('should allow owner to remove an authorized address', async () => {
+			await tokenTransferProxy.removeAuthorizedAddress(authorized, {
+				from: owner,
+			});
+			notAuthorized = authorized;
+			authorized = null;
 
-            const isAuthorized = await tokenTransferProxy.authorized.call(notAuthorized);
-            expect(isAuthorized).to.be.false();
-        });
+			const isAuthorized = await tokenTransferProxy.authorized.call(notAuthorized);
+			expect(isAuthorized).to.be.false();
+		});
 
-        it('should throw if owner attempts to remove an address that is not authorized', async () => {
-            return expect(
-                tokenTransferProxy.removeAuthorizedAddress(notAuthorized, {
-                    from: owner,
-                }),
-            ).to.be.rejectedWith(constants.REVERT);
-        });
-    });
+		it('should throw if owner attempts to remove an address that is not authorized', async () => {
+			return expect(
+				tokenTransferProxy.removeAuthorizedAddress(notAuthorized, {
+					from: owner,
+				}),
+			).to.be.rejectedWith(constants.REVERT);
+		});
+	});
 
-    describe('getAuthorizedAddresses', () => {
-        it('should return all authorized addresses', async () => {
-            const initial = await tokenTransferProxy.getAuthorizedAddresses();
-            expect(initial).to.have.length(1);
-            await tokenTransferProxy.addAuthorizedAddress(notAuthorized, {
-                from: owner,
-            });
+	describe('getAuthorizedAddresses', () => {
+		it('should return all authorized addresses', async () => {
+			const initial = await tokenTransferProxy.getAuthorizedAddresses();
+			expect(initial).to.have.length(1);
+			await tokenTransferProxy.addAuthorizedAddress(notAuthorized, {
+				from: owner,
+			});
 
-            authorized = notAuthorized;
-            notAuthorized = null;
-            const afterAdd = await tokenTransferProxy.getAuthorizedAddresses();
-            expect(afterAdd).to.have.length(2);
-            expect(afterAdd).to.include(authorized);
+			authorized = notAuthorized;
+			notAuthorized = null;
+			const afterAdd = await tokenTransferProxy.getAuthorizedAddresses();
+			expect(afterAdd).to.have.length(2);
+			expect(afterAdd).to.include(authorized);
 
-            await tokenTransferProxy.removeAuthorizedAddress(authorized, {
-                from: owner,
-            });
-            notAuthorized = authorized;
-            authorized = null;
-            const afterRemove = await tokenTransferProxy.getAuthorizedAddresses();
-            expect(afterRemove).to.have.length(1);
-        });
-    });
+			await tokenTransferProxy.removeAuthorizedAddress(authorized, {
+				from: owner,
+			});
+			notAuthorized = authorized;
+			authorized = null;
+			const afterRemove = await tokenTransferProxy.getAuthorizedAddresses();
+			expect(afterRemove).to.have.length(1);
+		});
+	});
 });
diff --git a/packages/contracts/test/ts/token_transfer_proxy/transfer_from.ts b/packages/contracts/test/ts/token_transfer_proxy/transfer_from.ts
index e1aff6dae..847256598 100644
--- a/packages/contracts/test/ts/token_transfer_proxy/transfer_from.ts
+++ b/packages/contracts/test/ts/token_transfer_proxy/transfer_from.ts
@@ -11,63 +11,63 @@ const expect = chai.expect;
 const { TokenTransferProxy, DummyToken, TokenRegistry } = new Artifacts(artifacts);
 
 contract('TokenTransferProxy', (accounts: string[]) => {
-    const INIT_BAL = 100000000;
-    const INIT_ALLOW = 100000000;
+	const INIT_BAL = 100000000;
+	const INIT_ALLOW = 100000000;
 
-    const owner = accounts[0];
-    const notAuthorized = owner;
+	const owner = accounts[0];
+	const notAuthorized = owner;
 
-    let tokenTransferProxy: ContractInstance;
-    let tokenRegistry: ContractInstance;
-    let rep: ContractInstance;
-    let dmyBalances: Balances;
+	let tokenTransferProxy: ContractInstance;
+	let tokenRegistry: ContractInstance;
+	let rep: ContractInstance;
+	let dmyBalances: Balances;
 
-    before(async () => {
-        [tokenTransferProxy, tokenRegistry] = await Promise.all([
-            TokenTransferProxy.deployed(),
-            TokenRegistry.deployed(),
-        ]);
-        const repAddress = await tokenRegistry.getTokenAddressBySymbol('REP');
-        rep = DummyToken.at(repAddress);
+	before(async () => {
+		[tokenTransferProxy, tokenRegistry] = await Promise.all([
+			TokenTransferProxy.deployed(),
+			TokenRegistry.deployed(),
+		]);
+		const repAddress = await tokenRegistry.getTokenAddressBySymbol('REP');
+		rep = DummyToken.at(repAddress);
 
-        dmyBalances = new Balances([rep], [accounts[0], accounts[1]]);
-        await Promise.all([
-            rep.approve(TokenTransferProxy.address, INIT_ALLOW, {
-                from: accounts[0],
-            }),
-            rep.setBalance(accounts[0], INIT_BAL, { from: owner }),
-            rep.approve(TokenTransferProxy.address, INIT_ALLOW, {
-                from: accounts[1],
-            }),
-            rep.setBalance(accounts[1], INIT_BAL, { from: owner }),
-        ]);
-    });
+		dmyBalances = new Balances([rep], [accounts[0], accounts[1]]);
+		await Promise.all([
+			rep.approve(TokenTransferProxy.address, INIT_ALLOW, {
+				from: accounts[0],
+			}),
+			rep.setBalance(accounts[0], INIT_BAL, { from: owner }),
+			rep.approve(TokenTransferProxy.address, INIT_ALLOW, {
+				from: accounts[1],
+			}),
+			rep.setBalance(accounts[1], INIT_BAL, { from: owner }),
+		]);
+	});
 
-    describe('transferFrom', () => {
-        it('should throw when called by an unauthorized address', async () => {
-            expect(
-                tokenTransferProxy.transferFrom(rep.address, accounts[0], accounts[1], 1000, { from: notAuthorized }),
-            ).to.be.rejectedWith(constants.REVERT);
-        });
+	describe('transferFrom', () => {
+		it('should throw when called by an unauthorized address', async () => {
+			expect(
+				tokenTransferProxy.transferFrom(rep.address, accounts[0], accounts[1], 1000, { from: notAuthorized }),
+			).to.be.rejectedWith(constants.REVERT);
+		});
 
-        it('should allow an authorized address to transfer', async () => {
-            const balances = await dmyBalances.getAsync();
+		it('should allow an authorized address to transfer', async () => {
+			const balances = await dmyBalances.getAsync();
 
-            await tokenTransferProxy.addAuthorizedAddress(notAuthorized, {
-                from: owner,
-            });
-            const transferAmt = 10000;
-            await tokenTransferProxy.transferFrom(rep.address, accounts[0], accounts[1], transferAmt, {
-                from: notAuthorized,
-            });
+			await tokenTransferProxy.addAuthorizedAddress(notAuthorized, {
+				from: owner,
+			});
+			const transferAmt = 10000;
+			await tokenTransferProxy.transferFrom(rep.address, accounts[0], accounts[1], transferAmt, {
+				from: notAuthorized,
+			});
 
-            const newBalances = await dmyBalances.getAsync();
-            expect(newBalances[accounts[0]][rep.address]).to.be.bignumber.equal(
-                balances[accounts[0]][rep.address].minus(transferAmt),
-            );
-            expect(newBalances[accounts[1]][rep.address]).to.be.bignumber.equal(
-                balances[accounts[1]][rep.address].add(transferAmt),
-            );
-        });
-    });
+			const newBalances = await dmyBalances.getAsync();
+			expect(newBalances[accounts[0]][rep.address]).to.be.bignumber.equal(
+				balances[accounts[0]][rep.address].minus(transferAmt),
+			);
+			expect(newBalances[accounts[1]][rep.address]).to.be.bignumber.equal(
+				balances[accounts[1]][rep.address].add(transferAmt),
+			);
+		});
+	});
 });
diff --git a/packages/contracts/test/ts/unlimited_allowance_token.ts b/packages/contracts/test/ts/unlimited_allowance_token.ts
index c90a52095..f2e070fbb 100644
--- a/packages/contracts/test/ts/unlimited_allowance_token.ts
+++ b/packages/contracts/test/ts/unlimited_allowance_token.ts
@@ -15,113 +15,113 @@ chaiSetup.configure();
 const expect = chai.expect;
 
 contract('UnlimitedAllowanceToken', (accounts: string[]) => {
-    const config = {
-        networkId: constants.TESTRPC_NETWORK_ID,
-    };
-    const zeroEx = new ZeroEx(web3.currentProvider, config);
-    const owner = accounts[0];
-    const spender = accounts[1];
-
-    const MAX_MINT_VALUE = new BigNumber(100000000000000000000);
-    let tokenAddress: string;
-    let token: ContractInstance;
-
-    beforeEach(async () => {
-        token = await DummyToken.new({ from: owner });
-        await token.mint(MAX_MINT_VALUE, { from: owner });
-        tokenAddress = token.address;
-    });
-
-    describe('transfer', () => {
-        it('should transfer balance from sender to receiver', async () => {
-            const receiver = spender;
-            const initOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
-            const amountToTransfer = new BigNumber(1);
-            await zeroEx.token.transferAsync(tokenAddress, owner, receiver, amountToTransfer);
-            const finalOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
-            const finalReceiverBalance = await zeroEx.token.getBalanceAsync(tokenAddress, receiver);
-
-            const expectedFinalOwnerBalance = initOwnerBalance.minus(amountToTransfer);
-            const expectedFinalReceiverBalance = amountToTransfer;
-            expect(finalOwnerBalance).to.be.bignumber.equal(expectedFinalOwnerBalance);
-            expect(finalReceiverBalance).to.be.bignumber.equal(expectedFinalReceiverBalance);
-        });
-
-        it('should return true on a 0 value transfer', async () => {
-            const didReturnTrue = await token.transfer.call(spender, 0, {
-                from: owner,
-            });
-            expect(didReturnTrue).to.be.true();
-        });
-    });
-
-    describe('transferFrom', () => {
-        it('should return false if owner has insufficient balance', async () => {
-            const ownerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
-            const amountToTransfer = ownerBalance.plus(1);
-            await zeroEx.token.setAllowanceAsync(tokenAddress, owner, spender, amountToTransfer);
-            const didReturnTrue = await token.transferFrom.call(owner, spender, amountToTransfer, { from: spender });
-            expect(didReturnTrue).to.be.false();
-        });
-
-        it('should return false if spender has insufficient allowance', async () => {
-            const ownerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
-            const amountToTransfer = ownerBalance;
-
-            const spenderAllowance = await zeroEx.token.getAllowanceAsync(tokenAddress, owner, spender);
-            const spenderAllowanceIsInsufficient = spenderAllowance.cmp(amountToTransfer) < 0;
-            expect(spenderAllowanceIsInsufficient).to.be.true();
-
-            const didReturnTrue = await token.transferFrom.call(owner, spender, amountToTransfer, { from: spender });
-            expect(didReturnTrue).to.be.false();
-        });
-
-        it('should return true on a 0 value transfer', async () => {
-            const amountToTransfer = 0;
-            const didReturnTrue = await token.transferFrom.call(owner, spender, amountToTransfer, { from: spender });
-            expect(didReturnTrue).to.be.true();
-        });
-
-        it('should not modify spender allowance if spender allowance is 2^256 - 1', async () => {
-            const initOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
-            const amountToTransfer = initOwnerBalance;
-            const initSpenderAllowance = zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS;
-            await zeroEx.token.setAllowanceAsync(tokenAddress, owner, spender, initSpenderAllowance);
-            await zeroEx.token.transferFromAsync(tokenAddress, owner, spender, spender, amountToTransfer, {
-                gasLimit: constants.MAX_TOKEN_TRANSFERFROM_GAS,
-            });
-
-            const newSpenderAllowance = await zeroEx.token.getAllowanceAsync(tokenAddress, owner, spender);
-            expect(initSpenderAllowance).to.be.bignumber.equal(newSpenderAllowance);
-        });
-
-        it('should transfer the correct balances if spender has sufficient allowance', async () => {
-            const initOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
-            const amountToTransfer = initOwnerBalance;
-            const initSpenderAllowance = initOwnerBalance;
-            await zeroEx.token.setAllowanceAsync(tokenAddress, owner, spender, initSpenderAllowance);
-            await zeroEx.token.transferFromAsync(tokenAddress, owner, spender, spender, amountToTransfer, {
-                gasLimit: constants.MAX_TOKEN_TRANSFERFROM_GAS,
-            });
-
-            const newOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
-            const newSpenderBalance = await zeroEx.token.getBalanceAsync(tokenAddress, spender);
-
-            expect(newOwnerBalance).to.be.bignumber.equal(0);
-            expect(newSpenderBalance).to.be.bignumber.equal(initOwnerBalance);
-        });
-
-        it('should modify allowance if spender has sufficient allowance less than 2^256 - 1', async () => {
-            const initOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
-            const amountToTransfer = initOwnerBalance;
-            const initSpenderAllowance = initOwnerBalance;
-            await zeroEx.token.setAllowanceAsync(tokenAddress, owner, spender, initSpenderAllowance);
-            await zeroEx.token.transferFromAsync(tokenAddress, owner, spender, spender, amountToTransfer, {
-                gasLimit: constants.MAX_TOKEN_TRANSFERFROM_GAS,
-            });
-
-            const newSpenderAllowance = await zeroEx.token.getAllowanceAsync(tokenAddress, owner, spender);
-            expect(newSpenderAllowance).to.be.bignumber.equal(0);
-        });
-    });
+	const config = {
+		networkId: constants.TESTRPC_NETWORK_ID,
+	};
+	const zeroEx = new ZeroEx(web3.currentProvider, config);
+	const owner = accounts[0];
+	const spender = accounts[1];
+
+	const MAX_MINT_VALUE = new BigNumber(100000000000000000000);
+	let tokenAddress: string;
+	let token: ContractInstance;
+
+	beforeEach(async () => {
+		token = await DummyToken.new({ from: owner });
+		await token.mint(MAX_MINT_VALUE, { from: owner });
+		tokenAddress = token.address;
+	});
+
+	describe('transfer', () => {
+		it('should transfer balance from sender to receiver', async () => {
+			const receiver = spender;
+			const initOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
+			const amountToTransfer = new BigNumber(1);
+			await zeroEx.token.transferAsync(tokenAddress, owner, receiver, amountToTransfer);
+			const finalOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
+			const finalReceiverBalance = await zeroEx.token.getBalanceAsync(tokenAddress, receiver);
+
+			const expectedFinalOwnerBalance = initOwnerBalance.minus(amountToTransfer);
+			const expectedFinalReceiverBalance = amountToTransfer;
+			expect(finalOwnerBalance).to.be.bignumber.equal(expectedFinalOwnerBalance);
+			expect(finalReceiverBalance).to.be.bignumber.equal(expectedFinalReceiverBalance);
+		});
+
+		it('should return true on a 0 value transfer', async () => {
+			const didReturnTrue = await token.transfer.call(spender, 0, {
+				from: owner,
+			});
+			expect(didReturnTrue).to.be.true();
+		});
+	});
+
+	describe('transferFrom', () => {
+		it('should return false if owner has insufficient balance', async () => {
+			const ownerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
+			const amountToTransfer = ownerBalance.plus(1);
+			await zeroEx.token.setAllowanceAsync(tokenAddress, owner, spender, amountToTransfer);
+			const didReturnTrue = await token.transferFrom.call(owner, spender, amountToTransfer, { from: spender });
+			expect(didReturnTrue).to.be.false();
+		});
+
+		it('should return false if spender has insufficient allowance', async () => {
+			const ownerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
+			const amountToTransfer = ownerBalance;
+
+			const spenderAllowance = await zeroEx.token.getAllowanceAsync(tokenAddress, owner, spender);
+			const spenderAllowanceIsInsufficient = spenderAllowance.cmp(amountToTransfer) < 0;
+			expect(spenderAllowanceIsInsufficient).to.be.true();
+
+			const didReturnTrue = await token.transferFrom.call(owner, spender, amountToTransfer, { from: spender });
+			expect(didReturnTrue).to.be.false();
+		});
+
+		it('should return true on a 0 value transfer', async () => {
+			const amountToTransfer = 0;
+			const didReturnTrue = await token.transferFrom.call(owner, spender, amountToTransfer, { from: spender });
+			expect(didReturnTrue).to.be.true();
+		});
+
+		it('should not modify spender allowance if spender allowance is 2^256 - 1', async () => {
+			const initOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
+			const amountToTransfer = initOwnerBalance;
+			const initSpenderAllowance = zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS;
+			await zeroEx.token.setAllowanceAsync(tokenAddress, owner, spender, initSpenderAllowance);
+			await zeroEx.token.transferFromAsync(tokenAddress, owner, spender, spender, amountToTransfer, {
+				gasLimit: constants.MAX_TOKEN_TRANSFERFROM_GAS,
+			});
+
+			const newSpenderAllowance = await zeroEx.token.getAllowanceAsync(tokenAddress, owner, spender);
+			expect(initSpenderAllowance).to.be.bignumber.equal(newSpenderAllowance);
+		});
+
+		it('should transfer the correct balances if spender has sufficient allowance', async () => {
+			const initOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
+			const amountToTransfer = initOwnerBalance;
+			const initSpenderAllowance = initOwnerBalance;
+			await zeroEx.token.setAllowanceAsync(tokenAddress, owner, spender, initSpenderAllowance);
+			await zeroEx.token.transferFromAsync(tokenAddress, owner, spender, spender, amountToTransfer, {
+				gasLimit: constants.MAX_TOKEN_TRANSFERFROM_GAS,
+			});
+
+			const newOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
+			const newSpenderBalance = await zeroEx.token.getBalanceAsync(tokenAddress, spender);
+
+			expect(newOwnerBalance).to.be.bignumber.equal(0);
+			expect(newSpenderBalance).to.be.bignumber.equal(initOwnerBalance);
+		});
+
+		it('should modify allowance if spender has sufficient allowance less than 2^256 - 1', async () => {
+			const initOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
+			const amountToTransfer = initOwnerBalance;
+			const initSpenderAllowance = initOwnerBalance;
+			await zeroEx.token.setAllowanceAsync(tokenAddress, owner, spender, initSpenderAllowance);
+			await zeroEx.token.transferFromAsync(tokenAddress, owner, spender, spender, amountToTransfer, {
+				gasLimit: constants.MAX_TOKEN_TRANSFERFROM_GAS,
+			});
+
+			const newSpenderAllowance = await zeroEx.token.getAllowanceAsync(tokenAddress, owner, spender);
+			expect(newSpenderAllowance).to.be.bignumber.equal(0);
+		});
+	});
 });
diff --git a/packages/contracts/test/ts/unlimited_allowance_token_v2.ts b/packages/contracts/test/ts/unlimited_allowance_token_v2.ts
index 1b29a02ba..4f2ab2e1e 100644
--- a/packages/contracts/test/ts/unlimited_allowance_token_v2.ts
+++ b/packages/contracts/test/ts/unlimited_allowance_token_v2.ts
@@ -15,127 +15,127 @@ chaiSetup.configure();
 const expect = chai.expect;
 
 contract('UnlimitedAllowanceTokenV2', (accounts: string[]) => {
-    const config = {
-        networkId: constants.TESTRPC_NETWORK_ID,
-    };
-    const zeroEx = new ZeroEx(web3.currentProvider, config);
-    const owner = accounts[0];
-    const spender = accounts[1];
-
-    const MAX_MINT_VALUE = new BigNumber(100000000000000000000);
-    let tokenAddress: string;
-    let token: ContractInstance;
-
-    beforeEach(async () => {
-        token = await DummyTokenV2.new({ from: owner });
-        await token.mint(MAX_MINT_VALUE, { from: owner });
-        tokenAddress = token.address;
-    });
-
-    describe('transfer', () => {
-        it('should throw if owner has insufficient balance', async () => {
-            const ownerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
-            const amountToTransfer = ownerBalance.plus(1);
-            return expect(token.transfer.call(spender, amountToTransfer, { from: owner })).to.be.rejectedWith(
-                constants.REVERT,
-            );
-        });
-
-        it('should transfer balance from sender to receiver', async () => {
-            const receiver = spender;
-            const initOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
-            const amountToTransfer = new BigNumber(1);
-            await zeroEx.token.transferAsync(tokenAddress, owner, receiver, amountToTransfer);
-            const finalOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
-            const finalReceiverBalance = await zeroEx.token.getBalanceAsync(tokenAddress, receiver);
-
-            const expectedFinalOwnerBalance = initOwnerBalance.minus(amountToTransfer);
-            const expectedFinalReceiverBalance = amountToTransfer;
-            expect(finalOwnerBalance).to.be.bignumber.equal(expectedFinalOwnerBalance);
-            expect(finalReceiverBalance).to.be.bignumber.equal(expectedFinalReceiverBalance);
-        });
-
-        it('should return true on a 0 value transfer', async () => {
-            const didReturnTrue = await token.transfer.call(spender, 0, {
-                from: owner,
-            });
-            expect(didReturnTrue).to.be.true();
-        });
-    });
-
-    describe('transferFrom', () => {
-        it('should throw if owner has insufficient balance', async () => {
-            const ownerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
-            const amountToTransfer = ownerBalance.plus(1);
-            await zeroEx.token.setAllowanceAsync(tokenAddress, owner, spender, amountToTransfer);
-            return expect(
-                token.transferFrom.call(owner, spender, amountToTransfer, {
-                    from: spender,
-                }),
-            ).to.be.rejectedWith(constants.REVERT);
-        });
-
-        it('should throw if spender has insufficient allowance', async () => {
-            const ownerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
-            const amountToTransfer = ownerBalance;
-
-            const spenderAllowance = await zeroEx.token.getAllowanceAsync(tokenAddress, owner, spender);
-            const spenderAllowanceIsInsufficient = spenderAllowance.cmp(amountToTransfer) < 0;
-            expect(spenderAllowanceIsInsufficient).to.be.true();
-
-            return expect(
-                token.transferFrom.call(owner, spender, amountToTransfer, {
-                    from: spender,
-                }),
-            ).to.be.rejectedWith(constants.REVERT);
-        });
-
-        it('should return true on a 0 value transfer', async () => {
-            const amountToTransfer = 0;
-            const didReturnTrue = await token.transferFrom.call(owner, spender, amountToTransfer, { from: spender });
-            expect(didReturnTrue).to.be.true();
-        });
-
-        it('should not modify spender allowance if spender allowance is 2^256 - 1', async () => {
-            const initOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
-            const amountToTransfer = initOwnerBalance;
-            const initSpenderAllowance = zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS;
-            await zeroEx.token.setAllowanceAsync(tokenAddress, owner, spender, initSpenderAllowance);
-            await zeroEx.token.transferFromAsync(tokenAddress, owner, spender, spender, amountToTransfer, {
-                gasLimit: constants.MAX_TOKEN_TRANSFERFROM_GAS,
-            });
-
-            const newSpenderAllowance = await zeroEx.token.getAllowanceAsync(tokenAddress, owner, spender);
-            expect(initSpenderAllowance).to.be.bignumber.equal(newSpenderAllowance);
-        });
-
-        it('should transfer the correct balances if spender has sufficient allowance', async () => {
-            const initOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
-            const amountToTransfer = initOwnerBalance;
-            const initSpenderAllowance = initOwnerBalance;
-            await zeroEx.token.setAllowanceAsync(tokenAddress, owner, spender, initSpenderAllowance);
-            await zeroEx.token.transferFromAsync(tokenAddress, owner, spender, spender, amountToTransfer, {
-                gasLimit: constants.MAX_TOKEN_TRANSFERFROM_GAS,
-            });
-
-            const newOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
-            const newSpenderBalance = await zeroEx.token.getBalanceAsync(tokenAddress, spender);
-
-            expect(newOwnerBalance).to.be.bignumber.equal(0);
-            expect(newSpenderBalance).to.be.bignumber.equal(initOwnerBalance);
-        });
-
-        it('should modify allowance if spender has sufficient allowance less than 2^256 - 1', async () => {
-            const initOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
-            const amountToTransfer = initOwnerBalance;
-            const initSpenderAllowance = initOwnerBalance;
-            await zeroEx.token.setAllowanceAsync(tokenAddress, owner, spender, initSpenderAllowance);
-            await zeroEx.token.transferFromAsync(tokenAddress, owner, spender, spender, amountToTransfer, {
-                gasLimit: constants.MAX_TOKEN_TRANSFERFROM_GAS,
-            });
-
-            const newSpenderAllowance = await zeroEx.token.getAllowanceAsync(tokenAddress, owner, spender);
-            expect(newSpenderAllowance).to.be.bignumber.equal(0);
-        });
-    });
+	const config = {
+		networkId: constants.TESTRPC_NETWORK_ID,
+	};
+	const zeroEx = new ZeroEx(web3.currentProvider, config);
+	const owner = accounts[0];
+	const spender = accounts[1];
+
+	const MAX_MINT_VALUE = new BigNumber(100000000000000000000);
+	let tokenAddress: string;
+	let token: ContractInstance;
+
+	beforeEach(async () => {
+		token = await DummyTokenV2.new({ from: owner });
+		await token.mint(MAX_MINT_VALUE, { from: owner });
+		tokenAddress = token.address;
+	});
+
+	describe('transfer', () => {
+		it('should throw if owner has insufficient balance', async () => {
+			const ownerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
+			const amountToTransfer = ownerBalance.plus(1);
+			return expect(token.transfer.call(spender, amountToTransfer, { from: owner })).to.be.rejectedWith(
+				constants.REVERT,
+			);
+		});
+
+		it('should transfer balance from sender to receiver', async () => {
+			const receiver = spender;
+			const initOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
+			const amountToTransfer = new BigNumber(1);
+			await zeroEx.token.transferAsync(tokenAddress, owner, receiver, amountToTransfer);
+			const finalOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
+			const finalReceiverBalance = await zeroEx.token.getBalanceAsync(tokenAddress, receiver);
+
+			const expectedFinalOwnerBalance = initOwnerBalance.minus(amountToTransfer);
+			const expectedFinalReceiverBalance = amountToTransfer;
+			expect(finalOwnerBalance).to.be.bignumber.equal(expectedFinalOwnerBalance);
+			expect(finalReceiverBalance).to.be.bignumber.equal(expectedFinalReceiverBalance);
+		});
+
+		it('should return true on a 0 value transfer', async () => {
+			const didReturnTrue = await token.transfer.call(spender, 0, {
+				from: owner,
+			});
+			expect(didReturnTrue).to.be.true();
+		});
+	});
+
+	describe('transferFrom', () => {
+		it('should throw if owner has insufficient balance', async () => {
+			const ownerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
+			const amountToTransfer = ownerBalance.plus(1);
+			await zeroEx.token.setAllowanceAsync(tokenAddress, owner, spender, amountToTransfer);
+			return expect(
+				token.transferFrom.call(owner, spender, amountToTransfer, {
+					from: spender,
+				}),
+			).to.be.rejectedWith(constants.REVERT);
+		});
+
+		it('should throw if spender has insufficient allowance', async () => {
+			const ownerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
+			const amountToTransfer = ownerBalance;
+
+			const spenderAllowance = await zeroEx.token.getAllowanceAsync(tokenAddress, owner, spender);
+			const spenderAllowanceIsInsufficient = spenderAllowance.cmp(amountToTransfer) < 0;
+			expect(spenderAllowanceIsInsufficient).to.be.true();
+
+			return expect(
+				token.transferFrom.call(owner, spender, amountToTransfer, {
+					from: spender,
+				}),
+			).to.be.rejectedWith(constants.REVERT);
+		});
+
+		it('should return true on a 0 value transfer', async () => {
+			const amountToTransfer = 0;
+			const didReturnTrue = await token.transferFrom.call(owner, spender, amountToTransfer, { from: spender });
+			expect(didReturnTrue).to.be.true();
+		});
+
+		it('should not modify spender allowance if spender allowance is 2^256 - 1', async () => {
+			const initOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
+			const amountToTransfer = initOwnerBalance;
+			const initSpenderAllowance = zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS;
+			await zeroEx.token.setAllowanceAsync(tokenAddress, owner, spender, initSpenderAllowance);
+			await zeroEx.token.transferFromAsync(tokenAddress, owner, spender, spender, amountToTransfer, {
+				gasLimit: constants.MAX_TOKEN_TRANSFERFROM_GAS,
+			});
+
+			const newSpenderAllowance = await zeroEx.token.getAllowanceAsync(tokenAddress, owner, spender);
+			expect(initSpenderAllowance).to.be.bignumber.equal(newSpenderAllowance);
+		});
+
+		it('should transfer the correct balances if spender has sufficient allowance', async () => {
+			const initOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
+			const amountToTransfer = initOwnerBalance;
+			const initSpenderAllowance = initOwnerBalance;
+			await zeroEx.token.setAllowanceAsync(tokenAddress, owner, spender, initSpenderAllowance);
+			await zeroEx.token.transferFromAsync(tokenAddress, owner, spender, spender, amountToTransfer, {
+				gasLimit: constants.MAX_TOKEN_TRANSFERFROM_GAS,
+			});
+
+			const newOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
+			const newSpenderBalance = await zeroEx.token.getBalanceAsync(tokenAddress, spender);
+
+			expect(newOwnerBalance).to.be.bignumber.equal(0);
+			expect(newSpenderBalance).to.be.bignumber.equal(initOwnerBalance);
+		});
+
+		it('should modify allowance if spender has sufficient allowance less than 2^256 - 1', async () => {
+			const initOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
+			const amountToTransfer = initOwnerBalance;
+			const initSpenderAllowance = initOwnerBalance;
+			await zeroEx.token.setAllowanceAsync(tokenAddress, owner, spender, initSpenderAllowance);
+			await zeroEx.token.transferFromAsync(tokenAddress, owner, spender, spender, amountToTransfer, {
+				gasLimit: constants.MAX_TOKEN_TRANSFERFROM_GAS,
+			});
+
+			const newSpenderAllowance = await zeroEx.token.getAllowanceAsync(tokenAddress, owner, spender);
+			expect(newSpenderAllowance).to.be.bignumber.equal(0);
+		});
+	});
 });
diff --git a/packages/contracts/test/ts/utils/chai_setup.ts b/packages/contracts/test/ts/utils/chai_setup.ts
index 078edd309..e156b5f7c 100644
--- a/packages/contracts/test/ts/utils/chai_setup.ts
+++ b/packages/contracts/test/ts/utils/chai_setup.ts
@@ -4,10 +4,10 @@ import ChaiBigNumber = require('chai-bignumber');
 import * as dirtyChai from 'dirty-chai';
 
 export const chaiSetup = {
-    configure() {
-        chai.config.includeStack = true;
-        chai.use(ChaiBigNumber());
-        chai.use(dirtyChai);
-        chai.use(chaiAsPromised);
-    },
+	configure() {
+		chai.config.includeStack = true;
+		chai.use(ChaiBigNumber());
+		chai.use(dirtyChai);
+		chai.use(chaiAsPromised);
+	},
 };
diff --git a/packages/contracts/test/ts/zrx_token.ts b/packages/contracts/test/ts/zrx_token.ts
index 766c94c2a..a0b11cdb6 100644
--- a/packages/contracts/test/ts/zrx_token.ts
+++ b/packages/contracts/test/ts/zrx_token.ts
@@ -15,161 +15,161 @@ const { Exchange, ZRXToken } = new Artifacts(artifacts);
 const web3: Web3 = (global as any).web3;
 
 contract('ZRXToken', (accounts: string[]) => {
-    const owner = accounts[0];
-    const spender = accounts[1];
-    let zeroEx: ZeroEx;
-
-    let MAX_UINT: BigNumber;
-
-    let zrx: ContractInstance;
-    let zrxAddress: string;
-
-    beforeEach(async () => {
-        zeroEx = new ZeroEx(web3.currentProvider, {
-            exchangeContractAddress: Exchange.address,
-            networkId: constants.TESTRPC_NETWORK_ID,
-        });
-        zrx = await ZRXToken.new();
-        zrxAddress = zrx.address;
-        MAX_UINT = zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS;
-    });
-
-    describe('constants', () => {
-        it('should have 18 decimals', async () => {
-            const decimals = new BigNumber(await zrx.decimals.call());
-            const expectedDecimals = 18;
-            expect(decimals).to.be.bignumber.equal(expectedDecimals);
-        });
-
-        it('should have a total supply of 1 billion tokens', async () => {
-            const totalSupply = new BigNumber(await zrx.totalSupply.call());
-            const expectedTotalSupply = 1000000000;
-            expect(ZeroEx.toUnitAmount(totalSupply, 18)).to.be.bignumber.equal(expectedTotalSupply);
-        });
-
-        it('should be named 0x Protocol Token', async () => {
-            const name = await zrx.name.call();
-            const expectedName = '0x Protocol Token';
-            expect(name).to.be.equal(expectedName);
-        });
-
-        it('should have the symbol ZRX', async () => {
-            const symbol = await zrx.symbol.call();
-            const expectedSymbol = 'ZRX';
-            expect(symbol).to.be.equal(expectedSymbol);
-        });
-    });
-
-    describe('constructor', () => {
-        it('should initialize owner balance to totalSupply', async () => {
-            const ownerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner);
-            const totalSupply = new BigNumber(await zrx.totalSupply.call());
-            expect(totalSupply).to.be.bignumber.equal(ownerBalance);
-        });
-    });
-
-    describe('transfer', () => {
-        it('should transfer balance from sender to receiver', async () => {
-            const receiver = spender;
-            const initOwnerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner);
-            const amountToTransfer = new BigNumber(1);
-            const txHash = await zeroEx.token.transferAsync(zrxAddress, owner, receiver, amountToTransfer);
-            await zeroEx.awaitTransactionMinedAsync(txHash);
-            const finalOwnerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner);
-            const finalReceiverBalance = await zeroEx.token.getBalanceAsync(zrxAddress, receiver);
-
-            const expectedFinalOwnerBalance = initOwnerBalance.minus(amountToTransfer);
-            const expectedFinalReceiverBalance = amountToTransfer;
-            expect(finalOwnerBalance).to.be.bignumber.equal(expectedFinalOwnerBalance);
-            expect(finalReceiverBalance).to.be.bignumber.equal(expectedFinalReceiverBalance);
-        });
-
-        it('should return true on a 0 value transfer', async () => {
-            const didReturnTrue = await zrx.transfer.call(spender, 0, {
-                from: owner,
-            });
-            expect(didReturnTrue).to.be.true();
-        });
-    });
-
-    describe('transferFrom', () => {
-        it('should return false if owner has insufficient balance', async () => {
-            const ownerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner);
-            const amountToTransfer = ownerBalance.plus(1);
-            const txHash = await zeroEx.token.setAllowanceAsync(zrxAddress, owner, spender, amountToTransfer, {
-                gasLimit: constants.MAX_TOKEN_APPROVE_GAS,
-            });
-            await zeroEx.awaitTransactionMinedAsync(txHash);
-            const didReturnTrue = await zrx.transferFrom.call(owner, spender, amountToTransfer, { from: spender });
-            expect(didReturnTrue).to.be.false();
-        });
-
-        it('should return false if spender has insufficient allowance', async () => {
-            const ownerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner);
-            const amountToTransfer = ownerBalance;
-
-            const spenderAllowance = await zeroEx.token.getAllowanceAsync(zrxAddress, owner, spender);
-            const spenderAllowanceIsInsufficient = spenderAllowance.cmp(amountToTransfer) < 0;
-            expect(spenderAllowanceIsInsufficient).to.be.true();
-
-            const didReturnTrue = await zrx.transferFrom.call(owner, spender, amountToTransfer, { from: spender });
-            expect(didReturnTrue).to.be.false();
-        });
-
-        it('should return true on a 0 value transfer', async () => {
-            const amountToTransfer = 0;
-            const didReturnTrue = await zrx.transferFrom.call(owner, spender, amountToTransfer, { from: spender });
-            expect(didReturnTrue).to.be.true();
-        });
-
-        it('should not modify spender allowance if spender allowance is 2^256 - 1', async () => {
-            const initOwnerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner);
-            const amountToTransfer = initOwnerBalance;
-            const initSpenderAllowance = MAX_UINT;
-            let txHash = await zeroEx.token.setAllowanceAsync(zrxAddress, owner, spender, initSpenderAllowance, {
-                gasLimit: constants.MAX_TOKEN_APPROVE_GAS,
-            });
-            await zeroEx.awaitTransactionMinedAsync(txHash);
-            txHash = await zeroEx.token.transferFromAsync(zrxAddress, owner, spender, spender, amountToTransfer, {
-                gasLimit: constants.MAX_TOKEN_TRANSFERFROM_GAS,
-            });
-            await zeroEx.awaitTransactionMinedAsync(txHash);
-
-            const newSpenderAllowance = await zeroEx.token.getAllowanceAsync(zrxAddress, owner, spender);
-            expect(initSpenderAllowance).to.be.bignumber.equal(newSpenderAllowance);
-        });
-
-        it('should transfer the correct balances if spender has sufficient allowance', async () => {
-            const initOwnerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner);
-            const initSpenderBalance = await zeroEx.token.getBalanceAsync(zrxAddress, spender);
-            const amountToTransfer = initOwnerBalance;
-            const initSpenderAllowance = initOwnerBalance;
-            let txHash = await zeroEx.token.setAllowanceAsync(zrxAddress, owner, spender, initSpenderAllowance);
-            await zeroEx.awaitTransactionMinedAsync(txHash);
-            txHash = await zeroEx.token.transferFromAsync(zrxAddress, owner, spender, spender, amountToTransfer, {
-                gasLimit: constants.MAX_TOKEN_TRANSFERFROM_GAS,
-            });
-            await zeroEx.awaitTransactionMinedAsync(txHash);
-
-            const newOwnerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner);
-            const newSpenderBalance = await zeroEx.token.getBalanceAsync(zrxAddress, spender);
-
-            expect(newOwnerBalance).to.be.bignumber.equal(0);
-            expect(newSpenderBalance).to.be.bignumber.equal(initSpenderBalance.plus(initOwnerBalance));
-        });
-
-        it('should modify allowance if spender has sufficient allowance less than 2^256 - 1', async () => {
-            const initOwnerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner);
-            const amountToTransfer = initOwnerBalance;
-            let txHash = await zeroEx.token.setAllowanceAsync(zrxAddress, owner, spender, amountToTransfer);
-            await zeroEx.awaitTransactionMinedAsync(txHash);
-            txHash = await zeroEx.token.transferFromAsync(zrxAddress, owner, spender, spender, amountToTransfer, {
-                gasLimit: constants.MAX_TOKEN_TRANSFERFROM_GAS,
-            });
-            await zeroEx.awaitTransactionMinedAsync(txHash);
-
-            const newSpenderAllowance = await zeroEx.token.getAllowanceAsync(zrxAddress, owner, spender);
-            expect(newSpenderAllowance).to.be.bignumber.equal(0);
-        });
-    });
+	const owner = accounts[0];
+	const spender = accounts[1];
+	let zeroEx: ZeroEx;
+
+	let MAX_UINT: BigNumber;
+
+	let zrx: ContractInstance;
+	let zrxAddress: string;
+
+	beforeEach(async () => {
+		zeroEx = new ZeroEx(web3.currentProvider, {
+			exchangeContractAddress: Exchange.address,
+			networkId: constants.TESTRPC_NETWORK_ID,
+		});
+		zrx = await ZRXToken.new();
+		zrxAddress = zrx.address;
+		MAX_UINT = zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS;
+	});
+
+	describe('constants', () => {
+		it('should have 18 decimals', async () => {
+			const decimals = new BigNumber(await zrx.decimals.call());
+			const expectedDecimals = 18;
+			expect(decimals).to.be.bignumber.equal(expectedDecimals);
+		});
+
+		it('should have a total supply of 1 billion tokens', async () => {
+			const totalSupply = new BigNumber(await zrx.totalSupply.call());
+			const expectedTotalSupply = 1000000000;
+			expect(ZeroEx.toUnitAmount(totalSupply, 18)).to.be.bignumber.equal(expectedTotalSupply);
+		});
+
+		it('should be named 0x Protocol Token', async () => {
+			const name = await zrx.name.call();
+			const expectedName = '0x Protocol Token';
+			expect(name).to.be.equal(expectedName);
+		});
+
+		it('should have the symbol ZRX', async () => {
+			const symbol = await zrx.symbol.call();
+			const expectedSymbol = 'ZRX';
+			expect(symbol).to.be.equal(expectedSymbol);
+		});
+	});
+
+	describe('constructor', () => {
+		it('should initialize owner balance to totalSupply', async () => {
+			const ownerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner);
+			const totalSupply = new BigNumber(await zrx.totalSupply.call());
+			expect(totalSupply).to.be.bignumber.equal(ownerBalance);
+		});
+	});
+
+	describe('transfer', () => {
+		it('should transfer balance from sender to receiver', async () => {
+			const receiver = spender;
+			const initOwnerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner);
+			const amountToTransfer = new BigNumber(1);
+			const txHash = await zeroEx.token.transferAsync(zrxAddress, owner, receiver, amountToTransfer);
+			await zeroEx.awaitTransactionMinedAsync(txHash);
+			const finalOwnerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner);
+			const finalReceiverBalance = await zeroEx.token.getBalanceAsync(zrxAddress, receiver);
+
+			const expectedFinalOwnerBalance = initOwnerBalance.minus(amountToTransfer);
+			const expectedFinalReceiverBalance = amountToTransfer;
+			expect(finalOwnerBalance).to.be.bignumber.equal(expectedFinalOwnerBalance);
+			expect(finalReceiverBalance).to.be.bignumber.equal(expectedFinalReceiverBalance);
+		});
+
+		it('should return true on a 0 value transfer', async () => {
+			const didReturnTrue = await zrx.transfer.call(spender, 0, {
+				from: owner,
+			});
+			expect(didReturnTrue).to.be.true();
+		});
+	});
+
+	describe('transferFrom', () => {
+		it('should return false if owner has insufficient balance', async () => {
+			const ownerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner);
+			const amountToTransfer = ownerBalance.plus(1);
+			const txHash = await zeroEx.token.setAllowanceAsync(zrxAddress, owner, spender, amountToTransfer, {
+				gasLimit: constants.MAX_TOKEN_APPROVE_GAS,
+			});
+			await zeroEx.awaitTransactionMinedAsync(txHash);
+			const didReturnTrue = await zrx.transferFrom.call(owner, spender, amountToTransfer, { from: spender });
+			expect(didReturnTrue).to.be.false();
+		});
+
+		it('should return false if spender has insufficient allowance', async () => {
+			const ownerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner);
+			const amountToTransfer = ownerBalance;
+
+			const spenderAllowance = await zeroEx.token.getAllowanceAsync(zrxAddress, owner, spender);
+			const spenderAllowanceIsInsufficient = spenderAllowance.cmp(amountToTransfer) < 0;
+			expect(spenderAllowanceIsInsufficient).to.be.true();
+
+			const didReturnTrue = await zrx.transferFrom.call(owner, spender, amountToTransfer, { from: spender });
+			expect(didReturnTrue).to.be.false();
+		});
+
+		it('should return true on a 0 value transfer', async () => {
+			const amountToTransfer = 0;
+			const didReturnTrue = await zrx.transferFrom.call(owner, spender, amountToTransfer, { from: spender });
+			expect(didReturnTrue).to.be.true();
+		});
+
+		it('should not modify spender allowance if spender allowance is 2^256 - 1', async () => {
+			const initOwnerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner);
+			const amountToTransfer = initOwnerBalance;
+			const initSpenderAllowance = MAX_UINT;
+			let txHash = await zeroEx.token.setAllowanceAsync(zrxAddress, owner, spender, initSpenderAllowance, {
+				gasLimit: constants.MAX_TOKEN_APPROVE_GAS,
+			});
+			await zeroEx.awaitTransactionMinedAsync(txHash);
+			txHash = await zeroEx.token.transferFromAsync(zrxAddress, owner, spender, spender, amountToTransfer, {
+				gasLimit: constants.MAX_TOKEN_TRANSFERFROM_GAS,
+			});
+			await zeroEx.awaitTransactionMinedAsync(txHash);
+
+			const newSpenderAllowance = await zeroEx.token.getAllowanceAsync(zrxAddress, owner, spender);
+			expect(initSpenderAllowance).to.be.bignumber.equal(newSpenderAllowance);
+		});
+
+		it('should transfer the correct balances if spender has sufficient allowance', async () => {
+			const initOwnerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner);
+			const initSpenderBalance = await zeroEx.token.getBalanceAsync(zrxAddress, spender);
+			const amountToTransfer = initOwnerBalance;
+			const initSpenderAllowance = initOwnerBalance;
+			let txHash = await zeroEx.token.setAllowanceAsync(zrxAddress, owner, spender, initSpenderAllowance);
+			await zeroEx.awaitTransactionMinedAsync(txHash);
+			txHash = await zeroEx.token.transferFromAsync(zrxAddress, owner, spender, spender, amountToTransfer, {
+				gasLimit: constants.MAX_TOKEN_TRANSFERFROM_GAS,
+			});
+			await zeroEx.awaitTransactionMinedAsync(txHash);
+
+			const newOwnerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner);
+			const newSpenderBalance = await zeroEx.token.getBalanceAsync(zrxAddress, spender);
+
+			expect(newOwnerBalance).to.be.bignumber.equal(0);
+			expect(newSpenderBalance).to.be.bignumber.equal(initSpenderBalance.plus(initOwnerBalance));
+		});
+
+		it('should modify allowance if spender has sufficient allowance less than 2^256 - 1', async () => {
+			const initOwnerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner);
+			const amountToTransfer = initOwnerBalance;
+			let txHash = await zeroEx.token.setAllowanceAsync(zrxAddress, owner, spender, amountToTransfer);
+			await zeroEx.awaitTransactionMinedAsync(txHash);
+			txHash = await zeroEx.token.transferFromAsync(zrxAddress, owner, spender, spender, amountToTransfer, {
+				gasLimit: constants.MAX_TOKEN_TRANSFERFROM_GAS,
+			});
+			await zeroEx.awaitTransactionMinedAsync(txHash);
+
+			const newSpenderAllowance = await zeroEx.token.getAllowanceAsync(zrxAddress, owner, spender);
+			expect(newSpenderAllowance).to.be.bignumber.equal(0);
+		});
+	});
 });
diff --git a/packages/contracts/tsconfig.json b/packages/contracts/tsconfig.json
index 38008a542..e88b3c3f0 100644
--- a/packages/contracts/tsconfig.json
+++ b/packages/contracts/tsconfig.json
@@ -1,25 +1,25 @@
 {
-    "extends": "../../tsconfig",
-    "compilerOptions": {
-        "outDir": "lib",
-        "baseUrl": ".",
-        "declaration": false,
-        "strictNullChecks": false,
-        "strictFunctionTypes": false,
-        "allowJs": true
-    },
-    "include": [
-        "../../node_modules/types-ethereumjs-util/index.d.ts",
-        "../../node_modules/chai-typescript-typings/index.d.ts",
-        "../../node_modules/web3-typescript-typings/index.d.ts",
-        "../../node_modules/chai-as-promised-typescript-typings/index.d.ts",
-        "../../node_modules/types-ethereumjs-util/index.d.ts",
-        "../../node_modules/types-bn/index.d.ts",
-        "./globals.d.ts",
-        "./util/**/*",
-        "./test/**/*",
-        "./migrations/**/*",
-        "./deploy/**/*"
-    ],
-    "exclude": ["./deploy/solc/solc_bin"]
+	"extends": "../../tsconfig",
+	"compilerOptions": {
+		"outDir": "lib",
+		"baseUrl": ".",
+		"declaration": false,
+		"strictNullChecks": false,
+		"strictFunctionTypes": false,
+		"allowJs": true
+	},
+	"include": [
+		"../../node_modules/types-ethereumjs-util/index.d.ts",
+		"../../node_modules/chai-typescript-typings/index.d.ts",
+		"../../node_modules/web3-typescript-typings/index.d.ts",
+		"../../node_modules/chai-as-promised-typescript-typings/index.d.ts",
+		"../../node_modules/types-ethereumjs-util/index.d.ts",
+		"../../node_modules/types-bn/index.d.ts",
+		"./globals.d.ts",
+		"./util/**/*",
+		"./test/**/*",
+		"./migrations/**/*",
+		"./deploy/**/*"
+	],
+	"exclude": ["./deploy/solc/solc_bin"]
 }
diff --git a/packages/contracts/tslint.json b/packages/contracts/tslint.json
index ffaefe83a..e63054bfc 100644
--- a/packages/contracts/tslint.json
+++ b/packages/contracts/tslint.json
@@ -1,3 +1,3 @@
 {
-    "extends": ["@0xproject/tslint-config"]
+	"extends": ["@0xproject/tslint-config"]
 }
diff --git a/packages/contracts/util/artifacts.ts b/packages/contracts/util/artifacts.ts
index ecb18cbce..ab9518d41 100644
--- a/packages/contracts/util/artifacts.ts
+++ b/packages/contracts/util/artifacts.ts
@@ -1,28 +1,28 @@
 export class Artifacts {
-    public Migrations: any;
-    public TokenTransferProxy: any;
-    public TokenRegistry: any;
-    public MultiSigWalletWithTimeLock: any;
-    public Exchange: any;
-    public ZRXToken: any;
-    public DummyToken: any;
-    public DummyTokenV2: any;
-    public EtherToken: any;
-    public MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress: any;
-    public MaliciousToken: any;
-    constructor(artifacts: any) {
-        this.Migrations = artifacts.require('Migrations');
-        this.TokenTransferProxy = artifacts.require('TokenTransferProxy');
-        this.TokenRegistry = artifacts.require('TokenRegistry');
-        this.MultiSigWalletWithTimeLock = artifacts.require('MultiSigWalletWithTimeLock');
-        this.Exchange = artifacts.require('Exchange');
-        this.ZRXToken = artifacts.require('ZRXToken');
-        this.DummyToken = artifacts.require('DummyToken');
-        this.DummyTokenV2 = artifacts.require('DummyToken_v2');
-        this.EtherToken = artifacts.require('WETH9');
-        this.MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress = artifacts.require(
-            'MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress',
-        );
-        this.MaliciousToken = artifacts.require('MaliciousToken');
-    }
+	public Migrations: any;
+	public TokenTransferProxy: any;
+	public TokenRegistry: any;
+	public MultiSigWalletWithTimeLock: any;
+	public Exchange: any;
+	public ZRXToken: any;
+	public DummyToken: any;
+	public DummyTokenV2: any;
+	public EtherToken: any;
+	public MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress: any;
+	public MaliciousToken: any;
+	constructor(artifacts: any) {
+		this.Migrations = artifacts.require('Migrations');
+		this.TokenTransferProxy = artifacts.require('TokenTransferProxy');
+		this.TokenRegistry = artifacts.require('TokenRegistry');
+		this.MultiSigWalletWithTimeLock = artifacts.require('MultiSigWalletWithTimeLock');
+		this.Exchange = artifacts.require('Exchange');
+		this.ZRXToken = artifacts.require('ZRXToken');
+		this.DummyToken = artifacts.require('DummyToken');
+		this.DummyTokenV2 = artifacts.require('DummyToken_v2');
+		this.EtherToken = artifacts.require('WETH9');
+		this.MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress = artifacts.require(
+			'MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress',
+		);
+		this.MaliciousToken = artifacts.require('MaliciousToken');
+	}
 }
diff --git a/packages/contracts/util/balances.ts b/packages/contracts/util/balances.ts
index 6a1659ab1..f8c103670 100644
--- a/packages/contracts/util/balances.ts
+++ b/packages/contracts/util/balances.ts
@@ -4,24 +4,24 @@ import * as _ from 'lodash';
 import { BalancesByOwner, ContractInstance } from './types';
 
 export class Balances {
-    private _tokenContractInstances: ContractInstance[];
-    private _ownerAddresses: string[];
-    constructor(tokenContractInstances: ContractInstance[], ownerAddresses: string[]) {
-        this._tokenContractInstances = tokenContractInstances;
-        this._ownerAddresses = ownerAddresses;
-    }
-    public async getAsync(): Promise<BalancesByOwner> {
-        const balancesByOwner: BalancesByOwner = {};
-        for (const tokenContractInstance of this._tokenContractInstances) {
-            for (const ownerAddress of this._ownerAddresses) {
-                let balance = await tokenContractInstance.balanceOf(ownerAddress);
-                balance = new BigNumber(balance);
-                if (_.isUndefined(balancesByOwner[ownerAddress])) {
-                    balancesByOwner[ownerAddress] = {};
-                }
-                balancesByOwner[ownerAddress][tokenContractInstance.address] = balance;
-            }
-        }
-        return balancesByOwner;
-    }
+	private _tokenContractInstances: ContractInstance[];
+	private _ownerAddresses: string[];
+	constructor(tokenContractInstances: ContractInstance[], ownerAddresses: string[]) {
+		this._tokenContractInstances = tokenContractInstances;
+		this._ownerAddresses = ownerAddresses;
+	}
+	public async getAsync(): Promise<BalancesByOwner> {
+		const balancesByOwner: BalancesByOwner = {};
+		for (const tokenContractInstance of this._tokenContractInstances) {
+			for (const ownerAddress of this._ownerAddresses) {
+				let balance = await tokenContractInstance.balanceOf(ownerAddress);
+				balance = new BigNumber(balance);
+				if (_.isUndefined(balancesByOwner[ownerAddress])) {
+					balancesByOwner[ownerAddress] = {};
+				}
+				balancesByOwner[ownerAddress][tokenContractInstance.address] = balance;
+			}
+		}
+		return balancesByOwner;
+	}
 }
diff --git a/packages/contracts/util/constants.ts b/packages/contracts/util/constants.ts
index e61b2f802..85fd31be3 100644
--- a/packages/contracts/util/constants.ts
+++ b/packages/contracts/util/constants.ts
@@ -1,9 +1,9 @@
 export const constants = {
-    NULL_BYTES: '0x',
-    INVALID_OPCODE: 'invalid opcode',
-    REVERT: 'revert',
-    TESTRPC_NETWORK_ID: 50,
-    MAX_ETHERTOKEN_WITHDRAW_GAS: 43000,
-    MAX_TOKEN_TRANSFERFROM_GAS: 80000,
-    MAX_TOKEN_APPROVE_GAS: 60000,
+	NULL_BYTES: '0x',
+	INVALID_OPCODE: 'invalid opcode',
+	REVERT: 'revert',
+	TESTRPC_NETWORK_ID: 50,
+	MAX_ETHERTOKEN_WITHDRAW_GAS: 43000,
+	MAX_TOKEN_TRANSFERFROM_GAS: 80000,
+	MAX_TOKEN_APPROVE_GAS: 60000,
 };
diff --git a/packages/contracts/util/crypto.ts b/packages/contracts/util/crypto.ts
index 9173df643..29bbf206a 100644
--- a/packages/contracts/util/crypto.ts
+++ b/packages/contracts/util/crypto.ts
@@ -4,7 +4,7 @@ import ethUtil = require('ethereumjs-util');
 import * as _ from 'lodash';
 
 export const crypto = {
-    /*
+	/*
    * We convert types from JS to Solidity as follows:
    * BigNumber -> uint256
    * number -> uint8
@@ -12,26 +12,26 @@ export const crypto = {
    * boolean -> bool
    * valid Ethereum address -> address
    */
-    solSHA3(args: any[]): Buffer {
-        const argTypes: string[] = [];
-        _.each(args, (arg, i) => {
-            const isNumber = _.isFinite(arg);
-            if (isNumber) {
-                argTypes.push('uint8');
-            } else if (arg.isBigNumber) {
-                argTypes.push('uint256');
-                args[i] = new BN(arg.toString(10), 10);
-            } else if (ethUtil.isValidAddress(arg)) {
-                argTypes.push('address');
-            } else if (_.isString(arg)) {
-                argTypes.push('string');
-            } else if (_.isBoolean(arg)) {
-                argTypes.push('bool');
-            } else {
-                throw new Error(`Unable to guess arg type: ${arg}`);
-            }
-        });
-        const hash = ABI.soliditySHA3(argTypes, args);
-        return hash;
-    },
+	solSHA3(args: any[]): Buffer {
+		const argTypes: string[] = [];
+		_.each(args, (arg, i) => {
+			const isNumber = _.isFinite(arg);
+			if (isNumber) {
+				argTypes.push('uint8');
+			} else if (arg.isBigNumber) {
+				argTypes.push('uint256');
+				args[i] = new BN(arg.toString(10), 10);
+			} else if (ethUtil.isValidAddress(arg)) {
+				argTypes.push('address');
+			} else if (_.isString(arg)) {
+				argTypes.push('string');
+			} else if (_.isBoolean(arg)) {
+				argTypes.push('bool');
+			} else {
+				throw new Error(`Unable to guess arg type: ${arg}`);
+			}
+		});
+		const hash = ABI.soliditySHA3(argTypes, args);
+		return hash;
+	},
 };
diff --git a/packages/contracts/util/exchange_wrapper.ts b/packages/contracts/util/exchange_wrapper.ts
index ca79f92c4..3a3c44aae 100644
--- a/packages/contracts/util/exchange_wrapper.ts
+++ b/packages/contracts/util/exchange_wrapper.ts
@@ -6,186 +6,186 @@ import { Order } from './order';
 import { ContractInstance } from './types';
 
 export class ExchangeWrapper {
-    private _exchange: ContractInstance;
-    constructor(exchangeContractInstance: ContractInstance) {
-        this._exchange = exchangeContractInstance;
-    }
-    public async fillOrderAsync(
-        order: Order,
-        from: string,
-        opts: {
-            fillTakerTokenAmount?: BigNumber;
-            shouldThrowOnInsufficientBalanceOrAllowance?: boolean;
-        } = {},
-    ) {
-        const shouldThrowOnInsufficientBalanceOrAllowance = !!opts.shouldThrowOnInsufficientBalanceOrAllowance;
-        const params = order.createFill(shouldThrowOnInsufficientBalanceOrAllowance, opts.fillTakerTokenAmount);
-        const tx = await this._exchange.fillOrder(
-            params.orderAddresses,
-            params.orderValues,
-            params.fillTakerTokenAmount,
-            params.shouldThrowOnInsufficientBalanceOrAllowance,
-            params.v,
-            params.r,
-            params.s,
-            { from },
-        );
-        _.each(tx.logs, log => wrapLogBigNumbers(log));
-        return tx;
-    }
-    public async cancelOrderAsync(order: Order, from: string, opts: { cancelTakerTokenAmount?: BigNumber } = {}) {
-        const params = order.createCancel(opts.cancelTakerTokenAmount);
-        const tx = await this._exchange.cancelOrder(
-            params.orderAddresses,
-            params.orderValues,
-            params.cancelTakerTokenAmount,
-            { from },
-        );
-        _.each(tx.logs, log => wrapLogBigNumbers(log));
-        return tx;
-    }
-    public async fillOrKillOrderAsync(order: Order, from: string, opts: { fillTakerTokenAmount?: BigNumber } = {}) {
-        const shouldThrowOnInsufficientBalanceOrAllowance = true;
-        const params = order.createFill(shouldThrowOnInsufficientBalanceOrAllowance, opts.fillTakerTokenAmount);
-        const tx = await this._exchange.fillOrKillOrder(
-            params.orderAddresses,
-            params.orderValues,
-            params.fillTakerTokenAmount,
-            params.v,
-            params.r,
-            params.s,
-            { from },
-        );
-        _.each(tx.logs, log => wrapLogBigNumbers(log));
-        return tx;
-    }
-    public async batchFillOrdersAsync(
-        orders: Order[],
-        from: string,
-        opts: {
-            fillTakerTokenAmounts?: BigNumber[];
-            shouldThrowOnInsufficientBalanceOrAllowance?: boolean;
-        } = {},
-    ) {
-        const shouldThrowOnInsufficientBalanceOrAllowance = !!opts.shouldThrowOnInsufficientBalanceOrAllowance;
-        const params = formatters.createBatchFill(
-            orders,
-            shouldThrowOnInsufficientBalanceOrAllowance,
-            opts.fillTakerTokenAmounts,
-        );
-        const tx = await this._exchange.batchFillOrders(
-            params.orderAddresses,
-            params.orderValues,
-            params.fillTakerTokenAmounts,
-            params.shouldThrowOnInsufficientBalanceOrAllowance,
-            params.v,
-            params.r,
-            params.s,
-            { from },
-        );
-        _.each(tx.logs, log => wrapLogBigNumbers(log));
-        return tx;
-    }
-    public async batchFillOrKillOrdersAsync(
-        orders: Order[],
-        from: string,
-        opts: { fillTakerTokenAmounts?: BigNumber[] } = {},
-    ) {
-        const params = formatters.createBatchFill(orders, undefined, opts.fillTakerTokenAmounts);
-        const tx = await this._exchange.batchFillOrKillOrders(
-            params.orderAddresses,
-            params.orderValues,
-            params.fillTakerTokenAmounts,
-            params.v,
-            params.r,
-            params.s,
-            { from },
-        );
-        _.each(tx.logs, log => wrapLogBigNumbers(log));
-        return tx;
-    }
-    public async fillOrdersUpToAsync(
-        orders: Order[],
-        from: string,
-        opts: {
-            fillTakerTokenAmount?: BigNumber;
-            shouldThrowOnInsufficientBalanceOrAllowance?: boolean;
-        } = {},
-    ) {
-        const shouldThrowOnInsufficientBalanceOrAllowance = !!opts.shouldThrowOnInsufficientBalanceOrAllowance;
-        const params = formatters.createFillUpTo(
-            orders,
-            shouldThrowOnInsufficientBalanceOrAllowance,
-            opts.fillTakerTokenAmount,
-        );
-        const tx = await this._exchange.fillOrdersUpTo(
-            params.orderAddresses,
-            params.orderValues,
-            params.fillTakerTokenAmount,
-            params.shouldThrowOnInsufficientBalanceOrAllowance,
-            params.v,
-            params.r,
-            params.s,
-            { from },
-        );
-        _.each(tx.logs, log => wrapLogBigNumbers(log));
-        return tx;
-    }
-    public async batchCancelOrdersAsync(
-        orders: Order[],
-        from: string,
-        opts: { cancelTakerTokenAmounts?: BigNumber[] } = {},
-    ) {
-        const params = formatters.createBatchCancel(orders, opts.cancelTakerTokenAmounts);
-        const tx = await this._exchange.batchCancelOrders(
-            params.orderAddresses,
-            params.orderValues,
-            params.cancelTakerTokenAmounts,
-            { from },
-        );
-        _.each(tx.logs, log => wrapLogBigNumbers(log));
-        return tx;
-    }
-    public async getOrderHashAsync(order: Order): Promise<string> {
-        const shouldThrowOnInsufficientBalanceOrAllowance = false;
-        const params = order.createFill(shouldThrowOnInsufficientBalanceOrAllowance);
-        const orderHash = await this._exchange.getOrderHash(params.orderAddresses, params.orderValues);
-        return orderHash;
-    }
-    public async isValidSignatureAsync(order: Order): Promise<boolean> {
-        const isValidSignature = await this._exchange.isValidSignature(
-            order.params.maker,
-            order.params.orderHashHex,
-            order.params.v,
-            order.params.r,
-            order.params.s,
-        );
-        return isValidSignature;
-    }
-    public async isRoundingErrorAsync(
-        numerator: BigNumber,
-        denominator: BigNumber,
-        target: BigNumber,
-    ): Promise<boolean> {
-        const isRoundingError = await this._exchange.isRoundingError(numerator, denominator, target);
-        return isRoundingError;
-    }
-    public async getPartialAmountAsync(
-        numerator: BigNumber,
-        denominator: BigNumber,
-        target: BigNumber,
-    ): Promise<BigNumber> {
-        const partialAmount = new BigNumber(await this._exchange.getPartialAmount(numerator, denominator, target));
-        return partialAmount;
-    }
+	private _exchange: ContractInstance;
+	constructor(exchangeContractInstance: ContractInstance) {
+		this._exchange = exchangeContractInstance;
+	}
+	public async fillOrderAsync(
+		order: Order,
+		from: string,
+		opts: {
+			fillTakerTokenAmount?: BigNumber;
+			shouldThrowOnInsufficientBalanceOrAllowance?: boolean;
+		} = {},
+	) {
+		const shouldThrowOnInsufficientBalanceOrAllowance = !!opts.shouldThrowOnInsufficientBalanceOrAllowance;
+		const params = order.createFill(shouldThrowOnInsufficientBalanceOrAllowance, opts.fillTakerTokenAmount);
+		const tx = await this._exchange.fillOrder(
+			params.orderAddresses,
+			params.orderValues,
+			params.fillTakerTokenAmount,
+			params.shouldThrowOnInsufficientBalanceOrAllowance,
+			params.v,
+			params.r,
+			params.s,
+			{ from },
+		);
+		_.each(tx.logs, log => wrapLogBigNumbers(log));
+		return tx;
+	}
+	public async cancelOrderAsync(order: Order, from: string, opts: { cancelTakerTokenAmount?: BigNumber } = {}) {
+		const params = order.createCancel(opts.cancelTakerTokenAmount);
+		const tx = await this._exchange.cancelOrder(
+			params.orderAddresses,
+			params.orderValues,
+			params.cancelTakerTokenAmount,
+			{ from },
+		);
+		_.each(tx.logs, log => wrapLogBigNumbers(log));
+		return tx;
+	}
+	public async fillOrKillOrderAsync(order: Order, from: string, opts: { fillTakerTokenAmount?: BigNumber } = {}) {
+		const shouldThrowOnInsufficientBalanceOrAllowance = true;
+		const params = order.createFill(shouldThrowOnInsufficientBalanceOrAllowance, opts.fillTakerTokenAmount);
+		const tx = await this._exchange.fillOrKillOrder(
+			params.orderAddresses,
+			params.orderValues,
+			params.fillTakerTokenAmount,
+			params.v,
+			params.r,
+			params.s,
+			{ from },
+		);
+		_.each(tx.logs, log => wrapLogBigNumbers(log));
+		return tx;
+	}
+	public async batchFillOrdersAsync(
+		orders: Order[],
+		from: string,
+		opts: {
+			fillTakerTokenAmounts?: BigNumber[];
+			shouldThrowOnInsufficientBalanceOrAllowance?: boolean;
+		} = {},
+	) {
+		const shouldThrowOnInsufficientBalanceOrAllowance = !!opts.shouldThrowOnInsufficientBalanceOrAllowance;
+		const params = formatters.createBatchFill(
+			orders,
+			shouldThrowOnInsufficientBalanceOrAllowance,
+			opts.fillTakerTokenAmounts,
+		);
+		const tx = await this._exchange.batchFillOrders(
+			params.orderAddresses,
+			params.orderValues,
+			params.fillTakerTokenAmounts,
+			params.shouldThrowOnInsufficientBalanceOrAllowance,
+			params.v,
+			params.r,
+			params.s,
+			{ from },
+		);
+		_.each(tx.logs, log => wrapLogBigNumbers(log));
+		return tx;
+	}
+	public async batchFillOrKillOrdersAsync(
+		orders: Order[],
+		from: string,
+		opts: { fillTakerTokenAmounts?: BigNumber[] } = {},
+	) {
+		const params = formatters.createBatchFill(orders, undefined, opts.fillTakerTokenAmounts);
+		const tx = await this._exchange.batchFillOrKillOrders(
+			params.orderAddresses,
+			params.orderValues,
+			params.fillTakerTokenAmounts,
+			params.v,
+			params.r,
+			params.s,
+			{ from },
+		);
+		_.each(tx.logs, log => wrapLogBigNumbers(log));
+		return tx;
+	}
+	public async fillOrdersUpToAsync(
+		orders: Order[],
+		from: string,
+		opts: {
+			fillTakerTokenAmount?: BigNumber;
+			shouldThrowOnInsufficientBalanceOrAllowance?: boolean;
+		} = {},
+	) {
+		const shouldThrowOnInsufficientBalanceOrAllowance = !!opts.shouldThrowOnInsufficientBalanceOrAllowance;
+		const params = formatters.createFillUpTo(
+			orders,
+			shouldThrowOnInsufficientBalanceOrAllowance,
+			opts.fillTakerTokenAmount,
+		);
+		const tx = await this._exchange.fillOrdersUpTo(
+			params.orderAddresses,
+			params.orderValues,
+			params.fillTakerTokenAmount,
+			params.shouldThrowOnInsufficientBalanceOrAllowance,
+			params.v,
+			params.r,
+			params.s,
+			{ from },
+		);
+		_.each(tx.logs, log => wrapLogBigNumbers(log));
+		return tx;
+	}
+	public async batchCancelOrdersAsync(
+		orders: Order[],
+		from: string,
+		opts: { cancelTakerTokenAmounts?: BigNumber[] } = {},
+	) {
+		const params = formatters.createBatchCancel(orders, opts.cancelTakerTokenAmounts);
+		const tx = await this._exchange.batchCancelOrders(
+			params.orderAddresses,
+			params.orderValues,
+			params.cancelTakerTokenAmounts,
+			{ from },
+		);
+		_.each(tx.logs, log => wrapLogBigNumbers(log));
+		return tx;
+	}
+	public async getOrderHashAsync(order: Order): Promise<string> {
+		const shouldThrowOnInsufficientBalanceOrAllowance = false;
+		const params = order.createFill(shouldThrowOnInsufficientBalanceOrAllowance);
+		const orderHash = await this._exchange.getOrderHash(params.orderAddresses, params.orderValues);
+		return orderHash;
+	}
+	public async isValidSignatureAsync(order: Order): Promise<boolean> {
+		const isValidSignature = await this._exchange.isValidSignature(
+			order.params.maker,
+			order.params.orderHashHex,
+			order.params.v,
+			order.params.r,
+			order.params.s,
+		);
+		return isValidSignature;
+	}
+	public async isRoundingErrorAsync(
+		numerator: BigNumber,
+		denominator: BigNumber,
+		target: BigNumber,
+	): Promise<boolean> {
+		const isRoundingError = await this._exchange.isRoundingError(numerator, denominator, target);
+		return isRoundingError;
+	}
+	public async getPartialAmountAsync(
+		numerator: BigNumber,
+		denominator: BigNumber,
+		target: BigNumber,
+	): Promise<BigNumber> {
+		const partialAmount = new BigNumber(await this._exchange.getPartialAmount(numerator, denominator, target));
+		return partialAmount;
+	}
 }
 
 function wrapLogBigNumbers(log: any): any {
-    const argNames = _.keys(log.args);
-    for (const argName of argNames) {
-        const isWeb3BigNumber = _.startsWith(log.args[argName].constructor.toString(), 'function BigNumber(');
-        if (isWeb3BigNumber) {
-            log.args[argName] = new BigNumber(log.args[argName]);
-        }
-    }
+	const argNames = _.keys(log.args);
+	for (const argName of argNames) {
+		const isWeb3BigNumber = _.startsWith(log.args[argName].constructor.toString(), 'function BigNumber(');
+		if (isWeb3BigNumber) {
+			log.args[argName] = new BigNumber(log.args[argName]);
+		}
+	}
 }
diff --git a/packages/contracts/util/formatters.ts b/packages/contracts/util/formatters.ts
index 0d0ef6df4..c452b8e79 100644
--- a/packages/contracts/util/formatters.ts
+++ b/packages/contracts/util/formatters.ts
@@ -5,107 +5,107 @@ import { Order } from './order';
 import { BatchCancelOrders, BatchFillOrders, FillOrdersUpTo } from './types';
 
 export const formatters = {
-    createBatchFill(
-        orders: Order[],
-        shouldThrowOnInsufficientBalanceOrAllowance: boolean,
-        fillTakerTokenAmounts: BigNumber[] = [],
-    ) {
-        const batchFill: BatchFillOrders = {
-            orderAddresses: [],
-            orderValues: [],
-            fillTakerTokenAmounts,
-            shouldThrowOnInsufficientBalanceOrAllowance,
-            v: [],
-            r: [],
-            s: [],
-        };
-        _.forEach(orders, order => {
-            batchFill.orderAddresses.push([
-                order.params.maker,
-                order.params.taker,
-                order.params.makerToken,
-                order.params.takerToken,
-                order.params.feeRecipient,
-            ]);
-            batchFill.orderValues.push([
-                order.params.makerTokenAmount,
-                order.params.takerTokenAmount,
-                order.params.makerFee,
-                order.params.takerFee,
-                order.params.expirationTimestampInSec,
-                order.params.salt,
-            ]);
-            batchFill.v.push(order.params.v);
-            batchFill.r.push(order.params.r);
-            batchFill.s.push(order.params.s);
-            if (fillTakerTokenAmounts.length < orders.length) {
-                batchFill.fillTakerTokenAmounts.push(order.params.takerTokenAmount);
-            }
-        });
-        return batchFill;
-    },
-    createFillUpTo(
-        orders: Order[],
-        shouldThrowOnInsufficientBalanceOrAllowance: boolean,
-        fillTakerTokenAmount: BigNumber,
-    ) {
-        const fillUpTo: FillOrdersUpTo = {
-            orderAddresses: [],
-            orderValues: [],
-            fillTakerTokenAmount,
-            shouldThrowOnInsufficientBalanceOrAllowance,
-            v: [],
-            r: [],
-            s: [],
-        };
-        orders.forEach(order => {
-            fillUpTo.orderAddresses.push([
-                order.params.maker,
-                order.params.taker,
-                order.params.makerToken,
-                order.params.takerToken,
-                order.params.feeRecipient,
-            ]);
-            fillUpTo.orderValues.push([
-                order.params.makerTokenAmount,
-                order.params.takerTokenAmount,
-                order.params.makerFee,
-                order.params.takerFee,
-                order.params.expirationTimestampInSec,
-                order.params.salt,
-            ]);
-            fillUpTo.v.push(order.params.v);
-            fillUpTo.r.push(order.params.r);
-            fillUpTo.s.push(order.params.s);
-        });
-        return fillUpTo;
-    },
-    createBatchCancel(orders: Order[], cancelTakerTokenAmounts: BigNumber[] = []) {
-        const batchCancel: BatchCancelOrders = {
-            orderAddresses: [],
-            orderValues: [],
-            cancelTakerTokenAmounts,
-        };
-        orders.forEach(order => {
-            batchCancel.orderAddresses.push([
-                order.params.maker,
-                order.params.taker,
-                order.params.makerToken,
-                order.params.takerToken,
-                order.params.feeRecipient,
-            ]);
-            batchCancel.orderValues.push([
-                order.params.makerTokenAmount,
-                order.params.takerTokenAmount,
-                order.params.makerFee,
-                order.params.takerFee,
-                order.params.expirationTimestampInSec,
-                order.params.salt,
-            ]);
-            if (cancelTakerTokenAmounts.length < orders.length) {
-                batchCancel.cancelTakerTokenAmounts.push(order.params.takerTokenAmount);
-            }
-        });
-        return batchCancel;
-    },
+	createBatchFill(
+		orders: Order[],
+		shouldThrowOnInsufficientBalanceOrAllowance: boolean,
+		fillTakerTokenAmounts: BigNumber[] = [],
+	) {
+		const batchFill: BatchFillOrders = {
+			orderAddresses: [],
+			orderValues: [],
+			fillTakerTokenAmounts,
+			shouldThrowOnInsufficientBalanceOrAllowance,
+			v: [],
+			r: [],
+			s: [],
+		};
+		_.forEach(orders, order => {
+			batchFill.orderAddresses.push([
+				order.params.maker,
+				order.params.taker,
+				order.params.makerToken,
+				order.params.takerToken,
+				order.params.feeRecipient,
+			]);
+			batchFill.orderValues.push([
+				order.params.makerTokenAmount,
+				order.params.takerTokenAmount,
+				order.params.makerFee,
+				order.params.takerFee,
+				order.params.expirationTimestampInSec,
+				order.params.salt,
+			]);
+			batchFill.v.push(order.params.v);
+			batchFill.r.push(order.params.r);
+			batchFill.s.push(order.params.s);
+			if (fillTakerTokenAmounts.length < orders.length) {
+				batchFill.fillTakerTokenAmounts.push(order.params.takerTokenAmount);
+			}
+		});
+		return batchFill;
+	},
+	createFillUpTo(
+		orders: Order[],
+		shouldThrowOnInsufficientBalanceOrAllowance: boolean,
+		fillTakerTokenAmount: BigNumber,
+	) {
+		const fillUpTo: FillOrdersUpTo = {
+			orderAddresses: [],
+			orderValues: [],
+			fillTakerTokenAmount,
+			shouldThrowOnInsufficientBalanceOrAllowance,
+			v: [],
+			r: [],
+			s: [],
+		};
+		orders.forEach(order => {
+			fillUpTo.orderAddresses.push([
+				order.params.maker,
+				order.params.taker,
+				order.params.makerToken,
+				order.params.takerToken,
+				order.params.feeRecipient,
+			]);
+			fillUpTo.orderValues.push([
+				order.params.makerTokenAmount,
+				order.params.takerTokenAmount,
+				order.params.makerFee,
+				order.params.takerFee,
+				order.params.expirationTimestampInSec,
+				order.params.salt,
+			]);
+			fillUpTo.v.push(order.params.v);
+			fillUpTo.r.push(order.params.r);
+			fillUpTo.s.push(order.params.s);
+		});
+		return fillUpTo;
+	},
+	createBatchCancel(orders: Order[], cancelTakerTokenAmounts: BigNumber[] = []) {
+		const batchCancel: BatchCancelOrders = {
+			orderAddresses: [],
+			orderValues: [],
+			cancelTakerTokenAmounts,
+		};
+		orders.forEach(order => {
+			batchCancel.orderAddresses.push([
+				order.params.maker,
+				order.params.taker,
+				order.params.makerToken,
+				order.params.takerToken,
+				order.params.feeRecipient,
+			]);
+			batchCancel.orderValues.push([
+				order.params.makerTokenAmount,
+				order.params.takerTokenAmount,
+				order.params.makerFee,
+				order.params.takerFee,
+				order.params.expirationTimestampInSec,
+				order.params.salt,
+			]);
+			if (cancelTakerTokenAmounts.length < orders.length) {
+				batchCancel.cancelTakerTokenAmounts.push(order.params.takerTokenAmount);
+			}
+		});
+		return batchCancel;
+	},
 };
diff --git a/packages/contracts/util/multi_sig_wrapper.ts b/packages/contracts/util/multi_sig_wrapper.ts
index 0e2e671ec..ca9f07ce5 100644
--- a/packages/contracts/util/multi_sig_wrapper.ts
+++ b/packages/contracts/util/multi_sig_wrapper.ts
@@ -6,34 +6,34 @@ import * as Web3 from 'web3';
 import { ContractInstance, TransactionDataParams } from './types';
 
 export class MultiSigWrapper {
-    private _multiSig: ContractInstance;
-    public static encodeFnArgs(name: string, abi: Web3.AbiDefinition[], args: any[]) {
-        const abiEntity = _.find(abi, { name }) as Web3.MethodAbi;
-        if (_.isUndefined(abiEntity)) {
-            throw new Error(`Did not find abi entry for name: ${name}`);
-        }
-        const types = _.map(abiEntity.inputs, input => input.type);
-        const funcSig = ethUtil.bufferToHex(ABI.methodID(name, types));
-        const argsData = _.map(args, arg => {
-            const target = _.isBoolean(arg) ? +arg : arg;
-            const targetBuff = ethUtil.toBuffer(target);
-            return ethUtil.setLengthLeft(targetBuff, 32).toString('hex');
-        });
-        return funcSig + argsData.join('');
-    }
-    constructor(multiSigContractInstance: ContractInstance) {
-        this._multiSig = multiSigContractInstance;
-    }
-    public async submitTransactionAsync(
-        destination: string,
-        from: string,
-        dataParams: TransactionDataParams,
-        value: number = 0,
-    ) {
-        const { name, abi, args = [] } = dataParams;
-        const encoded = MultiSigWrapper.encodeFnArgs(name, abi, args);
-        return this._multiSig.submitTransaction(destination, value, encoded, {
-            from,
-        });
-    }
+	private _multiSig: ContractInstance;
+	public static encodeFnArgs(name: string, abi: Web3.AbiDefinition[], args: any[]) {
+		const abiEntity = _.find(abi, { name }) as Web3.MethodAbi;
+		if (_.isUndefined(abiEntity)) {
+			throw new Error(`Did not find abi entry for name: ${name}`);
+		}
+		const types = _.map(abiEntity.inputs, input => input.type);
+		const funcSig = ethUtil.bufferToHex(ABI.methodID(name, types));
+		const argsData = _.map(args, arg => {
+			const target = _.isBoolean(arg) ? +arg : arg;
+			const targetBuff = ethUtil.toBuffer(target);
+			return ethUtil.setLengthLeft(targetBuff, 32).toString('hex');
+		});
+		return funcSig + argsData.join('');
+	}
+	constructor(multiSigContractInstance: ContractInstance) {
+		this._multiSig = multiSigContractInstance;
+	}
+	public async submitTransactionAsync(
+		destination: string,
+		from: string,
+		dataParams: TransactionDataParams,
+		value: number = 0,
+	) {
+		const { name, abi, args = [] } = dataParams;
+		const encoded = MultiSigWrapper.encodeFnArgs(name, abi, args);
+		return this._multiSig.submitTransaction(destination, value, encoded, {
+			from,
+		});
+	}
 }
diff --git a/packages/contracts/util/order.ts b/packages/contracts/util/order.ts
index e202d485b..31194c03e 100644
--- a/packages/contracts/util/order.ts
+++ b/packages/contracts/util/order.ts
@@ -11,98 +11,98 @@ import { OrderParams } from './types';
 const web3: Web3 = (global as any).web3;
 
 export class Order {
-    public params: OrderParams;
-    constructor(params: OrderParams) {
-        this.params = params;
-    }
-    public isValidSignature() {
-        const { v, r, s } = this.params;
-        if (_.isUndefined(v) || _.isUndefined(r) || _.isUndefined(s)) {
-            throw new Error('Cannot call isValidSignature on unsigned order');
-        }
-        const orderHash = this._getOrderHash();
-        const msgHash = ethUtil.hashPersonalMessage(ethUtil.toBuffer(orderHash));
-        try {
-            const pubKey = ethUtil.ecrecover(msgHash, v, ethUtil.toBuffer(r), ethUtil.toBuffer(s));
-            const recoveredAddress = ethUtil.bufferToHex(ethUtil.pubToAddress(pubKey));
-            return recoveredAddress === this.params.maker;
-        } catch (err) {
-            return false;
-        }
-    }
-    public async signAsync() {
-        const orderHash = this._getOrderHash();
-        const signature = await promisify<string>(web3.eth.sign)(this.params.maker, orderHash);
-        const { v, r, s } = ethUtil.fromRpcSig(signature);
-        this.params = _.assign(this.params, {
-            orderHashHex: orderHash,
-            v,
-            r: ethUtil.bufferToHex(r),
-            s: ethUtil.bufferToHex(s),
-        });
-    }
-    public createFill(shouldThrowOnInsufficientBalanceOrAllowance?: boolean, fillTakerTokenAmount?: BigNumber) {
-        const fill = {
-            orderAddresses: [
-                this.params.maker,
-                this.params.taker,
-                this.params.makerToken,
-                this.params.takerToken,
-                this.params.feeRecipient,
-            ],
-            orderValues: [
-                this.params.makerTokenAmount,
-                this.params.takerTokenAmount,
-                this.params.makerFee,
-                this.params.takerFee,
-                this.params.expirationTimestampInSec,
-                this.params.salt,
-            ],
-            fillTakerTokenAmount: fillTakerTokenAmount || this.params.takerTokenAmount,
-            shouldThrowOnInsufficientBalanceOrAllowance: !!shouldThrowOnInsufficientBalanceOrAllowance,
-            v: this.params.v,
-            r: this.params.r,
-            s: this.params.s,
-        };
-        return fill;
-    }
-    public createCancel(cancelTakerTokenAmount?: BigNumber) {
-        const cancel = {
-            orderAddresses: [
-                this.params.maker,
-                this.params.taker,
-                this.params.makerToken,
-                this.params.takerToken,
-                this.params.feeRecipient,
-            ],
-            orderValues: [
-                this.params.makerTokenAmount,
-                this.params.takerTokenAmount,
-                this.params.makerFee,
-                this.params.takerFee,
-                this.params.expirationTimestampInSec,
-                this.params.salt,
-            ],
-            cancelTakerTokenAmount: cancelTakerTokenAmount || this.params.takerTokenAmount,
-        };
-        return cancel;
-    }
-    private _getOrderHash(): string {
-        const orderHash = crypto.solSHA3([
-            this.params.exchangeContractAddress,
-            this.params.maker,
-            this.params.taker,
-            this.params.makerToken,
-            this.params.takerToken,
-            this.params.feeRecipient,
-            this.params.makerTokenAmount,
-            this.params.takerTokenAmount,
-            this.params.makerFee,
-            this.params.takerFee,
-            this.params.expirationTimestampInSec,
-            this.params.salt,
-        ]);
-        const orderHashHex = ethUtil.bufferToHex(orderHash);
-        return orderHashHex;
-    }
+	public params: OrderParams;
+	constructor(params: OrderParams) {
+		this.params = params;
+	}
+	public isValidSignature() {
+		const { v, r, s } = this.params;
+		if (_.isUndefined(v) || _.isUndefined(r) || _.isUndefined(s)) {
+			throw new Error('Cannot call isValidSignature on unsigned order');
+		}
+		const orderHash = this._getOrderHash();
+		const msgHash = ethUtil.hashPersonalMessage(ethUtil.toBuffer(orderHash));
+		try {
+			const pubKey = ethUtil.ecrecover(msgHash, v, ethUtil.toBuffer(r), ethUtil.toBuffer(s));
+			const recoveredAddress = ethUtil.bufferToHex(ethUtil.pubToAddress(pubKey));
+			return recoveredAddress === this.params.maker;
+		} catch (err) {
+			return false;
+		}
+	}
+	public async signAsync() {
+		const orderHash = this._getOrderHash();
+		const signature = await promisify<string>(web3.eth.sign)(this.params.maker, orderHash);
+		const { v, r, s } = ethUtil.fromRpcSig(signature);
+		this.params = _.assign(this.params, {
+			orderHashHex: orderHash,
+			v,
+			r: ethUtil.bufferToHex(r),
+			s: ethUtil.bufferToHex(s),
+		});
+	}
+	public createFill(shouldThrowOnInsufficientBalanceOrAllowance?: boolean, fillTakerTokenAmount?: BigNumber) {
+		const fill = {
+			orderAddresses: [
+				this.params.maker,
+				this.params.taker,
+				this.params.makerToken,
+				this.params.takerToken,
+				this.params.feeRecipient,
+			],
+			orderValues: [
+				this.params.makerTokenAmount,
+				this.params.takerTokenAmount,
+				this.params.makerFee,
+				this.params.takerFee,
+				this.params.expirationTimestampInSec,
+				this.params.salt,
+			],
+			fillTakerTokenAmount: fillTakerTokenAmount || this.params.takerTokenAmount,
+			shouldThrowOnInsufficientBalanceOrAllowance: !!shouldThrowOnInsufficientBalanceOrAllowance,
+			v: this.params.v,
+			r: this.params.r,
+			s: this.params.s,
+		};
+		return fill;
+	}
+	public createCancel(cancelTakerTokenAmount?: BigNumber) {
+		const cancel = {
+			orderAddresses: [
+				this.params.maker,
+				this.params.taker,
+				this.params.makerToken,
+				this.params.takerToken,
+				this.params.feeRecipient,
+			],
+			orderValues: [
+				this.params.makerTokenAmount,
+				this.params.takerTokenAmount,
+				this.params.makerFee,
+				this.params.takerFee,
+				this.params.expirationTimestampInSec,
+				this.params.salt,
+			],
+			cancelTakerTokenAmount: cancelTakerTokenAmount || this.params.takerTokenAmount,
+		};
+		return cancel;
+	}
+	private _getOrderHash(): string {
+		const orderHash = crypto.solSHA3([
+			this.params.exchangeContractAddress,
+			this.params.maker,
+			this.params.taker,
+			this.params.makerToken,
+			this.params.takerToken,
+			this.params.feeRecipient,
+			this.params.makerTokenAmount,
+			this.params.takerTokenAmount,
+			this.params.makerFee,
+			this.params.takerFee,
+			this.params.expirationTimestampInSec,
+			this.params.salt,
+		]);
+		const orderHashHex = ethUtil.bufferToHex(orderHash);
+		return orderHashHex;
+	}
 }
diff --git a/packages/contracts/util/order_factory.ts b/packages/contracts/util/order_factory.ts
index a45877de0..55034655b 100644
--- a/packages/contracts/util/order_factory.ts
+++ b/packages/contracts/util/order_factory.ts
@@ -6,24 +6,24 @@ import { Order } from './order';
 import { DefaultOrderParams, OptionalOrderParams, OrderParams } from './types';
 
 export class OrderFactory {
-    private _defaultOrderParams: DefaultOrderParams;
-    constructor(defaultOrderParams: DefaultOrderParams) {
-        this._defaultOrderParams = defaultOrderParams;
-    }
-    public async newSignedOrderAsync(customOrderParams: OptionalOrderParams = {}) {
-        const randomExpiration = new BigNumber(Math.floor((Date.now() + Math.random() * 100000000000) / 1000));
-        const orderParams: OrderParams = _.assign(
-            {},
-            {
-                expirationTimestampInSec: randomExpiration,
-                salt: ZeroEx.generatePseudoRandomSalt(),
-                taker: ZeroEx.NULL_ADDRESS,
-            },
-            this._defaultOrderParams,
-            customOrderParams,
-        );
-        const order = new Order(orderParams);
-        await order.signAsync();
-        return order;
-    }
+	private _defaultOrderParams: DefaultOrderParams;
+	constructor(defaultOrderParams: DefaultOrderParams) {
+		this._defaultOrderParams = defaultOrderParams;
+	}
+	public async newSignedOrderAsync(customOrderParams: OptionalOrderParams = {}) {
+		const randomExpiration = new BigNumber(Math.floor((Date.now() + Math.random() * 100000000000) / 1000));
+		const orderParams: OrderParams = _.assign(
+			{},
+			{
+				expirationTimestampInSec: randomExpiration,
+				salt: ZeroEx.generatePseudoRandomSalt(),
+				taker: ZeroEx.NULL_ADDRESS,
+			},
+			this._defaultOrderParams,
+			customOrderParams,
+		);
+		const order = new Order(orderParams);
+		await order.signAsync();
+		return order;
+	}
 }
diff --git a/packages/contracts/util/token_registry_wrapper.ts b/packages/contracts/util/token_registry_wrapper.ts
index 07a577dea..d1983db7c 100644
--- a/packages/contracts/util/token_registry_wrapper.ts
+++ b/packages/contracts/util/token_registry_wrapper.ts
@@ -1,56 +1,56 @@
 import { ContractInstance, Token } from './types';
 
 export class TokenRegWrapper {
-    private _tokenReg: ContractInstance;
-    constructor(tokenRegContractInstance: ContractInstance) {
-        this._tokenReg = tokenRegContractInstance;
-    }
-    public addTokenAsync(token: Token, from: string) {
-        const tx = this._tokenReg.addToken(
-            token.address,
-            token.name,
-            token.symbol,
-            token.decimals,
-            token.ipfsHash,
-            token.swarmHash,
-            { from },
-        );
-        return tx;
-    }
-    public async getTokenMetaDataAsync(tokenAddress: string) {
-        const data = await this._tokenReg.getTokenMetaData(tokenAddress);
-        const token: Token = {
-            address: data[0],
-            name: data[1],
-            symbol: data[2],
-            decimals: data[3].toNumber(),
-            ipfsHash: data[4],
-            swarmHash: data[5],
-        };
-        return token;
-    }
-    public async getTokenByNameAsync(tokenName: string) {
-        const data = await this._tokenReg.getTokenByName(tokenName);
-        const token: Token = {
-            address: data[0],
-            name: data[1],
-            symbol: data[2],
-            decimals: data[3].toNumber(),
-            ipfsHash: data[4],
-            swarmHash: data[5],
-        };
-        return token;
-    }
-    public async getTokenBySymbolAsync(tokenSymbol: string) {
-        const data = await this._tokenReg.getTokenBySymbol(tokenSymbol);
-        const token: Token = {
-            address: data[0],
-            name: data[1],
-            symbol: data[2],
-            decimals: data[3].toNumber(),
-            ipfsHash: data[4],
-            swarmHash: data[5],
-        };
-        return token;
-    }
+	private _tokenReg: ContractInstance;
+	constructor(tokenRegContractInstance: ContractInstance) {
+		this._tokenReg = tokenRegContractInstance;
+	}
+	public addTokenAsync(token: Token, from: string) {
+		const tx = this._tokenReg.addToken(
+			token.address,
+			token.name,
+			token.symbol,
+			token.decimals,
+			token.ipfsHash,
+			token.swarmHash,
+			{ from },
+		);
+		return tx;
+	}
+	public async getTokenMetaDataAsync(tokenAddress: string) {
+		const data = await this._tokenReg.getTokenMetaData(tokenAddress);
+		const token: Token = {
+			address: data[0],
+			name: data[1],
+			symbol: data[2],
+			decimals: data[3].toNumber(),
+			ipfsHash: data[4],
+			swarmHash: data[5],
+		};
+		return token;
+	}
+	public async getTokenByNameAsync(tokenName: string) {
+		const data = await this._tokenReg.getTokenByName(tokenName);
+		const token: Token = {
+			address: data[0],
+			name: data[1],
+			symbol: data[2],
+			decimals: data[3].toNumber(),
+			ipfsHash: data[4],
+			swarmHash: data[5],
+		};
+		return token;
+	}
+	public async getTokenBySymbolAsync(tokenSymbol: string) {
+		const data = await this._tokenReg.getTokenBySymbol(tokenSymbol);
+		const token: Token = {
+			address: data[0],
+			name: data[1],
+			symbol: data[2],
+			decimals: data[3].toNumber(),
+			ipfsHash: data[4],
+			swarmHash: data[5],
+		};
+		return token;
+	}
 }
diff --git a/packages/contracts/util/types.ts b/packages/contracts/util/types.ts
index e511ca9f4..675f3f17d 100644
--- a/packages/contracts/util/types.ts
+++ b/packages/contracts/util/types.ts
@@ -2,118 +2,118 @@ import { BigNumber } from '@0xproject/utils';
 import * as Web3 from 'web3';
 
 export interface BalancesByOwner {
-    [ownerAddress: string]: {
-        [tokenAddress: string]: BigNumber;
-    };
+	[ownerAddress: string]: {
+		[tokenAddress: string]: BigNumber;
+	};
 }
 
 export interface BatchFillOrders {
-    orderAddresses: string[][];
-    orderValues: BigNumber[][];
-    fillTakerTokenAmounts: BigNumber[];
-    shouldThrowOnInsufficientBalanceOrAllowance: boolean;
-    v: number[];
-    r: string[];
-    s: string[];
+	orderAddresses: string[][];
+	orderValues: BigNumber[][];
+	fillTakerTokenAmounts: BigNumber[];
+	shouldThrowOnInsufficientBalanceOrAllowance: boolean;
+	v: number[];
+	r: string[];
+	s: string[];
 }
 
 export interface FillOrdersUpTo {
-    orderAddresses: string[][];
-    orderValues: BigNumber[][];
-    fillTakerTokenAmount: BigNumber;
-    shouldThrowOnInsufficientBalanceOrAllowance: boolean;
-    v: number[];
-    r: string[];
-    s: string[];
+	orderAddresses: string[][];
+	orderValues: BigNumber[][];
+	fillTakerTokenAmount: BigNumber;
+	shouldThrowOnInsufficientBalanceOrAllowance: boolean;
+	v: number[];
+	r: string[];
+	s: string[];
 }
 
 export interface BatchCancelOrders {
-    orderAddresses: string[][];
-    orderValues: BigNumber[][];
-    cancelTakerTokenAmounts: BigNumber[];
+	orderAddresses: string[][];
+	orderValues: BigNumber[][];
+	cancelTakerTokenAmounts: BigNumber[];
 }
 
 export interface DefaultOrderParams {
-    exchangeContractAddress: string;
-    maker: string;
-    feeRecipient: string;
-    makerToken: string;
-    takerToken: string;
-    makerTokenAmount: BigNumber;
-    takerTokenAmount: BigNumber;
-    makerFee: BigNumber;
-    takerFee: BigNumber;
+	exchangeContractAddress: string;
+	maker: string;
+	feeRecipient: string;
+	makerToken: string;
+	takerToken: string;
+	makerTokenAmount: BigNumber;
+	takerTokenAmount: BigNumber;
+	makerFee: BigNumber;
+	takerFee: BigNumber;
 }
 
 export interface OptionalOrderParams {
-    exchangeContractAddress?: string;
-    maker?: string;
-    taker?: string;
-    feeRecipient?: string;
-    makerToken?: string;
-    takerToken?: string;
-    makerTokenAmount?: BigNumber;
-    takerTokenAmount?: BigNumber;
-    makerFee?: BigNumber;
-    takerFee?: BigNumber;
-    expirationTimestampInSec?: BigNumber;
+	exchangeContractAddress?: string;
+	maker?: string;
+	taker?: string;
+	feeRecipient?: string;
+	makerToken?: string;
+	takerToken?: string;
+	makerTokenAmount?: BigNumber;
+	takerTokenAmount?: BigNumber;
+	makerFee?: BigNumber;
+	takerFee?: BigNumber;
+	expirationTimestampInSec?: BigNumber;
 }
 
 export interface OrderParams {
-    exchangeContractAddress: string;
-    maker: string;
-    taker: string;
-    feeRecipient: string;
-    makerToken: string;
-    takerToken: string;
-    makerTokenAmount: BigNumber;
-    takerTokenAmount: BigNumber;
-    makerFee: BigNumber;
-    takerFee: BigNumber;
-    expirationTimestampInSec: BigNumber;
-    salt: BigNumber;
-    orderHashHex?: string;
-    v?: number;
-    r?: string;
-    s?: string;
+	exchangeContractAddress: string;
+	maker: string;
+	taker: string;
+	feeRecipient: string;
+	makerToken: string;
+	takerToken: string;
+	makerTokenAmount: BigNumber;
+	takerTokenAmount: BigNumber;
+	makerFee: BigNumber;
+	takerFee: BigNumber;
+	expirationTimestampInSec: BigNumber;
+	salt: BigNumber;
+	orderHashHex?: string;
+	v?: number;
+	r?: string;
+	s?: string;
 }
 
 export interface TransactionDataParams {
-    name: string;
-    abi: Web3.AbiDefinition[];
-    args: any[];
+	name: string;
+	abi: Web3.AbiDefinition[];
+	args: any[];
 }
 
 export interface MultiSigConfig {
-    owners: string[];
-    confirmationsRequired: number;
-    secondsRequired: number;
+	owners: string[];
+	confirmationsRequired: number;
+	secondsRequired: number;
 }
 
 export interface MultiSigConfigByNetwork {
-    [networkName: string]: MultiSigConfig;
+	[networkName: string]: MultiSigConfig;
 }
 
 export interface Token {
-    address?: string;
-    name: string;
-    symbol: string;
-    decimals: number;
-    ipfsHash: string;
-    swarmHash: string;
+	address?: string;
+	name: string;
+	symbol: string;
+	decimals: number;
+	ipfsHash: string;
+	swarmHash: string;
 }
 
 export interface TokenInfoByNetwork {
-    development: Token[];
-    live: Token[];
+	development: Token[];
+	live: Token[];
 }
 
 // Named type aliases to improve readability
 export type ContractInstance = any;
 
 export enum ExchangeContractErrs {
-    ERROR_ORDER_EXPIRED,
-    ERROR_ORDER_FULLY_FILLED_OR_CANCELLED,
-    ERROR_ROUNDING_ERROR_TOO_LARGE,
-    ERROR_INSUFFICIENT_BALANCE_OR_ALLOWANCE,
+	ERROR_ORDER_EXPIRED,
+	ERROR_ORDER_FULLY_FILLED_OR_CANCELLED,
+	ERROR_ROUNDING_ERROR_TOO_LARGE,
+	ERROR_INSUFFICIENT_BALANCE_OR_ALLOWANCE,
 }
diff --git a/packages/deployer/package.json b/packages/deployer/package.json
index 423d3bad8..f78f49497 100644
--- a/packages/deployer/package.json
+++ b/packages/deployer/package.json
@@ -1,43 +1,43 @@
 {
-    "name": "@0xproject/deployer",
-    "version": "0.0.3",
-    "description": "Smart contract deployer of 0x protocol",
-    "main": "lib/src/cli.js",
-    "scripts": {
-        "build": "yarn clean && copyfiles 'test/fixtures/contracts/**/*' src/solc/solc_bin/* ./lib && tsc",
-        "test": "npm run build; mocha lib/test/*_test.js",
-        "compile": "npm run build; node lib/src/cli.js compile",
-        "clean": "rm -rf ./lib",
-        "migrate": "npm run build; node lib/src/cli.js migrate",
-        "lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'",
-        "test:circleci": "yarn test"
-    },
-    "bin": {
-        "0x-deployer": "lib/src/cli.js"
-    },
-    "repository": {
-        "type": "git",
-        "url": "https://github.com/0xProject/0x.js.git"
-    },
-    "author": "Amir Bandeali",
-    "license": "Apache-2.0",
-    "bugs": {
-        "url": "https://github.com/0xProject/0x.js/issues"
-    },
-    "homepage": "https://github.com/0xProject/0x.js/packages/deployer/README.md",
-    "devDependencies": {
-        "copyfiles": "^1.2.0",
-        "types-bn": "^0.0.1",
-        "typescript": "~2.6.1",
-        "web3-typescript-typings": "^0.9.6"
-    },
-    "dependencies": {
-        "@0xproject/utils": "^0.1.3",
-        "@0xproject/web3-wrapper": "^0.1.7",
-        "lodash": "^4.17.4",
-        "solc": "^0.4.18",
-        "web3": "^0.20.0",
-        "web3-eth-abi": "^1.0.0-beta.24",
-        "yargs": "^10.0.3"
-    }
+	"name": "@0xproject/deployer",
+	"version": "0.0.3",
+	"description": "Smart contract deployer of 0x protocol",
+	"main": "lib/src/cli.js",
+	"scripts": {
+		"build": "yarn clean && copyfiles 'test/fixtures/contracts/**/*' src/solc/solc_bin/* ./lib && tsc",
+		"test": "npm run build; mocha lib/test/*_test.js",
+		"compile": "npm run build; node lib/src/cli.js compile",
+		"clean": "rm -rf ./lib",
+		"migrate": "npm run build; node lib/src/cli.js migrate",
+		"lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'",
+		"test:circleci": "yarn test"
+	},
+	"bin": {
+		"0x-deployer": "lib/src/cli.js"
+	},
+	"repository": {
+		"type": "git",
+		"url": "https://github.com/0xProject/0x.js.git"
+	},
+	"author": "Amir Bandeali",
+	"license": "Apache-2.0",
+	"bugs": {
+		"url": "https://github.com/0xProject/0x.js/issues"
+	},
+	"homepage": "https://github.com/0xProject/0x.js/packages/deployer/README.md",
+	"devDependencies": {
+		"copyfiles": "^1.2.0",
+		"types-bn": "^0.0.1",
+		"typescript": "~2.6.1",
+		"web3-typescript-typings": "^0.9.6"
+	},
+	"dependencies": {
+		"@0xproject/utils": "^0.1.3",
+		"@0xproject/web3-wrapper": "^0.1.7",
+		"lodash": "^4.17.4",
+		"solc": "^0.4.18",
+		"web3": "^0.20.0",
+		"web3-eth-abi": "^1.0.0-beta.24",
+		"yargs": "^10.0.3"
+	}
 }
diff --git a/packages/deployer/src/cli.ts b/packages/deployer/src/cli.ts
index decb37fdc..f4241b1cc 100644
--- a/packages/deployer/src/cli.ts
+++ b/packages/deployer/src/cli.ts
@@ -20,13 +20,13 @@ const DEFAULT_GAS_PRICE = (10 ** 9 * 2).toString();
  * @param argv Instance of process.argv provided by yargs.
  */
 async function onCompileCommand(argv: CliOptions): Promise<void> {
-    const opts: CompilerOptions = {
-        contractsDir: argv.contractsDir,
-        networkId: argv.networkId,
-        optimizerEnabled: argv.shouldOptimize ? 1 : 0,
-        artifactsDir: argv.artifactsDir,
-    };
-    await commands.compileAsync(opts);
+	const opts: CompilerOptions = {
+		contractsDir: argv.contractsDir,
+		networkId: argv.networkId,
+		optimizerEnabled: argv.shouldOptimize ? 1 : 0,
+		artifactsDir: argv.artifactsDir,
+	};
+	await commands.compileAsync(opts);
 }
 /**
  * Compiles all contracts and runs migration script with options passed in through CLI.
@@ -34,123 +34,123 @@ async function onCompileCommand(argv: CliOptions): Promise<void> {
  * @param argv Instance of process.argv provided by yargs.
  */
 async function onMigrateCommand(argv: CliOptions): Promise<void> {
-    const url = `http://localhost:${argv.jsonrpcPort}`;
-    const web3Provider = new Web3.providers.HttpProvider(url);
-    const web3Wrapper = new Web3Wrapper(web3Provider);
-    const networkId = await web3Wrapper.getNetworkIdAsync();
-    const compilerOpts: CompilerOptions = {
-        contractsDir: argv.contractsDir,
-        networkId,
-        optimizerEnabled: argv.shouldOptimize ? 1 : 0,
-        artifactsDir: argv.artifactsDir,
-    };
-    await commands.compileAsync(compilerOpts);
+	const url = `http://localhost:${argv.jsonrpcPort}`;
+	const web3Provider = new Web3.providers.HttpProvider(url);
+	const web3Wrapper = new Web3Wrapper(web3Provider);
+	const networkId = await web3Wrapper.getNetworkIdAsync();
+	const compilerOpts: CompilerOptions = {
+		contractsDir: argv.contractsDir,
+		networkId,
+		optimizerEnabled: argv.shouldOptimize ? 1 : 0,
+		artifactsDir: argv.artifactsDir,
+	};
+	await commands.compileAsync(compilerOpts);
 
-    const defaults = {
-        gasPrice: new BigNumber(argv.gasPrice),
-        from: argv.account,
-    };
-    const deployerOpts = {
-        artifactsDir: argv.artifactsDir,
-        jsonrpcPort: argv.jsonrpcPort,
-        networkId,
-        defaults,
-    };
-    await commands.migrateAsync(deployerOpts);
+	const defaults = {
+		gasPrice: new BigNumber(argv.gasPrice),
+		from: argv.account,
+	};
+	const deployerOpts = {
+		artifactsDir: argv.artifactsDir,
+		jsonrpcPort: argv.jsonrpcPort,
+		networkId,
+		defaults,
+	};
+	await commands.migrateAsync(deployerOpts);
 }
 /**
  * Deploys a single contract with provided name and args.
  * @param argv Instance of process.argv provided by yargs.
  */
 async function onDeployCommand(argv: CliOptions): Promise<void> {
-    const url = `http://localhost:${argv.jsonrpcPort}`;
-    const web3Provider = new Web3.providers.HttpProvider(url);
-    const web3Wrapper = new Web3Wrapper(web3Provider);
-    const networkId = await web3Wrapper.getNetworkIdAsync();
-    const compilerOpts: CompilerOptions = {
-        contractsDir: argv.contractsDir,
-        networkId,
-        optimizerEnabled: argv.shouldOptimize ? 1 : 0,
-        artifactsDir: argv.artifactsDir,
-    };
-    await commands.compileAsync(compilerOpts);
+	const url = `http://localhost:${argv.jsonrpcPort}`;
+	const web3Provider = new Web3.providers.HttpProvider(url);
+	const web3Wrapper = new Web3Wrapper(web3Provider);
+	const networkId = await web3Wrapper.getNetworkIdAsync();
+	const compilerOpts: CompilerOptions = {
+		contractsDir: argv.contractsDir,
+		networkId,
+		optimizerEnabled: argv.shouldOptimize ? 1 : 0,
+		artifactsDir: argv.artifactsDir,
+	};
+	await commands.compileAsync(compilerOpts);
 
-    const defaults = {
-        gasPrice: new BigNumber(argv.gasPrice),
-        from: argv.account,
-    };
-    const deployerOpts: DeployerOptions = {
-        artifactsDir: argv.artifactsDir,
-        jsonrpcPort: argv.jsonrpcPort,
-        networkId,
-        defaults,
-    };
-    const deployerArgsString = argv.args;
-    const deployerArgs = deployerArgsString.split(',');
-    await commands.deployAsync(argv.contract, deployerArgs, deployerOpts);
+	const defaults = {
+		gasPrice: new BigNumber(argv.gasPrice),
+		from: argv.account,
+	};
+	const deployerOpts: DeployerOptions = {
+		artifactsDir: argv.artifactsDir,
+		jsonrpcPort: argv.jsonrpcPort,
+		networkId,
+		defaults,
+	};
+	const deployerArgsString = argv.args;
+	const deployerArgs = deployerArgsString.split(',');
+	await commands.deployAsync(argv.contract, deployerArgs, deployerOpts);
 }
 /**
  * Provides extra required options for deploy command.
  * @param yargsInstance yargs instance provided in builder function callback.
  */
 function deployCommandBuilder(yargsInstance: any) {
-    return yargsInstance
-        .option('contract', {
-            type: 'string',
-            description: 'name of contract to deploy, exluding .sol extension',
-        })
-        .option('args', {
-            type: 'string',
-            description: 'comma separated list of constructor args to deploy contract with',
-        })
-        .demandOption(['contract', 'args'])
-        .help().argv;
+	return yargsInstance
+		.option('contract', {
+			type: 'string',
+			description: 'name of contract to deploy, exluding .sol extension',
+		})
+		.option('args', {
+			type: 'string',
+			description: 'comma separated list of constructor args to deploy contract with',
+		})
+		.demandOption(['contract', 'args'])
+		.help().argv;
 }
 
 (() => {
-    const identityCommandBuilder = _.identity;
-    return yargs
-        .option('contracts-dir', {
-            type: 'string',
-            default: DEFAULT_CONTRACTS_DIR,
-            description: 'path of contracts directory to compile',
-        })
-        .option('network-id', {
-            type: 'number',
-            default: DEFAULT_NETWORK_ID,
-            description: 'mainnet=1, kovan=42, testrpc=50',
-        })
-        .option('should-optimize', {
-            type: 'boolean',
-            default: DEFAULT_OPTIMIZER_ENABLED,
-            description: 'enable optimizer',
-        })
-        .option('artifacts-dir', {
-            type: 'string',
-            default: DEFAULT_ARTIFACTS_DIR,
-            description: 'path to write contracts artifacts to',
-        })
-        .option('jsonrpc-port', {
-            type: 'number',
-            default: DEFAULT_JSONRPC_PORT,
-            description: 'port connected to JSON RPC',
-        })
-        .option('gas-price', {
-            type: 'string',
-            default: DEFAULT_GAS_PRICE,
-            description: 'gasPrice to be used for transactions',
-        })
-        .option('account', {
-            type: 'string',
-            description: 'account to use for deploying contracts',
-        })
-        .command('compile', 'compile contracts', identityCommandBuilder, onCompileCommand)
-        .command(
-            'migrate',
-            'compile and deploy contracts using migration scripts',
-            identityCommandBuilder,
-            onMigrateCommand,
-        )
-        .command('deploy', 'deploy a single contract with provided arguments', deployCommandBuilder, onDeployCommand)
-        .help().argv;
+	const identityCommandBuilder = _.identity;
+	return yargs
+		.option('contracts-dir', {
+			type: 'string',
+			default: DEFAULT_CONTRACTS_DIR,
+			description: 'path of contracts directory to compile',
+		})
+		.option('network-id', {
+			type: 'number',
+			default: DEFAULT_NETWORK_ID,
+			description: 'mainnet=1, kovan=42, testrpc=50',
+		})
+		.option('should-optimize', {
+			type: 'boolean',
+			default: DEFAULT_OPTIMIZER_ENABLED,
+			description: 'enable optimizer',
+		})
+		.option('artifacts-dir', {
+			type: 'string',
+			default: DEFAULT_ARTIFACTS_DIR,
+			description: 'path to write contracts artifacts to',
+		})
+		.option('jsonrpc-port', {
+			type: 'number',
+			default: DEFAULT_JSONRPC_PORT,
+			description: 'port connected to JSON RPC',
+		})
+		.option('gas-price', {
+			type: 'string',
+			default: DEFAULT_GAS_PRICE,
+			description: 'gasPrice to be used for transactions',
+		})
+		.option('account', {
+			type: 'string',
+			description: 'account to use for deploying contracts',
+		})
+		.command('compile', 'compile contracts', identityCommandBuilder, onCompileCommand)
+		.command(
+			'migrate',
+			'compile and deploy contracts using migration scripts',
+			identityCommandBuilder,
+			onMigrateCommand,
+		)
+		.command('deploy', 'deploy a single contract with provided arguments', deployCommandBuilder, onDeployCommand)
+		.help().argv;
 })();
diff --git a/packages/deployer/src/commands.ts b/packages/deployer/src/commands.ts
index 2acef8e8f..63e75685e 100644
--- a/packages/deployer/src/commands.ts
+++ b/packages/deployer/src/commands.ts
@@ -4,16 +4,16 @@ import { Deployer } from './deployer';
 import { CompilerOptions, DeployerOptions } from './utils/types';
 
 export const commands = {
-    async compileAsync(opts: CompilerOptions): Promise<void> {
-        const compiler = new Compiler(opts);
-        await compiler.compileAllAsync();
-    },
-    async migrateAsync(opts: DeployerOptions): Promise<void> {
-        const deployer = new Deployer(opts);
-        await migrator.runMigrationsAsync(deployer);
-    },
-    async deployAsync(contractName: string, args: any[], opts: DeployerOptions): Promise<void> {
-        const deployer = new Deployer(opts);
-        await deployer.deployAndSaveAsync(contractName, args);
-    },
+	async compileAsync(opts: CompilerOptions): Promise<void> {
+		const compiler = new Compiler(opts);
+		await compiler.compileAllAsync();
+	},
+	async migrateAsync(opts: DeployerOptions): Promise<void> {
+		const deployer = new Deployer(opts);
+		await migrator.runMigrationsAsync(deployer);
+	},
+	async deployAsync(contractName: string, args: any[], opts: DeployerOptions): Promise<void> {
+		const deployer = new Deployer(opts);
+		await deployer.deployAndSaveAsync(contractName, args);
+	},
 };
diff --git a/packages/deployer/src/compiler.ts b/packages/deployer/src/compiler.ts
index 63db6c865..bc003149c 100644
--- a/packages/deployer/src/compiler.ts
+++ b/packages/deployer/src/compiler.ts
@@ -7,245 +7,245 @@ import * as Web3 from 'web3';
 import { binPaths } from './solc/bin_paths';
 import { fsWrapper } from './utils/fs_wrapper';
 import {
-    CompilerOptions,
-    ContractArtifact,
-    ContractData,
-    ContractNetworks,
-    ContractSources,
-    ImportContents,
+	CompilerOptions,
+	ContractArtifact,
+	ContractData,
+	ContractNetworks,
+	ContractSources,
+	ImportContents,
 } from './utils/types';
 import { utils } from './utils/utils';
 
 const SOLIDITY_FILE_EXTENSION = '.sol';
 
 export class Compiler {
-    private _contractsDir: string;
-    private _networkId: number;
-    private _optimizerEnabled: number;
-    private _artifactsDir: string;
-    private _contractSourcesIfExists?: ContractSources;
-    private _solcErrors: Set<string>;
-    /**
-     * Recursively retrieves Solidity source code from directory.
-     * @param  dirPath Directory to search.
-     * @return Mapping of contract name to contract source.
-     */
-    private static async _getContractSourcesAsync(dirPath: string): Promise<ContractSources> {
-        let dirContents: string[] = [];
-        try {
-            dirContents = await fsWrapper.readdirAsync(dirPath);
-        } catch (err) {
-            throw new Error(`No directory found at ${dirPath}`);
-        }
-        let sources: ContractSources = {};
-        for (const name of dirContents) {
-            const contentPath = `${dirPath}/${name}`;
-            if (path.extname(name) === SOLIDITY_FILE_EXTENSION) {
-                try {
-                    const opts = {
-                        encoding: 'utf8',
-                    };
-                    sources[name] = await fsWrapper.readFileAsync(contentPath, opts);
-                    utils.consoleLog(`Reading ${name} source...`);
-                } catch (err) {
-                    utils.consoleLog(`Could not find file at ${contentPath}`);
-                }
-            } else {
-                try {
-                    const nestedSources = await Compiler._getContractSourcesAsync(contentPath);
-                    sources = {
-                        ...sources,
-                        ...nestedSources,
-                    };
-                } catch (err) {
-                    utils.consoleLog(`${contentPath} is not a directory or ${SOLIDITY_FILE_EXTENSION} file`);
-                }
-            }
-        }
-        return sources;
-    }
-    /**
-     * Searches Solidity source code for compiler version.
-     * @param  source Source code of contract.
-     * @return Solc compiler version.
-     */
-    private static _parseSolidityVersion(source: string): string {
-        const solcVersionMatch = source.match(/(?:solidity\s\^?)([0-9]{1,2}[.][0-9]{1,2}[.][0-9]{1,2})/);
-        if (_.isNull(solcVersionMatch)) {
-            throw new Error('Could not find Solidity version in source');
-        }
-        const solcVersion = solcVersionMatch[1];
-        return solcVersion;
-    }
-    /**
-     * Normalizes the path found in the error message.
-     * Example: converts 'base/Token.sol:6:46: Warning: Unused local variable'
-     *          to 'Token.sol:6:46: Warning: Unused local variable'
-     * This is used to prevent logging the same error multiple times.
-     * @param  errMsg An error message from the compiled output.
-     * @return The error message with directories truncated from the contract path.
-     */
-    private static _getNormalizedErrMsg(errMsg: string): string {
-        const errPathMatch = errMsg.match(/(.*\.sol)/);
-        if (_.isNull(errPathMatch)) {
-            throw new Error('Could not find a path in error message');
-        }
-        const errPath = errPathMatch[0];
-        const baseContract = path.basename(errPath);
-        const normalizedErrMsg = errMsg.replace(errPath, baseContract);
-        return normalizedErrMsg;
-    }
-    /**
-     * Instantiates a new instance of the Compiler class.
-     * @param opts Options specifying directories, network, and optimization settings.
-     * @return An instance of the Compiler class.
-     */
-    constructor(opts: CompilerOptions) {
-        this._contractsDir = opts.contractsDir;
-        this._networkId = opts.networkId;
-        this._optimizerEnabled = opts.optimizerEnabled;
-        this._artifactsDir = opts.artifactsDir;
-        this._solcErrors = new Set();
-    }
-    /**
-     * Compiles all Solidity files found in contractsDir and writes JSON artifacts to artifactsDir.
-     */
-    public async compileAllAsync(): Promise<void> {
-        await this._createArtifactsDirIfDoesNotExistAsync();
-        this._contractSourcesIfExists = await Compiler._getContractSourcesAsync(this._contractsDir);
-        const contractBaseNames = _.keys(this._contractSourcesIfExists);
-        const compiledContractPromises = _.map(contractBaseNames, async (contractBaseName: string): Promise<void> => {
-            return this._compileContractAsync(contractBaseName);
-        });
-        await Promise.all(compiledContractPromises);
+	private _contractsDir: string;
+	private _networkId: number;
+	private _optimizerEnabled: number;
+	private _artifactsDir: string;
+	private _contractSourcesIfExists?: ContractSources;
+	private _solcErrors: Set<string>;
+	/**
+	 * Recursively retrieves Solidity source code from directory.
+	 * @param  dirPath Directory to search.
+	 * @return Mapping of contract name to contract source.
+	 */
+	private static async _getContractSourcesAsync(dirPath: string): Promise<ContractSources> {
+		let dirContents: string[] = [];
+		try {
+			dirContents = await fsWrapper.readdirAsync(dirPath);
+		} catch (err) {
+			throw new Error(`No directory found at ${dirPath}`);
+		}
+		let sources: ContractSources = {};
+		for (const name of dirContents) {
+			const contentPath = `${dirPath}/${name}`;
+			if (path.extname(name) === SOLIDITY_FILE_EXTENSION) {
+				try {
+					const opts = {
+						encoding: 'utf8',
+					};
+					sources[name] = await fsWrapper.readFileAsync(contentPath, opts);
+					utils.consoleLog(`Reading ${name} source...`);
+				} catch (err) {
+					utils.consoleLog(`Could not find file at ${contentPath}`);
+				}
+			} else {
+				try {
+					const nestedSources = await Compiler._getContractSourcesAsync(contentPath);
+					sources = {
+						...sources,
+						...nestedSources,
+					};
+				} catch (err) {
+					utils.consoleLog(`${contentPath} is not a directory or ${SOLIDITY_FILE_EXTENSION} file`);
+				}
+			}
+		}
+		return sources;
+	}
+	/**
+	 * Searches Solidity source code for compiler version.
+	 * @param  source Source code of contract.
+	 * @return Solc compiler version.
+	 */
+	private static _parseSolidityVersion(source: string): string {
+		const solcVersionMatch = source.match(/(?:solidity\s\^?)([0-9]{1,2}[.][0-9]{1,2}[.][0-9]{1,2})/);
+		if (_.isNull(solcVersionMatch)) {
+			throw new Error('Could not find Solidity version in source');
+		}
+		const solcVersion = solcVersionMatch[1];
+		return solcVersion;
+	}
+	/**
+	 * Normalizes the path found in the error message.
+	 * Example: converts 'base/Token.sol:6:46: Warning: Unused local variable'
+	 *          to 'Token.sol:6:46: Warning: Unused local variable'
+	 * This is used to prevent logging the same error multiple times.
+	 * @param  errMsg An error message from the compiled output.
+	 * @return The error message with directories truncated from the contract path.
+	 */
+	private static _getNormalizedErrMsg(errMsg: string): string {
+		const errPathMatch = errMsg.match(/(.*\.sol)/);
+		if (_.isNull(errPathMatch)) {
+			throw new Error('Could not find a path in error message');
+		}
+		const errPath = errPathMatch[0];
+		const baseContract = path.basename(errPath);
+		const normalizedErrMsg = errMsg.replace(errPath, baseContract);
+		return normalizedErrMsg;
+	}
+	/**
+	 * Instantiates a new instance of the Compiler class.
+	 * @param opts Options specifying directories, network, and optimization settings.
+	 * @return An instance of the Compiler class.
+	 */
+	constructor(opts: CompilerOptions) {
+		this._contractsDir = opts.contractsDir;
+		this._networkId = opts.networkId;
+		this._optimizerEnabled = opts.optimizerEnabled;
+		this._artifactsDir = opts.artifactsDir;
+		this._solcErrors = new Set();
+	}
+	/**
+	 * Compiles all Solidity files found in contractsDir and writes JSON artifacts to artifactsDir.
+	 */
+	public async compileAllAsync(): Promise<void> {
+		await this._createArtifactsDirIfDoesNotExistAsync();
+		this._contractSourcesIfExists = await Compiler._getContractSourcesAsync(this._contractsDir);
+		const contractBaseNames = _.keys(this._contractSourcesIfExists);
+		const compiledContractPromises = _.map(contractBaseNames, async (contractBaseName: string): Promise<void> => {
+			return this._compileContractAsync(contractBaseName);
+		});
+		await Promise.all(compiledContractPromises);
 
-        this._solcErrors.forEach(errMsg => {
-            utils.consoleLog(errMsg);
-        });
-    }
-    /**
-     * Compiles contract and saves artifact to artifactsDir.
-     * @param contractBaseName Name of contract with '.sol' extension.
-     */
-    private async _compileContractAsync(contractBaseName: string): Promise<void> {
-        if (_.isUndefined(this._contractSourcesIfExists)) {
-            throw new Error('Contract sources not yet initialized');
-        }
+		this._solcErrors.forEach(errMsg => {
+			utils.consoleLog(errMsg);
+		});
+	}
+	/**
+	 * Compiles contract and saves artifact to artifactsDir.
+	 * @param contractBaseName Name of contract with '.sol' extension.
+	 */
+	private async _compileContractAsync(contractBaseName: string): Promise<void> {
+		if (_.isUndefined(this._contractSourcesIfExists)) {
+			throw new Error('Contract sources not yet initialized');
+		}
 
-        const source = this._contractSourcesIfExists[contractBaseName];
-        const contractName = path.basename(contractBaseName, SOLIDITY_FILE_EXTENSION);
-        const currentArtifactPath = `${this._artifactsDir}/${contractName}.json`;
-        const sourceHash = `0x${ethUtil.sha3(source).toString('hex')}`;
+		const source = this._contractSourcesIfExists[contractBaseName];
+		const contractName = path.basename(contractBaseName, SOLIDITY_FILE_EXTENSION);
+		const currentArtifactPath = `${this._artifactsDir}/${contractName}.json`;
+		const sourceHash = `0x${ethUtil.sha3(source).toString('hex')}`;
 
-        let currentArtifactString: string;
-        let currentArtifact: ContractArtifact;
-        let oldNetworks: ContractNetworks;
-        let shouldCompile: boolean;
-        try {
-            const opts = {
-                encoding: 'utf8',
-            };
-            currentArtifactString = await fsWrapper.readFileAsync(currentArtifactPath, opts);
-            currentArtifact = JSON.parse(currentArtifactString);
-            oldNetworks = currentArtifact.networks;
-            const oldNetwork: ContractData = oldNetworks[this._networkId];
-            shouldCompile =
-                _.isUndefined(oldNetwork) ||
-                oldNetwork.keccak256 !== sourceHash ||
-                oldNetwork.optimizer_enabled !== this._optimizerEnabled;
-        } catch (err) {
-            shouldCompile = true;
-        }
+		let currentArtifactString: string;
+		let currentArtifact: ContractArtifact;
+		let oldNetworks: ContractNetworks;
+		let shouldCompile: boolean;
+		try {
+			const opts = {
+				encoding: 'utf8',
+			};
+			currentArtifactString = await fsWrapper.readFileAsync(currentArtifactPath, opts);
+			currentArtifact = JSON.parse(currentArtifactString);
+			oldNetworks = currentArtifact.networks;
+			const oldNetwork: ContractData = oldNetworks[this._networkId];
+			shouldCompile =
+				_.isUndefined(oldNetwork) ||
+				oldNetwork.keccak256 !== sourceHash ||
+				oldNetwork.optimizer_enabled !== this._optimizerEnabled;
+		} catch (err) {
+			shouldCompile = true;
+		}
 
-        if (!shouldCompile) {
-            return;
-        }
+		if (!shouldCompile) {
+			return;
+		}
 
-        const input = {
-            [contractBaseName]: source,
-        };
-        const solcVersion = Compiler._parseSolidityVersion(source);
-        const fullSolcVersion = binPaths[solcVersion];
-        const solcBinPath = `./solc/solc_bin/${fullSolcVersion}`;
-        const solcBin = require(solcBinPath);
-        const solcInstance = solc.setupMethods(solcBin);
+		const input = {
+			[contractBaseName]: source,
+		};
+		const solcVersion = Compiler._parseSolidityVersion(source);
+		const fullSolcVersion = binPaths[solcVersion];
+		const solcBinPath = `./solc/solc_bin/${fullSolcVersion}`;
+		const solcBin = require(solcBinPath);
+		const solcInstance = solc.setupMethods(solcBin);
 
-        utils.consoleLog(`Compiling ${contractBaseName}...`);
-        const sourcesToCompile = {
-            sources: input,
-        };
-        const compiled = solcInstance.compile(
-            sourcesToCompile,
-            this._optimizerEnabled,
-            this._findImportsIfSourcesExist.bind(this),
-        );
+		utils.consoleLog(`Compiling ${contractBaseName}...`);
+		const sourcesToCompile = {
+			sources: input,
+		};
+		const compiled = solcInstance.compile(
+			sourcesToCompile,
+			this._optimizerEnabled,
+			this._findImportsIfSourcesExist.bind(this),
+		);
 
-        if (!_.isUndefined(compiled.errors)) {
-            _.each(compiled.errors, errMsg => {
-                const normalizedErrMsg = Compiler._getNormalizedErrMsg(errMsg);
-                this._solcErrors.add(normalizedErrMsg);
-            });
-        }
+		if (!_.isUndefined(compiled.errors)) {
+			_.each(compiled.errors, errMsg => {
+				const normalizedErrMsg = Compiler._getNormalizedErrMsg(errMsg);
+				this._solcErrors.add(normalizedErrMsg);
+			});
+		}
 
-        const contractIdentifier = `${contractBaseName}:${contractName}`;
-        const abi: Web3.ContractAbi = JSON.parse(compiled.contracts[contractIdentifier].interface);
-        const unlinked_binary = `0x${compiled.contracts[contractIdentifier].bytecode}`;
-        const updated_at = Date.now();
-        const contractData: ContractData = {
-            solc_version: solcVersion,
-            keccak256: sourceHash,
-            optimizer_enabled: this._optimizerEnabled,
-            abi,
-            unlinked_binary,
-            updated_at,
-        };
+		const contractIdentifier = `${contractBaseName}:${contractName}`;
+		const abi: Web3.ContractAbi = JSON.parse(compiled.contracts[contractIdentifier].interface);
+		const unlinked_binary = `0x${compiled.contracts[contractIdentifier].bytecode}`;
+		const updated_at = Date.now();
+		const contractData: ContractData = {
+			solc_version: solcVersion,
+			keccak256: sourceHash,
+			optimizer_enabled: this._optimizerEnabled,
+			abi,
+			unlinked_binary,
+			updated_at,
+		};
 
-        let newArtifact: ContractArtifact;
-        if (!_.isUndefined(currentArtifactString)) {
-            newArtifact = {
-                ...currentArtifact,
-                networks: {
-                    ...oldNetworks,
-                    [this._networkId]: contractData,
-                },
-            };
-        } else {
-            newArtifact = {
-                contract_name: contractName,
-                networks: {
-                    [this._networkId]: contractData,
-                },
-            };
-        }
+		let newArtifact: ContractArtifact;
+		if (!_.isUndefined(currentArtifactString)) {
+			newArtifact = {
+				...currentArtifact,
+				networks: {
+					...oldNetworks,
+					[this._networkId]: contractData,
+				},
+			};
+		} else {
+			newArtifact = {
+				contract_name: contractName,
+				networks: {
+					[this._networkId]: contractData,
+				},
+			};
+		}
 
-        const artifactString = utils.stringifyWithFormatting(newArtifact);
-        await fsWrapper.writeFileAsync(currentArtifactPath, artifactString);
-        utils.consoleLog(`${contractBaseName} artifact saved!`);
-    }
-    /**
-     * Callback to resolve dependencies with `solc.compile`.
-     * Throws error if contractSources not yet initialized.
-     * @param  importPath Path to an imported dependency.
-     * @return Import contents object containing source code of dependency.
-     */
-    private _findImportsIfSourcesExist(importPath: string): ImportContents {
-        if (_.isUndefined(this._contractSourcesIfExists)) {
-            throw new Error('Contract sources not yet initialized');
-        }
-        const contractBaseName = path.basename(importPath);
-        const source = this._contractSourcesIfExists[contractBaseName];
-        const importContents: ImportContents = {
-            contents: source,
-        };
-        return importContents;
-    }
-    /**
-     * Creates the artifacts directory if it does not already exist.
-     */
-    private async _createArtifactsDirIfDoesNotExistAsync(): Promise<void> {
-        if (!fsWrapper.doesPathExistSync(this._artifactsDir)) {
-            utils.consoleLog('Creating artifacts directory...');
-            await fsWrapper.mkdirAsync(this._artifactsDir);
-        }
-    }
+		const artifactString = utils.stringifyWithFormatting(newArtifact);
+		await fsWrapper.writeFileAsync(currentArtifactPath, artifactString);
+		utils.consoleLog(`${contractBaseName} artifact saved!`);
+	}
+	/**
+	 * Callback to resolve dependencies with `solc.compile`.
+	 * Throws error if contractSources not yet initialized.
+	 * @param  importPath Path to an imported dependency.
+	 * @return Import contents object containing source code of dependency.
+	 */
+	private _findImportsIfSourcesExist(importPath: string): ImportContents {
+		if (_.isUndefined(this._contractSourcesIfExists)) {
+			throw new Error('Contract sources not yet initialized');
+		}
+		const contractBaseName = path.basename(importPath);
+		const source = this._contractSourcesIfExists[contractBaseName];
+		const importContents: ImportContents = {
+			contents: source,
+		};
+		return importContents;
+	}
+	/**
+	 * Creates the artifacts directory if it does not already exist.
+	 */
+	private async _createArtifactsDirIfDoesNotExistAsync(): Promise<void> {
+		if (!fsWrapper.doesPathExistSync(this._artifactsDir)) {
+			utils.consoleLog('Creating artifacts directory...');
+			await fsWrapper.mkdirAsync(this._artifactsDir);
+		}
+	}
 }
diff --git a/packages/deployer/src/deployer.ts b/packages/deployer/src/deployer.ts
index 6f03581e8..34e20a197 100644
--- a/packages/deployer/src/deployer.ts
+++ b/packages/deployer/src/deployer.ts
@@ -13,168 +13,168 @@ import { utils } from './utils/utils';
 const EXTRA_GAS = 200000;
 
 export class Deployer {
-    public web3Wrapper: Web3Wrapper;
-    private _artifactsDir: string;
-    private _jsonrpcPort: number;
-    private _networkId: number;
-    private _defaults: Partial<TxData>;
+	public web3Wrapper: Web3Wrapper;
+	private _artifactsDir: string;
+	private _jsonrpcPort: number;
+	private _networkId: number;
+	private _defaults: Partial<TxData>;
 
-    constructor(opts: DeployerOptions) {
-        this._artifactsDir = opts.artifactsDir;
-        this._jsonrpcPort = opts.jsonrpcPort;
-        this._networkId = opts.networkId;
-        const jsonrpcUrl = `http://localhost:${this._jsonrpcPort}`;
-        const web3Provider = new Web3.providers.HttpProvider(jsonrpcUrl);
-        this._defaults = opts.defaults;
-        this.web3Wrapper = new Web3Wrapper(web3Provider, this._defaults);
-    }
-    /**
-     * Loads contract artifact and deploys contract with given arguments.
-     * @param contractName Name of the contract to deploy. Must match name of an artifact in artifacts directory.
-     * @param args Array of contract constructor arguments.
-     * @return Deployed contract instance.
-     */
-    public async deployAsync(contractName: string, args: any[] = []): Promise<Web3.ContractInstance> {
-        const contractArtifact: ContractArtifact = this._loadContractArtifactIfExists(contractName);
-        const contractData: ContractData = this._getContractDataFromArtifactIfExists(contractArtifact);
-        const data = contractData.unlinked_binary;
-        const from = await this._getFromAddressAsync();
-        const gas = await this._getAllowableGasEstimateAsync(data);
-        const txData = {
-            gasPrice: this._defaults.gasPrice,
-            from,
-            data,
-            gas,
-        };
-        const abi = contractData.abi;
-        const web3ContractInstance = await this._deployFromAbiAsync(abi, args, txData);
-        utils.consoleLog(`${contractName}.sol successfully deployed at ${web3ContractInstance.address}`);
-        const contractInstance = new Contract(web3ContractInstance, this._defaults);
-        return contractInstance;
-    }
-    /**
-     * Loads contract artifact, deploys with given arguments, and saves updated data to artifact.
-     * @param contractName Name of the contract to deploy. Must match name of an artifact in artifacts directory.
-     * @param args Array of contract constructor arguments.
-     * @return Deployed contract instance.
-     */
-    public async deployAndSaveAsync(contractName: string, args: any[] = []): Promise<Web3.ContractInstance> {
-        const contractInstance = await this.deployAsync(contractName, args);
-        await this._saveContractDataToArtifactAsync(contractName, contractInstance.address, args);
-        return contractInstance;
-    }
-    /**
-     * Deploys a contract given its ABI, arguments, and transaction data.
-     * @param abi ABI of contract to deploy.
-     * @param args Constructor arguments to use in deployment.
-     * @param txData Tx options used for deployment.
-     * @return Promise that resolves to a web3 contract instance.
-     */
-    private async _deployFromAbiAsync(abi: Web3.ContractAbi, args: any[], txData: Web3.TxData): Promise<any> {
-        const contract: Web3.Contract<Web3.ContractInstance> = this.web3Wrapper.getContractFromAbi(abi);
-        const deployPromise = new Promise((resolve, reject) => {
-            /**
-             * Contract is inferred as 'any' because TypeScript
-             * is not able to read 'new' from the Contract interface
-             */
-            (contract as any).new(...args, txData, (err: Error, res: any): any => {
-                if (err) {
-                    reject(err);
-                } else if (_.isUndefined(res.address) && !_.isUndefined(res.transactionHash)) {
-                    utils.consoleLog(`transactionHash: ${res.transactionHash}`);
-                } else {
-                    resolve(res);
-                }
-            });
-        });
-        return deployPromise;
-    }
-    /**
-     * Updates a contract artifact's address and encoded constructor arguments.
-     * @param contractName Name of contract. Must match an existing artifact.
-     * @param contractAddress Contract address to save to artifact.
-     * @param args Contract constructor arguments that will be encoded and saved to artifact.
-     */
-    private async _saveContractDataToArtifactAsync(
-        contractName: string,
-        contractAddress: string,
-        args: any[],
-    ): Promise<void> {
-        const contractArtifact: ContractArtifact = this._loadContractArtifactIfExists(contractName);
-        const contractData: ContractData = this._getContractDataFromArtifactIfExists(contractArtifact);
-        const abi = contractData.abi;
-        const encodedConstructorArgs = encoder.encodeConstructorArgsFromAbi(args, abi);
-        const newContractData = {
-            ...contractData,
-            address: contractAddress,
-            constructor_args: encodedConstructorArgs,
-        };
-        const newArtifact = {
-            ...contractArtifact,
-            networks: {
-                ...contractArtifact.networks,
-                [this._networkId]: newContractData,
-            },
-        };
-        const artifactString = utils.stringifyWithFormatting(newArtifact);
-        const artifactPath = `${this._artifactsDir}/${contractName}.json`;
-        await fsWrapper.writeFileAsync(artifactPath, artifactString);
-    }
-    /**
-     * Loads a contract artifact, if it exists.
-     * @param contractName Name of the contract, without the extension.
-     * @return The contract artifact.
-     */
-    private _loadContractArtifactIfExists(contractName: string): ContractArtifact {
-        const artifactPath = `${this._artifactsDir}/${contractName}.json`;
-        try {
-            const contractArtifact: ContractArtifact = require(artifactPath);
-            return contractArtifact;
-        } catch (err) {
-            throw new Error(`Artifact not found for contract: ${contractName}`);
-        }
-    }
-    /**
-     * Gets data for current networkId stored in artifact.
-     * @param contractArtifact The contract artifact.
-     * @return Network specific contract data.
-     */
-    private _getContractDataFromArtifactIfExists(contractArtifact: ContractArtifact): ContractData {
-        const contractData = contractArtifact.networks[this._networkId];
-        if (_.isUndefined(contractData)) {
-            throw new Error(`Data not found in artifact for contract: ${contractArtifact.contract_name}`);
-        }
-        return contractData;
-    }
-    /**
-     * Gets the address to use for sending a transaction.
-     * @return The default from address. If not specified, returns the first address accessible by web3.
-     */
-    private async _getFromAddressAsync(): Promise<string> {
-        let from: string;
-        if (_.isUndefined(this._defaults.from)) {
-            const accounts = await this.web3Wrapper.getAvailableAddressesAsync();
-            from = accounts[0];
-        } else {
-            from = this._defaults.from;
-        }
-        return from;
-    }
-    /**
-     * Estimates the gas required for a transaction.
-     * If gas would be over the block gas limit, the max allowable gas is returned instead.
-     * @param data Bytecode to estimate gas for.
-     * @return Gas estimate for transaction data.
-     */
-    private async _getAllowableGasEstimateAsync(data: string): Promise<number> {
-        const block = await this.web3Wrapper.getBlockAsync('latest');
-        let gas: number;
-        try {
-            const gasEstimate: number = await this.web3Wrapper.estimateGasAsync(data);
-            gas = Math.min(gasEstimate + EXTRA_GAS, block.gasLimit);
-        } catch (err) {
-            gas = block.gasLimit;
-        }
-        return gas;
-    }
+	constructor(opts: DeployerOptions) {
+		this._artifactsDir = opts.artifactsDir;
+		this._jsonrpcPort = opts.jsonrpcPort;
+		this._networkId = opts.networkId;
+		const jsonrpcUrl = `http://localhost:${this._jsonrpcPort}`;
+		const web3Provider = new Web3.providers.HttpProvider(jsonrpcUrl);
+		this._defaults = opts.defaults;
+		this.web3Wrapper = new Web3Wrapper(web3Provider, this._defaults);
+	}
+	/**
+	 * Loads contract artifact and deploys contract with given arguments.
+	 * @param contractName Name of the contract to deploy. Must match name of an artifact in artifacts directory.
+	 * @param args Array of contract constructor arguments.
+	 * @return Deployed contract instance.
+	 */
+	public async deployAsync(contractName: string, args: any[] = []): Promise<Web3.ContractInstance> {
+		const contractArtifact: ContractArtifact = this._loadContractArtifactIfExists(contractName);
+		const contractData: ContractData = this._getContractDataFromArtifactIfExists(contractArtifact);
+		const data = contractData.unlinked_binary;
+		const from = await this._getFromAddressAsync();
+		const gas = await this._getAllowableGasEstimateAsync(data);
+		const txData = {
+			gasPrice: this._defaults.gasPrice,
+			from,
+			data,
+			gas,
+		};
+		const abi = contractData.abi;
+		const web3ContractInstance = await this._deployFromAbiAsync(abi, args, txData);
+		utils.consoleLog(`${contractName}.sol successfully deployed at ${web3ContractInstance.address}`);
+		const contractInstance = new Contract(web3ContractInstance, this._defaults);
+		return contractInstance;
+	}
+	/**
+	 * Loads contract artifact, deploys with given arguments, and saves updated data to artifact.
+	 * @param contractName Name of the contract to deploy. Must match name of an artifact in artifacts directory.
+	 * @param args Array of contract constructor arguments.
+	 * @return Deployed contract instance.
+	 */
+	public async deployAndSaveAsync(contractName: string, args: any[] = []): Promise<Web3.ContractInstance> {
+		const contractInstance = await this.deployAsync(contractName, args);
+		await this._saveContractDataToArtifactAsync(contractName, contractInstance.address, args);
+		return contractInstance;
+	}
+	/**
+	 * Deploys a contract given its ABI, arguments, and transaction data.
+	 * @param abi ABI of contract to deploy.
+	 * @param args Constructor arguments to use in deployment.
+	 * @param txData Tx options used for deployment.
+	 * @return Promise that resolves to a web3 contract instance.
+	 */
+	private async _deployFromAbiAsync(abi: Web3.ContractAbi, args: any[], txData: Web3.TxData): Promise<any> {
+		const contract: Web3.Contract<Web3.ContractInstance> = this.web3Wrapper.getContractFromAbi(abi);
+		const deployPromise = new Promise((resolve, reject) => {
+			/**
+			 * Contract is inferred as 'any' because TypeScript
+			 * is not able to read 'new' from the Contract interface
+			 */
+			(contract as any).new(...args, txData, (err: Error, res: any): any => {
+				if (err) {
+					reject(err);
+				} else if (_.isUndefined(res.address) && !_.isUndefined(res.transactionHash)) {
+					utils.consoleLog(`transactionHash: ${res.transactionHash}`);
+				} else {
+					resolve(res);
+				}
+			});
+		});
+		return deployPromise;
+	}
+	/**
+	 * Updates a contract artifact's address and encoded constructor arguments.
+	 * @param contractName Name of contract. Must match an existing artifact.
+	 * @param contractAddress Contract address to save to artifact.
+	 * @param args Contract constructor arguments that will be encoded and saved to artifact.
+	 */
+	private async _saveContractDataToArtifactAsync(
+		contractName: string,
+		contractAddress: string,
+		args: any[],
+	): Promise<void> {
+		const contractArtifact: ContractArtifact = this._loadContractArtifactIfExists(contractName);
+		const contractData: ContractData = this._getContractDataFromArtifactIfExists(contractArtifact);
+		const abi = contractData.abi;
+		const encodedConstructorArgs = encoder.encodeConstructorArgsFromAbi(args, abi);
+		const newContractData = {
+			...contractData,
+			address: contractAddress,
+			constructor_args: encodedConstructorArgs,
+		};
+		const newArtifact = {
+			...contractArtifact,
+			networks: {
+				...contractArtifact.networks,
+				[this._networkId]: newContractData,
+			},
+		};
+		const artifactString = utils.stringifyWithFormatting(newArtifact);
+		const artifactPath = `${this._artifactsDir}/${contractName}.json`;
+		await fsWrapper.writeFileAsync(artifactPath, artifactString);
+	}
+	/**
+	 * Loads a contract artifact, if it exists.
+	 * @param contractName Name of the contract, without the extension.
+	 * @return The contract artifact.
+	 */
+	private _loadContractArtifactIfExists(contractName: string): ContractArtifact {
+		const artifactPath = `${this._artifactsDir}/${contractName}.json`;
+		try {
+			const contractArtifact: ContractArtifact = require(artifactPath);
+			return contractArtifact;
+		} catch (err) {
+			throw new Error(`Artifact not found for contract: ${contractName}`);
+		}
+	}
+	/**
+	 * Gets data for current networkId stored in artifact.
+	 * @param contractArtifact The contract artifact.
+	 * @return Network specific contract data.
+	 */
+	private _getContractDataFromArtifactIfExists(contractArtifact: ContractArtifact): ContractData {
+		const contractData = contractArtifact.networks[this._networkId];
+		if (_.isUndefined(contractData)) {
+			throw new Error(`Data not found in artifact for contract: ${contractArtifact.contract_name}`);
+		}
+		return contractData;
+	}
+	/**
+	 * Gets the address to use for sending a transaction.
+	 * @return The default from address. If not specified, returns the first address accessible by web3.
+	 */
+	private async _getFromAddressAsync(): Promise<string> {
+		let from: string;
+		if (_.isUndefined(this._defaults.from)) {
+			const accounts = await this.web3Wrapper.getAvailableAddressesAsync();
+			from = accounts[0];
+		} else {
+			from = this._defaults.from;
+		}
+		return from;
+	}
+	/**
+	 * Estimates the gas required for a transaction.
+	 * If gas would be over the block gas limit, the max allowable gas is returned instead.
+	 * @param data Bytecode to estimate gas for.
+	 * @return Gas estimate for transaction data.
+	 */
+	private async _getAllowableGasEstimateAsync(data: string): Promise<number> {
+		const block = await this.web3Wrapper.getBlockAsync('latest');
+		let gas: number;
+		try {
+			const gasEstimate: number = await this.web3Wrapper.estimateGasAsync(data);
+			gas = Math.min(gasEstimate + EXTRA_GAS, block.gasLimit);
+		} catch (err) {
+			gas = block.gasLimit;
+		}
+		return gas;
+	}
 }
diff --git a/packages/deployer/src/globals.d.ts b/packages/deployer/src/globals.d.ts
index 0a35002da..d61f54870 100644
--- a/packages/deployer/src/globals.d.ts
+++ b/packages/deployer/src/globals.d.ts
@@ -1,8 +1,8 @@
 declare module 'solc' {
-    export function compile(sources: any, optimizerEnabled: number, findImports: (importPath: string) => any): any;
-    export function setupMethods(solcBin: any): any;
+	export function compile(sources: any, optimizerEnabled: number, findImports: (importPath: string) => any): any;
+	export function setupMethods(solcBin: any): any;
 }
 
 declare module 'web3-eth-abi' {
-    export function encodeParameters(typesArray: string[], parameters: any[]): string;
+	export function encodeParameters(typesArray: string[], parameters: any[]): string;
 }
diff --git a/packages/deployer/src/migrations/config/multisig_sample.ts b/packages/deployer/src/migrations/config/multisig_sample.ts
index dabeb7a4f..d65ab06d2 100644
--- a/packages/deployer/src/migrations/config/multisig_sample.ts
+++ b/packages/deployer/src/migrations/config/multisig_sample.ts
@@ -2,9 +2,9 @@ import { MultiSigConfigByNetwork } from '../../types';
 
 // Make a copy of this file named `multisig.js` and input custom params as needed
 export const multiSig: MultiSigConfigByNetwork = {
-    kovan: {
-        owners: [],
-        confirmationsRequired: 0,
-        secondsRequired: 0,
-    },
+	kovan: {
+		owners: [],
+		confirmationsRequired: 0,
+		secondsRequired: 0,
+	},
 };
diff --git a/packages/deployer/src/migrations/config/token_info.ts b/packages/deployer/src/migrations/config/token_info.ts
index 7e822fc3b..ebcd3f796 100644
--- a/packages/deployer/src/migrations/config/token_info.ts
+++ b/packages/deployer/src/migrations/config/token_info.ts
@@ -2,39 +2,39 @@ import { constants } from '../../utils/constants';
 import { Token } from '../../types';
 
 export const tokenInfo: Token[] = [
-    {
-        name: 'Augur Reputation Token',
-        symbol: 'REP',
-        decimals: 18,
-        ipfsHash: constants.NULL_BYTES,
-        swarmHash: constants.NULL_BYTES,
-    },
-    {
-        name: 'Digix DAO Token',
-        symbol: 'DGD',
-        decimals: 18,
-        ipfsHash: constants.NULL_BYTES,
-        swarmHash: constants.NULL_BYTES,
-    },
-    {
-        name: 'Golem Network Token',
-        symbol: 'GNT',
-        decimals: 18,
-        ipfsHash: constants.NULL_BYTES,
-        swarmHash: constants.NULL_BYTES,
-    },
-    {
-        name: 'MakerDAO',
-        symbol: 'MKR',
-        decimals: 18,
-        ipfsHash: constants.NULL_BYTES,
-        swarmHash: constants.NULL_BYTES,
-    },
-    {
-        name: 'Melon Token',
-        symbol: 'MLN',
-        decimals: 18,
-        ipfsHash: constants.NULL_BYTES,
-        swarmHash: constants.NULL_BYTES,
-    },
+	{
+		name: 'Augur Reputation Token',
+		symbol: 'REP',
+		decimals: 18,
+		ipfsHash: constants.NULL_BYTES,
+		swarmHash: constants.NULL_BYTES,
+	},
+	{
+		name: 'Digix DAO Token',
+		symbol: 'DGD',
+		decimals: 18,
+		ipfsHash: constants.NULL_BYTES,
+		swarmHash: constants.NULL_BYTES,
+	},
+	{
+		name: 'Golem Network Token',
+		symbol: 'GNT',
+		decimals: 18,
+		ipfsHash: constants.NULL_BYTES,
+		swarmHash: constants.NULL_BYTES,
+	},
+	{
+		name: 'MakerDAO',
+		symbol: 'MKR',
+		decimals: 18,
+		ipfsHash: constants.NULL_BYTES,
+		swarmHash: constants.NULL_BYTES,
+	},
+	{
+		name: 'Melon Token',
+		symbol: 'MLN',
+		decimals: 18,
+		ipfsHash: constants.NULL_BYTES,
+		swarmHash: constants.NULL_BYTES,
+	},
 ];
diff --git a/packages/deployer/src/migrations/migrate.ts b/packages/deployer/src/migrations/migrate.ts
index 393806b45..48cf93000 100644
--- a/packages/deployer/src/migrations/migrate.ts
+++ b/packages/deployer/src/migrations/migrate.ts
@@ -7,84 +7,84 @@ import { constants } from '../utils/constants';
 import { tokenInfo } from './config/token_info';
 
 export const migrator = {
-    /**
-     * Custom migrations should be defined in this function. This will be called with the CLI 'migrate' command.
-     * Some operations might be completed in parallel, but we don't do that on purpose.
-     * That way the addresses are deterministic.
-     * @param deployer Deployer instance.
-     */
-    async runMigrationsAsync(deployer: Deployer): Promise<void> {
-        const web3Wrapper: Web3Wrapper = deployer.web3Wrapper;
-        const accounts: string[] = await web3Wrapper.getAvailableAddressesAsync();
+	/**
+	 * Custom migrations should be defined in this function. This will be called with the CLI 'migrate' command.
+	 * Some operations might be completed in parallel, but we don't do that on purpose.
+	 * That way the addresses are deterministic.
+	 * @param deployer Deployer instance.
+	 */
+	async runMigrationsAsync(deployer: Deployer): Promise<void> {
+		const web3Wrapper: Web3Wrapper = deployer.web3Wrapper;
+		const accounts: string[] = await web3Wrapper.getAvailableAddressesAsync();
 
-        const tokenTransferProxy = await deployer.deployAndSaveAsync('TokenTransferProxy');
-        const zrxToken = await deployer.deployAndSaveAsync('ZRXToken');
-        const etherToken = await deployer.deployAndSaveAsync('WETH9');
-        const tokenReg = await deployer.deployAndSaveAsync('TokenRegistry');
+		const tokenTransferProxy = await deployer.deployAndSaveAsync('TokenTransferProxy');
+		const zrxToken = await deployer.deployAndSaveAsync('ZRXToken');
+		const etherToken = await deployer.deployAndSaveAsync('WETH9');
+		const tokenReg = await deployer.deployAndSaveAsync('TokenRegistry');
 
-        const exchangeArgs = [zrxToken.address, tokenTransferProxy.address];
-        const owners = [accounts[0], accounts[1]];
-        const confirmationsRequired = new BigNumber(2);
-        const secondsRequired = new BigNumber(0);
-        const multiSigArgs = [owners, confirmationsRequired, secondsRequired, tokenTransferProxy.address];
-        const exchange = await deployer.deployAndSaveAsync('Exchange', exchangeArgs);
-        const multiSig = await deployer.deployAndSaveAsync(
-            'MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress',
-            multiSigArgs,
-        );
+		const exchangeArgs = [zrxToken.address, tokenTransferProxy.address];
+		const owners = [accounts[0], accounts[1]];
+		const confirmationsRequired = new BigNumber(2);
+		const secondsRequired = new BigNumber(0);
+		const multiSigArgs = [owners, confirmationsRequired, secondsRequired, tokenTransferProxy.address];
+		const exchange = await deployer.deployAndSaveAsync('Exchange', exchangeArgs);
+		const multiSig = await deployer.deployAndSaveAsync(
+			'MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress',
+			multiSigArgs,
+		);
 
-        const owner = accounts[0];
-        await tokenTransferProxy.addAuthorizedAddress.sendTransactionAsync(exchange.address, { from: owner });
-        await tokenTransferProxy.transferOwnership.sendTransactionAsync(multiSig.address, { from: owner });
-        const addTokenGasEstimate = await tokenReg.addToken.estimateGasAsync(
-            zrxToken.address,
-            tokenInfo[0].name,
-            tokenInfo[0].symbol,
-            tokenInfo[0].decimals,
-            tokenInfo[0].ipfsHash,
-            tokenInfo[0].swarmHash,
-            { from: owner },
-        );
-        await tokenReg.addToken.sendTransactionAsync(
-            zrxToken.address,
-            '0x Protocol Token',
-            'ZRX',
-            18,
-            constants.NULL_BYTES,
-            constants.NULL_BYTES,
-            {
-                from: owner,
-                gas: addTokenGasEstimate,
-            },
-        );
-        await tokenReg.addToken.sendTransactionAsync(
-            etherToken.address,
-            'Ether Token',
-            'WETH',
-            18,
-            constants.NULL_BYTES,
-            constants.NULL_BYTES,
-            {
-                from: owner,
-                gas: addTokenGasEstimate,
-            },
-        );
-        for (const token of tokenInfo) {
-            const totalSupply = new BigNumber(0);
-            const args = [token.name, token.symbol, token.decimals, totalSupply];
-            const dummyToken = await deployer.deployAsync('DummyToken', args);
-            await tokenReg.addToken.sendTransactionAsync(
-                dummyToken.address,
-                token.name,
-                token.symbol,
-                token.decimals,
-                token.ipfsHash,
-                token.swarmHash,
-                {
-                    from: owner,
-                    gas: addTokenGasEstimate,
-                },
-            );
-        }
-    },
+		const owner = accounts[0];
+		await tokenTransferProxy.addAuthorizedAddress.sendTransactionAsync(exchange.address, { from: owner });
+		await tokenTransferProxy.transferOwnership.sendTransactionAsync(multiSig.address, { from: owner });
+		const addTokenGasEstimate = await tokenReg.addToken.estimateGasAsync(
+			zrxToken.address,
+			tokenInfo[0].name,
+			tokenInfo[0].symbol,
+			tokenInfo[0].decimals,
+			tokenInfo[0].ipfsHash,
+			tokenInfo[0].swarmHash,
+			{ from: owner },
+		);
+		await tokenReg.addToken.sendTransactionAsync(
+			zrxToken.address,
+			'0x Protocol Token',
+			'ZRX',
+			18,
+			constants.NULL_BYTES,
+			constants.NULL_BYTES,
+			{
+				from: owner,
+				gas: addTokenGasEstimate,
+			},
+		);
+		await tokenReg.addToken.sendTransactionAsync(
+			etherToken.address,
+			'Ether Token',
+			'WETH',
+			18,
+			constants.NULL_BYTES,
+			constants.NULL_BYTES,
+			{
+				from: owner,
+				gas: addTokenGasEstimate,
+			},
+		);
+		for (const token of tokenInfo) {
+			const totalSupply = new BigNumber(0);
+			const args = [token.name, token.symbol, token.decimals, totalSupply];
+			const dummyToken = await deployer.deployAsync('DummyToken', args);
+			await tokenReg.addToken.sendTransactionAsync(
+				dummyToken.address,
+				token.name,
+				token.symbol,
+				token.decimals,
+				token.ipfsHash,
+				token.swarmHash,
+				{
+					from: owner,
+					gas: addTokenGasEstimate,
+				},
+			);
+		}
+	},
 };
diff --git a/packages/deployer/src/solc/bin_paths.ts b/packages/deployer/src/solc/bin_paths.ts
index e5b107101..7a22f911a 100644
--- a/packages/deployer/src/solc/bin_paths.ts
+++ b/packages/deployer/src/solc/bin_paths.ts
@@ -1,15 +1,15 @@
 export interface BinaryPaths {
-    [key: string]: string;
+	[key: string]: string;
 }
 
 export const binPaths: BinaryPaths = {
-    '0.4.10': 'soljson-v0.4.10+commit.f0d539ae.js',
-    '0.4.11': 'soljson-v0.4.11+commit.68ef5810.js',
-    '0.4.12': 'soljson-v0.4.12+commit.194ff033.js',
-    '0.4.13': 'soljson-v0.4.13+commit.fb4cb1a.js',
-    '0.4.14': 'soljson-v0.4.14+commit.c2215d46.js',
-    '0.4.15': 'soljson-v0.4.15+commit.bbb8e64f.js',
-    '0.4.16': 'soljson-v0.4.16+commit.d7661dd9.js',
-    '0.4.17': 'soljson-v0.4.17+commit.bdeb9e52.js',
-    '0.4.18': 'soljson-v0.4.18+commit.9cf6e910.js',
+	'0.4.10': 'soljson-v0.4.10+commit.f0d539ae.js',
+	'0.4.11': 'soljson-v0.4.11+commit.68ef5810.js',
+	'0.4.12': 'soljson-v0.4.12+commit.194ff033.js',
+	'0.4.13': 'soljson-v0.4.13+commit.fb4cb1a.js',
+	'0.4.14': 'soljson-v0.4.14+commit.c2215d46.js',
+	'0.4.15': 'soljson-v0.4.15+commit.bbb8e64f.js',
+	'0.4.16': 'soljson-v0.4.16+commit.d7661dd9.js',
+	'0.4.17': 'soljson-v0.4.17+commit.bdeb9e52.js',
+	'0.4.18': 'soljson-v0.4.18+commit.9cf6e910.js',
 };
diff --git a/packages/deployer/src/types.ts b/packages/deployer/src/types.ts
index 58d1e5b4f..aeff39d46 100644
--- a/packages/deployer/src/types.ts
+++ b/packages/deployer/src/types.ts
@@ -1,23 +1,23 @@
 export interface MultiSigConfig {
-    owners: string[];
-    confirmationsRequired: number;
-    secondsRequired: number;
+	owners: string[];
+	confirmationsRequired: number;
+	secondsRequired: number;
 }
 
 export interface MultiSigConfigByNetwork {
-    [networkName: string]: MultiSigConfig;
+	[networkName: string]: MultiSigConfig;
 }
 
 export interface Token {
-    address?: string;
-    name: string;
-    symbol: string;
-    decimals: number;
-    ipfsHash: string;
-    swarmHash: string;
+	address?: string;
+	name: string;
+	symbol: string;
+	decimals: number;
+	ipfsHash: string;
+	swarmHash: string;
 }
 
 export interface TokenInfoByNetwork {
-    development: Token[];
-    live: Token[];
+	development: Token[];
+	live: Token[];
 }
diff --git a/packages/deployer/src/utils/constants.ts b/packages/deployer/src/utils/constants.ts
index 8871a470d..9f22114e7 100644
--- a/packages/deployer/src/utils/constants.ts
+++ b/packages/deployer/src/utils/constants.ts
@@ -1,3 +1,3 @@
 export const constants = {
-    NULL_BYTES: '0x',
+	NULL_BYTES: '0x',
 };
diff --git a/packages/deployer/src/utils/contract.ts b/packages/deployer/src/utils/contract.ts
index 546e82dfb..473ca95c8 100644
--- a/packages/deployer/src/utils/contract.ts
+++ b/packages/deployer/src/utils/contract.ts
@@ -6,76 +6,76 @@ import * as Web3 from 'web3';
 import { AbiType } from './types';
 
 export class Contract implements Web3.ContractInstance {
-    public address: string;
-    public abi: Web3.ContractAbi;
-    private _contract: Web3.ContractInstance;
-    private _defaults: Partial<Web3.TxData>;
-    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<Web3.TxData>) {
-        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) as Web3.FunctionAbi[];
-        _.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) as Web3.EventAbi[];
-        _.forEach(eventsAbi, (eventAbi: Web3.EventAbi) => {
-            this[eventAbi.name] = this._contract[eventAbi.name];
-        });
-    }
-    private _promisifyWithDefaultParams(fn: (...args: any[]) => void): (...args: any[]) => Promise<any> {
-        const promisifiedWithDefaultParams = async (...args: any[]) => {
-            const promise = new Promise((resolve, reject) => {
-                const lastArg = args[args.length - 1];
-                let txData: Partial<Web3.TxData> = {};
-                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;
-    }
+	public address: string;
+	public abi: Web3.ContractAbi;
+	private _contract: Web3.ContractInstance;
+	private _defaults: Partial<Web3.TxData>;
+	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<Web3.TxData>) {
+		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) as Web3.FunctionAbi[];
+		_.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) as Web3.EventAbi[];
+		_.forEach(eventsAbi, (eventAbi: Web3.EventAbi) => {
+			this[eventAbi.name] = this._contract[eventAbi.name];
+		});
+	}
+	private _promisifyWithDefaultParams(fn: (...args: any[]) => void): (...args: any[]) => Promise<any> {
+		const promisifiedWithDefaultParams = async (...args: any[]) => {
+			const promise = new Promise((resolve, reject) => {
+				const lastArg = args[args.length - 1];
+				let txData: Partial<Web3.TxData> = {};
+				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/packages/deployer/src/utils/encoder.ts b/packages/deployer/src/utils/encoder.ts
index d5f807774..30772b4bc 100644
--- a/packages/deployer/src/utils/encoder.ts
+++ b/packages/deployer/src/utils/encoder.ts
@@ -5,16 +5,16 @@ import * as web3Abi from 'web3-eth-abi';
 import { AbiType } from './types';
 
 export const encoder = {
-    encodeConstructorArgsFromAbi(args: any[], abi: Web3.ContractAbi): string {
-        const constructorTypes: string[] = [];
-        _.each(abi, (element: Web3.AbiDefinition) => {
-            if (element.type === AbiType.Constructor) {
-                _.each(element.inputs, (input: Web3.FunctionParameter) => {
-                    constructorTypes.push(input.type);
-                });
-            }
-        });
-        const encodedParameters = web3Abi.encodeParameters(constructorTypes, args);
-        return encodedParameters;
-    },
+	encodeConstructorArgsFromAbi(args: any[], abi: Web3.ContractAbi): string {
+		const constructorTypes: string[] = [];
+		_.each(abi, (element: Web3.AbiDefinition) => {
+			if (element.type === AbiType.Constructor) {
+				_.each(element.inputs, (input: Web3.FunctionParameter) => {
+					constructorTypes.push(input.type);
+				});
+			}
+		});
+		const encodedParameters = web3Abi.encodeParameters(constructorTypes, args);
+		return encodedParameters;
+	},
 };
diff --git a/packages/deployer/src/utils/fs_wrapper.ts b/packages/deployer/src/utils/fs_wrapper.ts
index 34c7caa0e..42bdc9969 100644
--- a/packages/deployer/src/utils/fs_wrapper.ts
+++ b/packages/deployer/src/utils/fs_wrapper.ts
@@ -2,10 +2,10 @@ import { promisify } from '@0xproject/utils';
 import * as fs from 'fs';
 
 export const fsWrapper = {
-    readdirAsync: promisify<string[]>(fs.readdir),
-    readFileAsync: promisify<string>(fs.readFile),
-    writeFileAsync: promisify<undefined>(fs.writeFile),
-    mkdirAsync: promisify<undefined>(fs.mkdir),
-    doesPathExistSync: fs.existsSync,
-    removeFileAsync: promisify<undefined>(fs.unlink),
+	readdirAsync: promisify<string[]>(fs.readdir),
+	readFileAsync: promisify<string>(fs.readFile),
+	writeFileAsync: promisify<undefined>(fs.writeFile),
+	mkdirAsync: promisify<undefined>(fs.mkdir),
+	doesPathExistSync: fs.existsSync,
+	removeFileAsync: promisify<undefined>(fs.unlink),
 };
diff --git a/packages/deployer/src/utils/types.ts b/packages/deployer/src/utils/types.ts
index e054b9cc2..9e1378e24 100644
--- a/packages/deployer/src/utils/types.ts
+++ b/packages/deployer/src/utils/types.ts
@@ -3,95 +3,95 @@ import * as Web3 from 'web3';
 import * as yargs from 'yargs';
 
 export enum AbiType {
-    Function = 'function',
-    Constructor = 'constructor',
-    Event = 'event',
-    Fallback = 'fallback',
+	Function = 'function',
+	Constructor = 'constructor',
+	Event = 'event',
+	Fallback = 'fallback',
 }
 
 export interface ContractArtifact {
-    contract_name: string;
-    networks: ContractNetworks;
+	contract_name: string;
+	networks: ContractNetworks;
 }
 
 export interface ContractNetworks {
-    [key: number]: ContractData;
+	[key: number]: ContractData;
 }
 
 export interface ContractData {
-    solc_version: string;
-    optimizer_enabled: number;
-    keccak256: string;
-    abi: Web3.ContractAbi;
-    unlinked_binary: string;
-    address?: string;
-    constructor_args?: string;
-    updated_at: number;
+	solc_version: string;
+	optimizer_enabled: number;
+	keccak256: string;
+	abi: Web3.ContractAbi;
+	unlinked_binary: string;
+	address?: string;
+	constructor_args?: string;
+	updated_at: number;
 }
 
 export interface SolcErrors {
-    [key: string]: boolean;
+	[key: string]: boolean;
 }
 
 export interface CliOptions extends yargs.Arguments {
-    artifactsDir: string;
-    contractsDir: string;
-    jsonrpcPort: number;
-    networkId: number;
-    shouldOptimize: boolean;
-    gasPrice: string;
-    account?: string;
-    contract?: string;
-    args?: string;
+	artifactsDir: string;
+	contractsDir: string;
+	jsonrpcPort: number;
+	networkId: number;
+	shouldOptimize: boolean;
+	gasPrice: string;
+	account?: string;
+	contract?: string;
+	args?: string;
 }
 
 export interface CompilerOptions {
-    contractsDir: string;
-    networkId: number;
-    optimizerEnabled: number;
-    artifactsDir: string;
+	contractsDir: string;
+	networkId: number;
+	optimizerEnabled: number;
+	artifactsDir: string;
 }
 
 export interface DeployerOptions {
-    artifactsDir: string;
-    jsonrpcPort: number;
-    networkId: number;
-    defaults: Partial<TxData>;
+	artifactsDir: string;
+	jsonrpcPort: number;
+	networkId: number;
+	defaults: Partial<TxData>;
 }
 
 export interface ContractSources {
-    [key: string]: string;
+	[key: string]: string;
 }
 
 export interface ImportContents {
-    contents: string;
+	contents: string;
 }
 
 // TODO: Consolidate with 0x.js definitions once types are moved into a separate package.
 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',
+	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',
 }
 
 export interface Token {
-    address?: string;
-    name: string;
-    symbol: string;
-    decimals: number;
-    ipfsHash: string;
-    swarmHash: string;
+	address?: string;
+	name: string;
+	symbol: string;
+	decimals: number;
+	ipfsHash: string;
+	swarmHash: string;
 }
 
 export type DoneCallback = (err?: Error) => void;
diff --git a/packages/deployer/src/utils/utils.ts b/packages/deployer/src/utils/utils.ts
index 4390d8813..931ad6f73 100644
--- a/packages/deployer/src/utils/utils.ts
+++ b/packages/deployer/src/utils/utils.ts
@@ -1,13 +1,13 @@
 export const utils = {
-    consoleLog(message: string): void {
-        /* tslint:disable */
-        console.log(message);
-        /* tslint:enable */
-    },
-    stringifyWithFormatting(obj: any): string {
-        const jsonReplacer: null = null;
-        const numberOfJsonSpaces = 4;
-        const stringifiedObj = JSON.stringify(obj, jsonReplacer, numberOfJsonSpaces);
-        return stringifiedObj;
-    },
+	consoleLog(message: string): void {
+		/* tslint:disable */
+		console.log(message);
+		/* tslint:enable */
+	},
+	stringifyWithFormatting(obj: any): string {
+		const jsonReplacer: null = null;
+		const numberOfJsonSpaces = 4;
+		const stringifiedObj = JSON.stringify(obj, jsonReplacer, numberOfJsonSpaces);
+		return stringifiedObj;
+	},
 };
diff --git a/packages/deployer/test/deploy_test.ts b/packages/deployer/test/deploy_test.ts
index 5df729a04..583601154 100644
--- a/packages/deployer/test/deploy_test.ts
+++ b/packages/deployer/test/deploy_test.ts
@@ -13,79 +13,79 @@ const artifactsDir = `${__dirname}/fixtures/artifacts`;
 const contractsDir = `${__dirname}/fixtures/contracts`;
 const exchangeArtifactPath = `${artifactsDir}/Exchange.json`;
 const compilerOpts: CompilerOptions = {
-    artifactsDir,
-    contractsDir,
-    networkId: constants.networkId,
-    optimizerEnabled: constants.optimizerEnabled,
+	artifactsDir,
+	contractsDir,
+	networkId: constants.networkId,
+	optimizerEnabled: constants.optimizerEnabled,
 };
 const compiler = new Compiler(compilerOpts);
 const deployerOpts = {
-    artifactsDir,
-    networkId: constants.networkId,
-    jsonrpcPort: constants.jsonrpcPort,
-    defaults: {
-        gasPrice: constants.gasPrice,
-    },
+	artifactsDir,
+	networkId: constants.networkId,
+	jsonrpcPort: constants.jsonrpcPort,
+	defaults: {
+		gasPrice: constants.gasPrice,
+	},
 };
 const deployer = new Deployer(deployerOpts);
 
 /* tslint:disable */
 beforeEach(function(done: DoneCallback) {
-    this.timeout(constants.timeoutMs);
-    (async () => {
-        if (fsWrapper.doesPathExistSync(exchangeArtifactPath)) {
-            await fsWrapper.removeFileAsync(exchangeArtifactPath);
-        }
-        await compiler.compileAllAsync();
-        done();
-    })().catch(done);
+	this.timeout(constants.timeoutMs);
+	(async () => {
+		if (fsWrapper.doesPathExistSync(exchangeArtifactPath)) {
+			await fsWrapper.removeFileAsync(exchangeArtifactPath);
+		}
+		await compiler.compileAllAsync();
+		done();
+	})().catch(done);
 });
 /* tslint:enable */
 
 describe('#Compiler', () => {
-    it('should create an Exchange artifact with the correct unlinked binary', async () => {
-        const opts = {
-            encoding: 'utf8',
-        };
-        const exchangeArtifactString = await fsWrapper.readFileAsync(exchangeArtifactPath, opts);
-        const exchangeArtifact: ContractArtifact = JSON.parse(exchangeArtifactString);
-        const exchangeContractData: ContractData = exchangeArtifact.networks[constants.networkId];
-        // The last 43 bytes of the binaries are metadata which may not be equivalent
-        const unlinkedBinaryWithoutMetadata = exchangeContractData.unlinked_binary.slice(0, -86);
-        const exchangeBinaryWithoutMetadata = exchange_binary.slice(0, -86);
-        expect(unlinkedBinaryWithoutMetadata).to.equal(exchangeBinaryWithoutMetadata);
-    });
+	it('should create an Exchange artifact with the correct unlinked binary', async () => {
+		const opts = {
+			encoding: 'utf8',
+		};
+		const exchangeArtifactString = await fsWrapper.readFileAsync(exchangeArtifactPath, opts);
+		const exchangeArtifact: ContractArtifact = JSON.parse(exchangeArtifactString);
+		const exchangeContractData: ContractData = exchangeArtifact.networks[constants.networkId];
+		// The last 43 bytes of the binaries are metadata which may not be equivalent
+		const unlinkedBinaryWithoutMetadata = exchangeContractData.unlinked_binary.slice(0, -86);
+		const exchangeBinaryWithoutMetadata = exchange_binary.slice(0, -86);
+		expect(unlinkedBinaryWithoutMetadata).to.equal(exchangeBinaryWithoutMetadata);
+	});
 });
 describe('#Deployer', () => {
-    describe('#deployAsync', () => {
-        it('should deploy the Exchange contract without updating the Exchange artifact', async () => {
-            const exchangeConstructorArgs = [constants.zrxTokenAddress, constants.tokenTransferProxyAddress];
-            const exchangeContractInstance = await deployer.deployAsync('Exchange', exchangeConstructorArgs);
-            const opts = {
-                encoding: 'utf8',
-            };
-            const exchangeArtifactString = await fsWrapper.readFileAsync(exchangeArtifactPath, opts);
-            const exchangeArtifact: ContractArtifact = JSON.parse(exchangeArtifactString);
-            const exchangeContractData: ContractData = exchangeArtifact.networks[constants.networkId];
-            const exchangeAddress = exchangeContractInstance.address;
-            expect(exchangeAddress).to.not.equal(undefined);
-            expect(exchangeContractData.address).to.equal(undefined);
-            expect(exchangeContractData.constructor_args).to.equal(undefined);
-        });
-    });
-    describe('#deployAndSaveAsync', () => {
-        it('should save the correct contract address and constructor arguments to the Exchange artifact', async () => {
-            const exchangeConstructorArgs = [constants.zrxTokenAddress, constants.tokenTransferProxyAddress];
-            const exchangeContractInstance = await deployer.deployAndSaveAsync('Exchange', exchangeConstructorArgs);
-            const opts = {
-                encoding: 'utf8',
-            };
-            const exchangeArtifactString = await fsWrapper.readFileAsync(exchangeArtifactPath, opts);
-            const exchangeArtifact: ContractArtifact = JSON.parse(exchangeArtifactString);
-            const exchangeContractData: ContractData = exchangeArtifact.networks[constants.networkId];
-            const exchangeAddress = exchangeContractInstance.address;
-            expect(exchangeAddress).to.be.equal(exchangeContractData.address);
-            expect(constructor_args).to.be.equal(exchangeContractData.constructor_args);
-        });
-    });
+	describe('#deployAsync', () => {
+		it('should deploy the Exchange contract without updating the Exchange artifact', async () => {
+			const exchangeConstructorArgs = [constants.zrxTokenAddress, constants.tokenTransferProxyAddress];
+			const exchangeContractInstance = await deployer.deployAsync('Exchange', exchangeConstructorArgs);
+			const opts = {
+				encoding: 'utf8',
+			};
+			const exchangeArtifactString = await fsWrapper.readFileAsync(exchangeArtifactPath, opts);
+			const exchangeArtifact: ContractArtifact = JSON.parse(exchangeArtifactString);
+			const exchangeContractData: ContractData = exchangeArtifact.networks[constants.networkId];
+			const exchangeAddress = exchangeContractInstance.address;
+			expect(exchangeAddress).to.not.equal(undefined);
+			expect(exchangeContractData.address).to.equal(undefined);
+			expect(exchangeContractData.constructor_args).to.equal(undefined);
+		});
+	});
+	describe('#deployAndSaveAsync', () => {
+		it('should save the correct contract address and constructor arguments to the Exchange artifact', async () => {
+			const exchangeConstructorArgs = [constants.zrxTokenAddress, constants.tokenTransferProxyAddress];
+			const exchangeContractInstance = await deployer.deployAndSaveAsync('Exchange', exchangeConstructorArgs);
+			const opts = {
+				encoding: 'utf8',
+			};
+			const exchangeArtifactString = await fsWrapper.readFileAsync(exchangeArtifactPath, opts);
+			const exchangeArtifact: ContractArtifact = JSON.parse(exchangeArtifactString);
+			const exchangeContractData: ContractData = exchangeArtifact.networks[constants.networkId];
+			const exchangeAddress = exchangeContractInstance.address;
+			expect(exchangeAddress).to.be.equal(exchangeContractData.address);
+			expect(constructor_args).to.be.equal(exchangeContractData.constructor_args);
+		});
+	});
 });
diff --git a/packages/deployer/test/fixtures/exchange_bin.ts b/packages/deployer/test/fixtures/exchange_bin.ts
index a6eae515e..9c58b5e02 100644
--- a/packages/deployer/test/fixtures/exchange_bin.ts
+++ b/packages/deployer/test/fixtures/exchange_bin.ts
@@ -1,4 +1,4 @@
 export const constructor_args =
-    '0x000000000000000000000000e41d2489571d322189246dafa5ebde1f4699f4980000000000000000000000008da0d80f5007ef1e431dd2127178d224e32c2ef4';
+	'0x000000000000000000000000e41d2489571d322189246dafa5ebde1f4699f4980000000000000000000000008da0d80f5007ef1e431dd2127178d224e32c2ef4';
 export const exchange_binary =
-    '0x6060604052341561000f57600080fd5b604051604080612c4d833981016040528080519060200190919080519060200190919050505b816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b50505b612b84806100c96000396000f300606060405236156100fa576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806314df96ee146100ff578063288cdc911461014c5780632ac1262214610187578063363349be146101c2578063394c21e7146103bc5780633b30ba591461044b5780634f150787146104a0578063741bcc93146106b25780637e9abb50146107535780638163681e1461078e57806398024a8b14610812578063add1cbc51461085b578063b7b2c7d6146108b0578063baa0181d14610acd578063bc61394a14610c1f578063cfc4d0ec14610cdf578063f06bbf7514610d6d578063ffa1ad7414610d9e575b600080fd5b341561010a57600080fd5b6101326004808035906020019091908035906020019091908035906020019091905050610e2d565b604051808215151515815260200191505060405180910390f35b341561015757600080fd5b610171600480803560001916906020019091905050610e7c565b6040518082815260200191505060405180910390f35b341561019257600080fd5b6101ac600480803560001916906020019091905050610e94565b6040518082815260200191505060405180910390f35b34156101cd57600080fd5b6103a660048080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b8282101561024857848483905060a002016005806020026040519081016040528092919082600560200280828437820191505050505081526020019060010190610203565b5050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b828210156102c457848483905060c00201600680602002604051908101604052809291908260066020028082843782019150505050508152602001906001019061027f565b5050505050919080359060200190919080351515906020019091908035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091905050610eac565b6040518082815260200191505060405180910390f35b34156103c757600080fd5b6104356004808060a001906005806020026040519081016040528092919082600560200280828437820191505050505091908060c001906006806020026040519081016040528092919082600660200280828437820191505050505091908035906020019091905050611013565b6040518082815260200191505060405180910390f35b341561045657600080fd5b61045e6114fb565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156104ab57600080fd5b6106b060048080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b8282101561052657848483905060a0020160058060200260405190810160405280929190826005602002808284378201915050505050815260200190600101906104e1565b5050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b828210156105a257848483905060c00201600680602002604051908101604052809291908260066020028082843782019150505050508152602001906001019061055d565b50505050509190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091908035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091905050611520565b005b34156106bd57600080fd5b6107516004808060a001906005806020026040519081016040528092919082600560200280828437820191505050505091908060c00190600680602002604051908101604052809291908260066020028082843782019150505050509190803590602001909190803560ff1690602001909190803560001916906020019091908035600019169060200190919050506115df565b005b341561075e57600080fd5b610778600480803560001916906020019091905050611605565b6040518082815260200191505060405180910390f35b341561079957600080fd5b6107f8600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919080356000191690602001909190803560ff16906020019091908035600019169060200190919080356000191690602001909190505061164f565b604051808215151515815260200191505060405180910390f35b341561081d57600080fd5b6108456004808035906020019091908035906020019091908035906020019091905050611757565b6040518082815260200191505060405180910390f35b341561086657600080fd5b61086e611776565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156108bb57600080fd5b610acb60048080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b8282101561093657848483905060a0020160058060200260405190810160405280929190826005602002808284378201915050505050815260200190600101906108f1565b5050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b828210156109b257848483905060c00201600680602002604051908101604052809291908260066020028082843782019150505050508152602001906001019061096d565b50505050509190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091908035151590602001909190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091908035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509190505061179c565b005b3415610ad857600080fd5b610c1d60048080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b82821015610b5357848483905060a002016005806020026040519081016040528092919082600560200280828437820191505050505081526020019060010190610b0e565b5050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b82821015610bcf57848483905060c002016006806020026040519081016040528092919082600660200280828437820191505050505081526020019060010190610b8a565b5050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509190505061185e565b005b3415610c2a57600080fd5b610cc96004808060a001906005806020026040519081016040528092919082600560200280828437820191505050505091908060c001906006806020026040519081016040528092919082600660200280828437820191505050505091908035906020019091908035151590602001909190803560ff1690602001909190803560001916906020019091908035600019169060200190919050506118d3565b6040518082815260200191505060405180910390f35b3415610cea57600080fd5b610d4f6004808060a001906005806020026040519081016040528092919082600560200280828437820191505050505091908060c001906006806020026040519081016040528092919082600660200280828437820191505050505091905050612073565b60405180826000191660001916815260200191505060405180910390f35b3415610d7857600080fd5b610d8061231f565b604051808261ffff1661ffff16815260200191505060405180910390f35b3415610da957600080fd5b610db1612325565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610df25780820151818401525b602081019050610dd6565b50505050905090810190601f168015610e1f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60008060008486850991506000821415610e4a5760009250610e73565b610e69610e5a83620f424061235e565b610e64888761235e565b612392565b90506103e8811192505b50509392505050565b60026020528060005260406000206000915090505481565b60036020528060005260406000206000915090505481565b6000806000809150600090505b895181101561100257896000815181101515610ed157fe5b906020019060200201516003600581101515610ee957fe5b602002015173ffffffffffffffffffffffffffffffffffffffff168a82815181101515610f1257fe5b906020019060200201516003600581101515610f2a57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff16141515610f5157600080fd5b610fe582610fe08c84815181101515610f6657fe5b906020019060200201518c85815181101515610f7e57fe5b90602001906020020151610f928d886123ae565b8c8c88815181101515610fa157fe5b906020019060200201518c89815181101515610fb957fe5b906020019060200201518c8a815181101515610fd157fe5b906020019060200201516118d3565b6123c8565b915087821415610ff457611002565b5b8080600101915050610eb9565b8192505b5050979650505050505050565b600061101d612a8c565b6000806101606040519081016040528088600060058110151561103c57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff16815260200188600160058110151561106b57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff16815260200188600260058110151561109a57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018860036005811015156110c957fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018860046005811015156110f857fe5b602002015173ffffffffffffffffffffffffffffffffffffffff16815260200187600060068110151561112757fe5b6020020151815260200187600160068110151561114057fe5b6020020151815260200187600260068110151561115957fe5b6020020151815260200187600360068110151561117257fe5b6020020151815260200187600460068110151561118b57fe5b6020020151815260200161119f8989612073565b6000191681525092503373ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff161415156111e657600080fd5b60008360a001511180156111fe575060008360c00151115b801561120a5750600085115b151561121557600080fd5b8261012001514210151561127257826101400151600019166000600381111561123a57fe5b60ff167f36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e9060405160405180910390a3600093506114f1565b61128d8360c00151611288856101400151611605565b6123ae565b915061129985836123e7565b905060008114156112f35782610140015160001916600160038111156112bb57fe5b60ff167f36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e9060405160405180910390a3600093506114f1565b61131d600360008561014001516000191660001916815260200190815260200160002054826123c8565b60036000856101400151600019166000191681526020019081526020016000208190555082604001518360600151604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c0100000000000000000000000002815260140192505050604051809103902060001916836080015173ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff167f67d66f160bc93d925d05dae1794c90d2d6d6688b29b84ff069398a9b0458713186604001518760600151611455878a60c001518b60a00151611757565b878a6101400151604051808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200184815260200183815260200182600019166000191681526020019550505050505060405180910390a48093505b5050509392505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008090505b86518110156115d5576115c7878281518110151561154057fe5b90602001906020020151878381518110151561155857fe5b90602001906020020151878481518110151561157057fe5b90602001906020020151878581518110151561158857fe5b9060200190602002015187868151811015156115a057fe5b9060200190602002015187878151811015156115b857fe5b906020019060200201516115df565b5b8080600101915050611526565b5b50505050505050565b836115f087878760008888886118d3565b1415156115fc57600080fd5b5b505050505050565b600061164760026000846000191660001916815260200190815260200160002054600360008560001916600019168152602001908152602001600020546123c8565b90505b919050565b600060018560405180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c0182600019166000191681526020019150506040518091039020858585604051600081526020016040526000604051602001526040518085600019166000191681526020018460ff1660ff16815260200183600019166000191681526020018260001916600019168152602001945050505050602060405160208103908084039060008661646e5a03f1151561171457600080fd5b50506020604051035173ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161490505b95945050505050565b600061176c611766858461235e565b84612392565b90505b9392505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008090505b87518110156118535761184488828151811015156117bc57fe5b9060200190602002015188838151811015156117d457fe5b9060200190602002015188848151811015156117ec57fe5b9060200190602002015188888681518110151561180557fe5b90602001906020020151888781518110151561181d57fe5b90602001906020020151888881518110151561183557fe5b906020019060200201516118d3565b505b80806001019150506117a2565b5b5050505050505050565b60008090505b83518110156118cc576118bd848281518110151561187e57fe5b90602001906020020151848381518110151561189657fe5b9060200190602002015184848151811015156118ae57fe5b90602001906020020151611013565b505b8080600101915050611864565b5b50505050565b60006118dd612a8c565b600080600080610160604051908101604052808e60006005811015156118ff57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018e600160058110151561192e57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018e600260058110151561195d57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018e600360058110151561198c57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018e60046005811015156119bb57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018d60006006811015156119ea57fe5b602002015181526020018d6001600681101515611a0357fe5b602002015181526020018d6002600681101515611a1c57fe5b602002015181526020018d6003600681101515611a3557fe5b602002015181526020018d6004600681101515611a4e57fe5b60200201518152602001611a628f8f612073565b600019168152509450600073ffffffffffffffffffffffffffffffffffffffff16856020015173ffffffffffffffffffffffffffffffffffffffff161480611ad957503373ffffffffffffffffffffffffffffffffffffffff16856020015173ffffffffffffffffffffffffffffffffffffffff16145b1515611ae457600080fd5b60008560a00151118015611afc575060008560c00151115b8015611b08575060008b115b1515611b1357600080fd5b611b2985600001518661014001518b8b8b61164f565b1515611b3457600080fd5b84610120015142101515611b91578461014001516000191660006003811115611b5957fe5b60ff167f36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e9060405160405180910390a360009550612063565b611bac8560c00151611ba7876101400151611605565b6123ae565b9350611bb88b856123e7565b95506000861415611c12578461014001516000191660016003811115611bda57fe5b60ff167f36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e9060405160405180910390a360009550612063565b611c25868660c001518760a00151610e2d565b15611c79578461014001516000191660026003811115611c4157fe5b60ff167f36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e9060405160405180910390a360009550612063565b89158015611c8e5750611c8c8587612401565b155b15611ce15784610140015160001916600380811115611ca957fe5b60ff167f36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e9060405160405180910390a360009550612063565b611cf4868660c001518760a00151611757565b9250611d20600260008761014001516000191660001916815260200190815260200160002054876123c8565b600260008761014001516000191660001916815260200190815260200160002081905550611d58856040015186600001513386612751565b1515611d6357600080fd5b611d77856060015133876000015189612751565b1515611d8257600080fd5b600073ffffffffffffffffffffffffffffffffffffffff16856080015173ffffffffffffffffffffffffffffffffffffffff16141515611e815760008560e001511115611e1f57611ddc868660c001518760e00151611757565b9150611e136000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168660000151876080015185612751565b1515611e1e57600080fd5b5b60008561010001511115611e8057611e41868660c00151876101000151611757565b9050611e746000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1633876080015184612751565b1515611e7f57600080fd5b5b5b84604001518560600151604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c0100000000000000000000000002815260140192505050604051809103902060001916856080015173ffffffffffffffffffffffffffffffffffffffff16866000015173ffffffffffffffffffffffffffffffffffffffff167f0d0b9391970d9a25552f37d436d2aae2925e2bfe1b2a923754bada030c498cb33389604001518a60600151898d8a8a8f6101400151604051808973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200186815260200185815260200184815260200183815260200182600019166000191681526020019850505050505050505060405180910390a48595505b5050505050979650505050505050565b60003083600060058110151561208557fe5b602002015184600160058110151561209957fe5b60200201518560026005811015156120ad57fe5b60200201518660036005811015156120c157fe5b60200201518760046005811015156120d557fe5b60200201518760006006811015156120e957fe5b60200201518860016006811015156120fd57fe5b602002015189600260068110151561211157fe5b60200201518a600360068110151561212557fe5b60200201518b600460068110151561213957fe5b60200201518c600560068110151561214d57fe5b6020020151604051808d73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018781526020018681526020018581526020018481526020018381526020018281526020019c50505050505050505050505050604051809103902090505b92915050565b61138781565b6040805190810160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b6000808284029050600084148061237f575082848281151561237c57fe5b04145b151561238757fe5b8091505b5092915050565b60008082848115156123a057fe5b0490508091505b5092915050565b60008282111515156123bc57fe5b81830390505b92915050565b60008082840190508381101515156123dc57fe5b8091505b5092915050565b60008183106123f657816123f8565b825b90505b92915050565b60008060008060008060008060003397506124258a8c60c001518d60a00151611757565b9650600073ffffffffffffffffffffffffffffffffffffffff168b6080015173ffffffffffffffffffffffffffffffffffffffff161415156126d2576000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168b6040015173ffffffffffffffffffffffffffffffffffffffff161495506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168b6060015173ffffffffffffffffffffffffffffffffffffffff161494506125208a8c60c001518d60e00151611757565b93506125368a8c60c001518d6101000151611757565b925085612543578361254e565b61254d87856123c8565b5b91508461255b5782612566565b6125658a846123c8565b5b9050816125986000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168d600001516128ae565b10806125d15750816125cf6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168d60000151612972565b105b806126055750806126036000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168a6128ae565b105b806126395750806126376000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168a612972565b105b156126475760009850612743565b851580156126805750866126638c604001518d600001516128ae565b108061267f57508661267d8c604001518d60000151612972565b105b5b1561268e5760009850612743565b841580156126bf5750896126a68c606001518a6128ae565b10806126be5750896126bc8c606001518a612972565b105b5b156126cd5760009850612743565b61273e565b866126e58c604001518d600001516128ae565b10806127015750866126ff8c604001518d60000151612972565b105b806127185750896127168c606001518a6128ae565b105b8061272f57508961272d8c606001518a612972565b105b1561273d5760009850612743565b5b600198505b505050505050505092915050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166315dacbea868686866000604051602001526040518563ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001945050505050602060405180830381600087803b151561288857600080fd5b6102c65a03f1151561289957600080fd5b5050506040518051905090505b949350505050565b60008273ffffffffffffffffffffffffffffffffffffffff166370a0823161138761ffff16846040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600088803b151561295157600080fd5b87f1151561295e57600080fd5b505050506040518051905090505b92915050565b60008273ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e61138761ffff1684600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050602060405180830381600088803b1515612a6b57600080fd5b87f11515612a7857600080fd5b505050506040518051905090505b92915050565b61016060405190810160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160008152602001600081526020016000815260200160008152602001600081526020016000801916815250905600a165627a7a72305820df5cabdc3a116e993e10bfb14823d18d9b798038d4c463a1703f9a584c456b7e0029';
+	'0x6060604052341561000f57600080fd5b604051604080612c4d833981016040528080519060200190919080519060200190919050505b816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b50505b612b84806100c96000396000f300606060405236156100fa576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806314df96ee146100ff578063288cdc911461014c5780632ac1262214610187578063363349be146101c2578063394c21e7146103bc5780633b30ba591461044b5780634f150787146104a0578063741bcc93146106b25780637e9abb50146107535780638163681e1461078e57806398024a8b14610812578063add1cbc51461085b578063b7b2c7d6146108b0578063baa0181d14610acd578063bc61394a14610c1f578063cfc4d0ec14610cdf578063f06bbf7514610d6d578063ffa1ad7414610d9e575b600080fd5b341561010a57600080fd5b6101326004808035906020019091908035906020019091908035906020019091905050610e2d565b604051808215151515815260200191505060405180910390f35b341561015757600080fd5b610171600480803560001916906020019091905050610e7c565b6040518082815260200191505060405180910390f35b341561019257600080fd5b6101ac600480803560001916906020019091905050610e94565b6040518082815260200191505060405180910390f35b34156101cd57600080fd5b6103a660048080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b8282101561024857848483905060a002016005806020026040519081016040528092919082600560200280828437820191505050505081526020019060010190610203565b5050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b828210156102c457848483905060c00201600680602002604051908101604052809291908260066020028082843782019150505050508152602001906001019061027f565b5050505050919080359060200190919080351515906020019091908035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091905050610eac565b6040518082815260200191505060405180910390f35b34156103c757600080fd5b6104356004808060a001906005806020026040519081016040528092919082600560200280828437820191505050505091908060c001906006806020026040519081016040528092919082600660200280828437820191505050505091908035906020019091905050611013565b6040518082815260200191505060405180910390f35b341561045657600080fd5b61045e6114fb565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156104ab57600080fd5b6106b060048080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b8282101561052657848483905060a0020160058060200260405190810160405280929190826005602002808284378201915050505050815260200190600101906104e1565b5050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b828210156105a257848483905060c00201600680602002604051908101604052809291908260066020028082843782019150505050508152602001906001019061055d565b50505050509190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091908035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091905050611520565b005b34156106bd57600080fd5b6107516004808060a001906005806020026040519081016040528092919082600560200280828437820191505050505091908060c00190600680602002604051908101604052809291908260066020028082843782019150505050509190803590602001909190803560ff1690602001909190803560001916906020019091908035600019169060200190919050506115df565b005b341561075e57600080fd5b610778600480803560001916906020019091905050611605565b6040518082815260200191505060405180910390f35b341561079957600080fd5b6107f8600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919080356000191690602001909190803560ff16906020019091908035600019169060200190919080356000191690602001909190505061164f565b604051808215151515815260200191505060405180910390f35b341561081d57600080fd5b6108456004808035906020019091908035906020019091908035906020019091905050611757565b6040518082815260200191505060405180910390f35b341561086657600080fd5b61086e611776565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156108bb57600080fd5b610acb60048080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b8282101561093657848483905060a0020160058060200260405190810160405280929190826005602002808284378201915050505050815260200190600101906108f1565b5050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b828210156109b257848483905060c00201600680602002604051908101604052809291908260066020028082843782019150505050508152602001906001019061096d565b50505050509190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091908035151590602001909190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091908035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509190505061179c565b005b3415610ad857600080fd5b610c1d60048080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b82821015610b5357848483905060a002016005806020026040519081016040528092919082600560200280828437820191505050505081526020019060010190610b0e565b5050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b82821015610bcf57848483905060c002016006806020026040519081016040528092919082600660200280828437820191505050505081526020019060010190610b8a565b5050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509190505061185e565b005b3415610c2a57600080fd5b610cc96004808060a001906005806020026040519081016040528092919082600560200280828437820191505050505091908060c001906006806020026040519081016040528092919082600660200280828437820191505050505091908035906020019091908035151590602001909190803560ff1690602001909190803560001916906020019091908035600019169060200190919050506118d3565b6040518082815260200191505060405180910390f35b3415610cea57600080fd5b610d4f6004808060a001906005806020026040519081016040528092919082600560200280828437820191505050505091908060c001906006806020026040519081016040528092919082600660200280828437820191505050505091905050612073565b60405180826000191660001916815260200191505060405180910390f35b3415610d7857600080fd5b610d8061231f565b604051808261ffff1661ffff16815260200191505060405180910390f35b3415610da957600080fd5b610db1612325565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610df25780820151818401525b602081019050610dd6565b50505050905090810190601f168015610e1f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60008060008486850991506000821415610e4a5760009250610e73565b610e69610e5a83620f424061235e565b610e64888761235e565b612392565b90506103e8811192505b50509392505050565b60026020528060005260406000206000915090505481565b60036020528060005260406000206000915090505481565b6000806000809150600090505b895181101561100257896000815181101515610ed157fe5b906020019060200201516003600581101515610ee957fe5b602002015173ffffffffffffffffffffffffffffffffffffffff168a82815181101515610f1257fe5b906020019060200201516003600581101515610f2a57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff16141515610f5157600080fd5b610fe582610fe08c84815181101515610f6657fe5b906020019060200201518c85815181101515610f7e57fe5b90602001906020020151610f928d886123ae565b8c8c88815181101515610fa157fe5b906020019060200201518c89815181101515610fb957fe5b906020019060200201518c8a815181101515610fd157fe5b906020019060200201516118d3565b6123c8565b915087821415610ff457611002565b5b8080600101915050610eb9565b8192505b5050979650505050505050565b600061101d612a8c565b6000806101606040519081016040528088600060058110151561103c57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff16815260200188600160058110151561106b57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff16815260200188600260058110151561109a57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018860036005811015156110c957fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018860046005811015156110f857fe5b602002015173ffffffffffffffffffffffffffffffffffffffff16815260200187600060068110151561112757fe5b6020020151815260200187600160068110151561114057fe5b6020020151815260200187600260068110151561115957fe5b6020020151815260200187600360068110151561117257fe5b6020020151815260200187600460068110151561118b57fe5b6020020151815260200161119f8989612073565b6000191681525092503373ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff161415156111e657600080fd5b60008360a001511180156111fe575060008360c00151115b801561120a5750600085115b151561121557600080fd5b8261012001514210151561127257826101400151600019166000600381111561123a57fe5b60ff167f36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e9060405160405180910390a3600093506114f1565b61128d8360c00151611288856101400151611605565b6123ae565b915061129985836123e7565b905060008114156112f35782610140015160001916600160038111156112bb57fe5b60ff167f36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e9060405160405180910390a3600093506114f1565b61131d600360008561014001516000191660001916815260200190815260200160002054826123c8565b60036000856101400151600019166000191681526020019081526020016000208190555082604001518360600151604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c0100000000000000000000000002815260140192505050604051809103902060001916836080015173ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff167f67d66f160bc93d925d05dae1794c90d2d6d6688b29b84ff069398a9b0458713186604001518760600151611455878a60c001518b60a00151611757565b878a6101400151604051808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200184815260200183815260200182600019166000191681526020019550505050505060405180910390a48093505b5050509392505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008090505b86518110156115d5576115c7878281518110151561154057fe5b90602001906020020151878381518110151561155857fe5b90602001906020020151878481518110151561157057fe5b90602001906020020151878581518110151561158857fe5b9060200190602002015187868151811015156115a057fe5b9060200190602002015187878151811015156115b857fe5b906020019060200201516115df565b5b8080600101915050611526565b5b50505050505050565b836115f087878760008888886118d3565b1415156115fc57600080fd5b5b505050505050565b600061164760026000846000191660001916815260200190815260200160002054600360008560001916600019168152602001908152602001600020546123c8565b90505b919050565b600060018560405180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c0182600019166000191681526020019150506040518091039020858585604051600081526020016040526000604051602001526040518085600019166000191681526020018460ff1660ff16815260200183600019166000191681526020018260001916600019168152602001945050505050602060405160208103908084039060008661646e5a03f1151561171457600080fd5b50506020604051035173ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161490505b95945050505050565b600061176c611766858461235e565b84612392565b90505b9392505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008090505b87518110156118535761184488828151811015156117bc57fe5b9060200190602002015188838151811015156117d457fe5b9060200190602002015188848151811015156117ec57fe5b9060200190602002015188888681518110151561180557fe5b90602001906020020151888781518110151561181d57fe5b90602001906020020151888881518110151561183557fe5b906020019060200201516118d3565b505b80806001019150506117a2565b5b5050505050505050565b60008090505b83518110156118cc576118bd848281518110151561187e57fe5b90602001906020020151848381518110151561189657fe5b9060200190602002015184848151811015156118ae57fe5b90602001906020020151611013565b505b8080600101915050611864565b5b50505050565b60006118dd612a8c565b600080600080610160604051908101604052808e60006005811015156118ff57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018e600160058110151561192e57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018e600260058110151561195d57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018e600360058110151561198c57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018e60046005811015156119bb57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018d60006006811015156119ea57fe5b602002015181526020018d6001600681101515611a0357fe5b602002015181526020018d6002600681101515611a1c57fe5b602002015181526020018d6003600681101515611a3557fe5b602002015181526020018d6004600681101515611a4e57fe5b60200201518152602001611a628f8f612073565b600019168152509450600073ffffffffffffffffffffffffffffffffffffffff16856020015173ffffffffffffffffffffffffffffffffffffffff161480611ad957503373ffffffffffffffffffffffffffffffffffffffff16856020015173ffffffffffffffffffffffffffffffffffffffff16145b1515611ae457600080fd5b60008560a00151118015611afc575060008560c00151115b8015611b08575060008b115b1515611b1357600080fd5b611b2985600001518661014001518b8b8b61164f565b1515611b3457600080fd5b84610120015142101515611b91578461014001516000191660006003811115611b5957fe5b60ff167f36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e9060405160405180910390a360009550612063565b611bac8560c00151611ba7876101400151611605565b6123ae565b9350611bb88b856123e7565b95506000861415611c12578461014001516000191660016003811115611bda57fe5b60ff167f36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e9060405160405180910390a360009550612063565b611c25868660c001518760a00151610e2d565b15611c79578461014001516000191660026003811115611c4157fe5b60ff167f36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e9060405160405180910390a360009550612063565b89158015611c8e5750611c8c8587612401565b155b15611ce15784610140015160001916600380811115611ca957fe5b60ff167f36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e9060405160405180910390a360009550612063565b611cf4868660c001518760a00151611757565b9250611d20600260008761014001516000191660001916815260200190815260200160002054876123c8565b600260008761014001516000191660001916815260200190815260200160002081905550611d58856040015186600001513386612751565b1515611d6357600080fd5b611d77856060015133876000015189612751565b1515611d8257600080fd5b600073ffffffffffffffffffffffffffffffffffffffff16856080015173ffffffffffffffffffffffffffffffffffffffff16141515611e815760008560e001511115611e1f57611ddc868660c001518760e00151611757565b9150611e136000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168660000151876080015185612751565b1515611e1e57600080fd5b5b60008561010001511115611e8057611e41868660c00151876101000151611757565b9050611e746000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1633876080015184612751565b1515611e7f57600080fd5b5b5b84604001518560600151604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c0100000000000000000000000002815260140192505050604051809103902060001916856080015173ffffffffffffffffffffffffffffffffffffffff16866000015173ffffffffffffffffffffffffffffffffffffffff167f0d0b9391970d9a25552f37d436d2aae2925e2bfe1b2a923754bada030c498cb33389604001518a60600151898d8a8a8f6101400151604051808973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200186815260200185815260200184815260200183815260200182600019166000191681526020019850505050505050505060405180910390a48595505b5050505050979650505050505050565b60003083600060058110151561208557fe5b602002015184600160058110151561209957fe5b60200201518560026005811015156120ad57fe5b60200201518660036005811015156120c157fe5b60200201518760046005811015156120d557fe5b60200201518760006006811015156120e957fe5b60200201518860016006811015156120fd57fe5b602002015189600260068110151561211157fe5b60200201518a600360068110151561212557fe5b60200201518b600460068110151561213957fe5b60200201518c600560068110151561214d57fe5b6020020151604051808d73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018781526020018681526020018581526020018481526020018381526020018281526020019c50505050505050505050505050604051809103902090505b92915050565b61138781565b6040805190810160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b6000808284029050600084148061237f575082848281151561237c57fe5b04145b151561238757fe5b8091505b5092915050565b60008082848115156123a057fe5b0490508091505b5092915050565b60008282111515156123bc57fe5b81830390505b92915050565b60008082840190508381101515156123dc57fe5b8091505b5092915050565b60008183106123f657816123f8565b825b90505b92915050565b60008060008060008060008060003397506124258a8c60c001518d60a00151611757565b9650600073ffffffffffffffffffffffffffffffffffffffff168b6080015173ffffffffffffffffffffffffffffffffffffffff161415156126d2576000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168b6040015173ffffffffffffffffffffffffffffffffffffffff161495506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168b6060015173ffffffffffffffffffffffffffffffffffffffff161494506125208a8c60c001518d60e00151611757565b93506125368a8c60c001518d6101000151611757565b925085612543578361254e565b61254d87856123c8565b5b91508461255b5782612566565b6125658a846123c8565b5b9050816125986000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168d600001516128ae565b10806125d15750816125cf6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168d60000151612972565b105b806126055750806126036000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168a6128ae565b105b806126395750806126376000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168a612972565b105b156126475760009850612743565b851580156126805750866126638c604001518d600001516128ae565b108061267f57508661267d8c604001518d60000151612972565b105b5b1561268e5760009850612743565b841580156126bf5750896126a68c606001518a6128ae565b10806126be5750896126bc8c606001518a612972565b105b5b156126cd5760009850612743565b61273e565b866126e58c604001518d600001516128ae565b10806127015750866126ff8c604001518d60000151612972565b105b806127185750896127168c606001518a6128ae565b105b8061272f57508961272d8c606001518a612972565b105b1561273d5760009850612743565b5b600198505b505050505050505092915050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166315dacbea868686866000604051602001526040518563ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001945050505050602060405180830381600087803b151561288857600080fd5b6102c65a03f1151561289957600080fd5b5050506040518051905090505b949350505050565b60008273ffffffffffffffffffffffffffffffffffffffff166370a0823161138761ffff16846040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600088803b151561295157600080fd5b87f1151561295e57600080fd5b505050506040518051905090505b92915050565b60008273ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e61138761ffff1684600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050602060405180830381600088803b1515612a6b57600080fd5b87f11515612a7857600080fd5b505050506040518051905090505b92915050565b61016060405190810160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160008152602001600081526020016000815260200160008152602001600081526020016000801916815250905600a165627a7a72305820df5cabdc3a116e993e10bfb14823d18d9b798038d4c463a1703f9a584c456b7e0029';
diff --git a/packages/deployer/test/util/constants.ts b/packages/deployer/test/util/constants.ts
index d52076607..d69ce5385 100644
--- a/packages/deployer/test/util/constants.ts
+++ b/packages/deployer/test/util/constants.ts
@@ -1,11 +1,11 @@
 import { BigNumber } from '@0xproject/utils';
 
 export const constants = {
-    networkId: 0,
-    jsonrpcPort: 8545,
-    optimizerEnabled: 0,
-    gasPrice: new BigNumber(20000000000),
-    timeoutMs: 20000,
-    zrxTokenAddress: '0xe41d2489571d322189246dafa5ebde1f4699f498',
-    tokenTransferProxyAddress: '0x8da0d80f5007ef1e431dd2127178d224e32c2ef4',
+	networkId: 0,
+	jsonrpcPort: 8545,
+	optimizerEnabled: 0,
+	gasPrice: new BigNumber(20000000000),
+	timeoutMs: 20000,
+	zrxTokenAddress: '0xe41d2489571d322189246dafa5ebde1f4699f498',
+	tokenTransferProxyAddress: '0x8da0d80f5007ef1e431dd2127178d224e32c2ef4',
 };
diff --git a/packages/deployer/tsconfig.json b/packages/deployer/tsconfig.json
index 4e1edb510..f11c9245e 100644
--- a/packages/deployer/tsconfig.json
+++ b/packages/deployer/tsconfig.json
@@ -1,16 +1,16 @@
 {
-    "extends": "../../tsconfig",
-    "compilerOptions": {
-        "outDir": "lib",
-        "strictFunctionTypes": false,
-        "strictNullChecks": false
-    },
-    "include": [
-        "./src/**/*",
-        "./test/**/*",
-        "../../node_modules/types-bn/index.d.ts",
-        "../../node_modules/types-ethereumjs-util/index.d.ts",
-        "../../node_modules/chai-typescript-typings/index.d.ts",
-        "../../node_modules/web3-typescript-typings/index.d.ts"
-    ]
+	"extends": "../../tsconfig",
+	"compilerOptions": {
+		"outDir": "lib",
+		"strictFunctionTypes": false,
+		"strictNullChecks": false
+	},
+	"include": [
+		"./src/**/*",
+		"./test/**/*",
+		"../../node_modules/types-bn/index.d.ts",
+		"../../node_modules/types-ethereumjs-util/index.d.ts",
+		"../../node_modules/chai-typescript-typings/index.d.ts",
+		"../../node_modules/web3-typescript-typings/index.d.ts"
+	]
 }
diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json
index ea940fb1d..d7c764285 100644
--- a/packages/dev-utils/package.json
+++ b/packages/dev-utils/package.json
@@ -1,37 +1,37 @@
 {
-    "name": "@0xproject/dev-utils",
-    "version": "0.0.7",
-    "description": "0x dev TS utils",
-    "main": "lib/index.js",
-    "types": "lib/index.d.ts",
-    "scripts": {
-        "build": "tsc",
-        "clean": "shx rm -rf lib",
-        "lint": "tslint --project . 'src/**/*.ts'"
-    },
-    "license": "Apache-2.0",
-    "repository": {
-        "type": "git",
-        "url": "https://github.com/0xProject/0x.js.git"
-    },
-    "bugs": {
-        "url": "https://github.com/0xProject/0x.js/issues"
-    },
-    "homepage": "https://github.com/0xProject/0x.js/packages/dev-utils/README.md",
-    "devDependencies": {
-        "@0xproject/tslint-config": "^0.4.4",
-        "@types/lodash": "^4.14.86",
-        "npm-run-all": "^4.1.2",
-        "shx": "^0.2.2",
-        "tslint": "5.8.0",
-        "types-bn": "^0.0.1",
-        "types-ethereumjs-util": "0xProject/types-ethereumjs-util",
-        "typescript": "~2.6.1"
-    },
-    "dependencies": {
-        "@0xproject/utils": "^0.2.2",
-        "ethereumjs-util": "^5.1.2",
-        "lodash": "^4.17.4",
-        "request-promise-native": "^1.0.5"
-    }
+	"name": "@0xproject/dev-utils",
+	"version": "0.0.7",
+	"description": "0x dev TS utils",
+	"main": "lib/index.js",
+	"types": "lib/index.d.ts",
+	"scripts": {
+		"build": "tsc",
+		"clean": "shx rm -rf lib",
+		"lint": "tslint --project . 'src/**/*.ts'"
+	},
+	"license": "Apache-2.0",
+	"repository": {
+		"type": "git",
+		"url": "https://github.com/0xProject/0x.js.git"
+	},
+	"bugs": {
+		"url": "https://github.com/0xProject/0x.js/issues"
+	},
+	"homepage": "https://github.com/0xProject/0x.js/packages/dev-utils/README.md",
+	"devDependencies": {
+		"@0xproject/tslint-config": "^0.4.4",
+		"@types/lodash": "^4.14.86",
+		"npm-run-all": "^4.1.2",
+		"shx": "^0.2.2",
+		"tslint": "5.8.0",
+		"types-bn": "^0.0.1",
+		"types-ethereumjs-util": "0xProject/types-ethereumjs-util",
+		"typescript": "~2.6.1"
+	},
+	"dependencies": {
+		"@0xproject/utils": "^0.2.2",
+		"ethereumjs-util": "^5.1.2",
+		"lodash": "^4.17.4",
+		"request-promise-native": "^1.0.5"
+	}
 }
diff --git a/packages/dev-utils/src/blockchain_lifecycle.ts b/packages/dev-utils/src/blockchain_lifecycle.ts
index 18f5d5c61..fafa62c84 100644
--- a/packages/dev-utils/src/blockchain_lifecycle.ts
+++ b/packages/dev-utils/src/blockchain_lifecycle.ts
@@ -1,23 +1,23 @@
 import { RPC } from './rpc';
 
 export class BlockchainLifecycle {
-    private _rpc: RPC;
-    private _snapshotIdsStack: number[];
-    constructor(url: string) {
-        this._rpc = new RPC(url);
-        this._snapshotIdsStack = [];
-    }
-    // TODO: In order to run these tests on an actual node, we should check if we are running against
-    // TestRPC, if so, use snapshots, otherwise re-deploy contracts before every test
-    public async startAsync(): Promise<void> {
-        const snapshotId = await this._rpc.takeSnapshotAsync();
-        this._snapshotIdsStack.push(snapshotId);
-    }
-    public async revertAsync(): Promise<void> {
-        const snapshotId = this._snapshotIdsStack.pop() as number;
-        const didRevert = await this._rpc.revertSnapshotAsync(snapshotId);
-        if (!didRevert) {
-            throw new Error(`Snapshot with id #${snapshotId} failed to revert`);
-        }
-    }
+	private _rpc: RPC;
+	private _snapshotIdsStack: number[];
+	constructor(url: string) {
+		this._rpc = new RPC(url);
+		this._snapshotIdsStack = [];
+	}
+	// TODO: In order to run these tests on an actual node, we should check if we are running against
+	// TestRPC, if so, use snapshots, otherwise re-deploy contracts before every test
+	public async startAsync(): Promise<void> {
+		const snapshotId = await this._rpc.takeSnapshotAsync();
+		this._snapshotIdsStack.push(snapshotId);
+	}
+	public async revertAsync(): Promise<void> {
+		const snapshotId = this._snapshotIdsStack.pop() as number;
+		const didRevert = await this._rpc.revertSnapshotAsync(snapshotId);
+		if (!didRevert) {
+			throw new Error(`Snapshot with id #${snapshotId} failed to revert`);
+		}
+	}
 }
diff --git a/packages/dev-utils/src/rpc.ts b/packages/dev-utils/src/rpc.ts
index 36f8b1ef9..6241ab971 100644
--- a/packages/dev-utils/src/rpc.ts
+++ b/packages/dev-utils/src/rpc.ts
@@ -2,59 +2,59 @@ import * as ethUtil from 'ethereumjs-util';
 import * as request from 'request-promise-native';
 
 export class RPC {
-    private _url: string;
-    private _id: number;
-    constructor(url: string) {
-        this._url = url;
-        this._id = 0;
-    }
-    public async takeSnapshotAsync(): Promise<number> {
-        const method = 'evm_snapshot';
-        const params: any[] = [];
-        const payload = this._toPayload(method, params);
-        const snapshotIdHex = await this._sendAsync(payload);
-        const snapshotId = ethUtil.bufferToInt(ethUtil.toBuffer(snapshotIdHex));
-        return snapshotId;
-    }
-    public async revertSnapshotAsync(snapshotId: number): Promise<boolean> {
-        const method = 'evm_revert';
-        const params = [snapshotId];
-        const payload = this._toPayload(method, params);
-        const didRevert = await this._sendAsync(payload);
-        return didRevert;
-    }
-    public async increaseTimeAsync(time: number) {
-        const method = 'evm_increaseTime';
-        const params = [time];
-        const payload = this._toPayload(method, params);
-        return this._sendAsync(payload);
-    }
-    public async mineBlockAsync(): Promise<void> {
-        const method = 'evm_mine';
-        const params: any[] = [];
-        const payload = this._toPayload(method, params);
-        await this._sendAsync(payload);
-    }
-    private _toPayload(method: string, params: any[] = []): string {
-        const payload = JSON.stringify({
-            id: this._id,
-            method,
-            params,
-        });
-        this._id += 1;
-        return payload;
-    }
-    private async _sendAsync(payload: string): Promise<any> {
-        const opts = {
-            method: 'POST',
-            uri: this._url,
-            body: payload,
-            headers: {
-                'content-type': 'application/json',
-            },
-        };
-        const bodyString = await request(opts);
-        const body = JSON.parse(bodyString);
-        return body.result;
-    }
+	private _url: string;
+	private _id: number;
+	constructor(url: string) {
+		this._url = url;
+		this._id = 0;
+	}
+	public async takeSnapshotAsync(): Promise<number> {
+		const method = 'evm_snapshot';
+		const params: any[] = [];
+		const payload = this._toPayload(method, params);
+		const snapshotIdHex = await this._sendAsync(payload);
+		const snapshotId = ethUtil.bufferToInt(ethUtil.toBuffer(snapshotIdHex));
+		return snapshotId;
+	}
+	public async revertSnapshotAsync(snapshotId: number): Promise<boolean> {
+		const method = 'evm_revert';
+		const params = [snapshotId];
+		const payload = this._toPayload(method, params);
+		const didRevert = await this._sendAsync(payload);
+		return didRevert;
+	}
+	public async increaseTimeAsync(time: number) {
+		const method = 'evm_increaseTime';
+		const params = [time];
+		const payload = this._toPayload(method, params);
+		return this._sendAsync(payload);
+	}
+	public async mineBlockAsync(): Promise<void> {
+		const method = 'evm_mine';
+		const params: any[] = [];
+		const payload = this._toPayload(method, params);
+		await this._sendAsync(payload);
+	}
+	private _toPayload(method: string, params: any[] = []): string {
+		const payload = JSON.stringify({
+			id: this._id,
+			method,
+			params,
+		});
+		this._id += 1;
+		return payload;
+	}
+	private async _sendAsync(payload: string): Promise<any> {
+		const opts = {
+			method: 'POST',
+			uri: this._url,
+			body: payload,
+			headers: {
+				'content-type': 'application/json',
+			},
+		};
+		const bodyString = await request(opts);
+		const body = JSON.parse(bodyString);
+		return body.result;
+	}
 }
diff --git a/packages/dev-utils/tsconfig.json b/packages/dev-utils/tsconfig.json
index b28e45170..83a0e2451 100644
--- a/packages/dev-utils/tsconfig.json
+++ b/packages/dev-utils/tsconfig.json
@@ -1,11 +1,11 @@
 {
-    "extends": "../../tsconfig",
-    "compilerOptions": {
-        "outDir": "lib"
-    },
-    "include": [
-        "./src/**/*",
-        "../../node_modules/types-bn/index.d.ts",
-        "../../node_modules/types-ethereumjs-util/index.d.ts"
-    ]
+	"extends": "../../tsconfig",
+	"compilerOptions": {
+		"outDir": "lib"
+	},
+	"include": [
+		"./src/**/*",
+		"../../node_modules/types-bn/index.d.ts",
+		"../../node_modules/types-ethereumjs-util/index.d.ts"
+	]
 }
diff --git a/packages/dev-utils/tslint.json b/packages/dev-utils/tslint.json
index ffaefe83a..e63054bfc 100644
--- a/packages/dev-utils/tslint.json
+++ b/packages/dev-utils/tslint.json
@@ -1,3 +1,3 @@
 {
-    "extends": ["@0xproject/tslint-config"]
+	"extends": ["@0xproject/tslint-config"]
 }
diff --git a/packages/json-schemas/package.json b/packages/json-schemas/package.json
index d67cb64f7..30cccb12f 100644
--- a/packages/json-schemas/package.json
+++ b/packages/json-schemas/package.json
@@ -1,45 +1,45 @@
 {
-    "name": "@0xproject/json-schemas",
-    "version": "0.7.5",
-    "description": "0x-related json schemas",
-    "main": "lib/src/index.js",
-    "types": "lib/src/index.d.ts",
-    "scripts": {
-        "lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'",
-        "test": "run-s clean build run_mocha",
-        "test:circleci": "yarn test",
-        "run_mocha": "mocha lib/test/**/*_test.js",
-        "clean": "shx rm -rf _bundles lib test_temp",
-        "build": "tsc"
-    },
-    "repository": {
-        "type": "git",
-        "url": "https://github.com/0xProject/0x.js.git"
-    },
-    "author": "",
-    "license": "Apache-2.0",
-    "bugs": {
-        "url": "https://github.com/0xProject/0x.js/issues"
-    },
-    "homepage": "https://github.com/0xProject/0x.js/packages/json-schemas/README.md",
-    "dependencies": {
-        "jsonschema": "^1.2.0",
-        "lodash.values": "^4.3.0"
-    },
-    "devDependencies": {
-        "@0xproject/tslint-config": "^0.4.4",
-        "@0xproject/utils": "^0.2.2",
-        "@types/lodash.foreach": "^4.5.3",
-        "@types/lodash.values": "^4.3.3",
-        "@types/mocha": "^2.2.42",
-        "chai": "^4.0.1",
-        "chai-typescript-typings": "^0.0.2",
-        "dirty-chai": "^2.0.1",
-        "lodash.foreach": "^4.5.0",
-        "mocha": "^4.0.1",
-        "npm-run-all": "^4.1.2",
-        "shx": "^0.2.2",
-        "tslint": "5.8.0",
-        "typescript": "~2.6.1"
-    }
+	"name": "@0xproject/json-schemas",
+	"version": "0.7.5",
+	"description": "0x-related json schemas",
+	"main": "lib/src/index.js",
+	"types": "lib/src/index.d.ts",
+	"scripts": {
+		"lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'",
+		"test": "run-s clean build run_mocha",
+		"test:circleci": "yarn test",
+		"run_mocha": "mocha lib/test/**/*_test.js",
+		"clean": "shx rm -rf _bundles lib test_temp",
+		"build": "tsc"
+	},
+	"repository": {
+		"type": "git",
+		"url": "https://github.com/0xProject/0x.js.git"
+	},
+	"author": "",
+	"license": "Apache-2.0",
+	"bugs": {
+		"url": "https://github.com/0xProject/0x.js/issues"
+	},
+	"homepage": "https://github.com/0xProject/0x.js/packages/json-schemas/README.md",
+	"dependencies": {
+		"jsonschema": "^1.2.0",
+		"lodash.values": "^4.3.0"
+	},
+	"devDependencies": {
+		"@0xproject/tslint-config": "^0.4.4",
+		"@0xproject/utils": "^0.2.2",
+		"@types/lodash.foreach": "^4.5.3",
+		"@types/lodash.values": "^4.3.3",
+		"@types/mocha": "^2.2.42",
+		"chai": "^4.0.1",
+		"chai-typescript-typings": "^0.0.2",
+		"dirty-chai": "^2.0.1",
+		"lodash.foreach": "^4.5.0",
+		"mocha": "^4.0.1",
+		"npm-run-all": "^4.1.2",
+		"shx": "^0.2.2",
+		"tslint": "5.8.0",
+		"typescript": "~2.6.1"
+	}
 }
diff --git a/packages/json-schemas/schemas/basic_type_schemas.ts b/packages/json-schemas/schemas/basic_type_schemas.ts
index 9d81ff333..aa2eea867 100644
--- a/packages/json-schemas/schemas/basic_type_schemas.ts
+++ b/packages/json-schemas/schemas/basic_type_schemas.ts
@@ -1,11 +1,11 @@
 export const addressSchema = {
-    id: '/Address',
-    type: 'string',
-    pattern: '^0x[0-9a-f]{40}$',
+	id: '/Address',
+	type: 'string',
+	pattern: '^0x[0-9a-f]{40}$',
 };
 
 export const numberSchema = {
-    id: '/Number',
-    type: 'string',
-    pattern: '^\\d+(\\.\\d+)?$',
+	id: '/Number',
+	type: 'string',
+	pattern: '^\\d+(\\.\\d+)?$',
 };
diff --git a/packages/json-schemas/schemas/block_range_schema.ts b/packages/json-schemas/schemas/block_range_schema.ts
index 1f6a63151..8697bba96 100644
--- a/packages/json-schemas/schemas/block_range_schema.ts
+++ b/packages/json-schemas/schemas/block_range_schema.ts
@@ -1,20 +1,20 @@
 export const blockParamSchema = {
-    id: '/BlockParam',
-    oneOf: [
-        {
-            type: 'number',
-        },
-        {
-            enum: ['latest', 'earliest', 'pending'],
-        },
-    ],
+	id: '/BlockParam',
+	oneOf: [
+		{
+			type: 'number',
+		},
+		{
+			enum: ['latest', 'earliest', 'pending'],
+		},
+	],
 };
 
 export const blockRangeSchema = {
-    id: '/BlockRange',
-    properties: {
-        fromBlock: { $ref: '/BlockParam' },
-        toBlock: { $ref: '/BlockParam' },
-    },
-    type: 'object',
+	id: '/BlockRange',
+	properties: {
+		fromBlock: { $ref: '/BlockParam' },
+		toBlock: { $ref: '/BlockParam' },
+	},
+	type: 'object',
 };
diff --git a/packages/json-schemas/schemas/ec_signature_schema.ts b/packages/json-schemas/schemas/ec_signature_schema.ts
index 71b840dd8..299ca283b 100644
--- a/packages/json-schemas/schemas/ec_signature_schema.ts
+++ b/packages/json-schemas/schemas/ec_signature_schema.ts
@@ -1,20 +1,20 @@
 export const ecSignatureParameterSchema = {
-    id: '/ECSignatureParameter',
-    type: 'string',
-    pattern: '^0[xX][0-9A-Fa-f]{64}$',
+	id: '/ECSignatureParameter',
+	type: 'string',
+	pattern: '^0[xX][0-9A-Fa-f]{64}$',
 };
 
 export const ecSignatureSchema = {
-    id: '/ECSignature',
-    properties: {
-        v: {
-            type: 'number',
-            minimum: 27,
-            maximum: 28,
-        },
-        r: { $ref: '/ECSignatureParameter' },
-        s: { $ref: '/ECSignatureParameter' },
-    },
-    required: ['v', 'r', 's'],
-    type: 'object',
+	id: '/ECSignature',
+	properties: {
+		v: {
+			type: 'number',
+			minimum: 27,
+			maximum: 28,
+		},
+		r: { $ref: '/ECSignatureParameter' },
+		s: { $ref: '/ECSignatureParameter' },
+	},
+	required: ['v', 'r', 's'],
+	type: 'object',
 };
diff --git a/packages/json-schemas/schemas/index_filter_values_schema.ts b/packages/json-schemas/schemas/index_filter_values_schema.ts
index 3374d63e0..6e9f36c54 100644
--- a/packages/json-schemas/schemas/index_filter_values_schema.ts
+++ b/packages/json-schemas/schemas/index_filter_values_schema.ts
@@ -1,7 +1,7 @@
 export const indexFilterValuesSchema = {
-    id: '/IndexFilterValues',
-    additionalProperties: {
-        oneOf: [{ $ref: '/Number' }, { $ref: '/Address' }, { $ref: '/OrderHashSchema' }],
-    },
-    type: 'object',
+	id: '/IndexFilterValues',
+	additionalProperties: {
+		oneOf: [{ $ref: '/Number' }, { $ref: '/Address' }, { $ref: '/OrderHashSchema' }],
+	},
+	type: 'object',
 };
diff --git a/packages/json-schemas/schemas/order_cancel_schema.ts b/packages/json-schemas/schemas/order_cancel_schema.ts
index ad23d01cc..f2aa80e7a 100644
--- a/packages/json-schemas/schemas/order_cancel_schema.ts
+++ b/packages/json-schemas/schemas/order_cancel_schema.ts
@@ -1,12 +1,12 @@
 export const orderCancellationRequestsSchema = {
-    id: '/OrderCancellationRequests',
-    type: 'array',
-    items: {
-        properties: {
-            order: { $ref: '/Order' },
-            takerTokenCancelAmount: { $ref: '/Number' },
-        },
-        required: ['order', 'takerTokenCancelAmount'],
-        type: 'object',
-    },
+	id: '/OrderCancellationRequests',
+	type: 'array',
+	items: {
+		properties: {
+			order: { $ref: '/Order' },
+			takerTokenCancelAmount: { $ref: '/Number' },
+		},
+		required: ['order', 'takerTokenCancelAmount'],
+		type: 'object',
+	},
 };
diff --git a/packages/json-schemas/schemas/order_fill_or_kill_requests_schema.ts b/packages/json-schemas/schemas/order_fill_or_kill_requests_schema.ts
index 61f2c8849..f13bc9cc3 100644
--- a/packages/json-schemas/schemas/order_fill_or_kill_requests_schema.ts
+++ b/packages/json-schemas/schemas/order_fill_or_kill_requests_schema.ts
@@ -1,12 +1,12 @@
 export const orderFillOrKillRequestsSchema = {
-    id: '/OrderFillOrKillRequests',
-    type: 'array',
-    items: {
-        properties: {
-            signedOrder: { $ref: '/SignedOrder' },
-            fillTakerAmount: { $ref: '/Number' },
-        },
-        required: ['signedOrder', 'fillTakerAmount'],
-        type: 'object',
-    },
+	id: '/OrderFillOrKillRequests',
+	type: 'array',
+	items: {
+		properties: {
+			signedOrder: { $ref: '/SignedOrder' },
+			fillTakerAmount: { $ref: '/Number' },
+		},
+		required: ['signedOrder', 'fillTakerAmount'],
+		type: 'object',
+	},
 };
diff --git a/packages/json-schemas/schemas/order_fill_requests_schema.ts b/packages/json-schemas/schemas/order_fill_requests_schema.ts
index 419d0670f..45cd927be 100644
--- a/packages/json-schemas/schemas/order_fill_requests_schema.ts
+++ b/packages/json-schemas/schemas/order_fill_requests_schema.ts
@@ -1,12 +1,12 @@
 export const orderFillRequestsSchema = {
-    id: '/OrderFillRequests',
-    type: 'array',
-    items: {
-        properties: {
-            signedOrder: { $ref: '/SignedOrder' },
-            takerTokenFillAmount: { $ref: '/Number' },
-        },
-        required: ['signedOrder', 'takerTokenFillAmount'],
-        type: 'object',
-    },
+	id: '/OrderFillRequests',
+	type: 'array',
+	items: {
+		properties: {
+			signedOrder: { $ref: '/SignedOrder' },
+			takerTokenFillAmount: { $ref: '/Number' },
+		},
+		required: ['signedOrder', 'takerTokenFillAmount'],
+		type: 'object',
+	},
 };
diff --git a/packages/json-schemas/schemas/order_hash_schema.ts b/packages/json-schemas/schemas/order_hash_schema.ts
index 6af06927f..5eed112ca 100644
--- a/packages/json-schemas/schemas/order_hash_schema.ts
+++ b/packages/json-schemas/schemas/order_hash_schema.ts
@@ -1,5 +1,5 @@
 export const orderHashSchema = {
-    id: '/OrderHashSchema',
-    type: 'string',
-    pattern: '^0x[0-9a-fA-F]{64}$',
+	id: '/OrderHashSchema',
+	type: 'string',
+	pattern: '^0x[0-9a-fA-F]{64}$',
 };
diff --git a/packages/json-schemas/schemas/order_schemas.ts b/packages/json-schemas/schemas/order_schemas.ts
index 6f17224ad..ee5f2c137 100644
--- a/packages/json-schemas/schemas/order_schemas.ts
+++ b/packages/json-schemas/schemas/order_schemas.ts
@@ -1,43 +1,43 @@
 export const orderSchema = {
-    id: '/Order',
-    properties: {
-        maker: { $ref: '/Address' },
-        taker: { $ref: '/Address' },
-        makerFee: { $ref: '/Number' },
-        takerFee: { $ref: '/Number' },
-        makerTokenAmount: { $ref: '/Number' },
-        takerTokenAmount: { $ref: '/Number' },
-        makerTokenAddress: { $ref: '/Address' },
-        takerTokenAddress: { $ref: '/Address' },
-        salt: { $ref: '/Number' },
-        feeRecipient: { $ref: '/Address' },
-        expirationUnixTimestampSec: { $ref: '/Number' },
-        exchangeContractAddress: { $ref: '/Address' },
-    },
-    required: [
-        'maker',
-        'taker',
-        'makerFee',
-        'takerFee',
-        'makerTokenAmount',
-        'takerTokenAmount',
-        'salt',
-        'feeRecipient',
-        'expirationUnixTimestampSec',
-        'exchangeContractAddress',
-    ],
-    type: 'object',
+	id: '/Order',
+	properties: {
+		maker: { $ref: '/Address' },
+		taker: { $ref: '/Address' },
+		makerFee: { $ref: '/Number' },
+		takerFee: { $ref: '/Number' },
+		makerTokenAmount: { $ref: '/Number' },
+		takerTokenAmount: { $ref: '/Number' },
+		makerTokenAddress: { $ref: '/Address' },
+		takerTokenAddress: { $ref: '/Address' },
+		salt: { $ref: '/Number' },
+		feeRecipient: { $ref: '/Address' },
+		expirationUnixTimestampSec: { $ref: '/Number' },
+		exchangeContractAddress: { $ref: '/Address' },
+	},
+	required: [
+		'maker',
+		'taker',
+		'makerFee',
+		'takerFee',
+		'makerTokenAmount',
+		'takerTokenAmount',
+		'salt',
+		'feeRecipient',
+		'expirationUnixTimestampSec',
+		'exchangeContractAddress',
+	],
+	type: 'object',
 };
 
 export const signedOrderSchema = {
-    id: '/SignedOrder',
-    allOf: [
-        { $ref: '/Order' },
-        {
-            properties: {
-                ecSignature: { $ref: '/ECSignature' },
-            },
-            required: ['ecSignature'],
-        },
-    ],
+	id: '/SignedOrder',
+	allOf: [
+		{ $ref: '/Order' },
+		{
+			properties: {
+				ecSignature: { $ref: '/ECSignature' },
+			},
+			required: ['ecSignature'],
+		},
+	],
 };
diff --git a/packages/json-schemas/schemas/relayer_api_error_response_schema.ts b/packages/json-schemas/schemas/relayer_api_error_response_schema.ts
index 27fdb166f..3d3a96364 100644
--- a/packages/json-schemas/schemas/relayer_api_error_response_schema.ts
+++ b/packages/json-schemas/schemas/relayer_api_error_response_schema.ts
@@ -1,21 +1,21 @@
 export const relayerApiErrorResponseSchema = {
-    id: '/RelayerApiErrorResponse',
-    type: 'object',
-    properties: {
-        code: { type: 'number' },
-        reason: { type: 'string' },
-        validationErrors: {
-            type: 'array',
-            items: {
-                type: 'object',
-                properties: {
-                    field: { type: 'string' },
-                    code: { type: 'number' },
-                    reason: { type: 'string' },
-                },
-                required: ['field', 'code', 'reason'],
-            },
-        },
-    },
-    required: ['code', 'reason'],
+	id: '/RelayerApiErrorResponse',
+	type: 'object',
+	properties: {
+		code: { type: 'number' },
+		reason: { type: 'string' },
+		validationErrors: {
+			type: 'array',
+			items: {
+				type: 'object',
+				properties: {
+					field: { type: 'string' },
+					code: { type: 'number' },
+					reason: { type: 'string' },
+				},
+				required: ['field', 'code', 'reason'],
+			},
+		},
+	},
+	required: ['code', 'reason'],
 };
diff --git a/packages/json-schemas/schemas/relayer_api_fees_payload_schema.ts b/packages/json-schemas/schemas/relayer_api_fees_payload_schema.ts
index eaaf777a1..f79308594 100644
--- a/packages/json-schemas/schemas/relayer_api_fees_payload_schema.ts
+++ b/packages/json-schemas/schemas/relayer_api_fees_payload_schema.ts
@@ -1,24 +1,24 @@
 export const relayerApiFeesPayloadSchema = {
-    id: '/RelayerApiFeesPayload',
-    type: 'object',
-    properties: {
-        exchangeContractAddress: { $ref: '/Address' },
-        maker: { $ref: '/Address' },
-        taker: { $ref: '/Address' },
-        makerTokenAddress: { $ref: '/Address' },
-        takerTokenAddress: { $ref: '/Address' },
-        makerTokenAmount: { $ref: '/Number' },
-        takerTokenAmount: { $ref: '/Number' },
-        expirationUnixTimestampSec: { $ref: '/Number' },
-        salt: { $ref: '/Number' },
-    },
-    required: [
-        'exchangeContractAddress',
-        'maker',
-        'taker',
-        'makerTokenAddress',
-        'takerTokenAddress',
-        'expirationUnixTimestampSec',
-        'salt',
-    ],
+	id: '/RelayerApiFeesPayload',
+	type: 'object',
+	properties: {
+		exchangeContractAddress: { $ref: '/Address' },
+		maker: { $ref: '/Address' },
+		taker: { $ref: '/Address' },
+		makerTokenAddress: { $ref: '/Address' },
+		takerTokenAddress: { $ref: '/Address' },
+		makerTokenAmount: { $ref: '/Number' },
+		takerTokenAmount: { $ref: '/Number' },
+		expirationUnixTimestampSec: { $ref: '/Number' },
+		salt: { $ref: '/Number' },
+	},
+	required: [
+		'exchangeContractAddress',
+		'maker',
+		'taker',
+		'makerTokenAddress',
+		'takerTokenAddress',
+		'expirationUnixTimestampSec',
+		'salt',
+	],
 };
diff --git a/packages/json-schemas/schemas/relayer_api_fees_response_schema.ts b/packages/json-schemas/schemas/relayer_api_fees_response_schema.ts
index e7440613f..d87c2fcdb 100644
--- a/packages/json-schemas/schemas/relayer_api_fees_response_schema.ts
+++ b/packages/json-schemas/schemas/relayer_api_fees_response_schema.ts
@@ -1,10 +1,10 @@
 export const relayerApiFeesResponseSchema = {
-    id: '/RelayerApiFeesResponse',
-    type: 'object',
-    properties: {
-        makerFee: { $ref: '/Number' },
-        takerFee: { $ref: '/Number' },
-        feeRecipient: { $ref: '/Address' },
-    },
-    required: ['makerFee', 'takerFee', 'feeRecipient'],
+	id: '/RelayerApiFeesResponse',
+	type: 'object',
+	properties: {
+		makerFee: { $ref: '/Number' },
+		takerFee: { $ref: '/Number' },
+		feeRecipient: { $ref: '/Address' },
+	},
+	required: ['makerFee', 'takerFee', 'feeRecipient'],
 };
diff --git a/packages/json-schemas/schemas/relayer_api_orberbook_channel_subscribe_schema.ts b/packages/json-schemas/schemas/relayer_api_orberbook_channel_subscribe_schema.ts
index d93fa73d6..1d443c625 100644
--- a/packages/json-schemas/schemas/relayer_api_orberbook_channel_subscribe_schema.ts
+++ b/packages/json-schemas/schemas/relayer_api_orberbook_channel_subscribe_schema.ts
@@ -1,23 +1,23 @@
 export const relayerApiOrderbookChannelSubscribeSchema = {
-    id: '/RelayerApiOrderbookChannelSubscribe',
-    type: 'object',
-    properties: {
-        type: { enum: ['subscribe'] },
-        channel: { enum: ['orderbook'] },
-        requestId: { type: 'number' },
-        payload: { $ref: '/RelayerApiOrderbookChannelSubscribePayload' },
-    },
-    required: ['type', 'channel', 'requestId', 'payload'],
+	id: '/RelayerApiOrderbookChannelSubscribe',
+	type: 'object',
+	properties: {
+		type: { enum: ['subscribe'] },
+		channel: { enum: ['orderbook'] },
+		requestId: { type: 'number' },
+		payload: { $ref: '/RelayerApiOrderbookChannelSubscribePayload' },
+	},
+	required: ['type', 'channel', 'requestId', 'payload'],
 };
 
 export const relayerApiOrderbookChannelSubscribePayload = {
-    id: '/RelayerApiOrderbookChannelSubscribePayload',
-    type: 'object',
-    properties: {
-        baseTokenAddress: { $ref: '/Address' },
-        quoteTokenAddress: { $ref: '/Address' },
-        snapshot: { type: 'boolean' },
-        limit: { type: 'number' },
-    },
-    required: ['baseTokenAddress', 'quoteTokenAddress'],
+	id: '/RelayerApiOrderbookChannelSubscribePayload',
+	type: 'object',
+	properties: {
+		baseTokenAddress: { $ref: '/Address' },
+		quoteTokenAddress: { $ref: '/Address' },
+		snapshot: { type: 'boolean' },
+		limit: { type: 'number' },
+	},
+	required: ['baseTokenAddress', 'quoteTokenAddress'],
 };
diff --git a/packages/json-schemas/schemas/relayer_api_orderbook_channel_snapshot_schema.ts b/packages/json-schemas/schemas/relayer_api_orderbook_channel_snapshot_schema.ts
index fe1510d5b..e954185a8 100644
--- a/packages/json-schemas/schemas/relayer_api_orderbook_channel_snapshot_schema.ts
+++ b/packages/json-schemas/schemas/relayer_api_orderbook_channel_snapshot_schema.ts
@@ -1,21 +1,21 @@
 export const relayerApiOrderbookChannelSnapshotSchema = {
-    id: '/RelayerApiOrderbookChannelSnapshot',
-    type: 'object',
-    properties: {
-        type: { enum: ['snapshot'] },
-        channel: { enum: ['orderbook'] },
-        requestId: { type: 'number' },
-        payload: { $ref: '/RelayerApiOrderbookChannelSnapshotPayload' },
-    },
-    required: ['type', 'channel', 'requestId', 'payload'],
+	id: '/RelayerApiOrderbookChannelSnapshot',
+	type: 'object',
+	properties: {
+		type: { enum: ['snapshot'] },
+		channel: { enum: ['orderbook'] },
+		requestId: { type: 'number' },
+		payload: { $ref: '/RelayerApiOrderbookChannelSnapshotPayload' },
+	},
+	required: ['type', 'channel', 'requestId', 'payload'],
 };
 
 export const relayerApiOrderbookChannelSnapshotPayload = {
-    id: '/RelayerApiOrderbookChannelSnapshotPayload',
-    type: 'object',
-    properties: {
-        bids: { $ref: '/signedOrdersSchema' },
-        asks: { $ref: '/signedOrdersSchema' },
-    },
-    required: ['bids', 'asks'],
+	id: '/RelayerApiOrderbookChannelSnapshotPayload',
+	type: 'object',
+	properties: {
+		bids: { $ref: '/signedOrdersSchema' },
+		asks: { $ref: '/signedOrdersSchema' },
+	},
+	required: ['bids', 'asks'],
 };
diff --git a/packages/json-schemas/schemas/relayer_api_orderbook_channel_update_response_schema.ts b/packages/json-schemas/schemas/relayer_api_orderbook_channel_update_response_schema.ts
index 9a6d83d4c..7c2ba6531 100644
--- a/packages/json-schemas/schemas/relayer_api_orderbook_channel_update_response_schema.ts
+++ b/packages/json-schemas/schemas/relayer_api_orderbook_channel_update_response_schema.ts
@@ -1,11 +1,11 @@
 export const relayerApiOrderbookChannelUpdateSchema = {
-    id: '/RelayerApiOrderbookChannelUpdate',
-    type: 'object',
-    properties: {
-        type: { enum: ['update'] },
-        channel: { enum: ['orderbook'] },
-        requestId: { type: 'number' },
-        payload: { $ref: '/SignedOrder' },
-    },
-    required: ['type', 'channel', 'requestId', 'payload'],
+	id: '/RelayerApiOrderbookChannelUpdate',
+	type: 'object',
+	properties: {
+		type: { enum: ['update'] },
+		channel: { enum: ['orderbook'] },
+		requestId: { type: 'number' },
+		payload: { $ref: '/SignedOrder' },
+	},
+	required: ['type', 'channel', 'requestId', 'payload'],
 };
diff --git a/packages/json-schemas/schemas/relayer_api_orderbook_response_schema.ts b/packages/json-schemas/schemas/relayer_api_orderbook_response_schema.ts
index 5c409c807..d9abfc77d 100644
--- a/packages/json-schemas/schemas/relayer_api_orderbook_response_schema.ts
+++ b/packages/json-schemas/schemas/relayer_api_orderbook_response_schema.ts
@@ -1,9 +1,9 @@
 export const relayerApiOrderBookResponseSchema = {
-    id: '/RelayerApiOrderBookResponse',
-    type: 'object',
-    properties: {
-        bids: { $ref: '/signedOrdersSchema' },
-        asks: { $ref: '/signedOrdersSchema' },
-    },
-    required: ['bids', 'asks'],
+	id: '/RelayerApiOrderBookResponse',
+	type: 'object',
+	properties: {
+		bids: { $ref: '/signedOrdersSchema' },
+		asks: { $ref: '/signedOrdersSchema' },
+	},
+	required: ['bids', 'asks'],
 };
diff --git a/packages/json-schemas/schemas/relayer_api_token_pairs_response_schema.ts b/packages/json-schemas/schemas/relayer_api_token_pairs_response_schema.ts
index 5009c7955..471bed7b4 100644
--- a/packages/json-schemas/schemas/relayer_api_token_pairs_response_schema.ts
+++ b/packages/json-schemas/schemas/relayer_api_token_pairs_response_schema.ts
@@ -1,24 +1,24 @@
 export const relayerApiTokenPairsResponseSchema = {
-    id: '/RelayerApiTokenPairsResponse',
-    type: 'array',
-    items: {
-        properties: {
-            tokenA: { $ref: '/RelayerApiTokenTradeInfo' },
-            tokenB: { $ref: '/RelayerApiTokenTradeInfo' },
-        },
-        required: ['tokenA', 'tokenB'],
-        type: 'object',
-    },
+	id: '/RelayerApiTokenPairsResponse',
+	type: 'array',
+	items: {
+		properties: {
+			tokenA: { $ref: '/RelayerApiTokenTradeInfo' },
+			tokenB: { $ref: '/RelayerApiTokenTradeInfo' },
+		},
+		required: ['tokenA', 'tokenB'],
+		type: 'object',
+	},
 };
 
 export const relayerApiTokenTradeInfoSchema = {
-    id: '/RelayerApiTokenTradeInfo',
-    type: 'object',
-    properties: {
-        address: { $ref: '/Address' },
-        minAmount: { $ref: '/Number' },
-        maxAmount: { $ref: '/Number' },
-        precision: { type: 'number' },
-    },
-    required: ['address'],
+	id: '/RelayerApiTokenTradeInfo',
+	type: 'object',
+	properties: {
+		address: { $ref: '/Address' },
+		minAmount: { $ref: '/Number' },
+		maxAmount: { $ref: '/Number' },
+		precision: { type: 'number' },
+	},
+	required: ['address'],
 };
diff --git a/packages/json-schemas/schemas/signed_orders_schema.ts b/packages/json-schemas/schemas/signed_orders_schema.ts
index 34d956836..7d66b7027 100644
--- a/packages/json-schemas/schemas/signed_orders_schema.ts
+++ b/packages/json-schemas/schemas/signed_orders_schema.ts
@@ -1,5 +1,5 @@
 export const signedOrdersSchema = {
-    id: '/signedOrdersSchema',
-    type: 'array',
-    items: { $ref: '/SignedOrder' },
+	id: '/signedOrdersSchema',
+	type: 'array',
+	items: { $ref: '/SignedOrder' },
 };
diff --git a/packages/json-schemas/schemas/token_schema.ts b/packages/json-schemas/schemas/token_schema.ts
index e64565c8b..d2bb10f09 100644
--- a/packages/json-schemas/schemas/token_schema.ts
+++ b/packages/json-schemas/schemas/token_schema.ts
@@ -1,11 +1,11 @@
 export const tokenSchema = {
-    id: '/Token',
-    properties: {
-        name: { type: 'string' },
-        symbol: { type: 'string' },
-        decimals: { type: 'number' },
-        address: { $ref: '/Address' },
-    },
-    required: ['name', 'symbol', 'decimals', 'address'],
-    type: 'object',
+	id: '/Token',
+	properties: {
+		name: { type: 'string' },
+		symbol: { type: 'string' },
+		decimals: { type: 'number' },
+		address: { $ref: '/Address' },
+	},
+	required: ['name', 'symbol', 'decimals', 'address'],
+	type: 'object',
 };
diff --git a/packages/json-schemas/schemas/tx_data_schema.ts b/packages/json-schemas/schemas/tx_data_schema.ts
index 4274c553f..00c1d3e08 100644
--- a/packages/json-schemas/schemas/tx_data_schema.ts
+++ b/packages/json-schemas/schemas/tx_data_schema.ts
@@ -1,33 +1,33 @@
 export const jsNumber = {
-    id: '/JsNumber',
-    type: 'number',
-    minimum: 0,
+	id: '/JsNumber',
+	type: 'number',
+	minimum: 0,
 };
 
 export const txDataSchema = {
-    id: '/TxData',
-    properties: {
-        from: { $ref: '/Address' },
-        to: { $ref: '/Address' },
-        value: {
-            oneOf: [{ $ref: '/Number' }, { $ref: '/JsNumber' }],
-        },
-        gas: {
-            oneOf: [{ $ref: '/Number' }, { $ref: '/JsNumber' }],
-        },
-        gasPrice: {
-            oneOf: [{ $ref: '/Number' }, { $ref: '/JsNumber' }],
-        },
-        data: {
-            type: 'string',
-            pattern: '^0x[0-9a-f]*$',
-        },
-        nonce: {
-            type: 'number',
-            minimum: 0,
-        },
-    },
-    required: ['from'],
-    type: 'object',
-    additionalProperties: false,
+	id: '/TxData',
+	properties: {
+		from: { $ref: '/Address' },
+		to: { $ref: '/Address' },
+		value: {
+			oneOf: [{ $ref: '/Number' }, { $ref: '/JsNumber' }],
+		},
+		gas: {
+			oneOf: [{ $ref: '/Number' }, { $ref: '/JsNumber' }],
+		},
+		gasPrice: {
+			oneOf: [{ $ref: '/Number' }, { $ref: '/JsNumber' }],
+		},
+		data: {
+			type: 'string',
+			pattern: '^0x[0-9a-f]*$',
+		},
+		nonce: {
+			type: 'number',
+			minimum: 0,
+		},
+	},
+	required: ['from'],
+	type: 'object',
+	additionalProperties: false,
 };
diff --git a/packages/json-schemas/src/schema_validator.ts b/packages/json-schemas/src/schema_validator.ts
index e13326d2a..686c38d17 100644
--- a/packages/json-schemas/src/schema_validator.ts
+++ b/packages/json-schemas/src/schema_validator.ts
@@ -4,26 +4,26 @@ import values = require('lodash.values');
 import { schemas } from './schemas';
 
 export class SchemaValidator {
-    private _validator: Validator;
-    constructor() {
-        this._validator = new Validator();
-        for (const schema of values(schemas)) {
-            this._validator.addSchema(schema, schema.id);
-        }
-    }
-    public addSchema(schema: Schema) {
-        this._validator.addSchema(schema, schema.id);
-    }
-    // In order to validate a complex JS object using jsonschema, we must replace any complex
-    // sub-types (e.g BigNumber) with a simpler string representation. Since BigNumber and other
-    // complex types implement the `toString` method, we can stringify the object and
-    // then parse it. The resultant object can then be checked using jsonschema.
-    public validate(instance: any, schema: Schema): ValidatorResult {
-        const jsonSchemaCompatibleObject = JSON.parse(JSON.stringify(instance));
-        return this._validator.validate(jsonSchemaCompatibleObject, schema);
-    }
-    public isValid(instance: any, schema: Schema): boolean {
-        const isValid = this.validate(instance, schema).errors.length === 0;
-        return isValid;
-    }
+	private _validator: Validator;
+	constructor() {
+		this._validator = new Validator();
+		for (const schema of values(schemas)) {
+			this._validator.addSchema(schema, schema.id);
+		}
+	}
+	public addSchema(schema: Schema) {
+		this._validator.addSchema(schema, schema.id);
+	}
+	// In order to validate a complex JS object using jsonschema, we must replace any complex
+	// sub-types (e.g BigNumber) with a simpler string representation. Since BigNumber and other
+	// complex types implement the `toString` method, we can stringify the object and
+	// then parse it. The resultant object can then be checked using jsonschema.
+	public validate(instance: any, schema: Schema): ValidatorResult {
+		const jsonSchemaCompatibleObject = JSON.parse(JSON.stringify(instance));
+		return this._validator.validate(jsonSchemaCompatibleObject, schema);
+	}
+	public isValid(instance: any, schema: Schema): boolean {
+		const isValid = this.validate(instance, schema).errors.length === 0;
+		return isValid;
+	}
 }
diff --git a/packages/json-schemas/src/schemas.ts b/packages/json-schemas/src/schemas.ts
index 5cb07acfe..bdc227aea 100644
--- a/packages/json-schemas/src/schemas.ts
+++ b/packages/json-schemas/src/schemas.ts
@@ -11,50 +11,50 @@ import { relayerApiErrorResponseSchema } from '../schemas/relayer_api_error_resp
 import { relayerApiFeesPayloadSchema } from '../schemas/relayer_api_fees_payload_schema';
 import { relayerApiFeesResponseSchema } from '../schemas/relayer_api_fees_response_schema';
 import {
-    relayerApiOrderbookChannelSubscribePayload,
-    relayerApiOrderbookChannelSubscribeSchema,
+	relayerApiOrderbookChannelSubscribePayload,
+	relayerApiOrderbookChannelSubscribeSchema,
 } from '../schemas/relayer_api_orberbook_channel_subscribe_schema';
 import {
-    relayerApiOrderbookChannelSnapshotPayload,
-    relayerApiOrderbookChannelSnapshotSchema,
+	relayerApiOrderbookChannelSnapshotPayload,
+	relayerApiOrderbookChannelSnapshotSchema,
 } from '../schemas/relayer_api_orderbook_channel_snapshot_schema';
 import { relayerApiOrderbookChannelUpdateSchema } from '../schemas/relayer_api_orderbook_channel_update_response_schema';
 import { relayerApiOrderBookResponseSchema } from '../schemas/relayer_api_orderbook_response_schema';
 import {
-    relayerApiTokenPairsResponseSchema,
-    relayerApiTokenTradeInfoSchema,
+	relayerApiTokenPairsResponseSchema,
+	relayerApiTokenTradeInfoSchema,
 } from '../schemas/relayer_api_token_pairs_response_schema';
 import { signedOrdersSchema } from '../schemas/signed_orders_schema';
 import { tokenSchema } from '../schemas/token_schema';
 import { jsNumber, txDataSchema } from '../schemas/tx_data_schema';
 
 export const schemas = {
-    numberSchema,
-    addressSchema,
-    ecSignatureSchema,
-    ecSignatureParameterSchema,
-    indexFilterValuesSchema,
-    orderCancellationRequestsSchema,
-    orderFillOrKillRequestsSchema,
-    orderFillRequestsSchema,
-    orderHashSchema,
-    orderSchema,
-    signedOrderSchema,
-    signedOrdersSchema,
-    blockParamSchema,
-    blockRangeSchema,
-    tokenSchema,
-    jsNumber,
-    txDataSchema,
-    relayerApiErrorResponseSchema,
-    relayerApiFeesPayloadSchema,
-    relayerApiFeesResponseSchema,
-    relayerApiOrderBookResponseSchema,
-    relayerApiTokenPairsResponseSchema,
-    relayerApiTokenTradeInfoSchema,
-    relayerApiOrderbookChannelSubscribeSchema,
-    relayerApiOrderbookChannelSubscribePayload,
-    relayerApiOrderbookChannelUpdateSchema,
-    relayerApiOrderbookChannelSnapshotSchema,
-    relayerApiOrderbookChannelSnapshotPayload,
+	numberSchema,
+	addressSchema,
+	ecSignatureSchema,
+	ecSignatureParameterSchema,
+	indexFilterValuesSchema,
+	orderCancellationRequestsSchema,
+	orderFillOrKillRequestsSchema,
+	orderFillRequestsSchema,
+	orderHashSchema,
+	orderSchema,
+	signedOrderSchema,
+	signedOrdersSchema,
+	blockParamSchema,
+	blockRangeSchema,
+	tokenSchema,
+	jsNumber,
+	txDataSchema,
+	relayerApiErrorResponseSchema,
+	relayerApiFeesPayloadSchema,
+	relayerApiFeesResponseSchema,
+	relayerApiOrderBookResponseSchema,
+	relayerApiTokenPairsResponseSchema,
+	relayerApiTokenTradeInfoSchema,
+	relayerApiOrderbookChannelSubscribeSchema,
+	relayerApiOrderbookChannelSubscribePayload,
+	relayerApiOrderbookChannelUpdateSchema,
+	relayerApiOrderbookChannelSnapshotSchema,
+	relayerApiOrderbookChannelSnapshotPayload,
 };
diff --git a/packages/json-schemas/test/schema_test.ts b/packages/json-schemas/test/schema_test.ts
index 7b058781d..a6162c8e3 100644
--- a/packages/json-schemas/test/schema_test.ts
+++ b/packages/json-schemas/test/schema_test.ts
@@ -11,906 +11,906 @@ chai.use(dirtyChai);
 const expect = chai.expect;
 const NULL_ADDRESS = '0x0000000000000000000000000000000000000000';
 const {
-    numberSchema,
-    addressSchema,
-    ecSignatureSchema,
-    ecSignatureParameterSchema,
-    orderCancellationRequestsSchema,
-    orderFillOrKillRequestsSchema,
-    orderFillRequestsSchema,
-    orderHashSchema,
-    orderSchema,
-    signedOrderSchema,
-    signedOrdersSchema,
-    blockParamSchema,
-    blockRangeSchema,
-    tokenSchema,
-    jsNumber,
-    txDataSchema,
-    relayerApiErrorResponseSchema,
-    relayerApiOrderBookResponseSchema,
-    relayerApiTokenPairsResponseSchema,
-    relayerApiFeesPayloadSchema,
-    relayerApiFeesResponseSchema,
-    relayerApiOrderbookChannelSubscribeSchema,
-    relayerApiOrderbookChannelUpdateSchema,
-    relayerApiOrderbookChannelSnapshotSchema,
+	numberSchema,
+	addressSchema,
+	ecSignatureSchema,
+	ecSignatureParameterSchema,
+	orderCancellationRequestsSchema,
+	orderFillOrKillRequestsSchema,
+	orderFillRequestsSchema,
+	orderHashSchema,
+	orderSchema,
+	signedOrderSchema,
+	signedOrdersSchema,
+	blockParamSchema,
+	blockRangeSchema,
+	tokenSchema,
+	jsNumber,
+	txDataSchema,
+	relayerApiErrorResponseSchema,
+	relayerApiOrderBookResponseSchema,
+	relayerApiTokenPairsResponseSchema,
+	relayerApiFeesPayloadSchema,
+	relayerApiFeesResponseSchema,
+	relayerApiOrderbookChannelSubscribeSchema,
+	relayerApiOrderbookChannelUpdateSchema,
+	relayerApiOrderbookChannelSnapshotSchema,
 } = schemas;
 
 describe('Schema', () => {
-    const validator = new SchemaValidator();
-    const validateAgainstSchema = (testCases: any[], schema: any, shouldFail = false) => {
-        forEach(testCases, (testCase: any) => {
-            const validationResult = validator.validate(testCase, schema);
-            const hasErrors = validationResult.errors.length !== 0;
-            if (shouldFail) {
-                if (!hasErrors) {
-                    throw new Error(
-                        `Expected testCase: ${JSON.stringify(testCase, null, '\t')} to fail and it didn't.`,
-                    );
-                }
-            } else {
-                if (hasErrors) {
-                    throw new Error(JSON.stringify(validationResult.errors, null, '\t'));
-                }
-            }
-        });
-    };
-    describe('#numberSchema', () => {
-        it('should validate valid numbers', () => {
-            const testCases = ['42', '0', '1.3', '0.2', '00.00'];
-            validateAgainstSchema(testCases, numberSchema);
-        });
-        it('should fail for invalid numbers', () => {
-            const testCases = ['.3', '1.', 'abacaba', 'и', '1..0'];
-            const shouldFail = true;
-            validateAgainstSchema(testCases, numberSchema, shouldFail);
-        });
-    });
-    describe('#addressSchema', () => {
-        it('should validate valid addresses', () => {
-            const testCases = ['0x8b0292b11a196601ed2ce54b665cafeca0347d42', NULL_ADDRESS];
-            validateAgainstSchema(testCases, addressSchema);
-        });
-        it('should fail for invalid addresses', () => {
-            const testCases = [
-                '0x',
-                '0',
-                '0x00',
-                '0xzzzzzzB11a196601eD2ce54B665CaFEca0347D42',
-                '0x8b0292B11a196601eD2ce54B665CaFEca0347D42',
-            ];
-            const shouldFail = true;
-            validateAgainstSchema(testCases, addressSchema, shouldFail);
-        });
-    });
-    describe('#ecSignatureParameterSchema', () => {
-        it('should validate valid parameters', () => {
-            const testCases = [
-                '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
-                '0X40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
-            ];
-            validateAgainstSchema(testCases, ecSignatureParameterSchema);
-        });
-        it('should fail for invalid parameters', () => {
-            const testCases = [
-                '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc3', // shorter
-                '0xzzzz9190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254', // invalid characters
-                '40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254', // no 0x
-            ];
-            const shouldFail = true;
-            validateAgainstSchema(testCases, ecSignatureParameterSchema, shouldFail);
-        });
-    });
-    describe('#ecSignatureSchema', () => {
-        it('should validate valid signature', () => {
-            const signature = {
-                v: 27,
-                r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
-                s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
-            };
-            const testCases = [
-                signature,
-                {
-                    ...signature,
-                    v: 28,
-                },
-            ];
-            validateAgainstSchema(testCases, ecSignatureSchema);
-        });
-        it('should fail for invalid signature', () => {
-            const v = 27;
-            const r = '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33';
-            const s = '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254';
-            const testCases = [{}, { v }, { r, s, v: 31 }];
-            const shouldFail = true;
-            validateAgainstSchema(testCases, ecSignatureSchema, shouldFail);
-        });
-    });
-    describe('#orderHashSchema', () => {
-        it('should validate valid order hash', () => {
-            const testCases = [
-                '0x61a3ed31B43c8780e905a260a35faefEc527be7516aa11c0256729b5b351bc33',
-                '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
-            ];
-            validateAgainstSchema(testCases, orderHashSchema);
-        });
-        it('should fail for invalid order hash', () => {
-            const testCases = [
-                {},
-                '0x',
-                '0x8b0292B11a196601eD2ce54B665CaFEca0347D42',
-                '61a3ed31B43c8780e905a260a35faefEc527be7516aa11c0256729b5b351bc33',
-            ];
-            const shouldFail = true;
-            validateAgainstSchema(testCases, orderHashSchema, shouldFail);
-        });
-    });
-    describe('#blockParamSchema', () => {
-        it('should validate valid block param', () => {
-            const testCases = [42, 'latest', 'pending', 'earliest'];
-            validateAgainstSchema(testCases, blockParamSchema);
-        });
-        it('should fail for invalid block param', () => {
-            const testCases = [{}, '42', 'pemding'];
-            const shouldFail = true;
-            validateAgainstSchema(testCases, blockParamSchema, shouldFail);
-        });
-    });
-    describe('#blockRangeSchema', () => {
-        it('should validate valid subscription opts', () => {
-            const testCases = [{ fromBlock: 42, toBlock: 'latest' }, { fromBlock: 42 }, {}];
-            validateAgainstSchema(testCases, blockRangeSchema);
-        });
-        it('should fail for invalid subscription opts', () => {
-            const testCases = [{ fromBlock: '42' }];
-            const shouldFail = true;
-            validateAgainstSchema(testCases, blockRangeSchema, shouldFail);
-        });
-    });
-    describe('#tokenSchema', () => {
-        const token = {
-            name: 'Zero Ex',
-            symbol: 'ZRX',
-            decimals: 100500,
-            address: '0x8b0292b11a196601ed2ce54b665cafeca0347d42',
-            url: 'https://0xproject.com',
-        };
-        it('should validate valid token', () => {
-            const testCases = [token];
-            validateAgainstSchema(testCases, tokenSchema);
-        });
-        it('should fail for invalid token', () => {
-            const testCases = [
-                {
-                    ...token,
-                    address: null,
-                },
-                {
-                    ...token,
-                    decimals: undefined,
-                },
-                [],
-                4,
-            ];
-            const shouldFail = true;
-            validateAgainstSchema(testCases, tokenSchema, shouldFail);
-        });
-    });
-    describe('order including schemas', () => {
-        const order = {
-            maker: NULL_ADDRESS,
-            taker: NULL_ADDRESS,
-            makerFee: '1',
-            takerFee: '2',
-            makerTokenAmount: '1',
-            takerTokenAmount: '2',
-            makerTokenAddress: NULL_ADDRESS,
-            takerTokenAddress: NULL_ADDRESS,
-            salt: '67006738228878699843088602623665307406148487219438534730168799356281242528500',
-            feeRecipient: NULL_ADDRESS,
-            exchangeContractAddress: NULL_ADDRESS,
-            expirationUnixTimestampSec: '42',
-        };
-        describe('#orderSchema', () => {
-            it('should validate valid order', () => {
-                const testCases = [order];
-                validateAgainstSchema(testCases, orderSchema);
-            });
-            it('should fail for invalid order', () => {
-                const testCases = [
-                    {
-                        ...order,
-                        salt: undefined,
-                    },
-                    {
-                        ...order,
-                        salt: 'salt',
-                    },
-                    'order',
-                ];
-                const shouldFail = true;
-                validateAgainstSchema(testCases, orderSchema, shouldFail);
-            });
-        });
-        describe('signed order including schemas', () => {
-            const signedOrder = {
-                ...order,
-                ecSignature: {
-                    v: 27,
-                    r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
-                    s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
-                },
-            };
-            describe('#signedOrdersSchema', () => {
-                it('should validate valid signed orders', () => {
-                    const testCases = [[signedOrder], []];
-                    validateAgainstSchema(testCases, signedOrdersSchema);
-                });
-                it('should fail for invalid signed orders', () => {
-                    const testCases = [[signedOrder, 1]];
-                    const shouldFail = true;
-                    validateAgainstSchema(testCases, signedOrdersSchema, shouldFail);
-                });
-            });
-            describe('#signedOrderSchema', () => {
-                it('should validate valid signed order', () => {
-                    const testCases = [signedOrder];
-                    validateAgainstSchema(testCases, signedOrderSchema);
-                });
-                it('should fail for invalid signed order', () => {
-                    const testCases = [
-                        {
-                            ...signedOrder,
-                            ecSignature: undefined,
-                        },
-                    ];
-                    const shouldFail = true;
-                    validateAgainstSchema(testCases, signedOrderSchema, shouldFail);
-                });
-            });
-            describe('#orderFillOrKillRequestsSchema', () => {
-                const orderFillOrKillRequests = [
-                    {
-                        signedOrder,
-                        fillTakerAmount: '5',
-                    },
-                ];
-                it('should validate valid order fill or kill requests', () => {
-                    const testCases = [orderFillOrKillRequests];
-                    validateAgainstSchema(testCases, orderFillOrKillRequestsSchema);
-                });
-                it('should fail for invalid order fill or kill requests', () => {
-                    const testCases = [
-                        [
-                            {
-                                ...orderFillOrKillRequests[0],
-                                fillTakerAmount: undefined,
-                            },
-                        ],
-                    ];
-                    const shouldFail = true;
-                    validateAgainstSchema(testCases, orderFillOrKillRequestsSchema, shouldFail);
-                });
-            });
-            describe('#orderCancellationRequestsSchema', () => {
-                const orderCancellationRequests = [
-                    {
-                        order,
-                        takerTokenCancelAmount: '5',
-                    },
-                ];
-                it('should validate valid order cancellation requests', () => {
-                    const testCases = [orderCancellationRequests];
-                    validateAgainstSchema(testCases, orderCancellationRequestsSchema);
-                });
-                it('should fail for invalid order cancellation requests', () => {
-                    const testCases = [
-                        [
-                            {
-                                ...orderCancellationRequests[0],
-                                takerTokenCancelAmount: undefined,
-                            },
-                        ],
-                    ];
-                    const shouldFail = true;
-                    validateAgainstSchema(testCases, orderCancellationRequestsSchema, shouldFail);
-                });
-            });
-            describe('#orderFillRequestsSchema', () => {
-                const orderFillRequests = [
-                    {
-                        signedOrder,
-                        takerTokenFillAmount: '5',
-                    },
-                ];
-                it('should validate valid order fill requests', () => {
-                    const testCases = [orderFillRequests];
-                    validateAgainstSchema(testCases, orderFillRequestsSchema);
-                });
-                it('should fail for invalid order fill requests', () => {
-                    const testCases = [
-                        [
-                            {
-                                ...orderFillRequests[0],
-                                takerTokenFillAmount: undefined,
-                            },
-                        ],
-                    ];
-                    const shouldFail = true;
-                    validateAgainstSchema(testCases, orderFillRequestsSchema, shouldFail);
-                });
-            });
-            describe('#relayerApiOrderBookResponseSchema', () => {
-                it('should validate valid order book responses', () => {
-                    const testCases = [
-                        {
-                            bids: [],
-                            asks: [],
-                        },
-                        {
-                            bids: [signedOrder, signedOrder],
-                            asks: [],
-                        },
-                        {
-                            bids: [],
-                            asks: [signedOrder, signedOrder],
-                        },
-                        {
-                            bids: [signedOrder],
-                            asks: [signedOrder, signedOrder],
-                        },
-                    ];
-                    validateAgainstSchema(testCases, relayerApiOrderBookResponseSchema);
-                });
-                it('should fail for invalid order fill requests', () => {
-                    const testCases = [
-                        {},
-                        {
-                            bids: [signedOrder, signedOrder],
-                        },
-                        {
-                            asks: [signedOrder, signedOrder],
-                        },
-                        {
-                            bids: signedOrder,
-                            asks: [signedOrder, signedOrder],
-                        },
-                        {
-                            bids: [signedOrder],
-                            asks: signedOrder,
-                        },
-                    ];
-                    const shouldFail = true;
-                    validateAgainstSchema(testCases, relayerApiOrderBookResponseSchema, shouldFail);
-                });
-            });
-            describe('#relayerApiOrderbookChannelSubscribeSchema', () => {
-                it('should validate valid orderbook channel websocket subscribe message', () => {
-                    const testCases = [
-                        {
-                            type: 'subscribe',
-                            channel: 'orderbook',
-                            requestId: 1,
-                            payload: {
-                                baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-                                quoteTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-                                snapshot: true,
-                                limit: 100,
-                            },
-                        },
-                        {
-                            type: 'subscribe',
-                            channel: 'orderbook',
-                            requestId: 1,
-                            payload: {
-                                baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-                                quoteTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-                            },
-                        },
-                    ];
-                    validateAgainstSchema(testCases, relayerApiOrderbookChannelSubscribeSchema);
-                });
-                it('should fail for invalid orderbook channel websocket subscribe message', () => {
-                    const checksummedAddress = '0xA2b31daCf30a9C50ca473337c01d8A201ae33e32';
-                    const testCases = [
-                        {
-                            type: 'subscribe',
-                            channel: 'orderbook',
-                            payload: {
-                                baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-                                quoteTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-                                snapshot: true,
-                                limit: 100,
-                            },
-                        },
-                        {
-                            type: 'foo',
-                            channel: 'orderbook',
-                            requestId: 1,
-                            payload: {
-                                baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-                                quoteTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-                            },
-                        },
-                        {
-                            type: 'subscribe',
-                            channel: 'bar',
-                            requestId: 1,
-                            payload: {
-                                baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-                                quoteTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-                            },
-                        },
-                        {
-                            type: 'subscribe',
-                            channel: 'orderbook',
-                            requestId: 1,
-                            payload: {
-                                baseTokenAddress: checksummedAddress,
-                                quoteTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-                            },
-                        },
-                        {
-                            type: 'subscribe',
-                            channel: 'orderbook',
-                            requestId: 1,
-                            payload: {
-                                baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-                                quoteTokenAddress: checksummedAddress,
-                            },
-                        },
-                        {
-                            type: 'subscribe',
-                            channel: 'orderbook',
-                            requestId: 1,
-                            payload: {
-                                quoteTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-                            },
-                        },
-                        {
-                            type: 'subscribe',
-                            channel: 'orderbook',
-                            requestId: 1,
-                            payload: {
-                                baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-                            },
-                        },
-                        {
-                            type: 'subscribe',
-                            channel: 'orderbook',
-                            requestId: 1,
-                            payload: {
-                                baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-                                quoteTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-                                snapshot: 'true',
-                                limit: 100,
-                            },
-                        },
-                        {
-                            type: 'subscribe',
-                            channel: 'orderbook',
-                            requestId: 1,
-                            payload: {
-                                baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-                                quoteTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-                                snapshot: true,
-                                limit: '100',
-                            },
-                        },
-                    ];
-                    const shouldFail = true;
-                    validateAgainstSchema(testCases, relayerApiOrderbookChannelSubscribeSchema, shouldFail);
-                });
-            });
-            describe('#relayerApiOrderbookChannelSnapshotSchema', () => {
-                it('should validate valid orderbook channel websocket snapshot message', () => {
-                    const testCases = [
-                        {
-                            type: 'snapshot',
-                            channel: 'orderbook',
-                            requestId: 2,
-                            payload: {
-                                bids: [],
-                                asks: [],
-                            },
-                        },
-                        {
-                            type: 'snapshot',
-                            channel: 'orderbook',
-                            requestId: 2,
-                            payload: {
-                                bids: [signedOrder],
-                                asks: [signedOrder],
-                            },
-                        },
-                    ];
-                    validateAgainstSchema(testCases, relayerApiOrderbookChannelSnapshotSchema);
-                });
-                it('should fail for invalid orderbook channel websocket snapshot message', () => {
-                    const testCases = [
-                        {
-                            type: 'foo',
-                            channel: 'orderbook',
-                            requestId: 2,
-                            payload: {
-                                bids: [signedOrder],
-                                asks: [signedOrder],
-                            },
-                        },
-                        {
-                            type: 'snapshot',
-                            channel: 'bar',
-                            requestId: 2,
-                            payload: {
-                                bids: [signedOrder],
-                                asks: [signedOrder],
-                            },
-                        },
-                        {
-                            type: 'snapshot',
-                            channel: 'orderbook',
-                            payload: {
-                                bids: [signedOrder],
-                                asks: [signedOrder],
-                            },
-                        },
-                        {
-                            type: 'snapshot',
-                            channel: 'orderbook',
-                            requestId: '2',
-                            payload: {
-                                bids: [signedOrder],
-                                asks: [signedOrder],
-                            },
-                        },
-                        {
-                            type: 'snapshot',
-                            channel: 'orderbook',
-                            requestId: 2,
-                            payload: {
-                                bids: [signedOrder],
-                            },
-                        },
-                        {
-                            type: 'snapshot',
-                            channel: 'orderbook',
-                            requestId: 2,
-                            payload: {
-                                asks: [signedOrder],
-                            },
-                        },
-                        {
-                            type: 'snapshot',
-                            channel: 'orderbook',
-                            requestId: 2,
-                            payload: {
-                                bids: [signedOrder],
-                                asks: [{}],
-                            },
-                        },
-                        {
-                            type: 'snapshot',
-                            channel: 'orderbook',
-                            requestId: 2,
-                            payload: {
-                                bids: [{}],
-                                asks: [signedOrder],
-                            },
-                        },
-                    ];
-                    const shouldFail = true;
-                    validateAgainstSchema(testCases, relayerApiOrderbookChannelSnapshotSchema, shouldFail);
-                });
-            });
-            describe('#relayerApiOrderbookChannelUpdateSchema', () => {
-                it('should validate valid orderbook channel websocket update message', () => {
-                    const testCases = [
-                        {
-                            type: 'update',
-                            channel: 'orderbook',
-                            requestId: 2,
-                            payload: signedOrder,
-                        },
-                    ];
-                    validateAgainstSchema(testCases, relayerApiOrderbookChannelUpdateSchema);
-                });
-                it('should fail for invalid orderbook channel websocket update message', () => {
-                    const testCases = [
-                        {
-                            type: 'foo',
-                            channel: 'orderbook',
-                            requestId: 2,
-                            payload: signedOrder,
-                        },
-                        {
-                            type: 'update',
-                            channel: 'bar',
-                            requestId: 2,
-                            payload: signedOrder,
-                        },
-                        {
-                            type: 'update',
-                            channel: 'orderbook',
-                            requestId: 2,
-                            payload: {},
-                        },
-                    ];
-                    const shouldFail = true;
-                    validateAgainstSchema(testCases, relayerApiOrderbookChannelUpdateSchema, shouldFail);
-                });
-            });
-        });
-    });
-    describe('BigNumber serialization', () => {
-        it('should correctly serialize BigNumbers', () => {
-            const testCases = {
-                '42': '42',
-                '0': '0',
-                '1.3': '1.3',
-                '0.2': '0.2',
-                '00.00': '0',
-                '.3': '0.3',
-            };
-            forEach(testCases, (serialized: string, input: string) => {
-                expect(JSON.parse(JSON.stringify(new BigNumber(input)))).to.be.equal(serialized);
-            });
-        });
-    });
-    describe('#relayerApiErrorResponseSchema', () => {
-        it('should validate valid errorResponse', () => {
-            const testCases = [
-                {
-                    code: 102,
-                    reason: 'Order submission disabled',
-                },
-                {
-                    code: 101,
-                    reason: 'Validation failed',
-                    validationErrors: [
-                        {
-                            field: 'maker',
-                            code: 1002,
-                            reason: 'Invalid address',
-                        },
-                    ],
-                },
-            ];
-            validateAgainstSchema(testCases, relayerApiErrorResponseSchema);
-        });
-        it('should fail for invalid error responses', () => {
-            const testCases = [
-                {},
-                {
-                    code: 102,
-                },
-                {
-                    code: '102',
-                    reason: 'Order submission disabled',
-                },
-                {
-                    reason: 'Order submission disabled',
-                },
-                {
-                    code: 101,
-                    reason: 'Validation failed',
-                    validationErrors: [
-                        {
-                            field: 'maker',
-                            reason: 'Invalid address',
-                        },
-                    ],
-                },
-                {
-                    code: 101,
-                    reason: 'Validation failed',
-                    validationErrors: [
-                        {
-                            field: 'maker',
-                            code: '1002',
-                            reason: 'Invalid address',
-                        },
-                    ],
-                },
-            ];
-            const shouldFail = true;
-            validateAgainstSchema(testCases, relayerApiErrorResponseSchema, shouldFail);
-        });
-    });
-    describe('#relayerApiFeesPayloadSchema', () => {
-        it('should validate valid fees payloads', () => {
-            const testCases = [
-                {
-                    exchangeContractAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-                    maker: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-                    taker: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-                    makerTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-                    takerTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
-                    makerTokenAmount: '10000000000000000000',
-                    takerTokenAmount: '30000000000000000000',
-                    expirationUnixTimestampSec: '42',
-                    salt: '67006738228878699843088602623665307406148487219438534730168799356281242528500',
-                },
-            ];
-            validateAgainstSchema(testCases, relayerApiFeesPayloadSchema);
-        });
-        it('should fail for invalid fees payloads', () => {
-            const checksummedAddress = '0xA2b31daCf30a9C50ca473337c01d8A201ae33e32';
-            const testCases = [
-                {},
-                {
-                    takerTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
-                    makerTokenAmount: '10000000000000000000',
-                    takerTokenAmount: '30000000000000000000',
-                },
-                {
-                    taker: checksummedAddress,
-                    makerTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-                    takerTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
-                    makerTokenAmount: '10000000000000000000',
-                    takerTokenAmount: '30000000000000000000',
-                },
-                {
-                    makerTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-                    takerTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
-                    makerTokenAmount: 10000000000000000000,
-                    takerTokenAmount: 30000000000000000000,
-                },
-            ];
-            const shouldFail = true;
-            validateAgainstSchema(testCases, relayerApiFeesPayloadSchema, shouldFail);
-        });
-    });
-    describe('#relayerApiFeesResponseSchema', () => {
-        it('should validate valid fees responses', () => {
-            const testCases = [
-                {
-                    makerFee: '10000000000000000',
-                    takerFee: '30000000000000000',
-                    feeRecipient: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-                },
-            ];
-            validateAgainstSchema(testCases, relayerApiFeesResponseSchema);
-        });
-        it('should fail for invalid fees responses', () => {
-            const checksummedAddress = '0xA2b31daCf30a9C50ca473337c01d8A201ae33e32';
-            const testCases = [
-                {},
-                {
-                    makerFee: 10000000000000000,
-                    takerFee: 30000000000000000,
-                },
-                {
-                    feeRecipient: checksummedAddress,
-                    takerToSpecify: checksummedAddress,
-                    makerFee: '10000000000000000',
-                    takerFee: '30000000000000000',
-                },
-            ];
-            const shouldFail = true;
-            validateAgainstSchema(testCases, relayerApiFeesResponseSchema, shouldFail);
-        });
-    });
-    describe('#relayerApiTokenPairsResponseSchema', () => {
-        it('should validate valid tokenPairs response', () => {
-            const testCases = [
-                [],
-                [
-                    {
-                        tokenA: {
-                            address: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-                            minAmount: '0',
-                            maxAmount: '10000000000000000000',
-                            precision: 5,
-                        },
-                        tokenB: {
-                            address: '0xef7fff64389b814a946f3e92105513705ca6b990',
-                            minAmount: '0',
-                            maxAmount: '50000000000000000000',
-                            precision: 5,
-                        },
-                    },
-                ],
-                [
-                    {
-                        tokenA: {
-                            address: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-                        },
-                        tokenB: {
-                            address: '0xef7fff64389b814a946f3e92105513705ca6b990',
-                        },
-                    },
-                ],
-            ];
-            validateAgainstSchema(testCases, relayerApiTokenPairsResponseSchema);
-        });
-        it('should fail for invalid tokenPairs responses', () => {
-            const checksummedAddress = '0xA2b31daCf30a9C50ca473337c01d8A201ae33e32';
-            const testCases = [
-                [
-                    {
-                        tokenA: {
-                            address: checksummedAddress,
-                        },
-                        tokenB: {
-                            address: checksummedAddress,
-                        },
-                    },
-                ],
-                [
-                    {
-                        tokenA: {
-                            address: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-                            minAmount: 0,
-                            maxAmount: 10000000000000000000,
-                        },
-                        tokenB: {
-                            address: '0xef7fff64389b814a946f3e92105513705ca6b990',
-                            minAmount: 0,
-                            maxAmount: 50000000000000000000,
-                        },
-                    },
-                ],
-                [
-                    {
-                        tokenA: {
-                            address: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-                            precision: '5',
-                        },
-                        tokenB: {
-                            address: '0xef7fff64389b814a946f3e92105513705ca6b990',
-                            precision: '5',
-                        },
-                    },
-                ],
-            ];
-            const shouldFail = true;
-            validateAgainstSchema(testCases, relayerApiTokenPairsResponseSchema, shouldFail);
-        });
-    });
-    describe('#jsNumberSchema', () => {
-        it('should validate valid js number', () => {
-            const testCases = [1, 42];
-            validateAgainstSchema(testCases, jsNumber);
-        });
-        it('should fail for invalid js number', () => {
-            const testCases = [NaN, -1, new BigNumber(1)];
-            const shouldFail = true;
-            validateAgainstSchema(testCases, jsNumber, shouldFail);
-        });
-    });
-    describe('#txDataSchema', () => {
-        it('should validate valid txData', () => {
-            const testCases = [
-                {
-                    from: NULL_ADDRESS,
-                },
-                {
-                    from: NULL_ADDRESS,
-                    gas: new BigNumber(42),
-                },
-                {
-                    from: NULL_ADDRESS,
-                    gas: 42,
-                },
-            ];
-            validateAgainstSchema(testCases, txDataSchema);
-        });
-        it('should fail for invalid txData', () => {
-            const testCases = [
-                {
-                    gas: new BigNumber(42),
-                },
-                {
-                    from: NULL_ADDRESS,
-                    unknownProp: 'here',
-                },
-                {},
-                [],
-                new BigNumber(1),
-            ];
-            const shouldFail = true;
-            validateAgainstSchema(testCases, txDataSchema, shouldFail);
-        });
-    });
+	const validator = new SchemaValidator();
+	const validateAgainstSchema = (testCases: any[], schema: any, shouldFail = false) => {
+		forEach(testCases, (testCase: any) => {
+			const validationResult = validator.validate(testCase, schema);
+			const hasErrors = validationResult.errors.length !== 0;
+			if (shouldFail) {
+				if (!hasErrors) {
+					throw new Error(
+						`Expected testCase: ${JSON.stringify(testCase, null, '\t')} to fail and it didn't.`,
+					);
+				}
+			} else {
+				if (hasErrors) {
+					throw new Error(JSON.stringify(validationResult.errors, null, '\t'));
+				}
+			}
+		});
+	};
+	describe('#numberSchema', () => {
+		it('should validate valid numbers', () => {
+			const testCases = ['42', '0', '1.3', '0.2', '00.00'];
+			validateAgainstSchema(testCases, numberSchema);
+		});
+		it('should fail for invalid numbers', () => {
+			const testCases = ['.3', '1.', 'abacaba', 'и', '1..0'];
+			const shouldFail = true;
+			validateAgainstSchema(testCases, numberSchema, shouldFail);
+		});
+	});
+	describe('#addressSchema', () => {
+		it('should validate valid addresses', () => {
+			const testCases = ['0x8b0292b11a196601ed2ce54b665cafeca0347d42', NULL_ADDRESS];
+			validateAgainstSchema(testCases, addressSchema);
+		});
+		it('should fail for invalid addresses', () => {
+			const testCases = [
+				'0x',
+				'0',
+				'0x00',
+				'0xzzzzzzB11a196601eD2ce54B665CaFEca0347D42',
+				'0x8b0292B11a196601eD2ce54B665CaFEca0347D42',
+			];
+			const shouldFail = true;
+			validateAgainstSchema(testCases, addressSchema, shouldFail);
+		});
+	});
+	describe('#ecSignatureParameterSchema', () => {
+		it('should validate valid parameters', () => {
+			const testCases = [
+				'0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
+				'0X40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
+			];
+			validateAgainstSchema(testCases, ecSignatureParameterSchema);
+		});
+		it('should fail for invalid parameters', () => {
+			const testCases = [
+				'0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc3', // shorter
+				'0xzzzz9190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254', // invalid characters
+				'40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254', // no 0x
+			];
+			const shouldFail = true;
+			validateAgainstSchema(testCases, ecSignatureParameterSchema, shouldFail);
+		});
+	});
+	describe('#ecSignatureSchema', () => {
+		it('should validate valid signature', () => {
+			const signature = {
+				v: 27,
+				r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
+				s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
+			};
+			const testCases = [
+				signature,
+				{
+					...signature,
+					v: 28,
+				},
+			];
+			validateAgainstSchema(testCases, ecSignatureSchema);
+		});
+		it('should fail for invalid signature', () => {
+			const v = 27;
+			const r = '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33';
+			const s = '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254';
+			const testCases = [{}, { v }, { r, s, v: 31 }];
+			const shouldFail = true;
+			validateAgainstSchema(testCases, ecSignatureSchema, shouldFail);
+		});
+	});
+	describe('#orderHashSchema', () => {
+		it('should validate valid order hash', () => {
+			const testCases = [
+				'0x61a3ed31B43c8780e905a260a35faefEc527be7516aa11c0256729b5b351bc33',
+				'0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
+			];
+			validateAgainstSchema(testCases, orderHashSchema);
+		});
+		it('should fail for invalid order hash', () => {
+			const testCases = [
+				{},
+				'0x',
+				'0x8b0292B11a196601eD2ce54B665CaFEca0347D42',
+				'61a3ed31B43c8780e905a260a35faefEc527be7516aa11c0256729b5b351bc33',
+			];
+			const shouldFail = true;
+			validateAgainstSchema(testCases, orderHashSchema, shouldFail);
+		});
+	});
+	describe('#blockParamSchema', () => {
+		it('should validate valid block param', () => {
+			const testCases = [42, 'latest', 'pending', 'earliest'];
+			validateAgainstSchema(testCases, blockParamSchema);
+		});
+		it('should fail for invalid block param', () => {
+			const testCases = [{}, '42', 'pemding'];
+			const shouldFail = true;
+			validateAgainstSchema(testCases, blockParamSchema, shouldFail);
+		});
+	});
+	describe('#blockRangeSchema', () => {
+		it('should validate valid subscription opts', () => {
+			const testCases = [{ fromBlock: 42, toBlock: 'latest' }, { fromBlock: 42 }, {}];
+			validateAgainstSchema(testCases, blockRangeSchema);
+		});
+		it('should fail for invalid subscription opts', () => {
+			const testCases = [{ fromBlock: '42' }];
+			const shouldFail = true;
+			validateAgainstSchema(testCases, blockRangeSchema, shouldFail);
+		});
+	});
+	describe('#tokenSchema', () => {
+		const token = {
+			name: 'Zero Ex',
+			symbol: 'ZRX',
+			decimals: 100500,
+			address: '0x8b0292b11a196601ed2ce54b665cafeca0347d42',
+			url: 'https://0xproject.com',
+		};
+		it('should validate valid token', () => {
+			const testCases = [token];
+			validateAgainstSchema(testCases, tokenSchema);
+		});
+		it('should fail for invalid token', () => {
+			const testCases = [
+				{
+					...token,
+					address: null,
+				},
+				{
+					...token,
+					decimals: undefined,
+				},
+				[],
+				4,
+			];
+			const shouldFail = true;
+			validateAgainstSchema(testCases, tokenSchema, shouldFail);
+		});
+	});
+	describe('order including schemas', () => {
+		const order = {
+			maker: NULL_ADDRESS,
+			taker: NULL_ADDRESS,
+			makerFee: '1',
+			takerFee: '2',
+			makerTokenAmount: '1',
+			takerTokenAmount: '2',
+			makerTokenAddress: NULL_ADDRESS,
+			takerTokenAddress: NULL_ADDRESS,
+			salt: '67006738228878699843088602623665307406148487219438534730168799356281242528500',
+			feeRecipient: NULL_ADDRESS,
+			exchangeContractAddress: NULL_ADDRESS,
+			expirationUnixTimestampSec: '42',
+		};
+		describe('#orderSchema', () => {
+			it('should validate valid order', () => {
+				const testCases = [order];
+				validateAgainstSchema(testCases, orderSchema);
+			});
+			it('should fail for invalid order', () => {
+				const testCases = [
+					{
+						...order,
+						salt: undefined,
+					},
+					{
+						...order,
+						salt: 'salt',
+					},
+					'order',
+				];
+				const shouldFail = true;
+				validateAgainstSchema(testCases, orderSchema, shouldFail);
+			});
+		});
+		describe('signed order including schemas', () => {
+			const signedOrder = {
+				...order,
+				ecSignature: {
+					v: 27,
+					r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
+					s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
+				},
+			};
+			describe('#signedOrdersSchema', () => {
+				it('should validate valid signed orders', () => {
+					const testCases = [[signedOrder], []];
+					validateAgainstSchema(testCases, signedOrdersSchema);
+				});
+				it('should fail for invalid signed orders', () => {
+					const testCases = [[signedOrder, 1]];
+					const shouldFail = true;
+					validateAgainstSchema(testCases, signedOrdersSchema, shouldFail);
+				});
+			});
+			describe('#signedOrderSchema', () => {
+				it('should validate valid signed order', () => {
+					const testCases = [signedOrder];
+					validateAgainstSchema(testCases, signedOrderSchema);
+				});
+				it('should fail for invalid signed order', () => {
+					const testCases = [
+						{
+							...signedOrder,
+							ecSignature: undefined,
+						},
+					];
+					const shouldFail = true;
+					validateAgainstSchema(testCases, signedOrderSchema, shouldFail);
+				});
+			});
+			describe('#orderFillOrKillRequestsSchema', () => {
+				const orderFillOrKillRequests = [
+					{
+						signedOrder,
+						fillTakerAmount: '5',
+					},
+				];
+				it('should validate valid order fill or kill requests', () => {
+					const testCases = [orderFillOrKillRequests];
+					validateAgainstSchema(testCases, orderFillOrKillRequestsSchema);
+				});
+				it('should fail for invalid order fill or kill requests', () => {
+					const testCases = [
+						[
+							{
+								...orderFillOrKillRequests[0],
+								fillTakerAmount: undefined,
+							},
+						],
+					];
+					const shouldFail = true;
+					validateAgainstSchema(testCases, orderFillOrKillRequestsSchema, shouldFail);
+				});
+			});
+			describe('#orderCancellationRequestsSchema', () => {
+				const orderCancellationRequests = [
+					{
+						order,
+						takerTokenCancelAmount: '5',
+					},
+				];
+				it('should validate valid order cancellation requests', () => {
+					const testCases = [orderCancellationRequests];
+					validateAgainstSchema(testCases, orderCancellationRequestsSchema);
+				});
+				it('should fail for invalid order cancellation requests', () => {
+					const testCases = [
+						[
+							{
+								...orderCancellationRequests[0],
+								takerTokenCancelAmount: undefined,
+							},
+						],
+					];
+					const shouldFail = true;
+					validateAgainstSchema(testCases, orderCancellationRequestsSchema, shouldFail);
+				});
+			});
+			describe('#orderFillRequestsSchema', () => {
+				const orderFillRequests = [
+					{
+						signedOrder,
+						takerTokenFillAmount: '5',
+					},
+				];
+				it('should validate valid order fill requests', () => {
+					const testCases = [orderFillRequests];
+					validateAgainstSchema(testCases, orderFillRequestsSchema);
+				});
+				it('should fail for invalid order fill requests', () => {
+					const testCases = [
+						[
+							{
+								...orderFillRequests[0],
+								takerTokenFillAmount: undefined,
+							},
+						],
+					];
+					const shouldFail = true;
+					validateAgainstSchema(testCases, orderFillRequestsSchema, shouldFail);
+				});
+			});
+			describe('#relayerApiOrderBookResponseSchema', () => {
+				it('should validate valid order book responses', () => {
+					const testCases = [
+						{
+							bids: [],
+							asks: [],
+						},
+						{
+							bids: [signedOrder, signedOrder],
+							asks: [],
+						},
+						{
+							bids: [],
+							asks: [signedOrder, signedOrder],
+						},
+						{
+							bids: [signedOrder],
+							asks: [signedOrder, signedOrder],
+						},
+					];
+					validateAgainstSchema(testCases, relayerApiOrderBookResponseSchema);
+				});
+				it('should fail for invalid order fill requests', () => {
+					const testCases = [
+						{},
+						{
+							bids: [signedOrder, signedOrder],
+						},
+						{
+							asks: [signedOrder, signedOrder],
+						},
+						{
+							bids: signedOrder,
+							asks: [signedOrder, signedOrder],
+						},
+						{
+							bids: [signedOrder],
+							asks: signedOrder,
+						},
+					];
+					const shouldFail = true;
+					validateAgainstSchema(testCases, relayerApiOrderBookResponseSchema, shouldFail);
+				});
+			});
+			describe('#relayerApiOrderbookChannelSubscribeSchema', () => {
+				it('should validate valid orderbook channel websocket subscribe message', () => {
+					const testCases = [
+						{
+							type: 'subscribe',
+							channel: 'orderbook',
+							requestId: 1,
+							payload: {
+								baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+								quoteTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+								snapshot: true,
+								limit: 100,
+							},
+						},
+						{
+							type: 'subscribe',
+							channel: 'orderbook',
+							requestId: 1,
+							payload: {
+								baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+								quoteTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+							},
+						},
+					];
+					validateAgainstSchema(testCases, relayerApiOrderbookChannelSubscribeSchema);
+				});
+				it('should fail for invalid orderbook channel websocket subscribe message', () => {
+					const checksummedAddress = '0xA2b31daCf30a9C50ca473337c01d8A201ae33e32';
+					const testCases = [
+						{
+							type: 'subscribe',
+							channel: 'orderbook',
+							payload: {
+								baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+								quoteTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+								snapshot: true,
+								limit: 100,
+							},
+						},
+						{
+							type: 'foo',
+							channel: 'orderbook',
+							requestId: 1,
+							payload: {
+								baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+								quoteTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+							},
+						},
+						{
+							type: 'subscribe',
+							channel: 'bar',
+							requestId: 1,
+							payload: {
+								baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+								quoteTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+							},
+						},
+						{
+							type: 'subscribe',
+							channel: 'orderbook',
+							requestId: 1,
+							payload: {
+								baseTokenAddress: checksummedAddress,
+								quoteTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+							},
+						},
+						{
+							type: 'subscribe',
+							channel: 'orderbook',
+							requestId: 1,
+							payload: {
+								baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+								quoteTokenAddress: checksummedAddress,
+							},
+						},
+						{
+							type: 'subscribe',
+							channel: 'orderbook',
+							requestId: 1,
+							payload: {
+								quoteTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+							},
+						},
+						{
+							type: 'subscribe',
+							channel: 'orderbook',
+							requestId: 1,
+							payload: {
+								baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+							},
+						},
+						{
+							type: 'subscribe',
+							channel: 'orderbook',
+							requestId: 1,
+							payload: {
+								baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+								quoteTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+								snapshot: 'true',
+								limit: 100,
+							},
+						},
+						{
+							type: 'subscribe',
+							channel: 'orderbook',
+							requestId: 1,
+							payload: {
+								baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+								quoteTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+								snapshot: true,
+								limit: '100',
+							},
+						},
+					];
+					const shouldFail = true;
+					validateAgainstSchema(testCases, relayerApiOrderbookChannelSubscribeSchema, shouldFail);
+				});
+			});
+			describe('#relayerApiOrderbookChannelSnapshotSchema', () => {
+				it('should validate valid orderbook channel websocket snapshot message', () => {
+					const testCases = [
+						{
+							type: 'snapshot',
+							channel: 'orderbook',
+							requestId: 2,
+							payload: {
+								bids: [],
+								asks: [],
+							},
+						},
+						{
+							type: 'snapshot',
+							channel: 'orderbook',
+							requestId: 2,
+							payload: {
+								bids: [signedOrder],
+								asks: [signedOrder],
+							},
+						},
+					];
+					validateAgainstSchema(testCases, relayerApiOrderbookChannelSnapshotSchema);
+				});
+				it('should fail for invalid orderbook channel websocket snapshot message', () => {
+					const testCases = [
+						{
+							type: 'foo',
+							channel: 'orderbook',
+							requestId: 2,
+							payload: {
+								bids: [signedOrder],
+								asks: [signedOrder],
+							},
+						},
+						{
+							type: 'snapshot',
+							channel: 'bar',
+							requestId: 2,
+							payload: {
+								bids: [signedOrder],
+								asks: [signedOrder],
+							},
+						},
+						{
+							type: 'snapshot',
+							channel: 'orderbook',
+							payload: {
+								bids: [signedOrder],
+								asks: [signedOrder],
+							},
+						},
+						{
+							type: 'snapshot',
+							channel: 'orderbook',
+							requestId: '2',
+							payload: {
+								bids: [signedOrder],
+								asks: [signedOrder],
+							},
+						},
+						{
+							type: 'snapshot',
+							channel: 'orderbook',
+							requestId: 2,
+							payload: {
+								bids: [signedOrder],
+							},
+						},
+						{
+							type: 'snapshot',
+							channel: 'orderbook',
+							requestId: 2,
+							payload: {
+								asks: [signedOrder],
+							},
+						},
+						{
+							type: 'snapshot',
+							channel: 'orderbook',
+							requestId: 2,
+							payload: {
+								bids: [signedOrder],
+								asks: [{}],
+							},
+						},
+						{
+							type: 'snapshot',
+							channel: 'orderbook',
+							requestId: 2,
+							payload: {
+								bids: [{}],
+								asks: [signedOrder],
+							},
+						},
+					];
+					const shouldFail = true;
+					validateAgainstSchema(testCases, relayerApiOrderbookChannelSnapshotSchema, shouldFail);
+				});
+			});
+			describe('#relayerApiOrderbookChannelUpdateSchema', () => {
+				it('should validate valid orderbook channel websocket update message', () => {
+					const testCases = [
+						{
+							type: 'update',
+							channel: 'orderbook',
+							requestId: 2,
+							payload: signedOrder,
+						},
+					];
+					validateAgainstSchema(testCases, relayerApiOrderbookChannelUpdateSchema);
+				});
+				it('should fail for invalid orderbook channel websocket update message', () => {
+					const testCases = [
+						{
+							type: 'foo',
+							channel: 'orderbook',
+							requestId: 2,
+							payload: signedOrder,
+						},
+						{
+							type: 'update',
+							channel: 'bar',
+							requestId: 2,
+							payload: signedOrder,
+						},
+						{
+							type: 'update',
+							channel: 'orderbook',
+							requestId: 2,
+							payload: {},
+						},
+					];
+					const shouldFail = true;
+					validateAgainstSchema(testCases, relayerApiOrderbookChannelUpdateSchema, shouldFail);
+				});
+			});
+		});
+	});
+	describe('BigNumber serialization', () => {
+		it('should correctly serialize BigNumbers', () => {
+			const testCases = {
+				'42': '42',
+				'0': '0',
+				'1.3': '1.3',
+				'0.2': '0.2',
+				'00.00': '0',
+				'.3': '0.3',
+			};
+			forEach(testCases, (serialized: string, input: string) => {
+				expect(JSON.parse(JSON.stringify(new BigNumber(input)))).to.be.equal(serialized);
+			});
+		});
+	});
+	describe('#relayerApiErrorResponseSchema', () => {
+		it('should validate valid errorResponse', () => {
+			const testCases = [
+				{
+					code: 102,
+					reason: 'Order submission disabled',
+				},
+				{
+					code: 101,
+					reason: 'Validation failed',
+					validationErrors: [
+						{
+							field: 'maker',
+							code: 1002,
+							reason: 'Invalid address',
+						},
+					],
+				},
+			];
+			validateAgainstSchema(testCases, relayerApiErrorResponseSchema);
+		});
+		it('should fail for invalid error responses', () => {
+			const testCases = [
+				{},
+				{
+					code: 102,
+				},
+				{
+					code: '102',
+					reason: 'Order submission disabled',
+				},
+				{
+					reason: 'Order submission disabled',
+				},
+				{
+					code: 101,
+					reason: 'Validation failed',
+					validationErrors: [
+						{
+							field: 'maker',
+							reason: 'Invalid address',
+						},
+					],
+				},
+				{
+					code: 101,
+					reason: 'Validation failed',
+					validationErrors: [
+						{
+							field: 'maker',
+							code: '1002',
+							reason: 'Invalid address',
+						},
+					],
+				},
+			];
+			const shouldFail = true;
+			validateAgainstSchema(testCases, relayerApiErrorResponseSchema, shouldFail);
+		});
+	});
+	describe('#relayerApiFeesPayloadSchema', () => {
+		it('should validate valid fees payloads', () => {
+			const testCases = [
+				{
+					exchangeContractAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+					maker: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+					taker: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+					makerTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+					takerTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
+					makerTokenAmount: '10000000000000000000',
+					takerTokenAmount: '30000000000000000000',
+					expirationUnixTimestampSec: '42',
+					salt: '67006738228878699843088602623665307406148487219438534730168799356281242528500',
+				},
+			];
+			validateAgainstSchema(testCases, relayerApiFeesPayloadSchema);
+		});
+		it('should fail for invalid fees payloads', () => {
+			const checksummedAddress = '0xA2b31daCf30a9C50ca473337c01d8A201ae33e32';
+			const testCases = [
+				{},
+				{
+					takerTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
+					makerTokenAmount: '10000000000000000000',
+					takerTokenAmount: '30000000000000000000',
+				},
+				{
+					taker: checksummedAddress,
+					makerTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+					takerTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
+					makerTokenAmount: '10000000000000000000',
+					takerTokenAmount: '30000000000000000000',
+				},
+				{
+					makerTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+					takerTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
+					makerTokenAmount: 10000000000000000000,
+					takerTokenAmount: 30000000000000000000,
+				},
+			];
+			const shouldFail = true;
+			validateAgainstSchema(testCases, relayerApiFeesPayloadSchema, shouldFail);
+		});
+	});
+	describe('#relayerApiFeesResponseSchema', () => {
+		it('should validate valid fees responses', () => {
+			const testCases = [
+				{
+					makerFee: '10000000000000000',
+					takerFee: '30000000000000000',
+					feeRecipient: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+				},
+			];
+			validateAgainstSchema(testCases, relayerApiFeesResponseSchema);
+		});
+		it('should fail for invalid fees responses', () => {
+			const checksummedAddress = '0xA2b31daCf30a9C50ca473337c01d8A201ae33e32';
+			const testCases = [
+				{},
+				{
+					makerFee: 10000000000000000,
+					takerFee: 30000000000000000,
+				},
+				{
+					feeRecipient: checksummedAddress,
+					takerToSpecify: checksummedAddress,
+					makerFee: '10000000000000000',
+					takerFee: '30000000000000000',
+				},
+			];
+			const shouldFail = true;
+			validateAgainstSchema(testCases, relayerApiFeesResponseSchema, shouldFail);
+		});
+	});
+	describe('#relayerApiTokenPairsResponseSchema', () => {
+		it('should validate valid tokenPairs response', () => {
+			const testCases = [
+				[],
+				[
+					{
+						tokenA: {
+							address: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+							minAmount: '0',
+							maxAmount: '10000000000000000000',
+							precision: 5,
+						},
+						tokenB: {
+							address: '0xef7fff64389b814a946f3e92105513705ca6b990',
+							minAmount: '0',
+							maxAmount: '50000000000000000000',
+							precision: 5,
+						},
+					},
+				],
+				[
+					{
+						tokenA: {
+							address: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+						},
+						tokenB: {
+							address: '0xef7fff64389b814a946f3e92105513705ca6b990',
+						},
+					},
+				],
+			];
+			validateAgainstSchema(testCases, relayerApiTokenPairsResponseSchema);
+		});
+		it('should fail for invalid tokenPairs responses', () => {
+			const checksummedAddress = '0xA2b31daCf30a9C50ca473337c01d8A201ae33e32';
+			const testCases = [
+				[
+					{
+						tokenA: {
+							address: checksummedAddress,
+						},
+						tokenB: {
+							address: checksummedAddress,
+						},
+					},
+				],
+				[
+					{
+						tokenA: {
+							address: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+							minAmount: 0,
+							maxAmount: 10000000000000000000,
+						},
+						tokenB: {
+							address: '0xef7fff64389b814a946f3e92105513705ca6b990',
+							minAmount: 0,
+							maxAmount: 50000000000000000000,
+						},
+					},
+				],
+				[
+					{
+						tokenA: {
+							address: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+							precision: '5',
+						},
+						tokenB: {
+							address: '0xef7fff64389b814a946f3e92105513705ca6b990',
+							precision: '5',
+						},
+					},
+				],
+			];
+			const shouldFail = true;
+			validateAgainstSchema(testCases, relayerApiTokenPairsResponseSchema, shouldFail);
+		});
+	});
+	describe('#jsNumberSchema', () => {
+		it('should validate valid js number', () => {
+			const testCases = [1, 42];
+			validateAgainstSchema(testCases, jsNumber);
+		});
+		it('should fail for invalid js number', () => {
+			const testCases = [NaN, -1, new BigNumber(1)];
+			const shouldFail = true;
+			validateAgainstSchema(testCases, jsNumber, shouldFail);
+		});
+	});
+	describe('#txDataSchema', () => {
+		it('should validate valid txData', () => {
+			const testCases = [
+				{
+					from: NULL_ADDRESS,
+				},
+				{
+					from: NULL_ADDRESS,
+					gas: new BigNumber(42),
+				},
+				{
+					from: NULL_ADDRESS,
+					gas: 42,
+				},
+			];
+			validateAgainstSchema(testCases, txDataSchema);
+		});
+		it('should fail for invalid txData', () => {
+			const testCases = [
+				{
+					gas: new BigNumber(42),
+				},
+				{
+					from: NULL_ADDRESS,
+					unknownProp: 'here',
+				},
+				{},
+				[],
+				new BigNumber(1),
+			];
+			const shouldFail = true;
+			validateAgainstSchema(testCases, txDataSchema, shouldFail);
+		});
+	});
 }); // tslint:disable:max-file-line-count
diff --git a/packages/json-schemas/tsconfig.json b/packages/json-schemas/tsconfig.json
index 88a467ccb..8314a9459 100644
--- a/packages/json-schemas/tsconfig.json
+++ b/packages/json-schemas/tsconfig.json
@@ -1,7 +1,7 @@
 {
-    "extends": "../../tsconfig",
-    "compilerOptions": {
-        "outDir": "lib"
-    },
-    "include": ["./src/**/*", "./test/**/*", "../../node_modules/chai-typescript-typings/index.d.ts"]
+	"extends": "../../tsconfig",
+	"compilerOptions": {
+		"outDir": "lib"
+	},
+	"include": ["./src/**/*", "./test/**/*", "../../node_modules/chai-typescript-typings/index.d.ts"]
 }
diff --git a/packages/json-schemas/tslint.json b/packages/json-schemas/tslint.json
index ffaefe83a..e63054bfc 100644
--- a/packages/json-schemas/tslint.json
+++ b/packages/json-schemas/tslint.json
@@ -1,3 +1,3 @@
 {
-    "extends": ["@0xproject/tslint-config"]
+	"extends": ["@0xproject/tslint-config"]
 }
diff --git a/packages/monorepo-scripts/package.json b/packages/monorepo-scripts/package.json
index 2bf2aa796..31eaf6eca 100644
--- a/packages/monorepo-scripts/package.json
+++ b/packages/monorepo-scripts/package.json
@@ -1,34 +1,34 @@
 {
-    "name": "@0xproject/monorepo-scripts",
-    "version": "0.1.6",
-    "private": true,
-    "description": "Helper scripts for the monorepo",
-    "scripts": {
-        "deps_versions": "node ./lib/deps_versions.js",
-        "lint": "tslint --project . 'src/**/*.ts'",
-        "clean": "shx rm -rf lib",
-        "build": "tsc"
-    },
-    "repository": {
-        "type": "git",
-        "url": "https://github.com/0xProject/0x.js.git"
-    },
-    "license": "Apache-2.0",
-    "bugs": {
-        "url": "https://github.com/0xProject/0x.js/issues"
-    },
-    "homepage": "https://github.com/0xProject/0x.js/packages/monorepo-scripts/README.md",
-    "devDependencies": {
-        "@0xproject/tslint-config": "^0.4.4",
-        "@types/glob": "^5.0.33",
-        "@types/node": "^8.0.53",
-        "shx": "^0.2.2",
-        "tslint": "5.8.0",
-        "typescript": "~2.6.1"
-    },
-    "dependencies": {
-        "chalk": "^2.3.0",
-        "glob": "^7.1.2",
-        "lodash": "^4.17.4"
-    }
+	"name": "@0xproject/monorepo-scripts",
+	"version": "0.1.6",
+	"private": true,
+	"description": "Helper scripts for the monorepo",
+	"scripts": {
+		"deps_versions": "node ./lib/deps_versions.js",
+		"lint": "tslint --project . 'src/**/*.ts'",
+		"clean": "shx rm -rf lib",
+		"build": "tsc"
+	},
+	"repository": {
+		"type": "git",
+		"url": "https://github.com/0xProject/0x.js.git"
+	},
+	"license": "Apache-2.0",
+	"bugs": {
+		"url": "https://github.com/0xProject/0x.js/issues"
+	},
+	"homepage": "https://github.com/0xProject/0x.js/packages/monorepo-scripts/README.md",
+	"devDependencies": {
+		"@0xproject/tslint-config": "^0.4.4",
+		"@types/glob": "^5.0.33",
+		"@types/node": "^8.0.53",
+		"shx": "^0.2.2",
+		"tslint": "5.8.0",
+		"typescript": "~2.6.1"
+	},
+	"dependencies": {
+		"chalk": "^2.3.0",
+		"glob": "^7.1.2",
+		"lodash": "^4.17.4"
+	}
 }
diff --git a/packages/monorepo-scripts/src/deps_versions.ts b/packages/monorepo-scripts/src/deps_versions.ts
index 5c9a2d6ff..2c0aa6c54 100644
--- a/packages/monorepo-scripts/src/deps_versions.ts
+++ b/packages/monorepo-scripts/src/deps_versions.ts
@@ -6,51 +6,51 @@ import { sync as globSync } from 'glob';
 import * as _ from 'lodash';
 
 interface Dependencies {
-    [depName: string]: string;
+	[depName: string]: string;
 }
 interface Versions {
-    [packageName: string]: string;
+	[packageName: string]: string;
 }
 interface VersionsByDependency {
-    [depName: string]: Versions;
+	[depName: string]: Versions;
 }
 
 const PACKAGE_JSON_GLOB = '../*/package.json';
 
 function log(...args: any[]) {
-    console.log(...args); // tslint:disable-line:no-console
+	console.log(...args); // tslint:disable-line:no-console
 }
 
 function getDependencies(path: string): Dependencies {
-    const file = fs.readFileSync(path).toString();
-    const parsed = JSON.parse(file);
-    const dependencies = {
-        ...parsed.dependencies,
-        ...parsed.devDependencies,
-    };
-    return dependencies;
+	const file = fs.readFileSync(path).toString();
+	const parsed = JSON.parse(file);
+	const dependencies = {
+		...parsed.dependencies,
+		...parsed.devDependencies,
+	};
+	return dependencies;
 }
 
 const files = globSync(PACKAGE_JSON_GLOB);
 const versionsByDependency: VersionsByDependency = {};
 files.map(path => {
-    const [_1, packageName, _2] = path.split('/');
-    const dependencies = getDependencies(path);
-    _.map(dependencies, (version: string, depName: string) => {
-        if (_.isUndefined(versionsByDependency[depName])) {
-            versionsByDependency[depName] = {};
-        }
-        versionsByDependency[depName][packageName] = version;
-    });
+	const [_1, packageName, _2] = path.split('/');
+	const dependencies = getDependencies(path);
+	_.map(dependencies, (version: string, depName: string) => {
+		if (_.isUndefined(versionsByDependency[depName])) {
+			versionsByDependency[depName] = {};
+		}
+		versionsByDependency[depName][packageName] = version;
+	});
 });
 
 _.map(versionsByDependency, (versions: Versions, depName: string) => {
-    if (_.uniq(_.values(versions)).length === 1) {
-        delete versionsByDependency[depName];
-    } else {
-        log(chalk.bold(depName));
-        _.map(versions, (version: string, packageName: string) => {
-            log(`├── ${packageName} -> ${version}`);
-        });
-    }
+	if (_.uniq(_.values(versions)).length === 1) {
+		delete versionsByDependency[depName];
+	} else {
+		log(chalk.bold(depName));
+		_.map(versions, (version: string, packageName: string) => {
+			log(`├── ${packageName} -> ${version}`);
+		});
+	}
 });
diff --git a/packages/monorepo-scripts/tsconfig.json b/packages/monorepo-scripts/tsconfig.json
index c56d255d5..ad674c2b0 100644
--- a/packages/monorepo-scripts/tsconfig.json
+++ b/packages/monorepo-scripts/tsconfig.json
@@ -1,7 +1,7 @@
 {
-    "extends": "../../tsconfig",
-    "compilerOptions": {
-        "outDir": "lib"
-    },
-    "include": ["./src/**/*"]
+	"extends": "../../tsconfig",
+	"compilerOptions": {
+		"outDir": "lib"
+	},
+	"include": ["./src/**/*"]
 }
diff --git a/packages/monorepo-scripts/tslint.json b/packages/monorepo-scripts/tslint.json
index ffaefe83a..e63054bfc 100644
--- a/packages/monorepo-scripts/tslint.json
+++ b/packages/monorepo-scripts/tslint.json
@@ -1,3 +1,3 @@
 {
-    "extends": ["@0xproject/tslint-config"]
+	"extends": ["@0xproject/tslint-config"]
 }
diff --git a/packages/subproviders/package.json b/packages/subproviders/package.json
index 146c94496..1da019e2d 100644
--- a/packages/subproviders/package.json
+++ b/packages/subproviders/package.json
@@ -1,55 +1,55 @@
 {
-    "name": "@0xproject/subproviders",
-    "version": "0.3.3",
-    "main": "lib/src/index.js",
-    "types": "lib/src/index.d.ts",
-    "license": "Apache-2.0",
-    "scripts": {
-        "clean": "shx rm -rf lib",
-        "build": "tsc",
-        "lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'",
-        "run_mocha_unit": "mocha lib/test/unit/**/*_test.js --timeout 10000 --bail --exit",
-        "run_mocha_integration": "mocha lib/test/integration/**/*_test.js --timeout 10000 --bail --exit",
-        "test": "npm run test:unit",
-        "test:circleci": "npm run test:unit",
-        "test:all": "run-s test:unit test:integration",
-        "test:unit": "run-s clean build run_mocha_unit",
-        "test:integration": "run-s clean build run_mocha_integration"
-    },
-    "dependencies": {
-        "@0xproject/assert": "^0.0.13",
-        "@0xproject/utils": "^0.2.2",
-        "bn.js": "^4.11.8",
-        "es6-promisify": "^5.0.0",
-        "ethereumjs-tx": "^1.3.3",
-        "ethereumjs-util": "^5.1.1",
-        "hdkey": "^0.7.1",
-        "ledgerco": "0xProject/ledger-node-js-api",
-        "lodash": "^4.17.4",
-        "semaphore-async-await": "^1.5.1",
-        "web3": "^0.20.0",
-        "web3-provider-engine": "^13.0.1"
-    },
-    "devDependencies": {
-        "@0xproject/tslint-config": "^0.4.4",
-        "@0xproject/utils": "^0.2.2",
-        "@types/lodash": "^4.14.86",
-        "@types/mocha": "^2.2.42",
-        "@types/node": "^8.0.53",
-        "awesome-typescript-loader": "^3.1.3",
-        "chai": "^4.0.1",
-        "chai-as-promised": "^7.1.0",
-        "chai-as-promised-typescript-typings": "^0.0.6",
-        "chai-typescript-typings": "^0.0.2",
-        "dirty-chai": "^2.0.1",
-        "mocha": "^4.0.1",
-        "npm-run-all": "^4.1.2",
-        "shx": "^0.2.2",
-        "tslint": "5.8.0",
-        "types-bn": "^0.0.1",
-        "types-ethereumjs-util": "0xproject/types-ethereumjs-util",
-        "typescript": "~2.6.1",
-        "web3-typescript-typings": "^0.7.2",
-        "webpack": "^3.1.0"
-    }
+	"name": "@0xproject/subproviders",
+	"version": "0.3.3",
+	"main": "lib/src/index.js",
+	"types": "lib/src/index.d.ts",
+	"license": "Apache-2.0",
+	"scripts": {
+		"clean": "shx rm -rf lib",
+		"build": "tsc",
+		"lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'",
+		"run_mocha_unit": "mocha lib/test/unit/**/*_test.js --timeout 10000 --bail --exit",
+		"run_mocha_integration": "mocha lib/test/integration/**/*_test.js --timeout 10000 --bail --exit",
+		"test": "npm run test:unit",
+		"test:circleci": "npm run test:unit",
+		"test:all": "run-s test:unit test:integration",
+		"test:unit": "run-s clean build run_mocha_unit",
+		"test:integration": "run-s clean build run_mocha_integration"
+	},
+	"dependencies": {
+		"@0xproject/assert": "^0.0.13",
+		"@0xproject/utils": "^0.2.2",
+		"bn.js": "^4.11.8",
+		"es6-promisify": "^5.0.0",
+		"ethereumjs-tx": "^1.3.3",
+		"ethereumjs-util": "^5.1.1",
+		"hdkey": "^0.7.1",
+		"ledgerco": "0xProject/ledger-node-js-api",
+		"lodash": "^4.17.4",
+		"semaphore-async-await": "^1.5.1",
+		"web3": "^0.20.0",
+		"web3-provider-engine": "^13.0.1"
+	},
+	"devDependencies": {
+		"@0xproject/tslint-config": "^0.4.4",
+		"@0xproject/utils": "^0.2.2",
+		"@types/lodash": "^4.14.86",
+		"@types/mocha": "^2.2.42",
+		"@types/node": "^8.0.53",
+		"awesome-typescript-loader": "^3.1.3",
+		"chai": "^4.0.1",
+		"chai-as-promised": "^7.1.0",
+		"chai-as-promised-typescript-typings": "^0.0.6",
+		"chai-typescript-typings": "^0.0.2",
+		"dirty-chai": "^2.0.1",
+		"mocha": "^4.0.1",
+		"npm-run-all": "^4.1.2",
+		"shx": "^0.2.2",
+		"tslint": "5.8.0",
+		"types-bn": "^0.0.1",
+		"types-ethereumjs-util": "0xproject/types-ethereumjs-util",
+		"typescript": "~2.6.1",
+		"web3-typescript-typings": "^0.7.2",
+		"webpack": "^3.1.0"
+	}
 }
diff --git a/packages/subproviders/src/globals.d.ts b/packages/subproviders/src/globals.d.ts
index 53457fa24..ed4fbc145 100644
--- a/packages/subproviders/src/globals.d.ts
+++ b/packages/subproviders/src/globals.d.ts
@@ -8,103 +8,103 @@ declare module 'es6-promisify';
 
 // Ethereumjs-tx declarations
 declare module 'ethereumjs-tx' {
-    class EthereumTx {
-        public raw: Buffer[];
-        public r: Buffer;
-        public s: Buffer;
-        public v: Buffer;
-        public serialize(): Buffer;
-        constructor(txParams: any);
-    }
-    export = EthereumTx;
+	class EthereumTx {
+		public raw: Buffer[];
+		public r: Buffer;
+		public s: Buffer;
+		public v: Buffer;
+		public serialize(): Buffer;
+		constructor(txParams: any);
+	}
+	export = EthereumTx;
 }
 
 // Ledgerco declarations
 interface ECSignatureString {
-    v: string;
-    r: string;
-    s: string;
+	v: string;
+	r: string;
+	s: string;
 }
 interface ECSignature {
-    v: number;
-    r: string;
-    s: string;
+	v: number;
+	r: string;
+	s: string;
 }
 declare module 'ledgerco' {
-    interface comm {
-        close_async(): Promise<void>;
-    }
-    export class comm_node implements comm {
-        public static create_async(timeoutMilliseconds?: number): Promise<comm_node>;
-        public close_async(): Promise<void>;
-    }
-    export class comm_u2f implements comm {
-        public static create_async(): Promise<comm_u2f>;
-        public close_async(): Promise<void>;
-    }
-    export class eth {
-        public comm: comm;
-        constructor(comm: comm);
-        public getAddress_async(
-            path: string,
-            display?: boolean,
-            chaincode?: boolean,
-        ): Promise<{ publicKey: string; address: string; chainCode: string }>;
-        public signTransaction_async(path: string, rawTxHex: string): Promise<ECSignatureString>;
-        public getAppConfiguration_async(): Promise<{
-            arbitraryDataEnabled: number;
-            version: string;
-        }>;
-        public signPersonalMessage_async(path: string, messageHex: string): Promise<ECSignature>;
-    }
+	interface comm {
+		close_async(): Promise<void>;
+	}
+	export class comm_node implements comm {
+		public static create_async(timeoutMilliseconds?: number): Promise<comm_node>;
+		public close_async(): Promise<void>;
+	}
+	export class comm_u2f implements comm {
+		public static create_async(): Promise<comm_u2f>;
+		public close_async(): Promise<void>;
+	}
+	export class eth {
+		public comm: comm;
+		constructor(comm: comm);
+		public getAddress_async(
+			path: string,
+			display?: boolean,
+			chaincode?: boolean,
+		): Promise<{ publicKey: string; address: string; chainCode: string }>;
+		public signTransaction_async(path: string, rawTxHex: string): Promise<ECSignatureString>;
+		public getAppConfiguration_async(): Promise<{
+			arbitraryDataEnabled: number;
+			version: string;
+		}>;
+		public signPersonalMessage_async(path: string, messageHex: string): Promise<ECSignature>;
+	}
 }
 
 // Semaphore-async-await declarations
 declare module 'semaphore-async-await' {
-    class Semaphore {
-        constructor(permits: number);
-        public wait(): Promise<void>;
-        public signal(): void;
-    }
-    export default Semaphore;
+	class Semaphore {
+		constructor(permits: number);
+		public wait(): Promise<void>;
+		public signal(): void;
+	}
+	export default Semaphore;
 }
 
 // web3-provider-engine declarations
 declare module 'web3-provider-engine/subproviders/subprovider' {
-    class Subprovider {}
-    export = Subprovider;
+	class Subprovider {}
+	export = Subprovider;
 }
 declare module 'web3-provider-engine/subproviders/rpc' {
-    import * as Web3 from 'web3';
-    class RpcSubprovider {
-        constructor(options: { rpcUrl: string });
-        public handleRequest(
-            payload: Web3.JSONRPCRequestPayload,
-            next: () => void,
-            end: (err: Error | null, data?: any) => void,
-        ): void;
-    }
-    export = RpcSubprovider;
+	import * as Web3 from 'web3';
+	class RpcSubprovider {
+		constructor(options: { rpcUrl: string });
+		public handleRequest(
+			payload: Web3.JSONRPCRequestPayload,
+			next: () => void,
+			end: (err: Error | null, data?: any) => void,
+		): void;
+	}
+	export = RpcSubprovider;
 }
 declare module 'web3-provider-engine' {
-    class Web3ProviderEngine {
-        public on(event: string, handler: () => void): void;
-        public send(payload: any): void;
-        public sendAsync(payload: any, callback: (error: any, response: any) => void): void;
-        public addProvider(provider: any): void;
-        public start(): void;
-        public stop(): void;
-    }
-    export = Web3ProviderEngine;
+	class Web3ProviderEngine {
+		public on(event: string, handler: () => void): void;
+		public send(payload: any): void;
+		public sendAsync(payload: any, callback: (error: any, response: any) => void): void;
+		public addProvider(provider: any): void;
+		public start(): void;
+		public stop(): void;
+	}
+	export = Web3ProviderEngine;
 }
 
 // hdkey declarations
 declare module 'hdkey' {
-    class HDNode {
-        public publicKey: Buffer;
-        public chainCode: Buffer;
-        public constructor();
-        public derive(path: string): HDNode;
-    }
-    export = HDNode;
+	class HDNode {
+		public publicKey: Buffer;
+		public chainCode: Buffer;
+		public constructor();
+		public derive(path: string): HDNode;
+	}
+	export = HDNode;
 }
diff --git a/packages/subproviders/src/index.ts b/packages/subproviders/src/index.ts
index 720c4362f..ecba186df 100644
--- a/packages/subproviders/src/index.ts
+++ b/packages/subproviders/src/index.ts
@@ -1,7 +1,7 @@
 import {
-    comm_node as LedgerNodeCommunication,
-    comm_u2f as LedgerBrowserCommunication,
-    eth as LedgerEthereumClientFn,
+	comm_node as LedgerNodeCommunication,
+	comm_u2f as LedgerBrowserCommunication,
+	eth as LedgerEthereumClientFn,
 } from 'ledgerco';
 
 import { LedgerEthereumClient } from './types';
@@ -16,9 +16,9 @@ export { ECSignature, LedgerWalletSubprovider, LedgerCommunicationClient } from
  * @return LedgerEthereumClient A browser client
  */
 export async function ledgerEthereumBrowserClientFactoryAsync(): Promise<LedgerEthereumClient> {
-    const ledgerConnection = await LedgerBrowserCommunication.create_async();
-    const ledgerEthClient = new LedgerEthereumClientFn(ledgerConnection);
-    return ledgerEthClient;
+	const ledgerConnection = await LedgerBrowserCommunication.create_async();
+	const ledgerEthClient = new LedgerEthereumClientFn(ledgerConnection);
+	return ledgerEthClient;
 }
 
 /**
@@ -26,7 +26,7 @@ export async function ledgerEthereumBrowserClientFactoryAsync(): Promise<LedgerE
  * @return LedgerEthereumClient A Node.js client
  */
 export async function ledgerEthereumNodeJsClientFactoryAsync(): Promise<LedgerEthereumClient> {
-    const ledgerConnection = await LedgerNodeCommunication.create_async();
-    const ledgerEthClient = new LedgerEthereumClientFn(ledgerConnection);
-    return ledgerEthClient;
+	const ledgerConnection = await LedgerNodeCommunication.create_async();
+	const ledgerEthClient = new LedgerEthereumClientFn(ledgerConnection);
+	return ledgerEthClient;
 }
diff --git a/packages/subproviders/src/subproviders/injected_web3.ts b/packages/subproviders/src/subproviders/injected_web3.ts
index bd29acb22..dc1b8b24c 100644
--- a/packages/subproviders/src/subproviders/injected_web3.ts
+++ b/packages/subproviders/src/subproviders/injected_web3.ts
@@ -9,41 +9,41 @@ import Web3ProviderEngine = require('web3-provider-engine');
  * Source: https://github.com/MetaMask/provider-engine/blob/master/subproviders/subprovider.js
  */
 export class InjectedWeb3Subprovider {
-    private _injectedWeb3: Web3;
-    constructor(injectedWeb3: Web3) {
-        this._injectedWeb3 = injectedWeb3;
-    }
-    public handleRequest(
-        payload: Web3.JSONRPCRequestPayload,
-        next: () => void,
-        end: (err: Error | null, result: any) => void,
-    ) {
-        switch (payload.method) {
-            case 'web3_clientVersion':
-                this._injectedWeb3.version.getNode(end);
-                return;
-            case 'eth_accounts':
-                this._injectedWeb3.eth.getAccounts(end);
-                return;
+	private _injectedWeb3: Web3;
+	constructor(injectedWeb3: Web3) {
+		this._injectedWeb3 = injectedWeb3;
+	}
+	public handleRequest(
+		payload: Web3.JSONRPCRequestPayload,
+		next: () => void,
+		end: (err: Error | null, result: any) => void,
+	) {
+		switch (payload.method) {
+			case 'web3_clientVersion':
+				this._injectedWeb3.version.getNode(end);
+				return;
+			case 'eth_accounts':
+				this._injectedWeb3.eth.getAccounts(end);
+				return;
 
-            case 'eth_sendTransaction':
-                const [txParams] = payload.params;
-                this._injectedWeb3.eth.sendTransaction(txParams, end);
-                return;
+			case 'eth_sendTransaction':
+				const [txParams] = payload.params;
+				this._injectedWeb3.eth.sendTransaction(txParams, end);
+				return;
 
-            case 'eth_sign':
-                const [address, message] = payload.params;
-                this._injectedWeb3.eth.sign(address, message, end);
-                return;
+			case 'eth_sign':
+				const [address, message] = payload.params;
+				this._injectedWeb3.eth.sign(address, message, end);
+				return;
 
-            default:
-                next();
-                return;
-        }
-    }
-    // Required to implement this method despite not needing it for this subprovider
-    // tslint:disable-next-line:prefer-function-over-method
-    public setEngine(engine: Web3ProviderEngine) {
-        // noop
-    }
+			default:
+				next();
+				return;
+		}
+	}
+	// Required to implement this method despite not needing it for this subprovider
+	// tslint:disable-next-line:prefer-function-over-method
+	public setEngine(engine: Web3ProviderEngine) {
+		// noop
+	}
 }
diff --git a/packages/subproviders/src/subproviders/ledger.ts b/packages/subproviders/src/subproviders/ledger.ts
index 7267a793e..00649873b 100644
--- a/packages/subproviders/src/subproviders/ledger.ts
+++ b/packages/subproviders/src/subproviders/ledger.ts
@@ -8,12 +8,12 @@ import Semaphore from 'semaphore-async-await';
 import Web3 = require('web3');
 
 import {
-    LedgerEthereumClient,
-    LedgerEthereumClientFactoryAsync,
-    LedgerSubproviderConfigs,
-    LedgerSubproviderErrors,
-    PartialTxParams,
-    ResponseWithTxParams,
+	LedgerEthereumClient,
+	LedgerEthereumClientFactoryAsync,
+	LedgerSubproviderConfigs,
+	LedgerSubproviderErrors,
+	PartialTxParams,
+	ResponseWithTxParams,
 } from '../types';
 
 import { Subprovider } from './subprovider';
@@ -24,284 +24,284 @@ const ASK_FOR_ON_DEVICE_CONFIRMATION = false;
 const SHOULD_GET_CHAIN_CODE = true;
 
 export class LedgerSubprovider extends Subprovider {
-    private _nonceLock: Semaphore;
-    private _connectionLock: Semaphore;
-    private _networkId: number;
-    private _derivationPath: string;
-    private _derivationPathIndex: number;
-    private _ledgerEthereumClientFactoryAsync: LedgerEthereumClientFactoryAsync;
-    private _ledgerClientIfExists?: LedgerEthereumClient;
-    private _shouldAlwaysAskForConfirmation: boolean;
-    private static _validateSender(sender: string) {
-        if (_.isUndefined(sender) || !addressUtils.isAddress(sender)) {
-            throw new Error(LedgerSubproviderErrors.SenderInvalidOrNotSupplied);
-        }
-    }
-    constructor(config: LedgerSubproviderConfigs) {
-        super();
-        this._nonceLock = new Semaphore(1);
-        this._connectionLock = new Semaphore(1);
-        this._networkId = config.networkId;
-        this._ledgerEthereumClientFactoryAsync = config.ledgerEthereumClientFactoryAsync;
-        this._derivationPath = config.derivationPath || DEFAULT_DERIVATION_PATH;
-        this._shouldAlwaysAskForConfirmation =
-            !_.isUndefined(config.accountFetchingConfigs) &&
-            !_.isUndefined(config.accountFetchingConfigs.shouldAskForOnDeviceConfirmation)
-                ? config.accountFetchingConfigs.shouldAskForOnDeviceConfirmation
-                : ASK_FOR_ON_DEVICE_CONFIRMATION;
-        this._derivationPathIndex = 0;
-    }
-    public getPath(): string {
-        return this._derivationPath;
-    }
-    public setPath(derivationPath: string) {
-        this._derivationPath = derivationPath;
-    }
-    public setPathIndex(pathIndex: number) {
-        this._derivationPathIndex = pathIndex;
-    }
-    public async handleRequest(
-        payload: Web3.JSONRPCRequestPayload,
-        next: () => void,
-        end: (err: Error | null, result?: any) => void,
-    ) {
-        let accounts;
-        let txParams;
-        switch (payload.method) {
-            case 'eth_coinbase':
-                try {
-                    accounts = await this.getAccountsAsync();
-                    end(null, accounts[0]);
-                } catch (err) {
-                    end(err);
-                }
-                return;
+	private _nonceLock: Semaphore;
+	private _connectionLock: Semaphore;
+	private _networkId: number;
+	private _derivationPath: string;
+	private _derivationPathIndex: number;
+	private _ledgerEthereumClientFactoryAsync: LedgerEthereumClientFactoryAsync;
+	private _ledgerClientIfExists?: LedgerEthereumClient;
+	private _shouldAlwaysAskForConfirmation: boolean;
+	private static _validateSender(sender: string) {
+		if (_.isUndefined(sender) || !addressUtils.isAddress(sender)) {
+			throw new Error(LedgerSubproviderErrors.SenderInvalidOrNotSupplied);
+		}
+	}
+	constructor(config: LedgerSubproviderConfigs) {
+		super();
+		this._nonceLock = new Semaphore(1);
+		this._connectionLock = new Semaphore(1);
+		this._networkId = config.networkId;
+		this._ledgerEthereumClientFactoryAsync = config.ledgerEthereumClientFactoryAsync;
+		this._derivationPath = config.derivationPath || DEFAULT_DERIVATION_PATH;
+		this._shouldAlwaysAskForConfirmation =
+			!_.isUndefined(config.accountFetchingConfigs) &&
+			!_.isUndefined(config.accountFetchingConfigs.shouldAskForOnDeviceConfirmation)
+				? config.accountFetchingConfigs.shouldAskForOnDeviceConfirmation
+				: ASK_FOR_ON_DEVICE_CONFIRMATION;
+		this._derivationPathIndex = 0;
+	}
+	public getPath(): string {
+		return this._derivationPath;
+	}
+	public setPath(derivationPath: string) {
+		this._derivationPath = derivationPath;
+	}
+	public setPathIndex(pathIndex: number) {
+		this._derivationPathIndex = pathIndex;
+	}
+	public async handleRequest(
+		payload: Web3.JSONRPCRequestPayload,
+		next: () => void,
+		end: (err: Error | null, result?: any) => void,
+	) {
+		let accounts;
+		let txParams;
+		switch (payload.method) {
+			case 'eth_coinbase':
+				try {
+					accounts = await this.getAccountsAsync();
+					end(null, accounts[0]);
+				} catch (err) {
+					end(err);
+				}
+				return;
 
-            case 'eth_accounts':
-                try {
-                    accounts = await this.getAccountsAsync();
-                    end(null, accounts);
-                } catch (err) {
-                    end(err);
-                }
-                return;
+			case 'eth_accounts':
+				try {
+					accounts = await this.getAccountsAsync();
+					end(null, accounts);
+				} catch (err) {
+					end(err);
+				}
+				return;
 
-            case 'eth_sendTransaction':
-                txParams = payload.params[0];
-                try {
-                    LedgerSubprovider._validateSender(txParams.from);
-                    const result = await this._sendTransactionAsync(txParams);
-                    end(null, result);
-                } catch (err) {
-                    end(err);
-                }
-                return;
+			case 'eth_sendTransaction':
+				txParams = payload.params[0];
+				try {
+					LedgerSubprovider._validateSender(txParams.from);
+					const result = await this._sendTransactionAsync(txParams);
+					end(null, result);
+				} catch (err) {
+					end(err);
+				}
+				return;
 
-            case 'eth_signTransaction':
-                txParams = payload.params[0];
-                try {
-                    const result = await this._signTransactionWithoutSendingAsync(txParams);
-                    end(null, result);
-                } catch (err) {
-                    end(err);
-                }
-                return;
+			case 'eth_signTransaction':
+				txParams = payload.params[0];
+				try {
+					const result = await this._signTransactionWithoutSendingAsync(txParams);
+					end(null, result);
+				} catch (err) {
+					end(err);
+				}
+				return;
 
-            case 'eth_sign':
-            case 'personal_sign':
-                const data = payload.method === 'eth_sign' ? payload.params[1] : payload.params[0];
-                try {
-                    if (_.isUndefined(data)) {
-                        throw new Error(LedgerSubproviderErrors.DataMissingForSignPersonalMessage);
-                    }
-                    assert.isHexString('data', data);
-                    const ecSignatureHex = await this.signPersonalMessageAsync(data);
-                    end(null, ecSignatureHex);
-                } catch (err) {
-                    end(err);
-                }
-                return;
+			case 'eth_sign':
+			case 'personal_sign':
+				const data = payload.method === 'eth_sign' ? payload.params[1] : payload.params[0];
+				try {
+					if (_.isUndefined(data)) {
+						throw new Error(LedgerSubproviderErrors.DataMissingForSignPersonalMessage);
+					}
+					assert.isHexString('data', data);
+					const ecSignatureHex = await this.signPersonalMessageAsync(data);
+					end(null, ecSignatureHex);
+				} catch (err) {
+					end(err);
+				}
+				return;
 
-            default:
-                next();
-                return;
-        }
-    }
-    public async getAccountsAsync(): Promise<string[]> {
-        this._ledgerClientIfExists = await this._createLedgerClientAsync();
+			default:
+				next();
+				return;
+		}
+	}
+	public async getAccountsAsync(): Promise<string[]> {
+		this._ledgerClientIfExists = await this._createLedgerClientAsync();
 
-        let ledgerResponse;
-        try {
-            ledgerResponse = await this._ledgerClientIfExists.getAddress_async(
-                this._derivationPath,
-                this._shouldAlwaysAskForConfirmation,
-                SHOULD_GET_CHAIN_CODE,
-            );
-        } finally {
-            await this._destroyLedgerClientAsync();
-        }
+		let ledgerResponse;
+		try {
+			ledgerResponse = await this._ledgerClientIfExists.getAddress_async(
+				this._derivationPath,
+				this._shouldAlwaysAskForConfirmation,
+				SHOULD_GET_CHAIN_CODE,
+			);
+		} finally {
+			await this._destroyLedgerClientAsync();
+		}
 
-        const hdKey = new HDNode();
-        hdKey.publicKey = new Buffer(ledgerResponse.publicKey, 'hex');
-        hdKey.chainCode = new Buffer(ledgerResponse.chainCode, 'hex');
+		const hdKey = new HDNode();
+		hdKey.publicKey = new Buffer(ledgerResponse.publicKey, 'hex');
+		hdKey.chainCode = new Buffer(ledgerResponse.chainCode, 'hex');
 
-        const accounts = [];
-        for (let i = 0; i < NUM_ADDRESSES_TO_FETCH; i++) {
-            const derivedHDNode = hdKey.derive(`m/${i + this._derivationPathIndex}`);
-            const derivedPublicKey = derivedHDNode.publicKey;
-            const shouldSanitizePublicKey = true;
-            const ethereumAddressUnprefixed = ethUtil
-                .publicToAddress(derivedPublicKey, shouldSanitizePublicKey)
-                .toString('hex');
-            const ethereumAddressPrefixed = ethUtil.addHexPrefix(ethereumAddressUnprefixed);
-            accounts.push(ethereumAddressPrefixed.toLowerCase());
-        }
-        return accounts;
-    }
-    public async signTransactionAsync(txParams: PartialTxParams): Promise<string> {
-        this._ledgerClientIfExists = await this._createLedgerClientAsync();
+		const accounts = [];
+		for (let i = 0; i < NUM_ADDRESSES_TO_FETCH; i++) {
+			const derivedHDNode = hdKey.derive(`m/${i + this._derivationPathIndex}`);
+			const derivedPublicKey = derivedHDNode.publicKey;
+			const shouldSanitizePublicKey = true;
+			const ethereumAddressUnprefixed = ethUtil
+				.publicToAddress(derivedPublicKey, shouldSanitizePublicKey)
+				.toString('hex');
+			const ethereumAddressPrefixed = ethUtil.addHexPrefix(ethereumAddressUnprefixed);
+			accounts.push(ethereumAddressPrefixed.toLowerCase());
+		}
+		return accounts;
+	}
+	public async signTransactionAsync(txParams: PartialTxParams): Promise<string> {
+		this._ledgerClientIfExists = await this._createLedgerClientAsync();
 
-        const tx = new EthereumTx(txParams);
+		const tx = new EthereumTx(txParams);
 
-        // Set the EIP155 bits
-        tx.raw[6] = Buffer.from([this._networkId]); // v
-        tx.raw[7] = Buffer.from([]); // r
-        tx.raw[8] = Buffer.from([]); // s
+		// Set the EIP155 bits
+		tx.raw[6] = Buffer.from([this._networkId]); // v
+		tx.raw[7] = Buffer.from([]); // r
+		tx.raw[8] = Buffer.from([]); // s
 
-        const txHex = tx.serialize().toString('hex');
-        try {
-            const derivationPath = this._getDerivationPath();
-            const result = await this._ledgerClientIfExists.signTransaction_async(derivationPath, txHex);
-            // Store signature in transaction
-            tx.r = Buffer.from(result.r, 'hex');
-            tx.s = Buffer.from(result.s, 'hex');
-            tx.v = Buffer.from(result.v, 'hex');
+		const txHex = tx.serialize().toString('hex');
+		try {
+			const derivationPath = this._getDerivationPath();
+			const result = await this._ledgerClientIfExists.signTransaction_async(derivationPath, txHex);
+			// Store signature in transaction
+			tx.r = Buffer.from(result.r, 'hex');
+			tx.s = Buffer.from(result.s, 'hex');
+			tx.v = Buffer.from(result.v, 'hex');
 
-            // EIP155: v should be chain_id * 2 + {35, 36}
-            const signedChainId = Math.floor((tx.v[0] - 35) / 2);
-            if (signedChainId !== this._networkId) {
-                await this._destroyLedgerClientAsync();
-                const err = new Error(LedgerSubproviderErrors.TooOldLedgerFirmware);
-                throw err;
-            }
+			// EIP155: v should be chain_id * 2 + {35, 36}
+			const signedChainId = Math.floor((tx.v[0] - 35) / 2);
+			if (signedChainId !== this._networkId) {
+				await this._destroyLedgerClientAsync();
+				const err = new Error(LedgerSubproviderErrors.TooOldLedgerFirmware);
+				throw err;
+			}
 
-            const signedTxHex = `0x${tx.serialize().toString('hex')}`;
-            await this._destroyLedgerClientAsync();
-            return signedTxHex;
-        } catch (err) {
-            await this._destroyLedgerClientAsync();
-            throw err;
-        }
-    }
-    public async signPersonalMessageAsync(data: string): Promise<string> {
-        this._ledgerClientIfExists = await this._createLedgerClientAsync();
-        try {
-            const derivationPath = this._getDerivationPath();
-            const result = await this._ledgerClientIfExists.signPersonalMessage_async(
-                derivationPath,
-                ethUtil.stripHexPrefix(data),
-            );
-            const v = result.v - 27;
-            let vHex = v.toString(16);
-            if (vHex.length < 2) {
-                vHex = `0${v}`;
-            }
-            const signature = `0x${result.r}${result.s}${vHex}`;
-            await this._destroyLedgerClientAsync();
-            return signature;
-        } catch (err) {
-            await this._destroyLedgerClientAsync();
-            throw err;
-        }
-    }
-    private _getDerivationPath() {
-        const derivationPath = `${this.getPath()}/${this._derivationPathIndex}`;
-        return derivationPath;
-    }
-    private async _createLedgerClientAsync(): Promise<LedgerEthereumClient> {
-        await this._connectionLock.wait();
-        if (!_.isUndefined(this._ledgerClientIfExists)) {
-            this._connectionLock.signal();
-            throw new Error(LedgerSubproviderErrors.MultipleOpenConnectionsDisallowed);
-        }
-        const ledgerEthereumClient = await this._ledgerEthereumClientFactoryAsync();
-        this._connectionLock.signal();
-        return ledgerEthereumClient;
-    }
-    private async _destroyLedgerClientAsync() {
-        await this._connectionLock.wait();
-        if (_.isUndefined(this._ledgerClientIfExists)) {
-            this._connectionLock.signal();
-            return;
-        }
-        await this._ledgerClientIfExists.comm.close_async();
-        this._ledgerClientIfExists = undefined;
-        this._connectionLock.signal();
-    }
-    private async _sendTransactionAsync(txParams: PartialTxParams): Promise<string> {
-        await this._nonceLock.wait();
-        try {
-            // fill in the extras
-            const filledParams = await this._populateMissingTxParamsAsync(txParams);
-            // sign it
-            const signedTx = await this.signTransactionAsync(filledParams);
-            // emit a submit
-            const payload = {
-                method: 'eth_sendRawTransaction',
-                params: [signedTx],
-            };
-            const result = await this.emitPayloadAsync(payload);
-            this._nonceLock.signal();
-            return result.result;
-        } catch (err) {
-            this._nonceLock.signal();
-            throw err;
-        }
-    }
-    private async _signTransactionWithoutSendingAsync(txParams: PartialTxParams): Promise<ResponseWithTxParams> {
-        await this._nonceLock.wait();
-        try {
-            // fill in the extras
-            const filledParams = await this._populateMissingTxParamsAsync(txParams);
-            // sign it
-            const signedTx = await this.signTransactionAsync(filledParams);
+			const signedTxHex = `0x${tx.serialize().toString('hex')}`;
+			await this._destroyLedgerClientAsync();
+			return signedTxHex;
+		} catch (err) {
+			await this._destroyLedgerClientAsync();
+			throw err;
+		}
+	}
+	public async signPersonalMessageAsync(data: string): Promise<string> {
+		this._ledgerClientIfExists = await this._createLedgerClientAsync();
+		try {
+			const derivationPath = this._getDerivationPath();
+			const result = await this._ledgerClientIfExists.signPersonalMessage_async(
+				derivationPath,
+				ethUtil.stripHexPrefix(data),
+			);
+			const v = result.v - 27;
+			let vHex = v.toString(16);
+			if (vHex.length < 2) {
+				vHex = `0${v}`;
+			}
+			const signature = `0x${result.r}${result.s}${vHex}`;
+			await this._destroyLedgerClientAsync();
+			return signature;
+		} catch (err) {
+			await this._destroyLedgerClientAsync();
+			throw err;
+		}
+	}
+	private _getDerivationPath() {
+		const derivationPath = `${this.getPath()}/${this._derivationPathIndex}`;
+		return derivationPath;
+	}
+	private async _createLedgerClientAsync(): Promise<LedgerEthereumClient> {
+		await this._connectionLock.wait();
+		if (!_.isUndefined(this._ledgerClientIfExists)) {
+			this._connectionLock.signal();
+			throw new Error(LedgerSubproviderErrors.MultipleOpenConnectionsDisallowed);
+		}
+		const ledgerEthereumClient = await this._ledgerEthereumClientFactoryAsync();
+		this._connectionLock.signal();
+		return ledgerEthereumClient;
+	}
+	private async _destroyLedgerClientAsync() {
+		await this._connectionLock.wait();
+		if (_.isUndefined(this._ledgerClientIfExists)) {
+			this._connectionLock.signal();
+			return;
+		}
+		await this._ledgerClientIfExists.comm.close_async();
+		this._ledgerClientIfExists = undefined;
+		this._connectionLock.signal();
+	}
+	private async _sendTransactionAsync(txParams: PartialTxParams): Promise<string> {
+		await this._nonceLock.wait();
+		try {
+			// fill in the extras
+			const filledParams = await this._populateMissingTxParamsAsync(txParams);
+			// sign it
+			const signedTx = await this.signTransactionAsync(filledParams);
+			// emit a submit
+			const payload = {
+				method: 'eth_sendRawTransaction',
+				params: [signedTx],
+			};
+			const result = await this.emitPayloadAsync(payload);
+			this._nonceLock.signal();
+			return result.result;
+		} catch (err) {
+			this._nonceLock.signal();
+			throw err;
+		}
+	}
+	private async _signTransactionWithoutSendingAsync(txParams: PartialTxParams): Promise<ResponseWithTxParams> {
+		await this._nonceLock.wait();
+		try {
+			// fill in the extras
+			const filledParams = await this._populateMissingTxParamsAsync(txParams);
+			// sign it
+			const signedTx = await this.signTransactionAsync(filledParams);
 
-            this._nonceLock.signal();
-            const result = {
-                raw: signedTx,
-                tx: txParams,
-            };
-            return result;
-        } catch (err) {
-            this._nonceLock.signal();
-            throw err;
-        }
-    }
-    private async _populateMissingTxParamsAsync(txParams: PartialTxParams): Promise<PartialTxParams> {
-        if (_.isUndefined(txParams.gasPrice)) {
-            const gasPriceResult = await this.emitPayloadAsync({
-                method: 'eth_gasPrice',
-                params: [],
-            });
-            const gasPrice = gasPriceResult.result.toString();
-            txParams.gasPrice = gasPrice;
-        }
-        if (_.isUndefined(txParams.nonce)) {
-            const nonceResult = await this.emitPayloadAsync({
-                method: 'eth_getTransactionCount',
-                params: [txParams.from, 'pending'],
-            });
-            const nonce = nonceResult.result;
-            txParams.nonce = nonce;
-        }
-        if (_.isUndefined(txParams.gas)) {
-            const gasResult = await this.emitPayloadAsync({
-                method: 'eth_estimateGas',
-                params: [txParams],
-            });
-            const gas = gasResult.result.toString();
-            txParams.gas = gas;
-        }
-        return txParams;
-    }
+			this._nonceLock.signal();
+			const result = {
+				raw: signedTx,
+				tx: txParams,
+			};
+			return result;
+		} catch (err) {
+			this._nonceLock.signal();
+			throw err;
+		}
+	}
+	private async _populateMissingTxParamsAsync(txParams: PartialTxParams): Promise<PartialTxParams> {
+		if (_.isUndefined(txParams.gasPrice)) {
+			const gasPriceResult = await this.emitPayloadAsync({
+				method: 'eth_gasPrice',
+				params: [],
+			});
+			const gasPrice = gasPriceResult.result.toString();
+			txParams.gasPrice = gasPrice;
+		}
+		if (_.isUndefined(txParams.nonce)) {
+			const nonceResult = await this.emitPayloadAsync({
+				method: 'eth_getTransactionCount',
+				params: [txParams.from, 'pending'],
+			});
+			const nonce = nonceResult.result;
+			txParams.nonce = nonce;
+		}
+		if (_.isUndefined(txParams.gas)) {
+			const gasResult = await this.emitPayloadAsync({
+				method: 'eth_estimateGas',
+				params: [txParams],
+			});
+			const gas = gasResult.result.toString();
+			txParams.gas = gas;
+		}
+		return txParams;
+	}
 }
diff --git a/packages/subproviders/src/subproviders/redundant_rpc.ts b/packages/subproviders/src/subproviders/redundant_rpc.ts
index a3cb463a8..92d7ae8ae 100644
--- a/packages/subproviders/src/subproviders/redundant_rpc.ts
+++ b/packages/subproviders/src/subproviders/redundant_rpc.ts
@@ -7,46 +7,46 @@ import { JSONRPCPayload } from '../types';
 import { Subprovider } from './subprovider';
 
 export class RedundantRPCSubprovider extends Subprovider {
-    private _rpcs: RpcSubprovider[];
-    private static async _firstSuccessAsync(
-        rpcs: RpcSubprovider[],
-        payload: JSONRPCPayload,
-        next: () => void,
-    ): Promise<any> {
-        let lastErr: Error | undefined;
-        for (const rpc of rpcs) {
-            try {
-                const data = await promisify(rpc.handleRequest.bind(rpc))(payload, next);
-                return data;
-            } catch (err) {
-                lastErr = err;
-                continue;
-            }
-        }
-        if (!_.isUndefined(lastErr)) {
-            throw lastErr;
-        }
-    }
-    constructor(endpoints: string[]) {
-        super();
-        this._rpcs = _.map(endpoints, endpoint => {
-            return new RpcSubprovider({
-                rpcUrl: endpoint,
-            });
-        });
-    }
-    // tslint:disable-next-line:async-suffix
-    public async handleRequest(
-        payload: JSONRPCPayload,
-        next: () => void,
-        end: (err: Error | null, data?: any) => void,
-    ): Promise<void> {
-        const rpcsCopy = this._rpcs.slice();
-        try {
-            const data = await RedundantRPCSubprovider._firstSuccessAsync(rpcsCopy, payload, next);
-            end(null, data);
-        } catch (err) {
-            end(err);
-        }
-    }
+	private _rpcs: RpcSubprovider[];
+	private static async _firstSuccessAsync(
+		rpcs: RpcSubprovider[],
+		payload: JSONRPCPayload,
+		next: () => void,
+	): Promise<any> {
+		let lastErr: Error | undefined;
+		for (const rpc of rpcs) {
+			try {
+				const data = await promisify(rpc.handleRequest.bind(rpc))(payload, next);
+				return data;
+			} catch (err) {
+				lastErr = err;
+				continue;
+			}
+		}
+		if (!_.isUndefined(lastErr)) {
+			throw lastErr;
+		}
+	}
+	constructor(endpoints: string[]) {
+		super();
+		this._rpcs = _.map(endpoints, endpoint => {
+			return new RpcSubprovider({
+				rpcUrl: endpoint,
+			});
+		});
+	}
+	// tslint:disable-next-line:async-suffix
+	public async handleRequest(
+		payload: JSONRPCPayload,
+		next: () => void,
+		end: (err: Error | null, data?: any) => void,
+	): Promise<void> {
+		const rpcsCopy = this._rpcs.slice();
+		try {
+			const data = await RedundantRPCSubprovider._firstSuccessAsync(rpcsCopy, payload, next);
+			end(null, data);
+		} catch (err) {
+			end(err);
+		}
+	}
 }
diff --git a/packages/subproviders/src/subproviders/subprovider.ts b/packages/subproviders/src/subproviders/subprovider.ts
index 6435c9f65..b6bb16918 100644
--- a/packages/subproviders/src/subproviders/subprovider.ts
+++ b/packages/subproviders/src/subproviders/subprovider.ts
@@ -8,33 +8,33 @@ import { JSONRPCPayload } from '../types';
  * Altered version of: https://github.com/MetaMask/provider-engine/blob/master/subproviders/subprovider.js
  */
 export class Subprovider {
-    private _engine: any;
-    // Ported from: https://github.com/MetaMask/provider-engine/blob/master/util/random-id.js
-    private static _getRandomId() {
-        const extraDigits = 3;
-        // 13 time digits
-        const datePart = new Date().getTime() * Math.pow(10, extraDigits);
-        // 3 random digits
-        const extraPart = Math.floor(Math.random() * Math.pow(10, extraDigits));
-        // 16 digits
-        return datePart + extraPart;
-    }
-    private static _createFinalPayload(payload: JSONRPCPayload): Web3.JSONRPCRequestPayload {
-        const finalPayload = {
-            // defaults
-            id: Subprovider._getRandomId(),
-            jsonrpc: '2.0',
-            params: [],
-            ...payload,
-        };
-        return finalPayload;
-    }
-    public setEngine(engine: any): void {
-        this._engine = engine;
-    }
-    public async emitPayloadAsync(payload: JSONRPCPayload): Promise<any> {
-        const finalPayload = Subprovider._createFinalPayload(payload);
-        const response = await promisify(this._engine.sendAsync, this._engine)(finalPayload);
-        return response;
-    }
+	private _engine: any;
+	// Ported from: https://github.com/MetaMask/provider-engine/blob/master/util/random-id.js
+	private static _getRandomId() {
+		const extraDigits = 3;
+		// 13 time digits
+		const datePart = new Date().getTime() * Math.pow(10, extraDigits);
+		// 3 random digits
+		const extraPart = Math.floor(Math.random() * Math.pow(10, extraDigits));
+		// 16 digits
+		return datePart + extraPart;
+	}
+	private static _createFinalPayload(payload: JSONRPCPayload): Web3.JSONRPCRequestPayload {
+		const finalPayload = {
+			// defaults
+			id: Subprovider._getRandomId(),
+			jsonrpc: '2.0',
+			params: [],
+			...payload,
+		};
+		return finalPayload;
+	}
+	public setEngine(engine: any): void {
+		this._engine = engine;
+	}
+	public async emitPayloadAsync(payload: JSONRPCPayload): Promise<any> {
+		const finalPayload = Subprovider._createFinalPayload(payload);
+		const response = await promisify(this._engine.sendAsync, this._engine)(finalPayload);
+		return response;
+	}
 }
diff --git a/packages/subproviders/src/types.ts b/packages/subproviders/src/types.ts
index 3db8be943..ec1eedd34 100644
--- a/packages/subproviders/src/types.ts
+++ b/packages/subproviders/src/types.ts
@@ -1,7 +1,7 @@
 import * as _ from 'lodash';
 
 export interface LedgerCommunicationClient {
-    close_async: () => Promise<void>;
+	close_async: () => Promise<void>;
 }
 
 /*
@@ -10,28 +10,28 @@ export interface LedgerCommunicationClient {
  * NodeJs and Browser communication are supported.
  */
 export interface LedgerEthereumClient {
-    // shouldGetChainCode is defined as `true` instead of `boolean` because other types rely on the assumption
-    // that we get back the chain code and we don't have dependent types to express it properly
-    getAddress_async: (
-        derivationPath: string,
-        askForDeviceConfirmation: boolean,
-        shouldGetChainCode: true,
-    ) => Promise<LedgerGetAddressResult>;
-    signPersonalMessage_async: (derivationPath: string, messageHex: string) => Promise<ECSignature>;
-    signTransaction_async: (derivationPath: string, txHex: string) => Promise<ECSignatureString>;
-    comm: LedgerCommunicationClient;
+	// shouldGetChainCode is defined as `true` instead of `boolean` because other types rely on the assumption
+	// that we get back the chain code and we don't have dependent types to express it properly
+	getAddress_async: (
+		derivationPath: string,
+		askForDeviceConfirmation: boolean,
+		shouldGetChainCode: true,
+	) => Promise<LedgerGetAddressResult>;
+	signPersonalMessage_async: (derivationPath: string, messageHex: string) => Promise<ECSignature>;
+	signTransaction_async: (derivationPath: string, txHex: string) => Promise<ECSignatureString>;
+	comm: LedgerCommunicationClient;
 }
 
 export interface ECSignatureString {
-    v: string;
-    r: string;
-    s: string;
+	v: string;
+	r: string;
+	s: string;
 }
 
 export interface ECSignature {
-    v: number;
-    r: string;
-    s: string;
+	v: number;
+	r: string;
+	s: string;
 }
 
 export type LedgerEthereumClientFactoryAsync = () => Promise<LedgerEthereumClient>;
@@ -43,10 +43,10 @@ export type LedgerEthereumClientFactoryAsync = () => Promise<LedgerEthereumClien
  * accountFetchingConfigs: configs related to fetching accounts from a Ledger
  */
 export interface LedgerSubproviderConfigs {
-    networkId: number;
-    ledgerEthereumClientFactoryAsync: LedgerEthereumClientFactoryAsync;
-    derivationPath?: string;
-    accountFetchingConfigs?: AccountFetchingConfigs;
+	networkId: number;
+	ledgerEthereumClientFactoryAsync: LedgerEthereumClientFactoryAsync;
+	derivationPath?: string;
+	accountFetchingConfigs?: AccountFetchingConfigs;
 }
 
 /*
@@ -55,60 +55,60 @@ export interface LedgerSubproviderConfigs {
  *                                   before fetching their addresses
  */
 export interface AccountFetchingConfigs {
-    numAddressesToReturn?: number;
-    shouldAskForOnDeviceConfirmation?: boolean;
+	numAddressesToReturn?: number;
+	shouldAskForOnDeviceConfirmation?: boolean;
 }
 
 export interface SignatureData {
-    hash: string;
-    r: string;
-    s: string;
-    v: number;
+	hash: string;
+	r: string;
+	s: string;
+	v: number;
 }
 
 export interface LedgerGetAddressResult {
-    address: string;
-    publicKey: string;
-    chainCode: string;
+	address: string;
+	publicKey: string;
+	chainCode: string;
 }
 
 export interface LedgerWalletSubprovider {
-    getPath: () => string;
-    setPath: (path: string) => void;
-    setPathIndex: (pathIndex: number) => void;
+	getPath: () => string;
+	setPath: (path: string) => void;
+	setPathIndex: (pathIndex: number) => void;
 }
 
 export interface PartialTxParams {
-    nonce: string;
-    gasPrice?: string;
-    gas: string;
-    to: string;
-    from?: string;
-    value?: string;
-    data?: string;
-    chainId: number; // EIP 155 chainId - mainnet: 1, ropsten: 3
+	nonce: string;
+	gasPrice?: string;
+	gas: string;
+	to: string;
+	from?: string;
+	value?: string;
+	data?: string;
+	chainId: number; // EIP 155 chainId - mainnet: 1, ropsten: 3
 }
 
 export type DoneCallback = (err?: Error) => void;
 
 export interface JSONRPCPayload {
-    params: any[];
-    method: string;
+	params: any[];
+	method: string;
 }
 
 export interface LedgerCommunication {
-    close_async: () => Promise<void>;
+	close_async: () => Promise<void>;
 }
 
 export interface ResponseWithTxParams {
-    raw: string;
-    tx: PartialTxParams;
+	raw: string;
+	tx: PartialTxParams;
 }
 
 export enum LedgerSubproviderErrors {
-    TooOldLedgerFirmware = 'TOO_OLD_LEDGER_FIRMWARE',
-    FromAddressMissingOrInvalid = 'FROM_ADDRESS_MISSING_OR_INVALID',
-    DataMissingForSignPersonalMessage = 'DATA_MISSING_FOR_SIGN_PERSONAL_MESSAGE',
-    SenderInvalidOrNotSupplied = 'SENDER_INVALID_OR_NOT_SUPPLIED',
-    MultipleOpenConnectionsDisallowed = 'MULTIPLE_OPEN_CONNECTIONS_DISALLOWED',
+	TooOldLedgerFirmware = 'TOO_OLD_LEDGER_FIRMWARE',
+	FromAddressMissingOrInvalid = 'FROM_ADDRESS_MISSING_OR_INVALID',
+	DataMissingForSignPersonalMessage = 'DATA_MISSING_FOR_SIGN_PERSONAL_MESSAGE',
+	SenderInvalidOrNotSupplied = 'SENDER_INVALID_OR_NOT_SUPPLIED',
+	MultipleOpenConnectionsDisallowed = 'MULTIPLE_OPEN_CONNECTIONS_DISALLOWED',
 }
diff --git a/packages/subproviders/test/chai_setup.ts b/packages/subproviders/test/chai_setup.ts
index a281bab6c..941a141d5 100644
--- a/packages/subproviders/test/chai_setup.ts
+++ b/packages/subproviders/test/chai_setup.ts
@@ -3,9 +3,9 @@ import chaiAsPromised = require('chai-as-promised');
 import * as dirtyChai from 'dirty-chai';
 
 export const chaiSetup = {
-    configure() {
-        chai.config.includeStack = true;
-        chai.use(dirtyChai);
-        chai.use(chaiAsPromised);
-    },
+	configure() {
+		chai.config.includeStack = true;
+		chai.use(dirtyChai);
+		chai.use(chaiAsPromised);
+	},
 };
diff --git a/packages/subproviders/test/integration/ledger_subprovider_test.ts b/packages/subproviders/test/integration/ledger_subprovider_test.ts
index 628b532d7..6c1de46aa 100644
--- a/packages/subproviders/test/integration/ledger_subprovider_test.ts
+++ b/packages/subproviders/test/integration/ledger_subprovider_test.ts
@@ -17,168 +17,168 @@ const expect = chai.expect;
 const TEST_RPC_ACCOUNT_0 = '0x5409ed021d9299bf6814279a6a1411a7e866a631';
 
 describe('LedgerSubprovider', () => {
-    let ledgerSubprovider: LedgerSubprovider;
-    const networkId: number = 42;
-    before(async () => {
-        ledgerSubprovider = new LedgerSubprovider({
-            networkId,
-            ledgerEthereumClientFactoryAsync: ledgerEthereumNodeJsClientFactoryAsync,
-        });
-    });
-    describe('direct method calls', () => {
-        it('returns a list of accounts', async () => {
-            const accounts = await ledgerSubprovider.getAccountsAsync();
-            expect(accounts[0]).to.not.be.an('undefined');
-            expect(accounts.length).to.be.equal(10);
-        });
-        it('signs a personal message', async () => {
-            const data = ethUtils.bufferToHex(ethUtils.toBuffer('hello world'));
-            const ecSignatureHex = await ledgerSubprovider.signPersonalMessageAsync(data);
-            expect(ecSignatureHex.length).to.be.equal(132);
-            expect(ecSignatureHex.substr(0, 2)).to.be.equal('0x');
-        });
-        it('signs a transaction', async () => {
-            const tx = {
-                nonce: '0x00',
-                gas: '0x2710',
-                to: '0x0000000000000000000000000000000000000000',
-                value: '0x00',
-                chainId: 3,
-            };
-            const txHex = await ledgerSubprovider.signTransactionAsync(tx);
-            expect(txHex).to.be.equal(
-                '0xf85f8080822710940000000000000000000000000000000000000000808077a088a95ef1378487bc82be558e82c8478baf840c545d5b887536bb1da63673a98ba0019f4a4b9a107d1e6752bf7f701e275f28c13791d6e76af895b07373462cefaa',
-            );
-        });
-    });
-    describe('calls through a provider', () => {
-        let defaultProvider: Web3ProviderEngine;
-        let ledgerProvider: Web3ProviderEngine;
-        before(() => {
-            ledgerProvider = new Web3ProviderEngine();
-            ledgerProvider.addProvider(ledgerSubprovider);
-            const httpProvider = new RpcSubprovider({
-                rpcUrl: 'http://localhost:8545',
-            });
-            ledgerProvider.addProvider(httpProvider);
-            ledgerProvider.start();
+	let ledgerSubprovider: LedgerSubprovider;
+	const networkId: number = 42;
+	before(async () => {
+		ledgerSubprovider = new LedgerSubprovider({
+			networkId,
+			ledgerEthereumClientFactoryAsync: ledgerEthereumNodeJsClientFactoryAsync,
+		});
+	});
+	describe('direct method calls', () => {
+		it('returns a list of accounts', async () => {
+			const accounts = await ledgerSubprovider.getAccountsAsync();
+			expect(accounts[0]).to.not.be.an('undefined');
+			expect(accounts.length).to.be.equal(10);
+		});
+		it('signs a personal message', async () => {
+			const data = ethUtils.bufferToHex(ethUtils.toBuffer('hello world'));
+			const ecSignatureHex = await ledgerSubprovider.signPersonalMessageAsync(data);
+			expect(ecSignatureHex.length).to.be.equal(132);
+			expect(ecSignatureHex.substr(0, 2)).to.be.equal('0x');
+		});
+		it('signs a transaction', async () => {
+			const tx = {
+				nonce: '0x00',
+				gas: '0x2710',
+				to: '0x0000000000000000000000000000000000000000',
+				value: '0x00',
+				chainId: 3,
+			};
+			const txHex = await ledgerSubprovider.signTransactionAsync(tx);
+			expect(txHex).to.be.equal(
+				'0xf85f8080822710940000000000000000000000000000000000000000808077a088a95ef1378487bc82be558e82c8478baf840c545d5b887536bb1da63673a98ba0019f4a4b9a107d1e6752bf7f701e275f28c13791d6e76af895b07373462cefaa',
+			);
+		});
+	});
+	describe('calls through a provider', () => {
+		let defaultProvider: Web3ProviderEngine;
+		let ledgerProvider: Web3ProviderEngine;
+		before(() => {
+			ledgerProvider = new Web3ProviderEngine();
+			ledgerProvider.addProvider(ledgerSubprovider);
+			const httpProvider = new RpcSubprovider({
+				rpcUrl: 'http://localhost:8545',
+			});
+			ledgerProvider.addProvider(httpProvider);
+			ledgerProvider.start();
 
-            defaultProvider = new Web3ProviderEngine();
-            defaultProvider.addProvider(httpProvider);
-            defaultProvider.start();
-        });
-        it('returns a list of accounts', (done: DoneCallback) => {
-            const payload = {
-                jsonrpc: '2.0',
-                method: 'eth_accounts',
-                params: [],
-                id: 1,
-            };
-            const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
-                expect(err).to.be.a('null');
-                expect(response.result.length).to.be.equal(10);
-                done();
-            });
-            ledgerProvider.sendAsync(payload, callback);
-        });
-        it('signs a personal message with eth_sign', (done: DoneCallback) => {
-            (async () => {
-                const messageHex = ethUtils.bufferToHex(ethUtils.toBuffer('hello world'));
-                const accounts = await ledgerSubprovider.getAccountsAsync();
-                const signer = accounts[0];
-                const payload = {
-                    jsonrpc: '2.0',
-                    method: 'eth_sign',
-                    params: [signer, messageHex],
-                    id: 1,
-                };
-                const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
-                    expect(err).to.be.a('null');
-                    expect(response.result.length).to.be.equal(132);
-                    expect(response.result.substr(0, 2)).to.be.equal('0x');
-                    done();
-                });
-                ledgerProvider.sendAsync(payload, callback);
-            })().catch(done);
-        });
-        it('signs a personal message with personal_sign', (done: DoneCallback) => {
-            (async () => {
-                const messageHex = ethUtils.bufferToHex(ethUtils.toBuffer('hello world'));
-                const accounts = await ledgerSubprovider.getAccountsAsync();
-                const signer = accounts[0];
-                const payload = {
-                    jsonrpc: '2.0',
-                    method: 'personal_sign',
-                    params: [messageHex, signer],
-                    id: 1,
-                };
-                const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
-                    expect(err).to.be.a('null');
-                    expect(response.result.length).to.be.equal(132);
-                    expect(response.result.substr(0, 2)).to.be.equal('0x');
-                    done();
-                });
-                ledgerProvider.sendAsync(payload, callback);
-            })().catch(done);
-        });
-        it('signs a transaction', (done: DoneCallback) => {
-            const tx = {
-                to: '0xafa3f8684e54059998bc3a7b0d2b0da075154d66',
-                value: '0x00',
-            };
-            const payload = {
-                jsonrpc: '2.0',
-                method: 'eth_signTransaction',
-                params: [tx],
-                id: 1,
-            };
-            const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
-                expect(err).to.be.a('null');
-                expect(response.result.raw.length).to.be.equal(206);
-                expect(response.result.raw.substr(0, 2)).to.be.equal('0x');
-                done();
-            });
-            ledgerProvider.sendAsync(payload, callback);
-        });
-        it('signs and sends a transaction', (done: DoneCallback) => {
-            (async () => {
-                const accounts = await ledgerSubprovider.getAccountsAsync();
+			defaultProvider = new Web3ProviderEngine();
+			defaultProvider.addProvider(httpProvider);
+			defaultProvider.start();
+		});
+		it('returns a list of accounts', (done: DoneCallback) => {
+			const payload = {
+				jsonrpc: '2.0',
+				method: 'eth_accounts',
+				params: [],
+				id: 1,
+			};
+			const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
+				expect(err).to.be.a('null');
+				expect(response.result.length).to.be.equal(10);
+				done();
+			});
+			ledgerProvider.sendAsync(payload, callback);
+		});
+		it('signs a personal message with eth_sign', (done: DoneCallback) => {
+			(async () => {
+				const messageHex = ethUtils.bufferToHex(ethUtils.toBuffer('hello world'));
+				const accounts = await ledgerSubprovider.getAccountsAsync();
+				const signer = accounts[0];
+				const payload = {
+					jsonrpc: '2.0',
+					method: 'eth_sign',
+					params: [signer, messageHex],
+					id: 1,
+				};
+				const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
+					expect(err).to.be.a('null');
+					expect(response.result.length).to.be.equal(132);
+					expect(response.result.substr(0, 2)).to.be.equal('0x');
+					done();
+				});
+				ledgerProvider.sendAsync(payload, callback);
+			})().catch(done);
+		});
+		it('signs a personal message with personal_sign', (done: DoneCallback) => {
+			(async () => {
+				const messageHex = ethUtils.bufferToHex(ethUtils.toBuffer('hello world'));
+				const accounts = await ledgerSubprovider.getAccountsAsync();
+				const signer = accounts[0];
+				const payload = {
+					jsonrpc: '2.0',
+					method: 'personal_sign',
+					params: [messageHex, signer],
+					id: 1,
+				};
+				const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
+					expect(err).to.be.a('null');
+					expect(response.result.length).to.be.equal(132);
+					expect(response.result.substr(0, 2)).to.be.equal('0x');
+					done();
+				});
+				ledgerProvider.sendAsync(payload, callback);
+			})().catch(done);
+		});
+		it('signs a transaction', (done: DoneCallback) => {
+			const tx = {
+				to: '0xafa3f8684e54059998bc3a7b0d2b0da075154d66',
+				value: '0x00',
+			};
+			const payload = {
+				jsonrpc: '2.0',
+				method: 'eth_signTransaction',
+				params: [tx],
+				id: 1,
+			};
+			const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
+				expect(err).to.be.a('null');
+				expect(response.result.raw.length).to.be.equal(206);
+				expect(response.result.raw.substr(0, 2)).to.be.equal('0x');
+				done();
+			});
+			ledgerProvider.sendAsync(payload, callback);
+		});
+		it('signs and sends a transaction', (done: DoneCallback) => {
+			(async () => {
+				const accounts = await ledgerSubprovider.getAccountsAsync();
 
-                // Give first account on Ledger sufficient ETH to complete tx send
-                let tx = {
-                    to: accounts[0],
-                    from: TEST_RPC_ACCOUNT_0,
-                    value: '0x8ac7230489e80000', // 10 ETH
-                };
-                let payload = {
-                    jsonrpc: '2.0',
-                    method: 'eth_sendTransaction',
-                    params: [tx],
-                    id: 1,
-                };
-                await promisify(defaultProvider.sendAsync, defaultProvider)(payload);
+				// Give first account on Ledger sufficient ETH to complete tx send
+				let tx = {
+					to: accounts[0],
+					from: TEST_RPC_ACCOUNT_0,
+					value: '0x8ac7230489e80000', // 10 ETH
+				};
+				let payload = {
+					jsonrpc: '2.0',
+					method: 'eth_sendTransaction',
+					params: [tx],
+					id: 1,
+				};
+				await promisify(defaultProvider.sendAsync, defaultProvider)(payload);
 
-                // Send transaction from Ledger
-                tx = {
-                    to: '0xafa3f8684e54059998bc3a7b0d2b0da075154d66',
-                    from: accounts[0],
-                    value: '0xde0b6b3a7640000',
-                };
-                payload = {
-                    jsonrpc: '2.0',
-                    method: 'eth_sendTransaction',
-                    params: [tx],
-                    id: 1,
-                };
-                const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
-                    expect(err).to.be.a('null');
-                    const result = response.result.result;
-                    expect(result.length).to.be.equal(66);
-                    expect(result.substr(0, 2)).to.be.equal('0x');
-                    done();
-                });
-                ledgerProvider.sendAsync(payload, callback);
-            })().catch(done);
-        });
-    });
+				// Send transaction from Ledger
+				tx = {
+					to: '0xafa3f8684e54059998bc3a7b0d2b0da075154d66',
+					from: accounts[0],
+					value: '0xde0b6b3a7640000',
+				};
+				payload = {
+					jsonrpc: '2.0',
+					method: 'eth_sendTransaction',
+					params: [tx],
+					id: 1,
+				};
+				const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
+					expect(err).to.be.a('null');
+					const result = response.result.result;
+					expect(result.length).to.be.equal(66);
+					expect(result.substr(0, 2)).to.be.equal('0x');
+					done();
+				});
+				ledgerProvider.sendAsync(payload, callback);
+			})().catch(done);
+		});
+	});
 });
diff --git a/packages/subproviders/test/unit/ledger_subprovider_test.ts b/packages/subproviders/test/unit/ledger_subprovider_test.ts
index 1c70dd3a6..101b6b906 100644
--- a/packages/subproviders/test/unit/ledger_subprovider_test.ts
+++ b/packages/subproviders/test/unit/ledger_subprovider_test.ts
@@ -15,230 +15,230 @@ const expect = chai.expect;
 const FAKE_ADDRESS = '0xb088a3bc93f71b4de97b9de773e9647645983688';
 
 describe('LedgerSubprovider', () => {
-    const networkId: number = 42;
-    let ledgerSubprovider: LedgerSubprovider;
-    before(async () => {
-        const ledgerEthereumClientFactoryAsync = async () => {
-            // tslint:disable:no-object-literal-type-assertion
-            const ledgerEthClient = {
-                getAddress_async: async () => {
-                    const publicKey =
-                        '04f428290f4c5ed6a198f71b8205f488141dbb3f0840c923bbfa798ecbee6370986c03b5575d94d506772fb48a6a44e345e4ebd4f028a6f609c44b655d6d3e71a1';
-                    const chainCode = 'ac055a5537c0c7e9e02d14a197cad6b857836da2a12043b46912a37d959b5ae8';
-                    const address = '0xBa388BA5e5EEF2c6cE42d831c2B3A28D3c99bdB1';
-                    return {
-                        publicKey,
-                        address,
-                        chainCode,
-                    };
-                },
-                signPersonalMessage_async: async () => {
-                    const ecSignature = {
-                        v: 28,
-                        r: 'a6cc284bff14b42bdf5e9286730c152be91719d478605ec46b3bebcd0ae49148',
-                        s: '0652a1a7b742ceb0213d1e744316e285f41f878d8af0b8e632cbca4c279132d0',
-                    };
-                    return ecSignature;
-                },
-                signTransaction_async: async (derivationPath: string, txHex: string) => {
-                    const ecSignature = {
-                        v: '77',
-                        r: '88a95ef1378487bc82be558e82c8478baf840c545d5b887536bb1da63673a98b',
-                        s: '019f4a4b9a107d1e6752bf7f701e275f28c13791d6e76af895b07373462cefaa',
-                    };
-                    return ecSignature;
-                },
-                comm: {
-                    close_async: _.noop,
-                } as LedgerCommunicationClient,
-            };
-            // tslint:enable:no-object-literal-type-assertion
-            return ledgerEthClient;
-        };
-        ledgerSubprovider = new LedgerSubprovider({
-            networkId,
-            ledgerEthereumClientFactoryAsync,
-        });
-    });
-    describe('direct method calls', () => {
-        describe('success cases', () => {
-            it('returns a list of accounts', async () => {
-                const accounts = await ledgerSubprovider.getAccountsAsync();
-                expect(accounts[0]).to.be.equal(FAKE_ADDRESS);
-                expect(accounts.length).to.be.equal(10);
-            });
-            it('signs a personal message', async () => {
-                const data = ethUtils.bufferToHex(ethUtils.toBuffer('hello world'));
-                const ecSignatureHex = await ledgerSubprovider.signPersonalMessageAsync(data);
-                expect(ecSignatureHex).to.be.equal(
-                    '0xa6cc284bff14b42bdf5e9286730c152be91719d478605ec46b3bebcd0ae491480652a1a7b742ceb0213d1e744316e285f41f878d8af0b8e632cbca4c279132d001',
-                );
-            });
-        });
-        describe('failure cases', () => {
-            it('cannot open multiple simultaneous connections to the Ledger device', async () => {
-                const data = ethUtils.bufferToHex(ethUtils.toBuffer('hello world'));
-                return expect(
-                    Promise.all([
-                        ledgerSubprovider.getAccountsAsync(),
-                        ledgerSubprovider.signPersonalMessageAsync(data),
-                    ]),
-                ).to.be.rejectedWith(LedgerSubproviderErrors.MultipleOpenConnectionsDisallowed);
-            });
-        });
-    });
-    describe('calls through a provider', () => {
-        let provider: Web3ProviderEngine;
-        before(() => {
-            provider = new Web3ProviderEngine();
-            provider.addProvider(ledgerSubprovider);
-            const httpProvider = new RpcSubprovider({
-                rpcUrl: 'http://localhost:8545',
-            });
-            provider.addProvider(httpProvider);
-            provider.start();
-        });
-        describe('success cases', () => {
-            it('returns a list of accounts', (done: DoneCallback) => {
-                const payload = {
-                    jsonrpc: '2.0',
-                    method: 'eth_accounts',
-                    params: [],
-                    id: 1,
-                };
-                const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
-                    expect(err).to.be.a('null');
-                    expect(response.result.length).to.be.equal(10);
-                    expect(response.result[0]).to.be.equal(FAKE_ADDRESS);
-                    done();
-                });
-                provider.sendAsync(payload, callback);
-            });
-            it('signs a personal message with eth_sign', (done: DoneCallback) => {
-                const messageHex = ethUtils.bufferToHex(ethUtils.toBuffer('hello world'));
-                const payload = {
-                    jsonrpc: '2.0',
-                    method: 'eth_sign',
-                    params: ['0x0000000000000000000000000000000000000000', messageHex],
-                    id: 1,
-                };
-                const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
-                    expect(err).to.be.a('null');
-                    expect(response.result).to.be.equal(
-                        '0xa6cc284bff14b42bdf5e9286730c152be91719d478605ec46b3bebcd0ae491480652a1a7b742ceb0213d1e744316e285f41f878d8af0b8e632cbca4c279132d001',
-                    );
-                    done();
-                });
-                provider.sendAsync(payload, callback);
-            });
-            it('signs a personal message with personal_sign', (done: DoneCallback) => {
-                const messageHex = ethUtils.bufferToHex(ethUtils.toBuffer('hello world'));
-                const payload = {
-                    jsonrpc: '2.0',
-                    method: 'personal_sign',
-                    params: [messageHex, '0x0000000000000000000000000000000000000000'],
-                    id: 1,
-                };
-                const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
-                    expect(err).to.be.a('null');
-                    expect(response.result).to.be.equal(
-                        '0xa6cc284bff14b42bdf5e9286730c152be91719d478605ec46b3bebcd0ae491480652a1a7b742ceb0213d1e744316e285f41f878d8af0b8e632cbca4c279132d001',
-                    );
-                    done();
-                });
-                provider.sendAsync(payload, callback);
-            });
-            it('signs a transaction', (done: DoneCallback) => {
-                const tx = {
-                    to: '0xafa3f8684e54059998bc3a7b0d2b0da075154d66',
-                    value: '0x00',
-                    gasPrice: '0x00',
-                    nonce: '0x00',
-                    gas: '0x00',
-                };
-                const payload = {
-                    jsonrpc: '2.0',
-                    method: 'eth_signTransaction',
-                    params: [tx],
-                    id: 1,
-                };
-                const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
-                    expect(err).to.be.a('null');
-                    expect(response.result.raw.length).to.be.equal(192);
-                    expect(response.result.raw.substr(0, 2)).to.be.equal('0x');
-                    done();
-                });
-                provider.sendAsync(payload, callback);
-            });
-        });
-        describe('failure cases', () => {
-            it('should throw if `data` param not hex when calling eth_sign', (done: DoneCallback) => {
-                const nonHexMessage = 'hello world';
-                const payload = {
-                    jsonrpc: '2.0',
-                    method: 'eth_sign',
-                    params: ['0x0000000000000000000000000000000000000000', nonHexMessage],
-                    id: 1,
-                };
-                const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
-                    expect(err).to.not.be.a('null');
-                    expect(err.message).to.be.equal('Expected data to be of type HexString, encountered: hello world');
-                    done();
-                });
-                provider.sendAsync(payload, callback);
-            });
-            it('should throw if `data` param not hex when calling personal_sign', (done: DoneCallback) => {
-                const nonHexMessage = 'hello world';
-                const payload = {
-                    jsonrpc: '2.0',
-                    method: 'personal_sign',
-                    params: [nonHexMessage, '0x0000000000000000000000000000000000000000'],
-                    id: 1,
-                };
-                const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
-                    expect(err).to.not.be.a('null');
-                    expect(err.message).to.be.equal('Expected data to be of type HexString, encountered: hello world');
-                    done();
-                });
-                provider.sendAsync(payload, callback);
-            });
-            it('should throw if `from` param missing when calling eth_sendTransaction', (done: DoneCallback) => {
-                const tx = {
-                    to: '0xafa3f8684e54059998bc3a7b0d2b0da075154d66',
-                    value: '0xde0b6b3a7640000',
-                };
-                const payload = {
-                    jsonrpc: '2.0',
-                    method: 'eth_sendTransaction',
-                    params: [tx],
-                    id: 1,
-                };
-                const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
-                    expect(err).to.not.be.a('null');
-                    expect(err.message).to.be.equal(LedgerSubproviderErrors.SenderInvalidOrNotSupplied);
-                    done();
-                });
-                provider.sendAsync(payload, callback);
-            });
-            it('should throw if `from` param invalid address when calling eth_sendTransaction', (done: DoneCallback) => {
-                const tx = {
-                    to: '0xafa3f8684e54059998bc3a7b0d2b0da075154d66',
-                    from: '0xIncorrectEthereumAddress',
-                    value: '0xde0b6b3a7640000',
-                };
-                const payload = {
-                    jsonrpc: '2.0',
-                    method: 'eth_sendTransaction',
-                    params: [tx],
-                    id: 1,
-                };
-                const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
-                    expect(err).to.not.be.a('null');
-                    expect(err.message).to.be.equal(LedgerSubproviderErrors.SenderInvalidOrNotSupplied);
-                    done();
-                });
-                provider.sendAsync(payload, callback);
-            });
-        });
-    });
+	const networkId: number = 42;
+	let ledgerSubprovider: LedgerSubprovider;
+	before(async () => {
+		const ledgerEthereumClientFactoryAsync = async () => {
+			// tslint:disable:no-object-literal-type-assertion
+			const ledgerEthClient = {
+				getAddress_async: async () => {
+					const publicKey =
+						'04f428290f4c5ed6a198f71b8205f488141dbb3f0840c923bbfa798ecbee6370986c03b5575d94d506772fb48a6a44e345e4ebd4f028a6f609c44b655d6d3e71a1';
+					const chainCode = 'ac055a5537c0c7e9e02d14a197cad6b857836da2a12043b46912a37d959b5ae8';
+					const address = '0xBa388BA5e5EEF2c6cE42d831c2B3A28D3c99bdB1';
+					return {
+						publicKey,
+						address,
+						chainCode,
+					};
+				},
+				signPersonalMessage_async: async () => {
+					const ecSignature = {
+						v: 28,
+						r: 'a6cc284bff14b42bdf5e9286730c152be91719d478605ec46b3bebcd0ae49148',
+						s: '0652a1a7b742ceb0213d1e744316e285f41f878d8af0b8e632cbca4c279132d0',
+					};
+					return ecSignature;
+				},
+				signTransaction_async: async (derivationPath: string, txHex: string) => {
+					const ecSignature = {
+						v: '77',
+						r: '88a95ef1378487bc82be558e82c8478baf840c545d5b887536bb1da63673a98b',
+						s: '019f4a4b9a107d1e6752bf7f701e275f28c13791d6e76af895b07373462cefaa',
+					};
+					return ecSignature;
+				},
+				comm: {
+					close_async: _.noop,
+				} as LedgerCommunicationClient,
+			};
+			// tslint:enable:no-object-literal-type-assertion
+			return ledgerEthClient;
+		};
+		ledgerSubprovider = new LedgerSubprovider({
+			networkId,
+			ledgerEthereumClientFactoryAsync,
+		});
+	});
+	describe('direct method calls', () => {
+		describe('success cases', () => {
+			it('returns a list of accounts', async () => {
+				const accounts = await ledgerSubprovider.getAccountsAsync();
+				expect(accounts[0]).to.be.equal(FAKE_ADDRESS);
+				expect(accounts.length).to.be.equal(10);
+			});
+			it('signs a personal message', async () => {
+				const data = ethUtils.bufferToHex(ethUtils.toBuffer('hello world'));
+				const ecSignatureHex = await ledgerSubprovider.signPersonalMessageAsync(data);
+				expect(ecSignatureHex).to.be.equal(
+					'0xa6cc284bff14b42bdf5e9286730c152be91719d478605ec46b3bebcd0ae491480652a1a7b742ceb0213d1e744316e285f41f878d8af0b8e632cbca4c279132d001',
+				);
+			});
+		});
+		describe('failure cases', () => {
+			it('cannot open multiple simultaneous connections to the Ledger device', async () => {
+				const data = ethUtils.bufferToHex(ethUtils.toBuffer('hello world'));
+				return expect(
+					Promise.all([
+						ledgerSubprovider.getAccountsAsync(),
+						ledgerSubprovider.signPersonalMessageAsync(data),
+					]),
+				).to.be.rejectedWith(LedgerSubproviderErrors.MultipleOpenConnectionsDisallowed);
+			});
+		});
+	});
+	describe('calls through a provider', () => {
+		let provider: Web3ProviderEngine;
+		before(() => {
+			provider = new Web3ProviderEngine();
+			provider.addProvider(ledgerSubprovider);
+			const httpProvider = new RpcSubprovider({
+				rpcUrl: 'http://localhost:8545',
+			});
+			provider.addProvider(httpProvider);
+			provider.start();
+		});
+		describe('success cases', () => {
+			it('returns a list of accounts', (done: DoneCallback) => {
+				const payload = {
+					jsonrpc: '2.0',
+					method: 'eth_accounts',
+					params: [],
+					id: 1,
+				};
+				const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
+					expect(err).to.be.a('null');
+					expect(response.result.length).to.be.equal(10);
+					expect(response.result[0]).to.be.equal(FAKE_ADDRESS);
+					done();
+				});
+				provider.sendAsync(payload, callback);
+			});
+			it('signs a personal message with eth_sign', (done: DoneCallback) => {
+				const messageHex = ethUtils.bufferToHex(ethUtils.toBuffer('hello world'));
+				const payload = {
+					jsonrpc: '2.0',
+					method: 'eth_sign',
+					params: ['0x0000000000000000000000000000000000000000', messageHex],
+					id: 1,
+				};
+				const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
+					expect(err).to.be.a('null');
+					expect(response.result).to.be.equal(
+						'0xa6cc284bff14b42bdf5e9286730c152be91719d478605ec46b3bebcd0ae491480652a1a7b742ceb0213d1e744316e285f41f878d8af0b8e632cbca4c279132d001',
+					);
+					done();
+				});
+				provider.sendAsync(payload, callback);
+			});
+			it('signs a personal message with personal_sign', (done: DoneCallback) => {
+				const messageHex = ethUtils.bufferToHex(ethUtils.toBuffer('hello world'));
+				const payload = {
+					jsonrpc: '2.0',
+					method: 'personal_sign',
+					params: [messageHex, '0x0000000000000000000000000000000000000000'],
+					id: 1,
+				};
+				const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
+					expect(err).to.be.a('null');
+					expect(response.result).to.be.equal(
+						'0xa6cc284bff14b42bdf5e9286730c152be91719d478605ec46b3bebcd0ae491480652a1a7b742ceb0213d1e744316e285f41f878d8af0b8e632cbca4c279132d001',
+					);
+					done();
+				});
+				provider.sendAsync(payload, callback);
+			});
+			it('signs a transaction', (done: DoneCallback) => {
+				const tx = {
+					to: '0xafa3f8684e54059998bc3a7b0d2b0da075154d66',
+					value: '0x00',
+					gasPrice: '0x00',
+					nonce: '0x00',
+					gas: '0x00',
+				};
+				const payload = {
+					jsonrpc: '2.0',
+					method: 'eth_signTransaction',
+					params: [tx],
+					id: 1,
+				};
+				const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
+					expect(err).to.be.a('null');
+					expect(response.result.raw.length).to.be.equal(192);
+					expect(response.result.raw.substr(0, 2)).to.be.equal('0x');
+					done();
+				});
+				provider.sendAsync(payload, callback);
+			});
+		});
+		describe('failure cases', () => {
+			it('should throw if `data` param not hex when calling eth_sign', (done: DoneCallback) => {
+				const nonHexMessage = 'hello world';
+				const payload = {
+					jsonrpc: '2.0',
+					method: 'eth_sign',
+					params: ['0x0000000000000000000000000000000000000000', nonHexMessage],
+					id: 1,
+				};
+				const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
+					expect(err).to.not.be.a('null');
+					expect(err.message).to.be.equal('Expected data to be of type HexString, encountered: hello world');
+					done();
+				});
+				provider.sendAsync(payload, callback);
+			});
+			it('should throw if `data` param not hex when calling personal_sign', (done: DoneCallback) => {
+				const nonHexMessage = 'hello world';
+				const payload = {
+					jsonrpc: '2.0',
+					method: 'personal_sign',
+					params: [nonHexMessage, '0x0000000000000000000000000000000000000000'],
+					id: 1,
+				};
+				const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
+					expect(err).to.not.be.a('null');
+					expect(err.message).to.be.equal('Expected data to be of type HexString, encountered: hello world');
+					done();
+				});
+				provider.sendAsync(payload, callback);
+			});
+			it('should throw if `from` param missing when calling eth_sendTransaction', (done: DoneCallback) => {
+				const tx = {
+					to: '0xafa3f8684e54059998bc3a7b0d2b0da075154d66',
+					value: '0xde0b6b3a7640000',
+				};
+				const payload = {
+					jsonrpc: '2.0',
+					method: 'eth_sendTransaction',
+					params: [tx],
+					id: 1,
+				};
+				const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
+					expect(err).to.not.be.a('null');
+					expect(err.message).to.be.equal(LedgerSubproviderErrors.SenderInvalidOrNotSupplied);
+					done();
+				});
+				provider.sendAsync(payload, callback);
+			});
+			it('should throw if `from` param invalid address when calling eth_sendTransaction', (done: DoneCallback) => {
+				const tx = {
+					to: '0xafa3f8684e54059998bc3a7b0d2b0da075154d66',
+					from: '0xIncorrectEthereumAddress',
+					value: '0xde0b6b3a7640000',
+				};
+				const payload = {
+					jsonrpc: '2.0',
+					method: 'eth_sendTransaction',
+					params: [tx],
+					id: 1,
+				};
+				const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
+					expect(err).to.not.be.a('null');
+					expect(err.message).to.be.equal(LedgerSubproviderErrors.SenderInvalidOrNotSupplied);
+					done();
+				});
+				provider.sendAsync(payload, callback);
+			});
+		});
+	});
 });
diff --git a/packages/subproviders/test/unit/redundant_rpc_subprovider_test.ts b/packages/subproviders/test/unit/redundant_rpc_subprovider_test.ts
index c3170745c..defb741dd 100644
--- a/packages/subproviders/test/unit/redundant_rpc_subprovider_test.ts
+++ b/packages/subproviders/test/unit/redundant_rpc_subprovider_test.ts
@@ -12,45 +12,45 @@ const expect = chai.expect;
 chaiSetup.configure();
 
 describe('RedundantRpcSubprovider', () => {
-    let provider: Web3ProviderEngine;
-    it('succeeds when supplied a healthy endpoint', (done: DoneCallback) => {
-        provider = new Web3ProviderEngine();
-        const endpoints = ['http://localhost:8545'];
-        const redundantSubprovider = new RedundantRPCSubprovider(endpoints);
-        provider.addProvider(redundantSubprovider);
-        provider.start();
+	let provider: Web3ProviderEngine;
+	it('succeeds when supplied a healthy endpoint', (done: DoneCallback) => {
+		provider = new Web3ProviderEngine();
+		const endpoints = ['http://localhost:8545'];
+		const redundantSubprovider = new RedundantRPCSubprovider(endpoints);
+		provider.addProvider(redundantSubprovider);
+		provider.start();
 
-        const payload = {
-            jsonrpc: '2.0',
-            method: 'eth_accounts',
-            params: [],
-            id: 1,
-        };
-        const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
-            expect(err).to.be.a('null');
-            expect(response.result.length).to.be.equal(10);
-            done();
-        });
-        provider.sendAsync(payload, callback);
-    });
-    it('succeeds when supplied at least one healthy endpoint', (done: DoneCallback) => {
-        provider = new Web3ProviderEngine();
-        const endpoints = ['http://does-not-exist:3000', 'http://localhost:8545'];
-        const redundantSubprovider = new RedundantRPCSubprovider(endpoints);
-        provider.addProvider(redundantSubprovider);
-        provider.start();
+		const payload = {
+			jsonrpc: '2.0',
+			method: 'eth_accounts',
+			params: [],
+			id: 1,
+		};
+		const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
+			expect(err).to.be.a('null');
+			expect(response.result.length).to.be.equal(10);
+			done();
+		});
+		provider.sendAsync(payload, callback);
+	});
+	it('succeeds when supplied at least one healthy endpoint', (done: DoneCallback) => {
+		provider = new Web3ProviderEngine();
+		const endpoints = ['http://does-not-exist:3000', 'http://localhost:8545'];
+		const redundantSubprovider = new RedundantRPCSubprovider(endpoints);
+		provider.addProvider(redundantSubprovider);
+		provider.start();
 
-        const payload = {
-            jsonrpc: '2.0',
-            method: 'eth_accounts',
-            params: [],
-            id: 1,
-        };
-        const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
-            expect(err).to.be.a('null');
-            expect(response.result.length).to.be.equal(10);
-            done();
-        });
-        provider.sendAsync(payload, callback);
-    });
+		const payload = {
+			jsonrpc: '2.0',
+			method: 'eth_accounts',
+			params: [],
+			id: 1,
+		};
+		const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
+			expect(err).to.be.a('null');
+			expect(response.result.length).to.be.equal(10);
+			done();
+		});
+		provider.sendAsync(payload, callback);
+	});
 });
diff --git a/packages/subproviders/test/utils/report_callback_errors.ts b/packages/subproviders/test/utils/report_callback_errors.ts
index 8a8f4d966..e6aadfa84 100644
--- a/packages/subproviders/test/utils/report_callback_errors.ts
+++ b/packages/subproviders/test/utils/report_callback_errors.ts
@@ -1,14 +1,14 @@
 import { DoneCallback } from '../../src/types';
 
 export const reportCallbackErrors = (done: DoneCallback) => {
-    return (f: (...args: any[]) => void) => {
-        const wrapped = async (...args: any[]) => {
-            try {
-                f(...args);
-            } catch (err) {
-                done(err);
-            }
-        };
-        return wrapped;
-    };
+	return (f: (...args: any[]) => void) => {
+		const wrapped = async (...args: any[]) => {
+			try {
+				f(...args);
+			} catch (err) {
+				done(err);
+			}
+		};
+		return wrapped;
+	};
 };
diff --git a/packages/subproviders/tsconfig.json b/packages/subproviders/tsconfig.json
index 9a65a0a97..4d92e88a5 100644
--- a/packages/subproviders/tsconfig.json
+++ b/packages/subproviders/tsconfig.json
@@ -1,15 +1,15 @@
 {
-    "extends": "../../tsconfig",
-    "compilerOptions": {
-        "outDir": "lib"
-    },
-    "include": [
-        "./src/**/*",
-        "./test/**/*",
-        "../../node_modules/chai-typescript-typings/index.d.ts",
-        "../../node_modules/web3-typescript-typings/index.d.ts",
-        "../../node_modules/types-bn/index.d.ts",
-        "../../node_modules/types-ethereumjs-util/index.d.ts",
-        "../../node_modules/chai-as-promised-typescript-typings/index.d.ts"
-    ]
+	"extends": "../../tsconfig",
+	"compilerOptions": {
+		"outDir": "lib"
+	},
+	"include": [
+		"./src/**/*",
+		"./test/**/*",
+		"../../node_modules/chai-typescript-typings/index.d.ts",
+		"../../node_modules/web3-typescript-typings/index.d.ts",
+		"../../node_modules/types-bn/index.d.ts",
+		"../../node_modules/types-ethereumjs-util/index.d.ts",
+		"../../node_modules/chai-as-promised-typescript-typings/index.d.ts"
+	]
 }
diff --git a/packages/subproviders/tslint.json b/packages/subproviders/tslint.json
index ffaefe83a..e63054bfc 100644
--- a/packages/subproviders/tslint.json
+++ b/packages/subproviders/tslint.json
@@ -1,3 +1,3 @@
 {
-    "extends": ["@0xproject/tslint-config"]
+	"extends": ["@0xproject/tslint-config"]
 }
diff --git a/packages/testnet-faucets/README.md b/packages/testnet-faucets/README.md
index a52d16a00..36322e76e 100644
--- a/packages/testnet-faucets/README.md
+++ b/packages/testnet-faucets/README.md
@@ -63,26 +63,26 @@ Returns a JSON payload describing the state of the queues for each network. For
 
 ```json
 {
-    "3": {
-        "ether": {
-            "full": false,
-            "size": 4
-        },
-        "zrx": {
-            "full": false,
-            "size": 6
-        }
-    },
-    "42": {
-        "ether": {
-            "full": false,
-            "size": 8
-        },
-        "zrx": {
-            "full": false,
-            "size": 20
-        }
-    }
+	"3": {
+		"ether": {
+			"full": false,
+			"size": 4
+		},
+		"zrx": {
+			"full": false,
+			"size": 6
+		}
+	},
+	"42": {
+		"ether": {
+			"full": false,
+			"size": 8
+		},
+		"zrx": {
+			"full": false,
+			"size": 20
+		}
+	}
 }
 ```
 
diff --git a/packages/testnet-faucets/package.json b/packages/testnet-faucets/package.json
index 6c27df0d5..4f8bcfdcf 100644
--- a/packages/testnet-faucets/package.json
+++ b/packages/testnet-faucets/package.json
@@ -1,43 +1,43 @@
 {
-    "private": true,
-    "name": "@0xproject/testnet-faucets",
-    "version": "1.0.7",
-    "description": "A faucet micro-service that dispenses test ERC20 tokens or Ether",
-    "main": "server.js",
-    "scripts": {
-        "build": "node ../../node_modules/gulp/bin/gulp.js build",
-        "dev": "node ../../node_modules/gulp/bin/gulp.js run",
-        "start": "node ./bin/server.js",
-        "lint": "tslint --project . 'src/**/*.ts'",
-        "clean": "shx rm -rf bin"
-    },
-    "author": "Fabio Berger",
-    "license": "Apache-2.0",
-    "dependencies": {
-        "0x.js": "^0.30.2",
-        "@0xproject/utils": "^0.2.2",
-        "body-parser": "^1.17.1",
-        "ethereumjs-tx": "^1.3.3",
-        "express": "^4.15.2",
-        "lodash": "^4.17.4",
-        "rollbar": "^0.6.5",
-        "web3": "^0.20.0",
-        "web3-provider-engine": "^13.0.1"
-    },
-    "devDependencies": {
-        "@0xproject/tslint-config": "^0.4.4",
-        "@types/body-parser": "^1.16.1",
-        "@types/express": "^4.0.35",
-        "@types/lodash": "^4.14.86",
-        "awesome-typescript-loader": "^3.1.3",
-        "gulp": "^3.9.1",
-        "nodemon": "^1.11.0",
-        "shx": "^0.2.2",
-        "source-map-loader": "^0.1.6",
-        "tslint": "5.8.0",
-        "typescript": "~2.6.1",
-        "web3-typescript-typings": "^0.9.6",
-        "webpack": "^3.1.0",
-        "webpack-node-externals": "^1.6.0"
-    }
+	"private": true,
+	"name": "@0xproject/testnet-faucets",
+	"version": "1.0.7",
+	"description": "A faucet micro-service that dispenses test ERC20 tokens or Ether",
+	"main": "server.js",
+	"scripts": {
+		"build": "node ../../node_modules/gulp/bin/gulp.js build",
+		"dev": "node ../../node_modules/gulp/bin/gulp.js run",
+		"start": "node ./bin/server.js",
+		"lint": "tslint --project . 'src/**/*.ts'",
+		"clean": "shx rm -rf bin"
+	},
+	"author": "Fabio Berger",
+	"license": "Apache-2.0",
+	"dependencies": {
+		"0x.js": "^0.30.2",
+		"@0xproject/utils": "^0.2.2",
+		"body-parser": "^1.17.1",
+		"ethereumjs-tx": "^1.3.3",
+		"express": "^4.15.2",
+		"lodash": "^4.17.4",
+		"rollbar": "^0.6.5",
+		"web3": "^0.20.0",
+		"web3-provider-engine": "^13.0.1"
+	},
+	"devDependencies": {
+		"@0xproject/tslint-config": "^0.4.4",
+		"@types/body-parser": "^1.16.1",
+		"@types/express": "^4.0.35",
+		"@types/lodash": "^4.14.86",
+		"awesome-typescript-loader": "^3.1.3",
+		"gulp": "^3.9.1",
+		"nodemon": "^1.11.0",
+		"shx": "^0.2.2",
+		"source-map-loader": "^0.1.6",
+		"tslint": "5.8.0",
+		"typescript": "~2.6.1",
+		"web3-typescript-typings": "^0.9.6",
+		"webpack": "^3.1.0",
+		"webpack-node-externals": "^1.6.0"
+	}
 }
diff --git a/packages/testnet-faucets/src/ts/configs.ts b/packages/testnet-faucets/src/ts/configs.ts
index 038c8e22a..038df5322 100644
--- a/packages/testnet-faucets/src/ts/configs.ts
+++ b/packages/testnet-faucets/src/ts/configs.ts
@@ -1,7 +1,7 @@
 export const configs = {
-    DISPENSER_ADDRESS: (process.env.DISPENSER_ADDRESS as string).toLowerCase(),
-    DISPENSER_PRIVATE_KEY: process.env.DISPENSER_PRIVATE_KEY,
-    ENVIRONMENT: process.env.FAUCET_ENVIRONMENT,
-    INFURA_API_KEY: process.env.INFURA_API_KEY,
-    ROLLBAR_ACCESS_KEY: process.env.FAUCET_ROLLBAR_ACCESS_KEY,
+	DISPENSER_ADDRESS: (process.env.DISPENSER_ADDRESS as string).toLowerCase(),
+	DISPENSER_PRIVATE_KEY: process.env.DISPENSER_PRIVATE_KEY,
+	ENVIRONMENT: process.env.FAUCET_ENVIRONMENT,
+	INFURA_API_KEY: process.env.INFURA_API_KEY,
+	ROLLBAR_ACCESS_KEY: process.env.FAUCET_ROLLBAR_ACCESS_KEY,
 };
diff --git a/packages/testnet-faucets/src/ts/error_reporter.ts b/packages/testnet-faucets/src/ts/error_reporter.ts
index 6865d3893..0cef6cfa8 100644
--- a/packages/testnet-faucets/src/ts/error_reporter.ts
+++ b/packages/testnet-faucets/src/ts/error_reporter.ts
@@ -5,36 +5,36 @@ import { configs } from './configs';
 import { utils } from './utils';
 
 export const errorReporter = {
-    setup() {
-        rollbar.init(configs.ROLLBAR_ACCESS_KEY, {
-            environment: configs.ENVIRONMENT,
-        });
+	setup() {
+		rollbar.init(configs.ROLLBAR_ACCESS_KEY, {
+			environment: configs.ENVIRONMENT,
+		});
 
-        rollbar.handleUncaughtExceptions(configs.ROLLBAR_ACCESS_KEY);
+		rollbar.handleUncaughtExceptions(configs.ROLLBAR_ACCESS_KEY);
 
-        process.on('unhandledRejection', async (err: Error) => {
-            utils.consoleLog(`Uncaught exception ${err}. Stack: ${err.stack}`);
-            await this.reportAsync(err);
-            process.exit(1);
-        });
-    },
-    async reportAsync(err: Error, req?: express.Request): Promise<any> {
-        if (configs.ENVIRONMENT === 'development') {
-            return; // Do not log development environment errors
-        }
+		process.on('unhandledRejection', async (err: Error) => {
+			utils.consoleLog(`Uncaught exception ${err}. Stack: ${err.stack}`);
+			await this.reportAsync(err);
+			process.exit(1);
+		});
+	},
+	async reportAsync(err: Error, req?: express.Request): Promise<any> {
+		if (configs.ENVIRONMENT === 'development') {
+			return; // Do not log development environment errors
+		}
 
-        return new Promise((resolve, reject) => {
-            rollbar.handleError(err, req, (rollbarErr: Error) => {
-                if (rollbarErr) {
-                    utils.consoleLog(`Error reporting to rollbar, ignoring: ${rollbarErr}`);
-                    reject(rollbarErr);
-                } else {
-                    resolve();
-                }
-            });
-        });
-    },
-    errorHandler() {
-        return rollbar.errorHandler(configs.ROLLBAR_ACCESS_KEY);
-    },
+		return new Promise((resolve, reject) => {
+			rollbar.handleError(err, req, (rollbarErr: Error) => {
+				if (rollbarErr) {
+					utils.consoleLog(`Error reporting to rollbar, ignoring: ${rollbarErr}`);
+					reject(rollbarErr);
+				} else {
+					resolve();
+				}
+			});
+		});
+	},
+	errorHandler() {
+		return rollbar.errorHandler(configs.ROLLBAR_ACCESS_KEY);
+	},
 };
diff --git a/packages/testnet-faucets/src/ts/ether_request_queue.ts b/packages/testnet-faucets/src/ts/ether_request_queue.ts
index 1c4b19ab9..aa75a00e4 100644
--- a/packages/testnet-faucets/src/ts/ether_request_queue.ts
+++ b/packages/testnet-faucets/src/ts/ether_request_queue.ts
@@ -9,19 +9,19 @@ import { utils } from './utils';
 const DISPENSE_AMOUNT_ETHER = 0.1;
 
 export class EtherRequestQueue extends RequestQueue {
-    protected async processNextRequestFireAndForgetAsync(recipientAddress: string) {
-        utils.consoleLog(`Processing ETH ${recipientAddress}`);
-        const sendTransactionAsync = promisify(this.web3.eth.sendTransaction);
-        try {
-            const txHash = await sendTransactionAsync({
-                from: configs.DISPENSER_ADDRESS,
-                to: recipientAddress,
-                value: this.web3.toWei(DISPENSE_AMOUNT_ETHER, 'ether'),
-            });
-            utils.consoleLog(`Sent ${DISPENSE_AMOUNT_ETHER} ETH to ${recipientAddress} tx: ${txHash}`);
-        } catch (err) {
-            utils.consoleLog(`Unexpected err: ${err} - ${JSON.stringify(err)}`);
-            await errorReporter.reportAsync(err);
-        }
-    }
+	protected async processNextRequestFireAndForgetAsync(recipientAddress: string) {
+		utils.consoleLog(`Processing ETH ${recipientAddress}`);
+		const sendTransactionAsync = promisify(this.web3.eth.sendTransaction);
+		try {
+			const txHash = await sendTransactionAsync({
+				from: configs.DISPENSER_ADDRESS,
+				to: recipientAddress,
+				value: this.web3.toWei(DISPENSE_AMOUNT_ETHER, 'ether'),
+			});
+			utils.consoleLog(`Sent ${DISPENSE_AMOUNT_ETHER} ETH to ${recipientAddress} tx: ${txHash}`);
+		} catch (err) {
+			utils.consoleLog(`Unexpected err: ${err} - ${JSON.stringify(err)}`);
+			await errorReporter.reportAsync(err);
+		}
+	}
 }
diff --git a/packages/testnet-faucets/src/ts/global.d.ts b/packages/testnet-faucets/src/ts/global.d.ts
index 97cd35680..90866565d 100644
--- a/packages/testnet-faucets/src/ts/global.d.ts
+++ b/packages/testnet-faucets/src/ts/global.d.ts
@@ -5,22 +5,22 @@ declare module 'web3-provider-engine/subproviders/nonce-tracker';
 declare module 'web3-provider-engine/subproviders/hooked-wallet';
 
 declare module '*.json' {
-    const json: any;
-    /* tslint:disable */
-    export default json;
-    /* tslint:enable */
+	const json: any;
+	/* tslint:disable */
+	export default json;
+	/* tslint:enable */
 }
 
 // Ethereumjs-tx declarations
 declare module 'ethereumjs-tx' {
-    class EthereumTx {
-        public raw: Buffer[];
-        public r: Buffer;
-        public s: Buffer;
-        public v: Buffer;
-        public serialize(): Buffer;
-        public sign(buffer: Buffer): void;
-        constructor(txParams: any);
-    }
-    export = EthereumTx;
+	class EthereumTx {
+		public raw: Buffer[];
+		public r: Buffer;
+		public s: Buffer;
+		public v: Buffer;
+		public serialize(): Buffer;
+		public sign(buffer: Buffer): void;
+		constructor(txParams: any);
+	}
+	export = EthereumTx;
 }
diff --git a/packages/testnet-faucets/src/ts/handler.ts b/packages/testnet-faucets/src/ts/handler.ts
index bf5b3e81e..455a925e3 100644
--- a/packages/testnet-faucets/src/ts/handler.ts
+++ b/packages/testnet-faucets/src/ts/handler.ts
@@ -20,95 +20,95 @@ import { ZRXRequestQueue } from './zrx_request_queue';
 import * as Web3 from 'web3';
 
 interface RequestQueueByNetworkId {
-    [networkId: string]: RequestQueue;
+	[networkId: string]: RequestQueue;
 }
 
 enum QueueType {
-    ETH = 'ETH',
-    ZRX = 'ZRX',
+	ETH = 'ETH',
+	ZRX = 'ZRX',
 }
 
 const DEFAULT_NETWORK_ID = 42; // kovan
 
 export class Handler {
-    private _etherRequestQueueByNetworkId: RequestQueueByNetworkId = {};
-    private _zrxRequestQueueByNetworkId: RequestQueueByNetworkId = {};
-    constructor() {
-        _.forIn(rpcUrls, (rpcUrl: string, networkId: string) => {
-            const providerObj = this._createProviderEngine(rpcUrl);
-            const web3 = new Web3(providerObj);
-            this._etherRequestQueueByNetworkId[networkId] = new EtherRequestQueue(web3);
-            this._zrxRequestQueueByNetworkId[networkId] = new ZRXRequestQueue(web3, +networkId);
-        });
-    }
-    public getQueueInfo(req: express.Request, res: express.Response) {
-        res.setHeader('Content-Type', 'application/json');
-        const queueInfo = _.mapValues(rpcUrls, (rpcUrl: string, networkId: string) => {
-            utils.consoleLog(networkId);
-            const etherRequestQueue = this._etherRequestQueueByNetworkId[networkId];
-            const zrxRequestQueue = this._zrxRequestQueueByNetworkId[networkId];
-            return {
-                ether: {
-                    full: etherRequestQueue.isFull(),
-                    size: etherRequestQueue.size(),
-                },
-                zrx: {
-                    full: zrxRequestQueue.isFull(),
-                    size: zrxRequestQueue.size(),
-                },
-            };
-        });
-        const payload = JSON.stringify(queueInfo);
-        res.status(200).send(payload);
-    }
-    public dispenseEther(req: express.Request, res: express.Response) {
-        this._dispense(req, res, this._etherRequestQueueByNetworkId, QueueType.ETH);
-    }
-    public dispenseZRX(req: express.Request, res: express.Response) {
-        this._dispense(req, res, this._zrxRequestQueueByNetworkId, QueueType.ZRX);
-    }
-    private _dispense(
-        req: express.Request,
-        res: express.Response,
-        requestQueueByNetworkId: RequestQueueByNetworkId,
-        queueType: QueueType,
-    ) {
-        const recipientAddress = req.params.recipient;
-        if (_.isUndefined(recipientAddress) || !this._isValidEthereumAddress(recipientAddress)) {
-            res.status(400).send('INVALID_RECIPIENT_ADDRESS');
-            return;
-        }
-        const networkId = _.get(req.query, 'networkId', DEFAULT_NETWORK_ID);
-        const requestQueue = _.get(requestQueueByNetworkId, networkId);
-        if (_.isUndefined(requestQueue)) {
-            res.status(400).send('INVALID_NETWORK_ID');
-            return;
-        }
-        const lowerCaseRecipientAddress = recipientAddress.toLowerCase();
-        const didAddToQueue = requestQueue.add(lowerCaseRecipientAddress);
-        if (!didAddToQueue) {
-            res.status(503).send('QUEUE_IS_FULL');
-            return;
-        }
-        utils.consoleLog(`Added ${lowerCaseRecipientAddress} to queue: ${queueType} networkId: ${networkId}`);
-        res.status(200).end();
-    }
-    // tslint:disable-next-line:prefer-function-over-method
-    private _createProviderEngine(rpcUrl: string) {
-        const engine = new ProviderEngine();
-        engine.addProvider(new NonceSubprovider());
-        engine.addProvider(new HookedWalletSubprovider(idManagement));
-        engine.addProvider(
-            new RpcSubprovider({
-                rpcUrl,
-            }),
-        );
-        engine.start();
-        return engine;
-    }
-    // tslint:disable-next-line:prefer-function-over-method
-    private _isValidEthereumAddress(address: string): boolean {
-        const lowercaseAddress = address.toLowerCase();
-        return addressUtils.isAddress(lowercaseAddress);
-    }
+	private _etherRequestQueueByNetworkId: RequestQueueByNetworkId = {};
+	private _zrxRequestQueueByNetworkId: RequestQueueByNetworkId = {};
+	constructor() {
+		_.forIn(rpcUrls, (rpcUrl: string, networkId: string) => {
+			const providerObj = this._createProviderEngine(rpcUrl);
+			const web3 = new Web3(providerObj);
+			this._etherRequestQueueByNetworkId[networkId] = new EtherRequestQueue(web3);
+			this._zrxRequestQueueByNetworkId[networkId] = new ZRXRequestQueue(web3, +networkId);
+		});
+	}
+	public getQueueInfo(req: express.Request, res: express.Response) {
+		res.setHeader('Content-Type', 'application/json');
+		const queueInfo = _.mapValues(rpcUrls, (rpcUrl: string, networkId: string) => {
+			utils.consoleLog(networkId);
+			const etherRequestQueue = this._etherRequestQueueByNetworkId[networkId];
+			const zrxRequestQueue = this._zrxRequestQueueByNetworkId[networkId];
+			return {
+				ether: {
+					full: etherRequestQueue.isFull(),
+					size: etherRequestQueue.size(),
+				},
+				zrx: {
+					full: zrxRequestQueue.isFull(),
+					size: zrxRequestQueue.size(),
+				},
+			};
+		});
+		const payload = JSON.stringify(queueInfo);
+		res.status(200).send(payload);
+	}
+	public dispenseEther(req: express.Request, res: express.Response) {
+		this._dispense(req, res, this._etherRequestQueueByNetworkId, QueueType.ETH);
+	}
+	public dispenseZRX(req: express.Request, res: express.Response) {
+		this._dispense(req, res, this._zrxRequestQueueByNetworkId, QueueType.ZRX);
+	}
+	private _dispense(
+		req: express.Request,
+		res: express.Response,
+		requestQueueByNetworkId: RequestQueueByNetworkId,
+		queueType: QueueType,
+	) {
+		const recipientAddress = req.params.recipient;
+		if (_.isUndefined(recipientAddress) || !this._isValidEthereumAddress(recipientAddress)) {
+			res.status(400).send('INVALID_RECIPIENT_ADDRESS');
+			return;
+		}
+		const networkId = _.get(req.query, 'networkId', DEFAULT_NETWORK_ID);
+		const requestQueue = _.get(requestQueueByNetworkId, networkId);
+		if (_.isUndefined(requestQueue)) {
+			res.status(400).send('INVALID_NETWORK_ID');
+			return;
+		}
+		const lowerCaseRecipientAddress = recipientAddress.toLowerCase();
+		const didAddToQueue = requestQueue.add(lowerCaseRecipientAddress);
+		if (!didAddToQueue) {
+			res.status(503).send('QUEUE_IS_FULL');
+			return;
+		}
+		utils.consoleLog(`Added ${lowerCaseRecipientAddress} to queue: ${queueType} networkId: ${networkId}`);
+		res.status(200).end();
+	}
+	// tslint:disable-next-line:prefer-function-over-method
+	private _createProviderEngine(rpcUrl: string) {
+		const engine = new ProviderEngine();
+		engine.addProvider(new NonceSubprovider());
+		engine.addProvider(new HookedWalletSubprovider(idManagement));
+		engine.addProvider(
+			new RpcSubprovider({
+				rpcUrl,
+			}),
+		);
+		engine.start();
+		return engine;
+	}
+	// tslint:disable-next-line:prefer-function-over-method
+	private _isValidEthereumAddress(address: string): boolean {
+		const lowercaseAddress = address.toLowerCase();
+		return addressUtils.isAddress(lowercaseAddress);
+	}
 }
diff --git a/packages/testnet-faucets/src/ts/id_management.ts b/packages/testnet-faucets/src/ts/id_management.ts
index db9b610a3..2f04b5ff9 100644
--- a/packages/testnet-faucets/src/ts/id_management.ts
+++ b/packages/testnet-faucets/src/ts/id_management.ts
@@ -5,17 +5,17 @@ import { configs } from './configs';
 type Callback = (err: Error | null, accounts: any) => void;
 
 export const idManagement = {
-    getAccounts(callback: Callback) {
-        callback(null, [configs.DISPENSER_ADDRESS]);
-    },
-    approveTransaction(txData: object, callback: Callback) {
-        callback(null, true);
-    },
-    signTransaction(txData: object, callback: Callback) {
-        const tx = new EthereumTx(txData);
-        const privateKeyBuffer = new Buffer(configs.DISPENSER_PRIVATE_KEY as string, 'hex');
-        tx.sign(privateKeyBuffer);
-        const rawTx = `0x${tx.serialize().toString('hex')}`;
-        callback(null, rawTx);
-    },
+	getAccounts(callback: Callback) {
+		callback(null, [configs.DISPENSER_ADDRESS]);
+	},
+	approveTransaction(txData: object, callback: Callback) {
+		callback(null, true);
+	},
+	signTransaction(txData: object, callback: Callback) {
+		const tx = new EthereumTx(txData);
+		const privateKeyBuffer = new Buffer(configs.DISPENSER_PRIVATE_KEY as string, 'hex');
+		tx.sign(privateKeyBuffer);
+		const rawTx = `0x${tx.serialize().toString('hex')}`;
+		callback(null, rawTx);
+	},
 };
diff --git a/packages/testnet-faucets/src/ts/request_queue.ts b/packages/testnet-faucets/src/ts/request_queue.ts
index 20f2833a1..37b5505f8 100644
--- a/packages/testnet-faucets/src/ts/request_queue.ts
+++ b/packages/testnet-faucets/src/ts/request_queue.ts
@@ -11,46 +11,46 @@ const MAX_QUEUE_SIZE = 500;
 const DEFAULT_QUEUE_INTERVAL_MS = 1000;
 
 export class RequestQueue {
-    protected queueIntervalMs: number;
-    protected queue: string[];
-    protected queueIntervalId: NodeJS.Timer;
-    protected web3: Web3;
-    constructor(web3: any) {
-        this.queueIntervalMs = DEFAULT_QUEUE_INTERVAL_MS;
-        this.queue = [];
+	protected queueIntervalMs: number;
+	protected queue: string[];
+	protected queueIntervalId: NodeJS.Timer;
+	protected web3: Web3;
+	constructor(web3: any) {
+		this.queueIntervalMs = DEFAULT_QUEUE_INTERVAL_MS;
+		this.queue = [];
 
-        this.web3 = web3;
+		this.web3 = web3;
 
-        this.start();
-    }
-    public add(recipientAddress: string): boolean {
-        if (this.isFull()) {
-            return false;
-        }
-        this.queue.push(recipientAddress);
-        return true;
-    }
-    public size(): number {
-        return this.queue.length;
-    }
-    public isFull(): boolean {
-        return this.size() >= MAX_QUEUE_SIZE;
-    }
-    protected start() {
-        this.queueIntervalId = timers.setInterval(() => {
-            const recipientAddress = this.queue.shift();
-            if (_.isUndefined(recipientAddress)) {
-                return;
-            }
-            // tslint:disable-next-line:no-floating-promises
-            this.processNextRequestFireAndForgetAsync(recipientAddress);
-        }, this.queueIntervalMs);
-    }
-    protected stop() {
-        clearInterval(this.queueIntervalId);
-    }
-    // tslint:disable-next-line:prefer-function-over-method
-    protected async processNextRequestFireAndForgetAsync(recipientAddress: string) {
-        throw new Error('Expected processNextRequestFireAndForgetAsync to be implemented by a subclass');
-    }
+		this.start();
+	}
+	public add(recipientAddress: string): boolean {
+		if (this.isFull()) {
+			return false;
+		}
+		this.queue.push(recipientAddress);
+		return true;
+	}
+	public size(): number {
+		return this.queue.length;
+	}
+	public isFull(): boolean {
+		return this.size() >= MAX_QUEUE_SIZE;
+	}
+	protected start() {
+		this.queueIntervalId = timers.setInterval(() => {
+			const recipientAddress = this.queue.shift();
+			if (_.isUndefined(recipientAddress)) {
+				return;
+			}
+			// tslint:disable-next-line:no-floating-promises
+			this.processNextRequestFireAndForgetAsync(recipientAddress);
+		}, this.queueIntervalMs);
+	}
+	protected stop() {
+		clearInterval(this.queueIntervalId);
+	}
+	// tslint:disable-next-line:prefer-function-over-method
+	protected async processNextRequestFireAndForgetAsync(recipientAddress: string) {
+		throw new Error('Expected processNextRequestFireAndForgetAsync to be implemented by a subclass');
+	}
 }
diff --git a/packages/testnet-faucets/src/ts/rpc_urls.ts b/packages/testnet-faucets/src/ts/rpc_urls.ts
index 25a3b938f..9e12bca37 100644
--- a/packages/testnet-faucets/src/ts/rpc_urls.ts
+++ b/packages/testnet-faucets/src/ts/rpc_urls.ts
@@ -1,13 +1,13 @@
 import { configs } from './configs';
 
 const productionRpcUrls = {
-    '2': `https://ropsten.infura.io/${configs.INFURA_API_KEY}`,
-    '3': `https://rinkeby.infura.io/${configs.INFURA_API_KEY}`,
-    '42': `https://kovan.infura.io/${configs.INFURA_API_KEY}`,
+	'2': `https://ropsten.infura.io/${configs.INFURA_API_KEY}`,
+	'3': `https://rinkeby.infura.io/${configs.INFURA_API_KEY}`,
+	'42': `https://kovan.infura.io/${configs.INFURA_API_KEY}`,
 };
 
 const developmentRpcUrls = {
-    '50': 'http://127.0.0.1:8545',
+	'50': 'http://127.0.0.1:8545',
 };
 
 export const rpcUrls = configs.ENVIRONMENT === 'development' ? developmentRpcUrls : productionRpcUrls;
diff --git a/packages/testnet-faucets/src/ts/server.ts b/packages/testnet-faucets/src/ts/server.ts
index 26edfff5a..6fb555538 100644
--- a/packages/testnet-faucets/src/ts/server.ts
+++ b/packages/testnet-faucets/src/ts/server.ts
@@ -10,14 +10,14 @@ errorReporter.setup();
 const app = express();
 app.use(bodyParser.json()); // for parsing application/json
 app.use((req, res, next) => {
-    res.header('Access-Control-Allow-Origin', '*');
-    res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
-    next();
+	res.header('Access-Control-Allow-Origin', '*');
+	res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
+	next();
 });
 
 const handler = new Handler();
 app.get('/ping', (req: express.Request, res: express.Response) => {
-    res.status(200).send('pong');
+	res.status(200).send('pong');
 });
 app.get('/info', handler.getQueueInfo.bind(handler));
 app.get('/ether/:recipient', handler.dispenseEther.bind(handler));
diff --git a/packages/testnet-faucets/src/ts/utils.ts b/packages/testnet-faucets/src/ts/utils.ts
index 893f82ca3..821fe453c 100644
--- a/packages/testnet-faucets/src/ts/utils.ts
+++ b/packages/testnet-faucets/src/ts/utils.ts
@@ -1,7 +1,7 @@
 export const utils = {
-    consoleLog(message: string) {
-        /* tslint:disable */
-        console.log(message);
-        /* tslint:enable */
-    },
+	consoleLog(message: string) {
+		/* tslint:disable */
+		console.log(message);
+		/* tslint:enable */
+	},
 };
diff --git a/packages/testnet-faucets/src/ts/zrx_request_queue.ts b/packages/testnet-faucets/src/ts/zrx_request_queue.ts
index 3d73f9dd2..b81a44cd1 100644
--- a/packages/testnet-faucets/src/ts/zrx_request_queue.ts
+++ b/packages/testnet-faucets/src/ts/zrx_request_queue.ts
@@ -17,30 +17,30 @@ const DISPENSE_AMOUNT_ZRX = new BigNumber(0.1);
 const QUEUE_INTERVAL_MS = 5000;
 
 export class ZRXRequestQueue extends RequestQueue {
-    private _zeroEx: ZeroEx;
-    constructor(web3: Web3, networkId: number) {
-        super(web3);
-        this.queueIntervalMs = QUEUE_INTERVAL_MS;
-        const zeroExConfig = {
-            networkId,
-        };
-        this._zeroEx = new ZeroEx(web3.currentProvider, zeroExConfig);
-    }
-    protected async processNextRequestFireAndForgetAsync(recipientAddress: string) {
-        utils.consoleLog(`Processing ZRX ${recipientAddress}`);
-        const baseUnitAmount = ZeroEx.toBaseUnitAmount(DISPENSE_AMOUNT_ZRX, 18);
-        try {
-            const zrxTokenAddress = this._zeroEx.exchange.getZRXTokenAddress();
-            const txHash = await this._zeroEx.token.transferAsync(
-                zrxTokenAddress,
-                configs.DISPENSER_ADDRESS,
-                recipientAddress,
-                baseUnitAmount,
-            );
-            utils.consoleLog(`Sent ${DISPENSE_AMOUNT_ZRX} ZRX to ${recipientAddress} tx: ${txHash}`);
-        } catch (err) {
-            utils.consoleLog(`Unexpected err: ${err} - ${JSON.stringify(err)}`);
-            await errorReporter.reportAsync(err);
-        }
-    }
+	private _zeroEx: ZeroEx;
+	constructor(web3: Web3, networkId: number) {
+		super(web3);
+		this.queueIntervalMs = QUEUE_INTERVAL_MS;
+		const zeroExConfig = {
+			networkId,
+		};
+		this._zeroEx = new ZeroEx(web3.currentProvider, zeroExConfig);
+	}
+	protected async processNextRequestFireAndForgetAsync(recipientAddress: string) {
+		utils.consoleLog(`Processing ZRX ${recipientAddress}`);
+		const baseUnitAmount = ZeroEx.toBaseUnitAmount(DISPENSE_AMOUNT_ZRX, 18);
+		try {
+			const zrxTokenAddress = this._zeroEx.exchange.getZRXTokenAddress();
+			const txHash = await this._zeroEx.token.transferAsync(
+				zrxTokenAddress,
+				configs.DISPENSER_ADDRESS,
+				recipientAddress,
+				baseUnitAmount,
+			);
+			utils.consoleLog(`Sent ${DISPENSE_AMOUNT_ZRX} ZRX to ${recipientAddress} tx: ${txHash}`);
+		} catch (err) {
+			utils.consoleLog(`Unexpected err: ${err} - ${JSON.stringify(err)}`);
+			await errorReporter.reportAsync(err);
+		}
+	}
 }
diff --git a/packages/testnet-faucets/tsconfig.json b/packages/testnet-faucets/tsconfig.json
index 7f0c084ff..e3353cc95 100644
--- a/packages/testnet-faucets/tsconfig.json
+++ b/packages/testnet-faucets/tsconfig.json
@@ -1,7 +1,7 @@
 {
-    "extends": "../../tsconfig",
-    "compilerOptions": {
-        "outDir": "lib"
-    },
-    "include": ["./src/ts/**/*", "../../node_modules/web3-typescript-typings/index.d.ts"]
+	"extends": "../../tsconfig",
+	"compilerOptions": {
+		"outDir": "lib"
+	},
+	"include": ["./src/ts/**/*", "../../node_modules/web3-typescript-typings/index.d.ts"]
 }
diff --git a/packages/testnet-faucets/tslint.json b/packages/testnet-faucets/tslint.json
index ffaefe83a..e63054bfc 100644
--- a/packages/testnet-faucets/tslint.json
+++ b/packages/testnet-faucets/tslint.json
@@ -1,3 +1,3 @@
 {
-    "extends": ["@0xproject/tslint-config"]
+	"extends": ["@0xproject/tslint-config"]
 }
diff --git a/packages/tslint-config/README.md b/packages/tslint-config/README.md
index 8a6fa8a2f..71fdd9772 100644
--- a/packages/tslint-config/README.md
+++ b/packages/tslint-config/README.md
@@ -14,7 +14,7 @@ Add the following to your `tslint.json` file
 
 ```json
 {
-    "extends": ["@0xproject/tslint-config"]
+	"extends": ["@0xproject/tslint-config"]
 }
 ```
 
diff --git a/packages/tslint-config/package.json b/packages/tslint-config/package.json
index fc015de26..95bd67ac6 100644
--- a/packages/tslint-config/package.json
+++ b/packages/tslint-config/package.json
@@ -1,47 +1,37 @@
 {
-    "name": "@0xproject/tslint-config",
-    "version": "0.4.4",
-    "description": "Lint rules related to 0xProject for TSLint",
-    "main": "tslint.json",
-    "scripts": {
-        "build": "tsc",
-        "clean": "shx rm -rf lib",
-        "lint": "tslint --project . 'rules/**/*.ts'"
-    },
-    "files": [
-        "tslint.js",
-        "README.md",
-        "LICENSE"
-    ],
-    "repository": {
-        "type": "git",
-        "url": "git://github.com/0xProject/0x.js.git"
-    },
-    "keywords": [
-        "tslint",
-        "config",
-        "0xProject",
-        "typescript",
-        "ts"
-    ],
-    "author": {
-        "name": "Fabio Berger",
-        "email": "fabio@0xproject.com"
-    },
-    "license": "Apache-2.0",
-    "bugs": {
-        "url": "https://github.com/0xProject/0x.js/issues"
-    },
-    "homepage": "https://github.com/0xProject/0x.js/packages/tslint-config/README.md",
-    "devDependencies": {
-        "@types/lodash": "^4.14.86",
-        "shx": "^0.2.2",
-        "tslint": "5.8.0",
-        "tslint-eslint-rules": "^4.1.1",
-        "typescript": "~2.6.1"
-    },
-    "dependencies": {
-        "lodash": "^4.17.4",
-        "tslint-react": "^3.2.0"
-    }
+	"name": "@0xproject/tslint-config",
+	"version": "0.4.4",
+	"description": "Lint rules related to 0xProject for TSLint",
+	"main": "tslint.json",
+	"scripts": {
+		"build": "tsc",
+		"clean": "shx rm -rf lib",
+		"lint": "tslint --project . 'rules/**/*.ts'"
+	},
+	"files": ["tslint.js", "README.md", "LICENSE"],
+	"repository": {
+		"type": "git",
+		"url": "git://github.com/0xProject/0x.js.git"
+	},
+	"keywords": ["tslint", "config", "0xProject", "typescript", "ts"],
+	"author": {
+		"name": "Fabio Berger",
+		"email": "fabio@0xproject.com"
+	},
+	"license": "Apache-2.0",
+	"bugs": {
+		"url": "https://github.com/0xProject/0x.js/issues"
+	},
+	"homepage": "https://github.com/0xProject/0x.js/packages/tslint-config/README.md",
+	"devDependencies": {
+		"@types/lodash": "^4.14.86",
+		"shx": "^0.2.2",
+		"tslint": "5.8.0",
+		"tslint-eslint-rules": "^4.1.1",
+		"typescript": "~2.6.1"
+	},
+	"dependencies": {
+		"lodash": "^4.17.4",
+		"tslint-react": "^3.2.0"
+	}
 }
diff --git a/packages/tslint-config/rules/asyncSuffixRule.ts b/packages/tslint-config/rules/asyncSuffixRule.ts
index 5215c7151..8af9d88d4 100644
--- a/packages/tslint-config/rules/asyncSuffixRule.ts
+++ b/packages/tslint-config/rules/asyncSuffixRule.ts
@@ -4,7 +4,7 @@ import * as ts from 'typescript';
 import { AsyncSuffixWalker } from './walkers/async_suffix';
 
 export class Rule extends Lint.Rules.AbstractRule {
-    public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
-        return this.applyWithWalker(new AsyncSuffixWalker(sourceFile, this.getOptions()));
-    }
+	public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
+		return this.applyWithWalker(new AsyncSuffixWalker(sourceFile, this.getOptions()));
+	}
 }
diff --git a/packages/tslint-config/rules/underscorePrivatesRule.ts b/packages/tslint-config/rules/underscorePrivatesRule.ts
index 472ea09ff..4d9ee69f7 100644
--- a/packages/tslint-config/rules/underscorePrivatesRule.ts
+++ b/packages/tslint-config/rules/underscorePrivatesRule.ts
@@ -4,58 +4,58 @@ import * as ts from 'typescript';
 const UNDERSCORE = '_';
 
 type RelevantClassMember =
-    | ts.MethodDeclaration
-    | ts.PropertyDeclaration
-    | ts.GetAccessorDeclaration
-    | ts.SetAccessorDeclaration;
+	| ts.MethodDeclaration
+	| ts.PropertyDeclaration
+	| ts.GetAccessorDeclaration
+	| ts.SetAccessorDeclaration;
 
 // Copied from: https://github.com/DanielRosenwasser/underscore-privates-tslint-rule
 // The version on github is not published on npm
 export class Rule extends Lint.Rules.AbstractRule {
-    public static FAILURE_STRING = 'private members must be prefixed with an underscore';
+	public static FAILURE_STRING = 'private members must be prefixed with an underscore';
 
-    public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
-        return this.applyWithFunction(sourceFile, walk);
-    }
+	public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
+		return this.applyWithFunction(sourceFile, walk);
+	}
 }
 function walk(ctx: Lint.WalkContext<void>): void {
-    traverse(ctx.sourceFile);
+	traverse(ctx.sourceFile);
 
-    function traverse(node: ts.Node): void {
-        checkNodeForViolations(ctx, node);
-        return ts.forEachChild(node, traverse);
-    }
+	function traverse(node: ts.Node): void {
+		checkNodeForViolations(ctx, node);
+		return ts.forEachChild(node, traverse);
+	}
 }
 function checkNodeForViolations(ctx: Lint.WalkContext<void>, node: ts.Node): void {
-    if (!isRelevantClassMember(node)) {
-        return;
-    }
-    // The declaration might have a computed property name or a numeric name.
-    const name = node.name;
-    if (!nameIsIdentifier(name)) {
-        return;
-    }
-    if (!nameStartsWithUnderscore(name.text) && memberIsPrivate(node)) {
-        ctx.addFailureAtNode(name, Rule.FAILURE_STRING);
-    }
+	if (!isRelevantClassMember(node)) {
+		return;
+	}
+	// The declaration might have a computed property name or a numeric name.
+	const name = node.name;
+	if (!nameIsIdentifier(name)) {
+		return;
+	}
+	if (!nameStartsWithUnderscore(name.text) && memberIsPrivate(node)) {
+		ctx.addFailureAtNode(name, Rule.FAILURE_STRING);
+	}
 }
 function isRelevantClassMember(node: ts.Node): node is RelevantClassMember {
-    switch (node.kind) {
-        case ts.SyntaxKind.MethodDeclaration:
-        case ts.SyntaxKind.PropertyDeclaration:
-        case ts.SyntaxKind.GetAccessor:
-        case ts.SyntaxKind.SetAccessor:
-            return true;
-        default:
-            return false;
-    }
+	switch (node.kind) {
+		case ts.SyntaxKind.MethodDeclaration:
+		case ts.SyntaxKind.PropertyDeclaration:
+		case ts.SyntaxKind.GetAccessor:
+		case ts.SyntaxKind.SetAccessor:
+			return true;
+		default:
+			return false;
+	}
 }
 function nameStartsWithUnderscore(text: string) {
-    return text.charCodeAt(0) === UNDERSCORE.charCodeAt(0);
+	return text.charCodeAt(0) === UNDERSCORE.charCodeAt(0);
 }
 function memberIsPrivate(node: ts.Declaration) {
-    return Lint.hasModifier(node.modifiers, ts.SyntaxKind.PrivateKeyword);
+	return Lint.hasModifier(node.modifiers, ts.SyntaxKind.PrivateKeyword);
 }
 function nameIsIdentifier(node: ts.Node): node is ts.Identifier {
-    return node.kind === ts.SyntaxKind.Identifier;
+	return node.kind === ts.SyntaxKind.Identifier;
 }
diff --git a/packages/tslint-config/rules/walkers/async_suffix.ts b/packages/tslint-config/rules/walkers/async_suffix.ts
index eaec9c5f6..e1138de8d 100644
--- a/packages/tslint-config/rules/walkers/async_suffix.ts
+++ b/packages/tslint-config/rules/walkers/async_suffix.ts
@@ -3,24 +3,24 @@ import * as Lint from 'tslint';
 import * as ts from 'typescript';
 
 export class AsyncSuffixWalker extends Lint.RuleWalker {
-    public static FAILURE_STRING = 'async functions must have an Async suffix';
-    public visitMethodDeclaration(node: ts.MethodDeclaration): void {
-        const methodNameNode = node.name;
-        const methodName = methodNameNode.getText();
-        if (!_.isUndefined(node.type)) {
-            if (node.type.kind === ts.SyntaxKind.TypeReference) {
-                // tslint:disable-next-line:no-unnecessary-type-assertion
-                const returnTypeName = (node.type as ts.TypeReferenceNode).typeName.getText();
-                if (returnTypeName === 'Promise' && !methodName.endsWith('Async')) {
-                    const failure = this.createFailure(
-                        methodNameNode.getStart(),
-                        methodNameNode.getWidth(),
-                        AsyncSuffixWalker.FAILURE_STRING,
-                    );
-                    this.addFailure(failure);
-                }
-            }
-        }
-        super.visitMethodDeclaration(node);
-    }
+	public static FAILURE_STRING = 'async functions must have an Async suffix';
+	public visitMethodDeclaration(node: ts.MethodDeclaration): void {
+		const methodNameNode = node.name;
+		const methodName = methodNameNode.getText();
+		if (!_.isUndefined(node.type)) {
+			if (node.type.kind === ts.SyntaxKind.TypeReference) {
+				// tslint:disable-next-line:no-unnecessary-type-assertion
+				const returnTypeName = (node.type as ts.TypeReferenceNode).typeName.getText();
+				if (returnTypeName === 'Promise' && !methodName.endsWith('Async')) {
+					const failure = this.createFailure(
+						methodNameNode.getStart(),
+						methodNameNode.getWidth(),
+						AsyncSuffixWalker.FAILURE_STRING,
+					);
+					this.addFailure(failure);
+				}
+			}
+		}
+		super.visitMethodDeclaration(node);
+	}
 }
diff --git a/packages/tslint-config/tsconfig.json b/packages/tslint-config/tsconfig.json
index 15da53092..83db0fcd2 100644
--- a/packages/tslint-config/tsconfig.json
+++ b/packages/tslint-config/tsconfig.json
@@ -1,7 +1,7 @@
 {
-    "extends": "../../tsconfig",
-    "compilerOptions": {
-        "outDir": "lib"
-    },
-    "include": ["./rules/**/*"]
+	"extends": "../../tsconfig",
+	"compilerOptions": {
+		"outDir": "lib"
+	},
+	"include": ["./rules/**/*"]
 }
diff --git a/packages/tslint-config/tslint.json b/packages/tslint-config/tslint.json
index 971588b08..f2a9558b9 100644
--- a/packages/tslint-config/tslint.json
+++ b/packages/tslint-config/tslint.json
@@ -1,101 +1,101 @@
 {
-    "extends": ["tslint:latest", "tslint-react", "tslint-eslint-rules"],
-    "rules": {
-        "adjacent-overload-signatures": true,
-        "arrow-parens": [true, "ban-single-arg-parens"],
-        "arrow-return-shorthand": true,
-        "async-suffix": true,
-        "await-promise": true,
-        "binary-expression-operand-order": true,
-        "callable-types": true,
-        "class-name": true,
-        "completed-docs": [
-            true,
-            {
-                "functions": { "visibilities": ["exported"] },
-                "methods": { "locations": "instance", "privacies": ["public", "protected"] }
-            }
-        ],
-        "curly": true,
-        "eofline": true,
-        "encoding": true,
-        "import-spacing": true,
-        "indent": [true, "spaces", 4],
-        "interface-name": false,
-        "interface-over-type-literal": true,
-        "linebreak-style": [true, "LF"],
-        "max-classes-per-file": false,
-        "max-classes-per-file": [true, 1],
-        "max-line-length": false,
-        "max-file-line-count": [true, 500],
-        "member-access": true,
-        "member-ordering": [true, "public-before-private", "static-before-instance", "variables-before-functions"],
-        "newline-before-return": false,
-        "new-parens": true,
-        "no-angle-bracket-type-assertion": true,
-        "no-boolean-literal-compare": true,
-        "no-default-export": true,
-        "no-empty-interface": false,
-        "no-floating-promises": true,
-        "no-non-null-assertion": true,
-        "no-parameter-reassignment": true,
-        "no-redundant-jsdoc": true,
-        "no-return-await": true,
-        "no-string-throw": true,
-        "no-submodule-imports": false,
-        "no-unnecessary-type-assertion": true,
-        "no-unused-variable": [true, { "ignore-pattern": "^_\\d*" }],
-        "no-implicit-dependencies": [true, "dev"],
-        "number-literal-format": true,
-        "object-literal-sort-keys": false,
-        "object-literal-key-quotes": false,
-        "ordered-imports": [
-            true,
-            {
-                "grouped-imports": true
-            }
-        ],
-        "prefer-const": true,
-        "prefer-for-of": true,
-        "prefer-function-over-method": true,
-        "promise-function-async": true,
-        "quotemark": [true, "single", "avoid-escape", "jsx-double"],
-        "restrict-plus-operands": true,
-        "semicolon": [true, "always"],
-        "space-before-function-paren": [
-            true,
-            {
-                "anonymous": "never",
-                "named": "never",
-                "method": "never",
-                "constructor": "never",
-                "asyncArrow": "always"
-            }
-        ],
-        "space-within-parens": false,
-        "type-literal-delimiter": true,
-        "underscore-privates": true,
-        "variable-name": [true, "ban-keywords", "allow-pascal-case"],
-        "whitespace": [
-            true,
-            "check-branch",
-            "check-decl",
-            "check-operator",
-            "check-separator",
-            "check-rest-spread",
-            "check-type",
-            "check-typecast",
-            "check-preblock"
-        ],
-        "jsx-alignment": true,
-        "jsx-boolean-value": true,
-        "jsx-curly-spacing": [true, "never"],
-        "jsx-no-lambda": true,
-        "jsx-no-multiline-js": false,
-        "jsx-no-string-ref": true,
-        "jsx-self-close": true,
-        "jsx-wrap-multiline": false,
-        "jsx-no-bind": false
-    },
-    "rulesDirectory": "lib"
+	"extends": ["tslint:latest", "tslint-react", "tslint-eslint-rules"],
+	"rules": {
+		"adjacent-overload-signatures": true,
+		"arrow-parens": [true, "ban-single-arg-parens"],
+		"arrow-return-shorthand": true,
+		"async-suffix": true,
+		"await-promise": true,
+		"binary-expression-operand-order": true,
+		"callable-types": true,
+		"class-name": true,
+		"completed-docs": [
+			true,
+			{
+				"functions": { "visibilities": ["exported"] },
+				"methods": { "locations": "instance", "privacies": ["public", "protected"] }
+			}
+		],
+		"curly": true,
+		"eofline": true,
+		"encoding": true,
+		"import-spacing": true,
+		"indent": [true, "spaces", 4],
+		"interface-name": false,
+		"interface-over-type-literal": true,
+		"linebreak-style": [true, "LF"],
+		"max-classes-per-file": false,
+		"max-classes-per-file": [true, 1],
+		"max-line-length": false,
+		"max-file-line-count": [true, 500],
+		"member-access": true,
+		"member-ordering": [true, "public-before-private", "static-before-instance", "variables-before-functions"],
+		"newline-before-return": false,
+		"new-parens": true,
+		"no-angle-bracket-type-assertion": true,
+		"no-boolean-literal-compare": true,
+		"no-default-export": true,
+		"no-empty-interface": false,
+		"no-floating-promises": true,
+		"no-non-null-assertion": true,
+		"no-parameter-reassignment": true,
+		"no-redundant-jsdoc": true,
+		"no-return-await": true,
+		"no-string-throw": true,
+		"no-submodule-imports": false,
+		"no-unnecessary-type-assertion": true,
+		"no-unused-variable": [true, { "ignore-pattern": "^_\\d*" }],
+		"no-implicit-dependencies": [true, "dev"],
+		"number-literal-format": true,
+		"object-literal-sort-keys": false,
+		"object-literal-key-quotes": false,
+		"ordered-imports": [
+			true,
+			{
+				"grouped-imports": true
+			}
+		],
+		"prefer-const": true,
+		"prefer-for-of": true,
+		"prefer-function-over-method": true,
+		"promise-function-async": true,
+		"quotemark": [true, "single", "avoid-escape", "jsx-double"],
+		"restrict-plus-operands": true,
+		"semicolon": [true, "always"],
+		"space-before-function-paren": [
+			true,
+			{
+				"anonymous": "never",
+				"named": "never",
+				"method": "never",
+				"constructor": "never",
+				"asyncArrow": "always"
+			}
+		],
+		"space-within-parens": false,
+		"type-literal-delimiter": true,
+		"underscore-privates": true,
+		"variable-name": [true, "ban-keywords", "allow-pascal-case"],
+		"whitespace": [
+			true,
+			"check-branch",
+			"check-decl",
+			"check-operator",
+			"check-separator",
+			"check-rest-spread",
+			"check-type",
+			"check-typecast",
+			"check-preblock"
+		],
+		"jsx-alignment": true,
+		"jsx-boolean-value": true,
+		"jsx-curly-spacing": [true, "never"],
+		"jsx-no-lambda": true,
+		"jsx-no-multiline-js": false,
+		"jsx-no-string-ref": true,
+		"jsx-self-close": true,
+		"jsx-wrap-multiline": false,
+		"jsx-no-bind": false
+	},
+	"rulesDirectory": "lib"
 }
diff --git a/packages/types/package.json b/packages/types/package.json
index 42a2be4e0..a7df01bde 100644
--- a/packages/types/package.json
+++ b/packages/types/package.json
@@ -1,31 +1,31 @@
 {
-    "name": "@0xproject/types",
-    "version": "0.1.6",
-    "description": "0x types",
-    "main": "lib/index.js",
-    "types": "lib/index.d.ts",
-    "scripts": {
-        "build": "tsc",
-        "clean": "shx rm -rf lib",
-        "lint": "tslint --project . 'src/**/*.ts'"
-    },
-    "license": "Apache-2.0",
-    "repository": {
-        "type": "git",
-        "url": "https://github.com/0xProject/0x.js.git"
-    },
-    "bugs": {
-        "url": "https://github.com/0xProject/0x.js/issues"
-    },
-    "homepage": "https://github.com/0xProject/0x.js/packages/types/README.md",
-    "devDependencies": {
-        "@0xproject/tslint-config": "^0.4.4",
-        "shx": "^0.2.2",
-        "tslint": "5.8.0",
-        "typescript": "~2.6.1"
-    },
-    "dependencies": {
-        "@0xproject/utils": "^0.2.2",
-        "web3": "^0.20.0"
-    }
+	"name": "@0xproject/types",
+	"version": "0.1.6",
+	"description": "0x types",
+	"main": "lib/index.js",
+	"types": "lib/index.d.ts",
+	"scripts": {
+		"build": "tsc",
+		"clean": "shx rm -rf lib",
+		"lint": "tslint --project . 'src/**/*.ts'"
+	},
+	"license": "Apache-2.0",
+	"repository": {
+		"type": "git",
+		"url": "https://github.com/0xProject/0x.js.git"
+	},
+	"bugs": {
+		"url": "https://github.com/0xProject/0x.js/issues"
+	},
+	"homepage": "https://github.com/0xProject/0x.js/packages/types/README.md",
+	"devDependencies": {
+		"@0xproject/tslint-config": "^0.4.4",
+		"shx": "^0.2.2",
+		"tslint": "5.8.0",
+		"typescript": "~2.6.1"
+	},
+	"dependencies": {
+		"@0xproject/utils": "^0.2.2",
+		"web3": "^0.20.0"
+	}
 }
diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts
index 9cf9bc7af..f8d211052 100644
--- a/packages/types/src/index.ts
+++ b/packages/types/src/index.ts
@@ -2,26 +2,26 @@ import { BigNumber } from '@0xproject/utils';
 import * as Web3 from 'web3';
 
 export interface TxData {
-    from?: string;
-    gas?: number;
-    gasPrice?: BigNumber;
-    nonce?: number;
+	from?: string;
+	gas?: number;
+	gasPrice?: BigNumber;
+	nonce?: number;
 }
 
 export interface TxDataPayable extends TxData {
-    value?: BigNumber;
+	value?: BigNumber;
 }
 
 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[];
+	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/packages/types/tsconfig.json b/packages/types/tsconfig.json
index 3d967d05f..fc88c962d 100644
--- a/packages/types/tsconfig.json
+++ b/packages/types/tsconfig.json
@@ -1,7 +1,7 @@
 {
-    "extends": "../../tsconfig",
-    "compilerOptions": {
-        "outDir": "lib"
-    },
-    "include": ["./src/**/*", "../../node_modules/web3-typescript-typings/index.d.ts"]
+	"extends": "../../tsconfig",
+	"compilerOptions": {
+		"outDir": "lib"
+	},
+	"include": ["./src/**/*", "../../node_modules/web3-typescript-typings/index.d.ts"]
 }
diff --git a/packages/types/tslint.json b/packages/types/tslint.json
index ffaefe83a..e63054bfc 100644
--- a/packages/types/tslint.json
+++ b/packages/types/tslint.json
@@ -1,3 +1,3 @@
 {
-    "extends": ["@0xproject/tslint-config"]
+	"extends": ["@0xproject/tslint-config"]
 }
diff --git a/packages/utils/package.json b/packages/utils/package.json
index 47a297859..7a5a10337 100644
--- a/packages/utils/package.json
+++ b/packages/utils/package.json
@@ -1,34 +1,34 @@
 {
-    "name": "@0xproject/utils",
-    "version": "0.2.2",
-    "description": "0x TS utils",
-    "main": "lib/index.js",
-    "types": "lib/index.d.ts",
-    "scripts": {
-        "build": "tsc",
-        "clean": "shx rm -rf lib",
-        "lint": "tslint --project . 'src/**/*.ts'"
-    },
-    "license": "Apache-2.0",
-    "repository": {
-        "type": "git",
-        "url": "https://github.com/0xProject/0x.js.git"
-    },
-    "bugs": {
-        "url": "https://github.com/0xProject/0x.js/issues"
-    },
-    "homepage": "https://github.com/0xProject/0x.js/packages/utils/README.md",
-    "devDependencies": {
-        "@0xproject/tslint-config": "^0.4.4",
-        "@types/lodash": "^4.14.86",
-        "npm-run-all": "^4.1.2",
-        "shx": "^0.2.2",
-        "tslint": "5.8.0",
-        "typescript": "~2.6.1"
-    },
-    "dependencies": {
-        "bignumber.js": "~4.1.0",
-        "js-sha3": "^0.7.0",
-        "lodash": "^4.17.4"
-    }
+	"name": "@0xproject/utils",
+	"version": "0.2.2",
+	"description": "0x TS utils",
+	"main": "lib/index.js",
+	"types": "lib/index.d.ts",
+	"scripts": {
+		"build": "tsc",
+		"clean": "shx rm -rf lib",
+		"lint": "tslint --project . 'src/**/*.ts'"
+	},
+	"license": "Apache-2.0",
+	"repository": {
+		"type": "git",
+		"url": "https://github.com/0xProject/0x.js.git"
+	},
+	"bugs": {
+		"url": "https://github.com/0xProject/0x.js/issues"
+	},
+	"homepage": "https://github.com/0xProject/0x.js/packages/utils/README.md",
+	"devDependencies": {
+		"@0xproject/tslint-config": "^0.4.4",
+		"@types/lodash": "^4.14.86",
+		"npm-run-all": "^4.1.2",
+		"shx": "^0.2.2",
+		"tslint": "5.8.0",
+		"typescript": "~2.6.1"
+	},
+	"dependencies": {
+		"bignumber.js": "~4.1.0",
+		"js-sha3": "^0.7.0",
+		"lodash": "^4.17.4"
+	}
 }
diff --git a/packages/utils/src/address_utils.ts b/packages/utils/src/address_utils.ts
index f94985441..07042cb43 100644
--- a/packages/utils/src/address_utils.ts
+++ b/packages/utils/src/address_utils.ts
@@ -4,33 +4,33 @@ const BASIC_ADDRESS_REGEX = /^(0x)?[0-9a-f]{40}$/i;
 const SAME_CASE_ADDRESS_REGEX = /^(0x)?([0-9a-f]{40}|[0-9A-F]{40})$/;
 
 export const addressUtils = {
-    isChecksumAddress(address: string): boolean {
-        // Check each case
-        const unprefixedAddress = address.replace('0x', '');
-        const addressHash = jsSHA3.keccak256(unprefixedAddress.toLowerCase());
+	isChecksumAddress(address: string): boolean {
+		// Check each case
+		const unprefixedAddress = address.replace('0x', '');
+		const addressHash = jsSHA3.keccak256(unprefixedAddress.toLowerCase());
 
-        for (let i = 0; i < 40; i++) {
-            // The nth letter should be uppercase if the nth digit of casemap is 1
-            if (
-                (parseInt(addressHash[i], 16) > 7 && unprefixedAddress[i].toUpperCase() !== unprefixedAddress[i]) ||
-                (parseInt(addressHash[i], 16) <= 7 && unprefixedAddress[i].toLowerCase() !== unprefixedAddress[i])
-            ) {
-                return false;
-            }
-        }
-        return true;
-    },
-    isAddress(address: string): boolean {
-        if (!BASIC_ADDRESS_REGEX.test(address)) {
-            // Check if it has the basic requirements of an address
-            return false;
-        } else if (SAME_CASE_ADDRESS_REGEX.test(address)) {
-            // If it's all small caps or all all caps, return true
-            return true;
-        } else {
-            // Otherwise check each case
-            const isValidChecksummedAddress = addressUtils.isChecksumAddress(address);
-            return isValidChecksummedAddress;
-        }
-    },
+		for (let i = 0; i < 40; i++) {
+			// The nth letter should be uppercase if the nth digit of casemap is 1
+			if (
+				(parseInt(addressHash[i], 16) > 7 && unprefixedAddress[i].toUpperCase() !== unprefixedAddress[i]) ||
+				(parseInt(addressHash[i], 16) <= 7 && unprefixedAddress[i].toLowerCase() !== unprefixedAddress[i])
+			) {
+				return false;
+			}
+		}
+		return true;
+	},
+	isAddress(address: string): boolean {
+		if (!BASIC_ADDRESS_REGEX.test(address)) {
+			// Check if it has the basic requirements of an address
+			return false;
+		} else if (SAME_CASE_ADDRESS_REGEX.test(address)) {
+			// If it's all small caps or all all caps, return true
+			return true;
+		} else {
+			// Otherwise check each case
+			const isValidChecksummedAddress = addressUtils.isChecksumAddress(address);
+			return isValidChecksummedAddress;
+		}
+	},
 };
diff --git a/packages/utils/src/class_utils.ts b/packages/utils/src/class_utils.ts
index 04e60ee57..7fb011f91 100644
--- a/packages/utils/src/class_utils.ts
+++ b/packages/utils/src/class_utils.ts
@@ -1,18 +1,18 @@
 import * as _ from 'lodash';
 
 export const classUtils = {
-    // This is useful for classes that have nested methods. Nested methods don't get bound out of the box.
-    bindAll(self: any, exclude: string[] = ['contructor'], thisArg?: any): void {
-        for (const key of Object.getOwnPropertyNames(self)) {
-            const val = self[key];
-            if (!_.includes(exclude, key)) {
-                if (_.isFunction(val)) {
-                    self[key] = val.bind(thisArg || self);
-                } else if (_.isObject(val)) {
-                    classUtils.bindAll(val, exclude, self);
-                }
-            }
-        }
-        return self;
-    },
+	// This is useful for classes that have nested methods. Nested methods don't get bound out of the box.
+	bindAll(self: any, exclude: string[] = ['contructor'], thisArg?: any): void {
+		for (const key of Object.getOwnPropertyNames(self)) {
+			const val = self[key];
+			if (!_.includes(exclude, key)) {
+				if (_.isFunction(val)) {
+					self[key] = val.bind(thisArg || self);
+				} else if (_.isObject(val)) {
+					classUtils.bindAll(val, exclude, self);
+				}
+			}
+		}
+		return self;
+	},
 };
diff --git a/packages/utils/src/configured_bignumber.ts b/packages/utils/src/configured_bignumber.ts
index e44c062c2..d819e9365 100644
--- a/packages/utils/src/configured_bignumber.ts
+++ b/packages/utils/src/configured_bignumber.ts
@@ -3,7 +3,7 @@ import { BigNumber } from 'bignumber.js';
 // 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,
+	EXPONENTIAL_AT: 1000,
 });
 
 export { BigNumber };
diff --git a/packages/utils/src/interval_utils.ts b/packages/utils/src/interval_utils.ts
index ebecc7015..65e51677b 100644
--- a/packages/utils/src/interval_utils.ts
+++ b/packages/utils/src/interval_utils.ts
@@ -1,37 +1,37 @@
 import * as _ from 'lodash';
 
 export const intervalUtils = {
-    setAsyncExcludingInterval(fn: () => Promise<void>, intervalMs: number, onError: (err: Error) => void) {
-        let locked = false;
-        const intervalId = setInterval(async () => {
-            if (locked) {
-                return;
-            } else {
-                locked = true;
-                try {
-                    await fn();
-                } catch (err) {
-                    onError(err);
-                }
-                locked = false;
-            }
-        }, intervalMs);
-        return intervalId;
-    },
-    clearAsyncExcludingInterval(intervalId: NodeJS.Timer): void {
-        clearInterval(intervalId);
-    },
-    setInterval(fn: () => void, intervalMs: number, onError: (err: Error) => void) {
-        const intervalId = setInterval(() => {
-            try {
-                fn();
-            } catch (err) {
-                onError(err);
-            }
-        }, intervalMs);
-        return intervalId;
-    },
-    clearInterval(intervalId: NodeJS.Timer): void {
-        clearInterval(intervalId);
-    },
+	setAsyncExcludingInterval(fn: () => Promise<void>, intervalMs: number, onError: (err: Error) => void) {
+		let locked = false;
+		const intervalId = setInterval(async () => {
+			if (locked) {
+				return;
+			} else {
+				locked = true;
+				try {
+					await fn();
+				} catch (err) {
+					onError(err);
+				}
+				locked = false;
+			}
+		}, intervalMs);
+		return intervalId;
+	},
+	clearAsyncExcludingInterval(intervalId: NodeJS.Timer): void {
+		clearInterval(intervalId);
+	},
+	setInterval(fn: () => void, intervalMs: number, onError: (err: Error) => void) {
+		const intervalId = setInterval(() => {
+			try {
+				fn();
+			} catch (err) {
+				onError(err);
+			}
+		}, intervalMs);
+		return intervalId;
+	},
+	clearInterval(intervalId: NodeJS.Timer): void {
+		clearInterval(intervalId);
+	},
 };
diff --git a/packages/utils/src/promisify.ts b/packages/utils/src/promisify.ts
index 29d626b61..6b29664f9 100644
--- a/packages/utils/src/promisify.ts
+++ b/packages/utils/src/promisify.ts
@@ -7,13 +7,13 @@ import * as _ from 'lodash';
  */
 // HACK: This can't be properly typed without variadic kinds https://github.com/Microsoft/TypeScript/issues/5453
 export function promisify<T>(originalFn: (...args: any[]) => void, thisArg?: any): (...callArgs: any[]) => Promise<T> {
-    const promisifiedFunction = async (...callArgs: any[]): Promise<T> => {
-        return new Promise<T>((resolve, reject) => {
-            const callback = (err: Error | null, data?: T) => {
-                _.isNull(err) ? resolve(data) : reject(err);
-            };
-            originalFn.apply(thisArg, [...callArgs, callback]);
-        });
-    };
-    return promisifiedFunction;
+	const promisifiedFunction = async (...callArgs: any[]): Promise<T> => {
+		return new Promise<T>((resolve, reject) => {
+			const callback = (err: Error | null, data?: T) => {
+				_.isNull(err) ? resolve(data) : reject(err);
+			};
+			originalFn.apply(thisArg, [...callArgs, callback]);
+		});
+	};
+	return promisifiedFunction;
 }
diff --git a/packages/utils/tsconfig.json b/packages/utils/tsconfig.json
index 3d967d05f..fc88c962d 100644
--- a/packages/utils/tsconfig.json
+++ b/packages/utils/tsconfig.json
@@ -1,7 +1,7 @@
 {
-    "extends": "../../tsconfig",
-    "compilerOptions": {
-        "outDir": "lib"
-    },
-    "include": ["./src/**/*", "../../node_modules/web3-typescript-typings/index.d.ts"]
+	"extends": "../../tsconfig",
+	"compilerOptions": {
+		"outDir": "lib"
+	},
+	"include": ["./src/**/*", "../../node_modules/web3-typescript-typings/index.d.ts"]
 }
diff --git a/packages/utils/tslint.json b/packages/utils/tslint.json
index ffaefe83a..e63054bfc 100644
--- a/packages/utils/tslint.json
+++ b/packages/utils/tslint.json
@@ -1,3 +1,3 @@
 {
-    "extends": ["@0xproject/tslint-config"]
+	"extends": ["@0xproject/tslint-config"]
 }
diff --git a/packages/web3-typescript-typings/index.d.ts b/packages/web3-typescript-typings/index.d.ts
index cd34759ed..b610d0e48 100644
--- a/packages/web3-typescript-typings/index.d.ts
+++ b/packages/web3-typescript-typings/index.d.ts
@@ -1,422 +1,422 @@
 declare module 'web3' {
-    import * as BigNumber from 'bignumber.js';
-
-    type MixedData = string | number | object | any[] | BigNumber.BigNumber;
-
-    class Web3 {
-        public static providers: typeof providers;
-        public currentProvider: Web3.Provider;
-
-        public eth: Web3.EthApi;
-        public personal: Web3.PersonalApi | undefined;
-        public version: Web3.VersionApi;
-        public net: Web3.NetApi;
-
-        public constructor(provider?: Web3.Provider);
-
-        public isConnected(): boolean;
-        public setProvider(provider: Web3.Provider): void;
-        public reset(keepIsSyncing: boolean): void;
-        public toHex(data: MixedData): string;
-        public toAscii(hex: string): string;
-        public fromAscii(ascii: string, padding?: number): string;
-        public toDecimal(hex: string): number;
-        public fromDecimal(value: number | string): string;
-        public fromWei(value: number | string, unit: Web3.Unit): string;
-        public fromWei(value: BigNumber.BigNumber, unit: Web3.Unit): BigNumber.BigNumber;
-        public toWei(amount: number | string, unit: Web3.Unit): string;
-        public toWei(amount: BigNumber.BigNumber, unit: Web3.Unit): BigNumber.BigNumber;
-        public toBigNumber(value: number | string): BigNumber.BigNumber;
-        public isAddress(address: string): boolean;
-        public isChecksumAddress(address: string): boolean;
-        public sha3(value: string, options?: Web3.Sha3Options): string;
-    }
-
-    namespace providers {
-        class HttpProvider implements Web3.Provider {
-            constructor(url?: string, timeout?: number, username?: string, password?: string);
-            public sendAsync(
-                payload: Web3.JSONRPCRequestPayload,
-                callback: (err: Error, result: Web3.JSONRPCResponsePayload) => void,
-            ): void;
-        }
-    }
-
-    namespace Web3 {
-        type ContractAbi = AbiDefinition[];
-
-        type AbiDefinition = FunctionAbi | EventAbi;
-
-        type FunctionAbi = MethodAbi | ConstructorAbi | FallbackAbi;
-
-        enum AbiType {
-            Function = 'function',
-            Constructor = 'constructor',
-            Event = 'event',
-            Fallback = 'fallback',
-        }
-
-        type ConstructorStateMutability = 'nonpayable' | 'payable';
-        type StateMutability = 'pure' | 'view' | ConstructorStateMutability;
-
-        interface MethodAbi {
-            type: AbiType.Function;
-            name: string;
-            inputs: FunctionParameter[];
-            outputs: FunctionParameter[];
-            constant: boolean;
-            stateMutability: StateMutability;
-            payable: boolean;
-        }
-
-        interface ConstructorAbi {
-            type: AbiType.Constructor;
-            inputs: FunctionParameter[];
-            payable: boolean;
-            stateMutability: ConstructorStateMutability;
-        }
-
-        interface FallbackAbi {
-            type: AbiType.Fallback;
-            payable: boolean;
-        }
-
-        interface EventParameter {
-            name: string;
-            type: string;
-            indexed: boolean;
-        }
-
-        interface EventAbi {
-            type: AbiType.Event;
-            name: string;
-            inputs: EventParameter[];
-            anonymous: boolean;
-        }
-
-        interface FunctionParameter {
-            name: string;
-            type: string;
-        }
-
-        interface ContractInstance {
-            address: string;
-            abi: Web3.ContractAbi;
-            [name: string]: any;
-        }
-
-        interface Contract<A extends ContractInstance> {
-            at(address: string): A;
-            getData(...args: any[]): string;
-            'new'(...args: any[]): A;
-        }
-
-        interface FilterObject {
-            fromBlock?: number | string;
-            toBlock?: number | string;
-            address?: string;
-            topics?: LogTopic[];
-        }
-
-        type LogTopic = null | string | string[];
-
-        interface DecodedLogEntry<A> extends LogEntry {
-            event: string;
-            args: A;
-        }
-
-        interface DecodedLogEntryEvent<A> extends DecodedLogEntry<A> {
-            removed: boolean;
-        }
-
-        interface LogEntryEvent extends LogEntry {
-            removed: boolean;
-        }
-
-        interface FilterResult {
-            get(callback: () => void): void;
-            watch(callback: (err: Error, result: LogEntryEvent) => void): void;
-            stopWatching(callback?: () => void): void;
-        }
-
-        export interface JSONRPCRequestPayload {
-            params: any[];
-            method: string;
-            id: number;
-            jsonrpc: string;
-        }
-
-        export interface JSONRPCResponsePayload {
-            result: any;
-            id: number;
-            jsonrpc: string;
-        }
-
-        interface Provider {
-            sendAsync(
-                payload: JSONRPCRequestPayload,
-                callback: (err: Error, result: JSONRPCResponsePayload) => void,
-            ): void;
-        }
-
-        interface Sha3Options {
-            encoding: 'hex';
-        }
-
-        interface EthApi {
-            coinbase: string;
-            mining: boolean;
-            hashrate: number;
-            gasPrice: BigNumber.BigNumber;
-            accounts: string[];
-            blockNumber: number;
-            defaultAccount?: string;
-            defaultBlock: Web3.BlockParam;
-            syncing: Web3.SyncingResult;
-            compile: {
-                solidity(sourceString: string, cb?: (err: Error, result: any) => void): object;
-            };
-            getMining(cd: (err: Error, mining: boolean) => void): void;
-            getHashrate(cd: (err: Error, hashrate: number) => void): void;
-            getGasPrice(cd: (err: Error, gasPrice: BigNumber.BigNumber) => void): void;
-            getAccounts(cd: (err: Error, accounts: string[]) => void): void;
-            getBlockNumber(callback: (err: Error, blockNumber: number) => void): void;
-            getSyncing(cd: (err: Error, syncing: Web3.SyncingResult) => void): void;
-            isSyncing(cb: (err: Error, isSyncing: boolean, syncingState: Web3.SyncingState) => void): Web3.IsSyncing;
-
-            getBlock(hashStringOrBlockNumber: string | Web3.BlockParam): Web3.BlockWithoutTransactionData;
-            getBlock(
-                hashStringOrBlockNumber: string | Web3.BlockParam,
-                callback: (err: Error, blockObj: Web3.BlockWithoutTransactionData) => void,
-            ): void;
-            getBlock(
-                hashStringOrBlockNumber: string | Web3.BlockParam,
-                returnTransactionObjects: true,
-            ): Web3.BlockWithTransactionData;
-            getBlock(
-                hashStringOrBlockNumber: string | Web3.BlockParam,
-                returnTransactionObjects: true,
-                callback: (err: Error, blockObj: Web3.BlockWithTransactionData) => void,
-            ): void;
-
-            getBlockTransactionCount(hashStringOrBlockNumber: string | Web3.BlockParam): number;
-            getBlockTransactionCount(
-                hashStringOrBlockNumber: string | Web3.BlockParam,
-                callback: (err: Error, blockTransactionCount: number) => void,
-            ): void;
-
-            // TODO returnTransactionObjects
-            getUncle(
-                hashStringOrBlockNumber: string | Web3.BlockParam,
-                uncleNumber: number,
-            ): Web3.BlockWithoutTransactionData;
-            getUncle(
-                hashStringOrBlockNumber: string | Web3.BlockParam,
-                uncleNumber: number,
-                callback: (err: Error, uncle: Web3.BlockWithoutTransactionData) => void,
-            ): void;
-
-            getTransaction(transactionHash: string): Web3.Transaction;
-            getTransaction(
-                transactionHash: string,
-                callback: (err: Error, transaction: Web3.Transaction) => void,
-            ): void;
-
-            getTransactionFromBlock(
-                hashStringOrBlockNumber: string | Web3.BlockParam,
-                indexNumber: number,
-            ): Web3.Transaction;
-            getTransactionFromBlock(
-                hashStringOrBlockNumber: string | Web3.BlockParam,
-                indexNumber: number,
-                callback: (err: Error, transaction: Web3.Transaction) => void,
-            ): void;
-
-            contract(abi: Web3.AbiDefinition[]): Web3.Contract<any>;
-
-            // TODO block param
-            getBalance(addressHexString: string): BigNumber.BigNumber;
-            getBalance(addressHexString: string, callback: (err: Error, result: BigNumber.BigNumber) => void): void;
-
-            // TODO block param
-            getStorageAt(address: string, position: number): string;
-            getStorageAt(address: string, position: number, callback: (err: Error, storage: string) => void): void;
-
-            // TODO block param
-            getCode(addressHexString: string): string;
-            getCode(addressHexString: string, callback: (err: Error, code: string) => void): void;
-
-            filter(value: string | Web3.FilterObject): Web3.FilterResult;
-
-            sendTransaction(txData: Web3.TxData): string;
-            sendTransaction(txData: Web3.TxData, callback: (err: Error, value: string) => void): void;
-
-            sendRawTransaction(rawTxData: string): string;
-            sendRawTransaction(rawTxData: string, callback: (err: Error, value: string) => void): void;
-
-            sign(address: string, data: string): string;
-            sign(address: string, data: string, callback: (err: Error, signature: string) => void): void;
-
-            getTransactionReceipt(txHash: string): Web3.TransactionReceipt | null;
-            getTransactionReceipt(
-                txHash: string,
-                callback: (err: Error, receipt: Web3.TransactionReceipt | null) => void,
-            ): void;
-
-            // TODO block param
-            call(callData: Web3.CallData): string;
-            call(callData: Web3.CallData, callback: (err: Error, result: string) => void): void;
-
-            estimateGas(callData: Web3.CallData): number;
-            estimateGas(callData: Web3.CallData, callback: (err: Error, gas: number) => void): void;
-
-            // TODO defaultBlock
-            getTransactionCount(address: string): number;
-            getTransactionCount(address: string, callback: (err: Error, count: number) => void): void;
-        }
-
-        interface VersionApi {
-            api: string;
-            network: string;
-            node: string;
-            ethereum: string;
-            whisper: string;
-            getNetwork(cd: (err: Error, networkId: string) => void): void;
-            getNode(cd: (err: Error, nodeVersion: string) => void): void;
-            getEthereum(cd: (err: Error, ethereum: string) => void): void;
-            getWhisper(cd: (err: Error, whisper: string) => void): void;
-        }
-
-        interface PersonalApi {
-            listAccounts: string[] | undefined;
-            newAccount(password?: string): string;
-            unlockAccount(address: string, password?: string, duration?: number): boolean;
-            lockAccount(address: string): boolean;
-            sign(message: string, account: string, password: string): string;
-            sign(hexMessage: string, account: string, callback: (error: Error, signature: string) => void): void;
-        }
-
-        interface NetApi {
-            listening: boolean;
-            peerCount: boolean;
-            getListening(cd: (err: Error, listening: boolean) => void): void;
-            getPeerCount(cd: (err: Error, peerCount: number) => void): void;
-        }
-
-        type BlockParam = number | 'earliest' | 'latest' | 'pending';
-
-        type Unit =
-            | 'kwei'
-            | 'ada'
-            | 'mwei'
-            | 'babbage'
-            | 'gwei'
-            | 'shannon'
-            | 'szabo'
-            | 'finney'
-            | 'ether'
-            | 'kether'
-            | 'grand'
-            | 'einstein'
-            | 'mether'
-            | 'gether'
-            | 'tether';
-
-        interface SyncingState {
-            startingBlock: number;
-            currentBlock: number;
-            highestBlock: number;
-        }
-        type SyncingResult = false | SyncingState;
-
-        interface IsSyncing {
-            addCallback(cb: (err: Error, isSyncing: boolean, syncingState: SyncingState) => void): void;
-            stopWatching(): void;
-        }
-
-        interface AbstractBlock {
-            number: number | null;
-            hash: string | null;
-            parentHash: string;
-            nonce: string | null;
-            sha3Uncles: string;
-            logsBloom: string | null;
-            transactionsRoot: string;
-            stateRoot: string;
-            miner: string;
-            difficulty: BigNumber.BigNumber;
-            totalDifficulty: BigNumber.BigNumber;
-            extraData: string;
-            size: number;
-            gasLimit: number;
-            gasUsed: number;
-            timestamp: number;
-            uncles: string[];
-        }
-        interface BlockWithoutTransactionData extends AbstractBlock {
-            transactions: string[];
-        }
-        interface BlockWithTransactionData extends AbstractBlock {
-            transactions: Transaction[];
-        }
-
-        interface Transaction {
-            hash: string;
-            nonce: number;
-            blockHash: string | null;
-            blockNumber: number | null;
-            transactionIndex: number | null;
-            from: string;
-            to: string | null;
-            value: BigNumber.BigNumber;
-            gasPrice: BigNumber.BigNumber;
-            gas: number;
-            input: string;
-        }
-
-        interface CallTxDataBase {
-            to?: string;
-            value?: number | string | BigNumber.BigNumber;
-            gas?: number | string | BigNumber.BigNumber;
-            gasPrice?: number | string | BigNumber.BigNumber;
-            data?: string;
-            nonce?: number;
-        }
-
-        interface TxData extends CallTxDataBase {
-            from: string;
-        }
-
-        interface CallData extends CallTxDataBase {
-            from?: string;
-        }
-
-        interface TransactionReceipt {
-            blockHash: string;
-            blockNumber: number;
-            transactionHash: string;
-            transactionIndex: number;
-            from: string;
-            to: string;
-            status: null | string | 0 | 1;
-            cumulativeGasUsed: number;
-            gasUsed: number;
-            contractAddress: string | null;
-            logs: LogEntry[];
-        }
-
-        interface LogEntry {
-            logIndex: number | null;
-            transactionIndex: number | null;
-            transactionHash: string;
-            blockHash: string | null;
-            blockNumber: number | null;
-            address: string;
-            data: string;
-            topics: string[];
-        }
-    }
-    /* tslint:disable */
-    export = Web3;
-    /* tslint:enable */
+	import * as BigNumber from 'bignumber.js';
+
+	type MixedData = string | number | object | any[] | BigNumber.BigNumber;
+
+	class Web3 {
+		public static providers: typeof providers;
+		public currentProvider: Web3.Provider;
+
+		public eth: Web3.EthApi;
+		public personal: Web3.PersonalApi | undefined;
+		public version: Web3.VersionApi;
+		public net: Web3.NetApi;
+
+		public constructor(provider?: Web3.Provider);
+
+		public isConnected(): boolean;
+		public setProvider(provider: Web3.Provider): void;
+		public reset(keepIsSyncing: boolean): void;
+		public toHex(data: MixedData): string;
+		public toAscii(hex: string): string;
+		public fromAscii(ascii: string, padding?: number): string;
+		public toDecimal(hex: string): number;
+		public fromDecimal(value: number | string): string;
+		public fromWei(value: number | string, unit: Web3.Unit): string;
+		public fromWei(value: BigNumber.BigNumber, unit: Web3.Unit): BigNumber.BigNumber;
+		public toWei(amount: number | string, unit: Web3.Unit): string;
+		public toWei(amount: BigNumber.BigNumber, unit: Web3.Unit): BigNumber.BigNumber;
+		public toBigNumber(value: number | string): BigNumber.BigNumber;
+		public isAddress(address: string): boolean;
+		public isChecksumAddress(address: string): boolean;
+		public sha3(value: string, options?: Web3.Sha3Options): string;
+	}
+
+	namespace providers {
+		class HttpProvider implements Web3.Provider {
+			constructor(url?: string, timeout?: number, username?: string, password?: string);
+			public sendAsync(
+				payload: Web3.JSONRPCRequestPayload,
+				callback: (err: Error, result: Web3.JSONRPCResponsePayload) => void,
+			): void;
+		}
+	}
+
+	namespace Web3 {
+		type ContractAbi = AbiDefinition[];
+
+		type AbiDefinition = FunctionAbi | EventAbi;
+
+		type FunctionAbi = MethodAbi | ConstructorAbi | FallbackAbi;
+
+		enum AbiType {
+			Function = 'function',
+			Constructor = 'constructor',
+			Event = 'event',
+			Fallback = 'fallback',
+		}
+
+		type ConstructorStateMutability = 'nonpayable' | 'payable';
+		type StateMutability = 'pure' | 'view' | ConstructorStateMutability;
+
+		interface MethodAbi {
+			type: AbiType.Function;
+			name: string;
+			inputs: FunctionParameter[];
+			outputs: FunctionParameter[];
+			constant: boolean;
+			stateMutability: StateMutability;
+			payable: boolean;
+		}
+
+		interface ConstructorAbi {
+			type: AbiType.Constructor;
+			inputs: FunctionParameter[];
+			payable: boolean;
+			stateMutability: ConstructorStateMutability;
+		}
+
+		interface FallbackAbi {
+			type: AbiType.Fallback;
+			payable: boolean;
+		}
+
+		interface EventParameter {
+			name: string;
+			type: string;
+			indexed: boolean;
+		}
+
+		interface EventAbi {
+			type: AbiType.Event;
+			name: string;
+			inputs: EventParameter[];
+			anonymous: boolean;
+		}
+
+		interface FunctionParameter {
+			name: string;
+			type: string;
+		}
+
+		interface ContractInstance {
+			address: string;
+			abi: Web3.ContractAbi;
+			[name: string]: any;
+		}
+
+		interface Contract<A extends ContractInstance> {
+			at(address: string): A;
+			getData(...args: any[]): string;
+			'new'(...args: any[]): A;
+		}
+
+		interface FilterObject {
+			fromBlock?: number | string;
+			toBlock?: number | string;
+			address?: string;
+			topics?: LogTopic[];
+		}
+
+		type LogTopic = null | string | string[];
+
+		interface DecodedLogEntry<A> extends LogEntry {
+			event: string;
+			args: A;
+		}
+
+		interface DecodedLogEntryEvent<A> extends DecodedLogEntry<A> {
+			removed: boolean;
+		}
+
+		interface LogEntryEvent extends LogEntry {
+			removed: boolean;
+		}
+
+		interface FilterResult {
+			get(callback: () => void): void;
+			watch(callback: (err: Error, result: LogEntryEvent) => void): void;
+			stopWatching(callback?: () => void): void;
+		}
+
+		export interface JSONRPCRequestPayload {
+			params: any[];
+			method: string;
+			id: number;
+			jsonrpc: string;
+		}
+
+		export interface JSONRPCResponsePayload {
+			result: any;
+			id: number;
+			jsonrpc: string;
+		}
+
+		interface Provider {
+			sendAsync(
+				payload: JSONRPCRequestPayload,
+				callback: (err: Error, result: JSONRPCResponsePayload) => void,
+			): void;
+		}
+
+		interface Sha3Options {
+			encoding: 'hex';
+		}
+
+		interface EthApi {
+			coinbase: string;
+			mining: boolean;
+			hashrate: number;
+			gasPrice: BigNumber.BigNumber;
+			accounts: string[];
+			blockNumber: number;
+			defaultAccount?: string;
+			defaultBlock: Web3.BlockParam;
+			syncing: Web3.SyncingResult;
+			compile: {
+				solidity(sourceString: string, cb?: (err: Error, result: any) => void): object;
+			};
+			getMining(cd: (err: Error, mining: boolean) => void): void;
+			getHashrate(cd: (err: Error, hashrate: number) => void): void;
+			getGasPrice(cd: (err: Error, gasPrice: BigNumber.BigNumber) => void): void;
+			getAccounts(cd: (err: Error, accounts: string[]) => void): void;
+			getBlockNumber(callback: (err: Error, blockNumber: number) => void): void;
+			getSyncing(cd: (err: Error, syncing: Web3.SyncingResult) => void): void;
+			isSyncing(cb: (err: Error, isSyncing: boolean, syncingState: Web3.SyncingState) => void): Web3.IsSyncing;
+
+			getBlock(hashStringOrBlockNumber: string | Web3.BlockParam): Web3.BlockWithoutTransactionData;
+			getBlock(
+				hashStringOrBlockNumber: string | Web3.BlockParam,
+				callback: (err: Error, blockObj: Web3.BlockWithoutTransactionData) => void,
+			): void;
+			getBlock(
+				hashStringOrBlockNumber: string | Web3.BlockParam,
+				returnTransactionObjects: true,
+			): Web3.BlockWithTransactionData;
+			getBlock(
+				hashStringOrBlockNumber: string | Web3.BlockParam,
+				returnTransactionObjects: true,
+				callback: (err: Error, blockObj: Web3.BlockWithTransactionData) => void,
+			): void;
+
+			getBlockTransactionCount(hashStringOrBlockNumber: string | Web3.BlockParam): number;
+			getBlockTransactionCount(
+				hashStringOrBlockNumber: string | Web3.BlockParam,
+				callback: (err: Error, blockTransactionCount: number) => void,
+			): void;
+
+			// TODO returnTransactionObjects
+			getUncle(
+				hashStringOrBlockNumber: string | Web3.BlockParam,
+				uncleNumber: number,
+			): Web3.BlockWithoutTransactionData;
+			getUncle(
+				hashStringOrBlockNumber: string | Web3.BlockParam,
+				uncleNumber: number,
+				callback: (err: Error, uncle: Web3.BlockWithoutTransactionData) => void,
+			): void;
+
+			getTransaction(transactionHash: string): Web3.Transaction;
+			getTransaction(
+				transactionHash: string,
+				callback: (err: Error, transaction: Web3.Transaction) => void,
+			): void;
+
+			getTransactionFromBlock(
+				hashStringOrBlockNumber: string | Web3.BlockParam,
+				indexNumber: number,
+			): Web3.Transaction;
+			getTransactionFromBlock(
+				hashStringOrBlockNumber: string | Web3.BlockParam,
+				indexNumber: number,
+				callback: (err: Error, transaction: Web3.Transaction) => void,
+			): void;
+
+			contract(abi: Web3.AbiDefinition[]): Web3.Contract<any>;
+
+			// TODO block param
+			getBalance(addressHexString: string): BigNumber.BigNumber;
+			getBalance(addressHexString: string, callback: (err: Error, result: BigNumber.BigNumber) => void): void;
+
+			// TODO block param
+			getStorageAt(address: string, position: number): string;
+			getStorageAt(address: string, position: number, callback: (err: Error, storage: string) => void): void;
+
+			// TODO block param
+			getCode(addressHexString: string): string;
+			getCode(addressHexString: string, callback: (err: Error, code: string) => void): void;
+
+			filter(value: string | Web3.FilterObject): Web3.FilterResult;
+
+			sendTransaction(txData: Web3.TxData): string;
+			sendTransaction(txData: Web3.TxData, callback: (err: Error, value: string) => void): void;
+
+			sendRawTransaction(rawTxData: string): string;
+			sendRawTransaction(rawTxData: string, callback: (err: Error, value: string) => void): void;
+
+			sign(address: string, data: string): string;
+			sign(address: string, data: string, callback: (err: Error, signature: string) => void): void;
+
+			getTransactionReceipt(txHash: string): Web3.TransactionReceipt | null;
+			getTransactionReceipt(
+				txHash: string,
+				callback: (err: Error, receipt: Web3.TransactionReceipt | null) => void,
+			): void;
+
+			// TODO block param
+			call(callData: Web3.CallData): string;
+			call(callData: Web3.CallData, callback: (err: Error, result: string) => void): void;
+
+			estimateGas(callData: Web3.CallData): number;
+			estimateGas(callData: Web3.CallData, callback: (err: Error, gas: number) => void): void;
+
+			// TODO defaultBlock
+			getTransactionCount(address: string): number;
+			getTransactionCount(address: string, callback: (err: Error, count: number) => void): void;
+		}
+
+		interface VersionApi {
+			api: string;
+			network: string;
+			node: string;
+			ethereum: string;
+			whisper: string;
+			getNetwork(cd: (err: Error, networkId: string) => void): void;
+			getNode(cd: (err: Error, nodeVersion: string) => void): void;
+			getEthereum(cd: (err: Error, ethereum: string) => void): void;
+			getWhisper(cd: (err: Error, whisper: string) => void): void;
+		}
+
+		interface PersonalApi {
+			listAccounts: string[] | undefined;
+			newAccount(password?: string): string;
+			unlockAccount(address: string, password?: string, duration?: number): boolean;
+			lockAccount(address: string): boolean;
+			sign(message: string, account: string, password: string): string;
+			sign(hexMessage: string, account: string, callback: (error: Error, signature: string) => void): void;
+		}
+
+		interface NetApi {
+			listening: boolean;
+			peerCount: boolean;
+			getListening(cd: (err: Error, listening: boolean) => void): void;
+			getPeerCount(cd: (err: Error, peerCount: number) => void): void;
+		}
+
+		type BlockParam = number | 'earliest' | 'latest' | 'pending';
+
+		type Unit =
+			| 'kwei'
+			| 'ada'
+			| 'mwei'
+			| 'babbage'
+			| 'gwei'
+			| 'shannon'
+			| 'szabo'
+			| 'finney'
+			| 'ether'
+			| 'kether'
+			| 'grand'
+			| 'einstein'
+			| 'mether'
+			| 'gether'
+			| 'tether';
+
+		interface SyncingState {
+			startingBlock: number;
+			currentBlock: number;
+			highestBlock: number;
+		}
+		type SyncingResult = false | SyncingState;
+
+		interface IsSyncing {
+			addCallback(cb: (err: Error, isSyncing: boolean, syncingState: SyncingState) => void): void;
+			stopWatching(): void;
+		}
+
+		interface AbstractBlock {
+			number: number | null;
+			hash: string | null;
+			parentHash: string;
+			nonce: string | null;
+			sha3Uncles: string;
+			logsBloom: string | null;
+			transactionsRoot: string;
+			stateRoot: string;
+			miner: string;
+			difficulty: BigNumber.BigNumber;
+			totalDifficulty: BigNumber.BigNumber;
+			extraData: string;
+			size: number;
+			gasLimit: number;
+			gasUsed: number;
+			timestamp: number;
+			uncles: string[];
+		}
+		interface BlockWithoutTransactionData extends AbstractBlock {
+			transactions: string[];
+		}
+		interface BlockWithTransactionData extends AbstractBlock {
+			transactions: Transaction[];
+		}
+
+		interface Transaction {
+			hash: string;
+			nonce: number;
+			blockHash: string | null;
+			blockNumber: number | null;
+			transactionIndex: number | null;
+			from: string;
+			to: string | null;
+			value: BigNumber.BigNumber;
+			gasPrice: BigNumber.BigNumber;
+			gas: number;
+			input: string;
+		}
+
+		interface CallTxDataBase {
+			to?: string;
+			value?: number | string | BigNumber.BigNumber;
+			gas?: number | string | BigNumber.BigNumber;
+			gasPrice?: number | string | BigNumber.BigNumber;
+			data?: string;
+			nonce?: number;
+		}
+
+		interface TxData extends CallTxDataBase {
+			from: string;
+		}
+
+		interface CallData extends CallTxDataBase {
+			from?: string;
+		}
+
+		interface TransactionReceipt {
+			blockHash: string;
+			blockNumber: number;
+			transactionHash: string;
+			transactionIndex: number;
+			from: string;
+			to: string;
+			status: null | string | 0 | 1;
+			cumulativeGasUsed: number;
+			gasUsed: number;
+			contractAddress: string | null;
+			logs: LogEntry[];
+		}
+
+		interface LogEntry {
+			logIndex: number | null;
+			transactionIndex: number | null;
+			transactionHash: string;
+			blockHash: string | null;
+			blockNumber: number | null;
+			address: string;
+			data: string;
+			topics: string[];
+		}
+	}
+	/* tslint:disable */
+	export = Web3;
+	/* tslint:enable */
 }
diff --git a/packages/web3-typescript-typings/package.json b/packages/web3-typescript-typings/package.json
index 958a4a646..edfdd9701 100644
--- a/packages/web3-typescript-typings/package.json
+++ b/packages/web3-typescript-typings/package.json
@@ -1,32 +1,30 @@
 {
-    "name": "web3-typescript-typings",
-    "version": "0.9.6",
-    "description": "Typescript type definitions for web3",
-    "main": "index.d.ts",
-    "types": "index.d.ts",
-    "scripts": {
-        "lint": "tslint index.d.ts"
-    },
-    "repository": {
-        "type": "git",
-        "url": "git+https://github.com/0xProject/0x.js.git"
-    },
-    "author": "Fabio Berger",
-    "contributors": [
-        "Leonid Logvinov <logvinov.leon@gmail.com>"
-    ],
-    "license": "Apache-2.0",
-    "bugs": {
-        "url": "https://github.com/0xProject/0x.js/issues"
-    },
-    "homepage": "https://github.com/0xProject/0x.js/packages/web3-typescript-typings#readme",
-    "devDependencies": {
-        "@types/bignumber.js": "^4.0.2",
-        "tslint": "^5.5.0",
-        "tslint-config-0xproject": "^0.0.2",
-        "typescript": "~2.6.1"
-    },
-    "dependencies": {
-        "bignumber.js": "~4.1.0"
-    }
+	"name": "web3-typescript-typings",
+	"version": "0.9.6",
+	"description": "Typescript type definitions for web3",
+	"main": "index.d.ts",
+	"types": "index.d.ts",
+	"scripts": {
+		"lint": "tslint index.d.ts"
+	},
+	"repository": {
+		"type": "git",
+		"url": "git+https://github.com/0xProject/0x.js.git"
+	},
+	"author": "Fabio Berger",
+	"contributors": ["Leonid Logvinov <logvinov.leon@gmail.com>"],
+	"license": "Apache-2.0",
+	"bugs": {
+		"url": "https://github.com/0xProject/0x.js/issues"
+	},
+	"homepage": "https://github.com/0xProject/0x.js/packages/web3-typescript-typings#readme",
+	"devDependencies": {
+		"@types/bignumber.js": "^4.0.2",
+		"tslint": "^5.5.0",
+		"tslint-config-0xproject": "^0.0.2",
+		"typescript": "~2.6.1"
+	},
+	"dependencies": {
+		"bignumber.js": "~4.1.0"
+	}
 }
diff --git a/packages/web3-typescript-typings/tslint.json b/packages/web3-typescript-typings/tslint.json
index 9a93a1f74..ef528b22e 100644
--- a/packages/web3-typescript-typings/tslint.json
+++ b/packages/web3-typescript-typings/tslint.json
@@ -1,3 +1,3 @@
 {
-    "extends": ["tslint-config-0xproject"]
+	"extends": ["tslint-config-0xproject"]
 }
diff --git a/packages/web3-wrapper/package.json b/packages/web3-wrapper/package.json
index 6a65582f9..d45480b35 100644
--- a/packages/web3-wrapper/package.json
+++ b/packages/web3-wrapper/package.json
@@ -1,36 +1,36 @@
 {
-    "name": "@0xproject/web3-wrapper",
-    "version": "0.1.7",
-    "description": "Wraps around web3 and gives a nicer interface",
-    "main": "lib/index.js",
-    "types": "lib/index.d.ts",
-    "scripts": {
-        "build": "tsc",
-        "clean": "shx rm -rf lib",
-        "lint": "tslint --project . 'src/**/*.ts'"
-    },
-    "license": "Apache-2.0",
-    "repository": {
-        "type": "git",
-        "url": "https://github.com/0xProject/0x.js.git"
-    },
-    "bugs": {
-        "url": "https://github.com/0xProject/0x.js/issues"
-    },
-    "homepage": "https://github.com/0xProject/0x.js/packages/web3-wrapper/README.md",
-    "devDependencies": {
-        "@0xproject/tslint-config": "^0.4.4",
-        "@0xproject/types": "^0.1.6",
-        "@types/lodash": "^4.14.86",
-        "npm-run-all": "^4.1.2",
-        "shx": "^0.2.2",
-        "tslint": "5.8.0",
-        "typescript": "~2.6.1",
-        "web3-typescript-typings": "^0.9.6"
-    },
-    "dependencies": {
-        "@0xproject/utils": "^0.2.2",
-        "lodash": "^4.17.4",
-        "web3": "^0.20.0"
-    }
+	"name": "@0xproject/web3-wrapper",
+	"version": "0.1.7",
+	"description": "Wraps around web3 and gives a nicer interface",
+	"main": "lib/index.js",
+	"types": "lib/index.d.ts",
+	"scripts": {
+		"build": "tsc",
+		"clean": "shx rm -rf lib",
+		"lint": "tslint --project . 'src/**/*.ts'"
+	},
+	"license": "Apache-2.0",
+	"repository": {
+		"type": "git",
+		"url": "https://github.com/0xProject/0x.js.git"
+	},
+	"bugs": {
+		"url": "https://github.com/0xProject/0x.js/issues"
+	},
+	"homepage": "https://github.com/0xProject/0x.js/packages/web3-wrapper/README.md",
+	"devDependencies": {
+		"@0xproject/tslint-config": "^0.4.4",
+		"@0xproject/types": "^0.1.6",
+		"@types/lodash": "^4.14.86",
+		"npm-run-all": "^4.1.2",
+		"shx": "^0.2.2",
+		"tslint": "5.8.0",
+		"typescript": "~2.6.1",
+		"web3-typescript-typings": "^0.9.6"
+	},
+	"dependencies": {
+		"@0xproject/utils": "^0.2.2",
+		"lodash": "^4.17.4",
+		"web3": "^0.20.0"
+	}
 }
diff --git a/packages/web3-wrapper/src/index.ts b/packages/web3-wrapper/src/index.ts
index c4826f2be..859333448 100644
--- a/packages/web3-wrapper/src/index.ts
+++ b/packages/web3-wrapper/src/index.ts
@@ -4,170 +4,170 @@ import * as _ from 'lodash';
 import * as Web3 from 'web3';
 
 interface RawLogEntry {
-    logIndex: string | null;
-    transactionIndex: string | null;
-    transactionHash: string;
-    blockHash: string | null;
-    blockNumber: string | null;
-    address: string;
-    data: string;
-    topics: string[];
+	logIndex: string | null;
+	transactionIndex: string | null;
+	transactionHash: string;
+	blockHash: string | null;
+	blockNumber: string | null;
+	address: string;
+	data: string;
+	topics: string[];
 }
 
 export class Web3Wrapper {
-    private _web3: Web3;
-    private _defaults: Partial<TxData>;
-    private _jsonRpcRequestId: number;
-    constructor(provider: Web3.Provider, defaults?: Partial<TxData>) {
-        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 getContractDefaults(): Partial<TxData> {
-        return this._defaults;
-    }
-    public setProvider(provider: Web3.Provider) {
-        this._web3.setProvider(provider);
-    }
-    public isAddress(address: string): boolean {
-        return this._web3.isAddress(address);
-    }
-    public async isSenderAddressAvailableAsync(senderAddress: string): Promise<boolean> {
-        const addresses = await this.getAvailableAddressesAsync();
-        return _.includes(addresses, senderAddress);
-    }
-    public async getNodeVersionAsync(): Promise<string> {
-        const nodeVersion = await promisify<string>(this._web3.version.getNode)();
-        return nodeVersion;
-    }
-    public async getNetworkIdAsync(): Promise<number> {
-        const networkIdStr = await promisify<string>(this._web3.version.getNetwork)();
-        const networkId = _.parseInt(networkIdStr);
-        return networkId;
-    }
-    public async getTransactionReceiptAsync(txHash: string): Promise<TransactionReceipt> {
-        const transactionReceipt = await promisify<TransactionReceipt>(this._web3.eth.getTransactionReceipt)(txHash);
-        if (!_.isNull(transactionReceipt)) {
-            transactionReceipt.status = this._normalizeTxReceiptStatus(transactionReceipt.status);
-        }
-        return transactionReceipt;
-    }
-    public getCurrentProvider(): Web3.Provider {
-        return this._web3.currentProvider;
-    }
-    public toWei(ethAmount: BigNumber): BigNumber {
-        const balanceWei = this._web3.toWei(ethAmount, 'ether');
-        return balanceWei;
-    }
-    public async getBalanceInWeiAsync(owner: string): Promise<BigNumber> {
-        let balanceInWei = await promisify<BigNumber>(this._web3.eth.getBalance)(owner);
-        // Rewrap in a new BigNumber
-        balanceInWei = new BigNumber(balanceInWei);
-        return balanceInWei;
-    }
-    public async doesContractExistAtAddressAsync(address: string): Promise<boolean> {
-        const code = await promisify<string>(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<string> {
-        const signData = await promisify<string>(this._web3.eth.sign)(address, message);
-        return signData;
-    }
-    public async getBlockNumberAsync(): Promise<number> {
-        const blockNumber = await promisify<number>(this._web3.eth.getBlockNumber)();
-        return blockNumber;
-    }
-    public async getBlockAsync(blockParam: string | Web3.BlockParam): Promise<Web3.BlockWithoutTransactionData> {
-        const block = await promisify<Web3.BlockWithoutTransactionData>(this._web3.eth.getBlock)(blockParam);
-        return block;
-    }
-    public async getBlockTimestampAsync(blockParam: string | Web3.BlockParam): Promise<number> {
-        const { timestamp } = await this.getBlockAsync(blockParam);
-        return timestamp;
-    }
-    public async getAvailableAddressesAsync(): Promise<string[]> {
-        const addresses = await promisify<string[]>(this._web3.eth.getAccounts)();
-        return addresses;
-    }
-    public async getLogsAsync(filter: Web3.FilterObject): Promise<Web3.LogEntry[]> {
-        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 rawLogs = await this._sendRawPayloadAsync<RawLogEntry[]>(payload);
-        const formattedLogs = _.map(rawLogs, this._formatLog.bind(this));
-        return formattedLogs;
-    }
-    public getContractFromAbi(abi: Web3.ContractAbi): Web3.Contract<any> {
-        const web3Contract = this._web3.eth.contract(abi);
-        return web3Contract;
-    }
-    public getContractInstance(abi: Web3.ContractAbi, address: string): Web3.ContractInstance {
-        const web3ContractInstance = this.getContractFromAbi(abi).at(address);
-        return web3ContractInstance;
-    }
-    public async estimateGasAsync(data: string): Promise<number> {
-        const gas = await promisify<number>(this._web3.eth.estimateGas)({ data });
-        return gas;
-    }
-    private async _sendRawPayloadAsync<A>(payload: Web3.JSONRPCRequestPayload): Promise<A> {
-        const sendAsync = this._web3.currentProvider.sendAsync.bind(this._web3.currentProvider);
-        const response = await promisify<Web3.JSONRPCResponsePayload>(sendAsync)(payload);
-        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;
-        }
-    }
-    private _formatLog(rawLog: RawLogEntry): Web3.LogEntry {
-        const formattedLog = {
-            ...rawLog,
-            logIndex: this._hexToDecimal(rawLog.logIndex),
-            blockNumber: this._hexToDecimal(rawLog.blockNumber),
-            transactionIndex: this._hexToDecimal(rawLog.transactionIndex),
-        };
-        return formattedLog;
-    }
-    private _hexToDecimal(hex: string | null): number | null {
-        if (_.isNull(hex)) {
-            return null;
-        }
-        const decimal = this._web3.toDecimal(hex);
-        return decimal;
-    }
+	private _web3: Web3;
+	private _defaults: Partial<TxData>;
+	private _jsonRpcRequestId: number;
+	constructor(provider: Web3.Provider, defaults?: Partial<TxData>) {
+		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 getContractDefaults(): Partial<TxData> {
+		return this._defaults;
+	}
+	public setProvider(provider: Web3.Provider) {
+		this._web3.setProvider(provider);
+	}
+	public isAddress(address: string): boolean {
+		return this._web3.isAddress(address);
+	}
+	public async isSenderAddressAvailableAsync(senderAddress: string): Promise<boolean> {
+		const addresses = await this.getAvailableAddressesAsync();
+		return _.includes(addresses, senderAddress);
+	}
+	public async getNodeVersionAsync(): Promise<string> {
+		const nodeVersion = await promisify<string>(this._web3.version.getNode)();
+		return nodeVersion;
+	}
+	public async getNetworkIdAsync(): Promise<number> {
+		const networkIdStr = await promisify<string>(this._web3.version.getNetwork)();
+		const networkId = _.parseInt(networkIdStr);
+		return networkId;
+	}
+	public async getTransactionReceiptAsync(txHash: string): Promise<TransactionReceipt> {
+		const transactionReceipt = await promisify<TransactionReceipt>(this._web3.eth.getTransactionReceipt)(txHash);
+		if (!_.isNull(transactionReceipt)) {
+			transactionReceipt.status = this._normalizeTxReceiptStatus(transactionReceipt.status);
+		}
+		return transactionReceipt;
+	}
+	public getCurrentProvider(): Web3.Provider {
+		return this._web3.currentProvider;
+	}
+	public toWei(ethAmount: BigNumber): BigNumber {
+		const balanceWei = this._web3.toWei(ethAmount, 'ether');
+		return balanceWei;
+	}
+	public async getBalanceInWeiAsync(owner: string): Promise<BigNumber> {
+		let balanceInWei = await promisify<BigNumber>(this._web3.eth.getBalance)(owner);
+		// Rewrap in a new BigNumber
+		balanceInWei = new BigNumber(balanceInWei);
+		return balanceInWei;
+	}
+	public async doesContractExistAtAddressAsync(address: string): Promise<boolean> {
+		const code = await promisify<string>(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<string> {
+		const signData = await promisify<string>(this._web3.eth.sign)(address, message);
+		return signData;
+	}
+	public async getBlockNumberAsync(): Promise<number> {
+		const blockNumber = await promisify<number>(this._web3.eth.getBlockNumber)();
+		return blockNumber;
+	}
+	public async getBlockAsync(blockParam: string | Web3.BlockParam): Promise<Web3.BlockWithoutTransactionData> {
+		const block = await promisify<Web3.BlockWithoutTransactionData>(this._web3.eth.getBlock)(blockParam);
+		return block;
+	}
+	public async getBlockTimestampAsync(blockParam: string | Web3.BlockParam): Promise<number> {
+		const { timestamp } = await this.getBlockAsync(blockParam);
+		return timestamp;
+	}
+	public async getAvailableAddressesAsync(): Promise<string[]> {
+		const addresses = await promisify<string[]>(this._web3.eth.getAccounts)();
+		return addresses;
+	}
+	public async getLogsAsync(filter: Web3.FilterObject): Promise<Web3.LogEntry[]> {
+		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 rawLogs = await this._sendRawPayloadAsync<RawLogEntry[]>(payload);
+		const formattedLogs = _.map(rawLogs, this._formatLog.bind(this));
+		return formattedLogs;
+	}
+	public getContractFromAbi(abi: Web3.ContractAbi): Web3.Contract<any> {
+		const web3Contract = this._web3.eth.contract(abi);
+		return web3Contract;
+	}
+	public getContractInstance(abi: Web3.ContractAbi, address: string): Web3.ContractInstance {
+		const web3ContractInstance = this.getContractFromAbi(abi).at(address);
+		return web3ContractInstance;
+	}
+	public async estimateGasAsync(data: string): Promise<number> {
+		const gas = await promisify<number>(this._web3.eth.estimateGas)({ data });
+		return gas;
+	}
+	private async _sendRawPayloadAsync<A>(payload: Web3.JSONRPCRequestPayload): Promise<A> {
+		const sendAsync = this._web3.currentProvider.sendAsync.bind(this._web3.currentProvider);
+		const response = await promisify<Web3.JSONRPCResponsePayload>(sendAsync)(payload);
+		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;
+		}
+	}
+	private _formatLog(rawLog: RawLogEntry): Web3.LogEntry {
+		const formattedLog = {
+			...rawLog,
+			logIndex: this._hexToDecimal(rawLog.logIndex),
+			blockNumber: this._hexToDecimal(rawLog.blockNumber),
+			transactionIndex: this._hexToDecimal(rawLog.transactionIndex),
+		};
+		return formattedLog;
+	}
+	private _hexToDecimal(hex: string | null): number | null {
+		if (_.isNull(hex)) {
+			return null;
+		}
+		const decimal = this._web3.toDecimal(hex);
+		return decimal;
+	}
 }
diff --git a/packages/web3-wrapper/tsconfig.json b/packages/web3-wrapper/tsconfig.json
index 3d967d05f..fc88c962d 100644
--- a/packages/web3-wrapper/tsconfig.json
+++ b/packages/web3-wrapper/tsconfig.json
@@ -1,7 +1,7 @@
 {
-    "extends": "../../tsconfig",
-    "compilerOptions": {
-        "outDir": "lib"
-    },
-    "include": ["./src/**/*", "../../node_modules/web3-typescript-typings/index.d.ts"]
+	"extends": "../../tsconfig",
+	"compilerOptions": {
+		"outDir": "lib"
+	},
+	"include": ["./src/**/*", "../../node_modules/web3-typescript-typings/index.d.ts"]
 }
diff --git a/packages/web3-wrapper/tslint.json b/packages/web3-wrapper/tslint.json
index ffaefe83a..e63054bfc 100644
--- a/packages/web3-wrapper/tslint.json
+++ b/packages/web3-wrapper/tslint.json
@@ -1,3 +1,3 @@
 {
-    "extends": ["@0xproject/tslint-config"]
+	"extends": ["@0xproject/tslint-config"]
 }
diff --git a/packages/website/contracts/Mintable.json b/packages/website/contracts/Mintable.json
index dc46dc829..eaadcf68f 100644
--- a/packages/website/contracts/Mintable.json
+++ b/packages/website/contracts/Mintable.json
@@ -1,190 +1,190 @@
 {
-    "contract_name": "Mintable",
-    "abi": [
-        {
-            "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": true,
-            "inputs": [
-                {
-                    "name": "_owner",
-                    "type": "address"
-                }
-            ],
-            "name": "balanceOf",
-            "outputs": [
-                {
-                    "name": "",
-                    "type": "uint256"
-                }
-            ],
-            "payable": false,
-            "type": "function"
-        },
-        {
-            "constant": false,
-            "inputs": [
-                {
-                    "name": "_value",
-                    "type": "uint256"
-                }
-            ],
-            "name": "mint",
-            "outputs": [],
-            "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": true,
-            "inputs": [
-                {
-                    "name": "_owner",
-                    "type": "address"
-                },
-                {
-                    "name": "_spender",
-                    "type": "address"
-                }
-            ],
-            "name": "allowance",
-            "outputs": [
-                {
-                    "name": "",
-                    "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":
-        "0x6060604052341561000c57fe5b5b6105018061001c6000396000f300606060405236156100675763ffffffff60e060020a600035041663095ea7b3811461006957806318160ddd1461009c57806323b872dd146100be57806370a08231146100f7578063a0712d6814610125578063a9059cbb1461013a578063dd62ed3e1461016d575bfe5b341561007157fe5b610088600160a060020a03600435166024356101a1565b604080519115158252519081900360200190f35b34156100a457fe5b6100ac61020c565b60408051918252519081900360200190f35b34156100c657fe5b610088600160a060020a0360043581169060243516604435610212565b604080519115158252519081900360200190f35b34156100ff57fe5b6100ac600160a060020a0360043516610335565b60408051918252519081900360200190f35b341561012d57fe5b610138600435610354565b005b341561014257fe5b610088600160a060020a03600435166024356103bc565b604080519115158252519081900360200190f35b341561017557fe5b6100ac600160a060020a036004358116906024351661046e565b60408051918252519081900360200190f35b600160a060020a03338116600081815260016020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b60025481565b600160a060020a03808416600081815260016020908152604080832033909516835293815283822054928252819052918220548390108015906102555750828110155b801561027b5750600160a060020a03841660009081526020819052604090205483810110155b1561032757600160a060020a03808516600090815260208190526040808220805487019055918716815220805484900390556000198110156102e557600160a060020a03808616600090815260016020908152604080832033909416835292905220805484900390555b83600160a060020a031685600160a060020a03166000805160206104b6833981519152856040518082815260200191505060405180910390a36001915061032c565b600091505b5b509392505050565b600160a060020a0381166000908152602081905260409020545b919050565b68056bc75e2d6310000081111561036b5760006000fd5b600160a060020a03331660009081526020819052604090205461038f90829061049b565b600160a060020a0333166000908152602081905260409020556002546103b5908261049b565b6002555b50565b600160a060020a0333166000908152602081905260408120548290108015906103ff5750600160a060020a03831660009081526020819052604090205482810110155b1561045f57600160a060020a0333811660008181526020818152604080832080548890039055938716808352918490208054870190558351868152935191936000805160206104b6833981519152929081900390910190a3506001610206565b506000610206565b5b92915050565b600160a060020a038083166000908152600160209081526040808320938516835292905220545b92915050565b6000828201838110156104aa57fe5b8091505b50929150505600ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa165627a7a72305820998c8326b9629e063eb4867166e72c68a8c2e3ebca6a9d35ebc78c041c7aa47b0029",
-    "networks": {},
-    "schema_version": "0.0.5",
-    "updated_at": 1503413048892
+	"contract_name": "Mintable",
+	"abi": [
+		{
+			"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": true,
+			"inputs": [
+				{
+					"name": "_owner",
+					"type": "address"
+				}
+			],
+			"name": "balanceOf",
+			"outputs": [
+				{
+					"name": "",
+					"type": "uint256"
+				}
+			],
+			"payable": false,
+			"type": "function"
+		},
+		{
+			"constant": false,
+			"inputs": [
+				{
+					"name": "_value",
+					"type": "uint256"
+				}
+			],
+			"name": "mint",
+			"outputs": [],
+			"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": true,
+			"inputs": [
+				{
+					"name": "_owner",
+					"type": "address"
+				},
+				{
+					"name": "_spender",
+					"type": "address"
+				}
+			],
+			"name": "allowance",
+			"outputs": [
+				{
+					"name": "",
+					"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":
+		"0x6060604052341561000c57fe5b5b6105018061001c6000396000f300606060405236156100675763ffffffff60e060020a600035041663095ea7b3811461006957806318160ddd1461009c57806323b872dd146100be57806370a08231146100f7578063a0712d6814610125578063a9059cbb1461013a578063dd62ed3e1461016d575bfe5b341561007157fe5b610088600160a060020a03600435166024356101a1565b604080519115158252519081900360200190f35b34156100a457fe5b6100ac61020c565b60408051918252519081900360200190f35b34156100c657fe5b610088600160a060020a0360043581169060243516604435610212565b604080519115158252519081900360200190f35b34156100ff57fe5b6100ac600160a060020a0360043516610335565b60408051918252519081900360200190f35b341561012d57fe5b610138600435610354565b005b341561014257fe5b610088600160a060020a03600435166024356103bc565b604080519115158252519081900360200190f35b341561017557fe5b6100ac600160a060020a036004358116906024351661046e565b60408051918252519081900360200190f35b600160a060020a03338116600081815260016020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b60025481565b600160a060020a03808416600081815260016020908152604080832033909516835293815283822054928252819052918220548390108015906102555750828110155b801561027b5750600160a060020a03841660009081526020819052604090205483810110155b1561032757600160a060020a03808516600090815260208190526040808220805487019055918716815220805484900390556000198110156102e557600160a060020a03808616600090815260016020908152604080832033909416835292905220805484900390555b83600160a060020a031685600160a060020a03166000805160206104b6833981519152856040518082815260200191505060405180910390a36001915061032c565b600091505b5b509392505050565b600160a060020a0381166000908152602081905260409020545b919050565b68056bc75e2d6310000081111561036b5760006000fd5b600160a060020a03331660009081526020819052604090205461038f90829061049b565b600160a060020a0333166000908152602081905260409020556002546103b5908261049b565b6002555b50565b600160a060020a0333166000908152602081905260408120548290108015906103ff5750600160a060020a03831660009081526020819052604090205482810110155b1561045f57600160a060020a0333811660008181526020818152604080832080548890039055938716808352918490208054870190558351868152935191936000805160206104b6833981519152929081900390910190a3506001610206565b506000610206565b5b92915050565b600160a060020a038083166000908152600160209081526040808320938516835292905220545b92915050565b6000828201838110156104aa57fe5b8091505b50929150505600ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa165627a7a72305820998c8326b9629e063eb4867166e72c68a8c2e3ebca6a9d35ebc78c041c7aa47b0029",
+	"networks": {},
+	"schema_version": "0.0.5",
+	"updated_at": 1503413048892
 }
diff --git a/packages/website/md/docs/0xjs/async.md b/packages/website/md/docs/0xjs/async.md
index 8abaef331..fa92e5bab 100644
--- a/packages/website/md/docs/0xjs/async.md
+++ b/packages/website/md/docs/0xjs/async.md
@@ -14,13 +14,13 @@ _Promise syntax:_
 
 ```javascript
 zeroEx
-    .getAvailableAddressesAsync()
-    .then(function(availableAddresses) {
-        console.log(availableAddresses);
-    })
-    .catch(function(error) {
-        console.log('Caught error: ', error);
-    });
+	.getAvailableAddressesAsync()
+	.then(function(availableAddresses) {
+		console.log(availableAddresses);
+	})
+	.catch(function(error) {
+		console.log('Caught error: ', error);
+	});
 ```
 
 As is the convention with promise-based libraries, if an error occurs, it is thrown. It is the callers responsibility to catch thrown errors and to handle them appropriately.
diff --git a/packages/website/package.json b/packages/website/package.json
index 6db74a20e..ac1bd2c13 100644
--- a/packages/website/package.json
+++ b/packages/website/package.json
@@ -1,109 +1,109 @@
 {
-    "name": "@0xproject/website",
-    "version": "0.0.9",
-    "private": true,
-    "description": "Website and 0x portal dapp",
-    "scripts": {
-        "build": "NODE_ENV=production webpack; exit 0;",
-        "clean": "shx rm -f public/bundle*",
-        "lint": "tslint --project . 'ts/**/*.ts' 'ts/**/*.tsx'",
-        "dev": "webpack-dev-server --content-base public --https",
-        "update_contracts":
-            "for i in ${npm_package_config_artifacts}; do copyfiles -u 4 ../contracts/build/contracts/$i.json ../website/contracts; done;",
-        "deploy_staging":
-            "npm run build; aws s3 sync ./public/. s3://staging-0xproject --profile 0xproject --region us-east-1 --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers",
-        "deploy_live":
-            "npm run build; aws s3 sync ./public/. s3://0xproject.com --profile 0xproject --region us-east-1 --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers"
-    },
-    "config": {
-        "artifacts": "Mintable"
-    },
-    "author": "Fabio Berger",
-    "license": "Apache-2.0",
-    "dependencies": {
-        "0x.js": "^0.30.2",
-        "@0xproject/subproviders": "^0.3.3",
-        "@0xproject/utils": "^0.2.2",
-        "accounting": "^0.4.1",
-        "basscss": "^8.0.3",
-        "blockies": "^0.0.2",
-        "compare-versions": "^3.0.1",
-        "dateformat": "^2.0.0",
-        "deep-equal": "^1.0.1",
-        "dharma-loan-frame": "^0.0.12",
-        "ethereumjs-tx": "^1.3.3",
-        "ethereumjs-util": "^5.1.1",
-        "find-versions": "^2.0.0",
-        "is-mobile": "^0.2.2",
-        "jsonschema": "^1.2.0",
-        "ledgerco": "0xProject/ledger-node-js-api",
-        "less": "^2.7.2",
-        "lodash": "^4.17.4",
-        "material-ui": "^0.17.1",
-        "moment": "^2.18.1",
-        "query-string": "^5.0.1",
-        "react": "15.6.1",
-        "react-copy-to-clipboard": "^4.2.3",
-        "react-document-title": "^2.0.3",
-        "react-dom": "15.6.1",
-        "react-highlight": "^0.10.0",
-        "react-html5video": "^2.1.0",
-        "react-inlinesvg": "^0.5.5",
-        "react-markdown": "^2.5.0",
-        "react-recaptcha": "^2.3.2",
-        "react-redux": "^5.0.3",
-        "react-router-dom": "^4.1.1",
-        "react-router-hash-link": "^1.1.0",
-        "react-scroll": "^1.5.2",
-        "react-tap-event-plugin": "^2.0.1",
-        "react-tooltip": "^3.2.7",
-        "react-waypoint": "^7.0.4",
-        "redux": "^3.6.0",
-        "scroll-to-element": "^2.0.0",
-        "semver-sort": "0.0.4",
-        "thenby": "^1.2.3",
-        "truffle-contract": "2.0.1",
-        "tslint-config-0xproject": "^0.0.2",
-        "web3": "^0.20.0",
-        "web3-provider-engine": "^13.0.1",
-        "whatwg-fetch": "^2.0.3",
-        "xml-js": "^1.3.2"
-    },
-    "devDependencies": {
-        "@types/accounting": "^0.4.1",
-        "@types/dateformat": "^1.0.1",
-        "@types/deep-equal": "^1.0.0",
-        "@types/jsonschema": "^1.1.1",
-        "@types/lodash": "^4.14.86",
-        "@types/material-ui": "0.18.0",
-        "@types/moment": "^2.13.0",
-        "@types/node": "^8.0.53",
-        "@types/query-string": "^5.0.1",
-        "@types/react": "^15.0.15",
-        "@types/react-copy-to-clipboard": "^4.2.0",
-        "@types/react-dom": "^0.14.23",
-        "@types/react-redux": "^4.4.37",
-        "@types/react-router-dom": "^4.0.4",
-        "@types/react-scroll": "0.0.31",
-        "@types/react-tap-event-plugin": "0.0.30",
-        "@types/redux": "^3.6.0",
-        "awesome-typescript-loader": "^3.1.3",
-        "copy-webpack-plugin": "^4.0.1",
-        "copyfiles": "^1.2.0",
-        "css-loader": "0.23.x",
-        "exports-loader": "0.6.x",
-        "imports-loader": "0.6.x",
-        "json-loader": "^0.5.4",
-        "less-loader": "^2.2.3",
-        "raw-loader": "^0.5.1",
-        "shx": "^0.2.2",
-        "source-map-loader": "^0.1.6",
-        "style-loader": "0.13.x",
-        "tslint": "5.8.0",
-        "typescript": "~2.6.1",
-        "web3-typescript-typings": "^0.9.6",
-        "webpack": "^3.1.0",
-        "webpack-dev-middleware": "^1.10.0",
-        "webpack-dev-server": "^2.5.0"
-    }
+	"name": "@0xproject/website",
+	"version": "0.0.9",
+	"private": true,
+	"description": "Website and 0x portal dapp",
+	"scripts": {
+		"build": "NODE_ENV=production webpack; exit 0;",
+		"clean": "shx rm -f public/bundle*",
+		"lint": "tslint --project . 'ts/**/*.ts' 'ts/**/*.tsx'",
+		"dev": "webpack-dev-server --content-base public --https",
+		"update_contracts":
+			"for i in ${npm_package_config_artifacts}; do copyfiles -u 4 ../contracts/build/contracts/$i.json ../website/contracts; done;",
+		"deploy_staging":
+			"npm run build; aws s3 sync ./public/. s3://staging-0xproject --profile 0xproject --region us-east-1 --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers",
+		"deploy_live":
+			"npm run build; aws s3 sync ./public/. s3://0xproject.com --profile 0xproject --region us-east-1 --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers"
+	},
+	"config": {
+		"artifacts": "Mintable"
+	},
+	"author": "Fabio Berger",
+	"license": "Apache-2.0",
+	"dependencies": {
+		"0x.js": "^0.30.2",
+		"@0xproject/subproviders": "^0.3.3",
+		"@0xproject/utils": "^0.2.2",
+		"accounting": "^0.4.1",
+		"basscss": "^8.0.3",
+		"blockies": "^0.0.2",
+		"compare-versions": "^3.0.1",
+		"dateformat": "^2.0.0",
+		"deep-equal": "^1.0.1",
+		"dharma-loan-frame": "^0.0.12",
+		"ethereumjs-tx": "^1.3.3",
+		"ethereumjs-util": "^5.1.1",
+		"find-versions": "^2.0.0",
+		"is-mobile": "^0.2.2",
+		"jsonschema": "^1.2.0",
+		"ledgerco": "0xProject/ledger-node-js-api",
+		"less": "^2.7.2",
+		"lodash": "^4.17.4",
+		"material-ui": "^0.17.1",
+		"moment": "^2.18.1",
+		"query-string": "^5.0.1",
+		"react": "15.6.1",
+		"react-copy-to-clipboard": "^4.2.3",
+		"react-document-title": "^2.0.3",
+		"react-dom": "15.6.1",
+		"react-highlight": "^0.10.0",
+		"react-html5video": "^2.1.0",
+		"react-inlinesvg": "^0.5.5",
+		"react-markdown": "^2.5.0",
+		"react-recaptcha": "^2.3.2",
+		"react-redux": "^5.0.3",
+		"react-router-dom": "^4.1.1",
+		"react-router-hash-link": "^1.1.0",
+		"react-scroll": "^1.5.2",
+		"react-tap-event-plugin": "^2.0.1",
+		"react-tooltip": "^3.2.7",
+		"react-waypoint": "^7.0.4",
+		"redux": "^3.6.0",
+		"scroll-to-element": "^2.0.0",
+		"semver-sort": "0.0.4",
+		"thenby": "^1.2.3",
+		"truffle-contract": "2.0.1",
+		"tslint-config-0xproject": "^0.0.2",
+		"web3": "^0.20.0",
+		"web3-provider-engine": "^13.0.1",
+		"whatwg-fetch": "^2.0.3",
+		"xml-js": "^1.3.2"
+	},
+	"devDependencies": {
+		"@types/accounting": "^0.4.1",
+		"@types/dateformat": "^1.0.1",
+		"@types/deep-equal": "^1.0.0",
+		"@types/jsonschema": "^1.1.1",
+		"@types/lodash": "^4.14.86",
+		"@types/material-ui": "0.18.0",
+		"@types/moment": "^2.13.0",
+		"@types/node": "^8.0.53",
+		"@types/query-string": "^5.0.1",
+		"@types/react": "^15.0.15",
+		"@types/react-copy-to-clipboard": "^4.2.0",
+		"@types/react-dom": "^0.14.23",
+		"@types/react-redux": "^4.4.37",
+		"@types/react-router-dom": "^4.0.4",
+		"@types/react-scroll": "0.0.31",
+		"@types/react-tap-event-plugin": "0.0.30",
+		"@types/redux": "^3.6.0",
+		"awesome-typescript-loader": "^3.1.3",
+		"copy-webpack-plugin": "^4.0.1",
+		"copyfiles": "^1.2.0",
+		"css-loader": "0.23.x",
+		"exports-loader": "0.6.x",
+		"imports-loader": "0.6.x",
+		"json-loader": "^0.5.4",
+		"less-loader": "^2.2.3",
+		"raw-loader": "^0.5.1",
+		"shx": "^0.2.2",
+		"source-map-loader": "^0.1.6",
+		"style-loader": "0.13.x",
+		"tslint": "5.8.0",
+		"typescript": "~2.6.1",
+		"web3-typescript-typings": "^0.9.6",
+		"webpack": "^3.1.0",
+		"webpack-dev-middleware": "^1.10.0",
+		"webpack-dev-server": "^2.5.0"
+	}
 }
diff --git a/packages/website/ts/blockchain.ts b/packages/website/ts/blockchain.ts
index 5530701c0..711c3329d 100644
--- a/packages/website/ts/blockchain.ts
+++ b/packages/website/ts/blockchain.ts
@@ -1,25 +1,25 @@
 import {
-    BlockParam,
-    BlockRange,
-    DecodedLogEvent,
-    ExchangeContractEventArgs,
-    ExchangeEvents,
-    IndexedFilterValues,
-    LogCancelContractEventArgs,
-    LogFillContractEventArgs,
-    LogWithDecodedArgs,
-    Order,
-    SignedOrder,
-    Token as ZeroExToken,
-    TransactionReceiptWithDecodedLogs,
-    ZeroEx,
+	BlockParam,
+	BlockRange,
+	DecodedLogEvent,
+	ExchangeContractEventArgs,
+	ExchangeEvents,
+	IndexedFilterValues,
+	LogCancelContractEventArgs,
+	LogFillContractEventArgs,
+	LogWithDecodedArgs,
+	Order,
+	SignedOrder,
+	Token as ZeroExToken,
+	TransactionReceiptWithDecodedLogs,
+	ZeroEx,
 } from '0x.js';
 import {
-    InjectedWeb3Subprovider,
-    ledgerEthereumBrowserClientFactoryAsync,
-    LedgerSubprovider,
-    LedgerWalletSubprovider,
-    RedundantRPCSubprovider,
+	InjectedWeb3Subprovider,
+	ledgerEthereumBrowserClientFactoryAsync,
+	LedgerSubprovider,
+	LedgerWalletSubprovider,
+	RedundantRPCSubprovider,
 } from '@0xproject/subproviders';
 import { BigNumber, intervalUtils, promisify } from '@0xproject/utils';
 import * as _ from 'lodash';
@@ -31,16 +31,16 @@ import { trackedTokenStorage } from 'ts/local_storage/tracked_token_storage';
 import { tradeHistoryStorage } from 'ts/local_storage/trade_history_storage';
 import { Dispatcher } from 'ts/redux/dispatcher';
 import {
-    BlockchainCallErrs,
-    BlockchainErrs,
-    ContractInstance,
-    EtherscanLinkSuffixes,
-    ProviderType,
-    Side,
-    SignatureData,
-    Token,
-    TokenByAddress,
-    TokenStateByAddress,
+	BlockchainCallErrs,
+	BlockchainErrs,
+	ContractInstance,
+	EtherscanLinkSuffixes,
+	ProviderType,
+	Side,
+	SignatureData,
+	Token,
+	TokenByAddress,
+	TokenStateByAddress,
 } from 'ts/types';
 import { configs } from 'ts/utils/configs';
 import { constants } from 'ts/utils/constants';
@@ -56,727 +56,727 @@ import * as MintableArtifacts from '../contracts/Mintable.json';
 const BLOCK_NUMBER_BACK_TRACK = 50;
 
 export class Blockchain {
-    public networkId: number;
-    public nodeVersion: string;
-    private _zeroEx: ZeroEx;
-    private _dispatcher: Dispatcher;
-    private _web3Wrapper?: Web3Wrapper;
-    private _exchangeAddress: string;
-    private _userAddress: string;
-    private _cachedProvider: Web3.Provider;
-    private _ledgerSubprovider: LedgerWalletSubprovider;
-    private _zrxPollIntervalId: NodeJS.Timer;
-    private static async _onPageLoadAsync(): Promise<void> {
-        if (document.readyState === 'complete') {
-            return; // Already loaded
-        }
-        return new Promise<void>((resolve, reject) => {
-            window.onload = () => resolve();
-        });
-    }
-    private static _getNameGivenProvider(provider: Web3.Provider): string {
-        if (!_.isUndefined((provider as any).isMetaMask)) {
-            return constants.PROVIDER_NAME_METAMASK;
-        }
-
-        // HACK: We use the fact that Parity Signer's provider is an instance of their
-        // internal `Web3FrameProvider` class.
-        const isParitySigner = _.startsWith(provider.constructor.toString(), 'function Web3FrameProvider');
-        if (isParitySigner) {
-            return constants.PROVIDER_NAME_PARITY_SIGNER;
-        }
-
-        return constants.PROVIDER_NAME_GENERIC;
-    }
-    private static async _getProviderAsync(injectedWeb3: Web3, networkIdIfExists: number) {
-        const doesInjectedWeb3Exist = !_.isUndefined(injectedWeb3);
-        const publicNodeUrlsIfExistsForNetworkId = configs.PUBLIC_NODE_URLS_BY_NETWORK_ID[networkIdIfExists];
-        const isPublicNodeAvailableForNetworkId = !_.isUndefined(publicNodeUrlsIfExistsForNetworkId);
-
-        let provider;
-        if (doesInjectedWeb3Exist && isPublicNodeAvailableForNetworkId) {
-            // We catch all requests involving a users account and send it to the injectedWeb3
-            // instance. All other requests go to the public hosted node.
-            provider = new ProviderEngine();
-            provider.addProvider(new InjectedWeb3Subprovider(injectedWeb3));
-            provider.addProvider(new FilterSubprovider());
-            provider.addProvider(new RedundantRPCSubprovider(publicNodeUrlsIfExistsForNetworkId));
-            provider.start();
-        } else if (doesInjectedWeb3Exist) {
-            // Since no public node for this network, all requests go to injectedWeb3 instance
-            provider = injectedWeb3.currentProvider;
-        } else {
-            // If no injectedWeb3 instance, all requests fallback to our public hosted mainnet/testnet node
-            // We do this so that users can still browse the 0x Portal DApp even if they do not have web3
-            // injected into their browser.
-            provider = new ProviderEngine();
-            provider.addProvider(new FilterSubprovider());
-            const networkId = configs.IS_MAINNET_ENABLED ? constants.NETWORK_ID_MAINNET : constants.NETWORK_ID_TESTNET;
-            provider.addProvider(new RedundantRPCSubprovider(configs.PUBLIC_NODE_URLS_BY_NETWORK_ID[networkId]));
-            provider.start();
-        }
-
-        return provider;
-    }
-    constructor(dispatcher: Dispatcher, isSalePage: boolean = false) {
-        this._dispatcher = dispatcher;
-        this._userAddress = '';
-        // tslint:disable-next-line:no-floating-promises
-        this._onPageLoadInitFireAndForgetAsync();
-    }
-    public async networkIdUpdatedFireAndForgetAsync(newNetworkId: number) {
-        const isConnected = !_.isUndefined(newNetworkId);
-        if (!isConnected) {
-            this.networkId = newNetworkId;
-            this._dispatcher.encounteredBlockchainError(BlockchainErrs.DisconnectedFromEthereumNode);
-            this._dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
-        } else if (this.networkId !== newNetworkId) {
-            this.networkId = newNetworkId;
-            this._dispatcher.encounteredBlockchainError(BlockchainErrs.NoError);
-            await this._fetchTokenInformationAsync();
-            await this._rehydrateStoreWithContractEvents();
-        }
-    }
-    public async userAddressUpdatedFireAndForgetAsync(newUserAddress: string) {
-        if (this._userAddress !== newUserAddress) {
-            this._userAddress = newUserAddress;
-            await this._fetchTokenInformationAsync();
-            await this._rehydrateStoreWithContractEvents();
-        }
-    }
-    public async nodeVersionUpdatedFireAndForgetAsync(nodeVersion: string) {
-        if (this.nodeVersion !== nodeVersion) {
-            this.nodeVersion = nodeVersion;
-        }
-    }
-    public async isAddressInTokenRegistryAsync(tokenAddress: string): Promise<boolean> {
-        utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
-        // HACK: temporarily whitelist the new WETH token address `as if` they were
-        // already in the tokenRegistry.
-        // TODO: Remove this hack once we've updated the TokenRegistries
-        // Airtable task: https://airtable.com/tblFe0Q9JuKJPYbTn/viwsOG2Y97qdIeCIO/recv3VGmIorFzHBVz
-        if (configs.SHOULD_DEPRECATE_OLD_WETH_TOKEN && tokenAddress === configs.NEW_WRAPPED_ETHERS[this.networkId]) {
-            return true;
-        }
-        const tokenIfExists = await this._zeroEx.tokenRegistry.getTokenIfExistsAsync(tokenAddress);
-        return !_.isUndefined(tokenIfExists);
-    }
-    public getLedgerDerivationPathIfExists(): string {
-        if (_.isUndefined(this._ledgerSubprovider)) {
-            return undefined;
-        }
-        const path = this._ledgerSubprovider.getPath();
-        return path;
-    }
-    public updateLedgerDerivationPathIfExists(path: string) {
-        if (_.isUndefined(this._ledgerSubprovider)) {
-            return; // noop
-        }
-        this._ledgerSubprovider.setPath(path);
-    }
-    public updateLedgerDerivationIndex(pathIndex: number) {
-        if (_.isUndefined(this._ledgerSubprovider)) {
-            return; // noop
-        }
-        this._ledgerSubprovider.setPathIndex(pathIndex);
-    }
-    public async providerTypeUpdatedFireAndForgetAsync(providerType: ProviderType) {
-        utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
-        // Should actually be Web3.Provider|ProviderEngine union type but it causes issues
-        // later on in the logic.
-        let provider;
-        switch (providerType) {
-            case ProviderType.Ledger: {
-                const isU2FSupported = await utils.isU2FSupportedAsync();
-                if (!isU2FSupported) {
-                    throw new Error('Cannot update providerType to LEDGER without U2F support');
-                }
-
-                // Cache injected provider so that we can switch the user back to it easily
-                this._cachedProvider = this._web3Wrapper.getProviderObj();
-
-                this._dispatcher.updateUserAddress(''); // Clear old userAddress
-
-                provider = new ProviderEngine();
-                const ledgerWalletConfigs = {
-                    networkId: this.networkId,
-                    ledgerEthereumClientFactoryAsync: ledgerEthereumBrowserClientFactoryAsync,
-                };
-                this._ledgerSubprovider = new LedgerSubprovider(ledgerWalletConfigs);
-                provider.addProvider(this._ledgerSubprovider);
-                provider.addProvider(new FilterSubprovider());
-                const networkId = configs.IS_MAINNET_ENABLED
-                    ? constants.NETWORK_ID_MAINNET
-                    : constants.NETWORK_ID_TESTNET;
-                provider.addProvider(new RedundantRPCSubprovider(configs.PUBLIC_NODE_URLS_BY_NETWORK_ID[networkId]));
-                provider.start();
-                this._web3Wrapper.destroy();
-                const shouldPollUserAddress = false;
-                this._web3Wrapper = new Web3Wrapper(this._dispatcher, provider, this.networkId, shouldPollUserAddress);
-                this._zeroEx.setProvider(provider, networkId);
-                await this._postInstantiationOrUpdatingProviderZeroExAsync();
-                break;
-            }
-
-            case ProviderType.Injected: {
-                if (_.isUndefined(this._cachedProvider)) {
-                    return; // Going from injected to injected, so we noop
-                }
-                provider = this._cachedProvider;
-                const shouldPollUserAddress = true;
-                this._web3Wrapper = new Web3Wrapper(this._dispatcher, provider, this.networkId, shouldPollUserAddress);
-                this._zeroEx.setProvider(provider, this.networkId);
-                await this._postInstantiationOrUpdatingProviderZeroExAsync();
-                delete this._ledgerSubprovider;
-                delete this._cachedProvider;
-                break;
-            }
-
-            default:
-                throw utils.spawnSwitchErr('providerType', providerType);
-        }
-
-        await this._fetchTokenInformationAsync();
-    }
-    public async setProxyAllowanceAsync(token: Token, amountInBaseUnits: BigNumber): Promise<void> {
-        utils.assert(this.isValidAddress(token.address), BlockchainCallErrs.TokenAddressIsInvalid);
-        utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
-        utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
-
-        const txHash = await this._zeroEx.token.setProxyAllowanceAsync(
-            token.address,
-            this._userAddress,
-            amountInBaseUnits,
-        );
-        await this._showEtherScanLinkAndAwaitTransactionMinedAsync(txHash);
-        const allowance = amountInBaseUnits;
-        this._dispatcher.replaceTokenAllowanceByAddress(token.address, allowance);
-    }
-    public async transferAsync(token: Token, toAddress: string, amountInBaseUnits: BigNumber): Promise<void> {
-        const txHash = await this._zeroEx.token.transferAsync(
-            token.address,
-            this._userAddress,
-            toAddress,
-            amountInBaseUnits,
-        );
-        await this._showEtherScanLinkAndAwaitTransactionMinedAsync(txHash);
-        const etherScanLinkIfExists = utils.getEtherScanLinkIfExists(txHash, this.networkId, EtherscanLinkSuffixes.Tx);
-        this._dispatcher.showFlashMessage(
-            React.createElement(TokenSendCompleted, {
-                etherScanLinkIfExists,
-                token,
-                toAddress,
-                amountInBaseUnits,
-            }),
-        );
-    }
-    public portalOrderToSignedOrder(
-        maker: string,
-        taker: string,
-        makerTokenAddress: string,
-        takerTokenAddress: string,
-        makerTokenAmount: BigNumber,
-        takerTokenAmount: BigNumber,
-        makerFee: BigNumber,
-        takerFee: BigNumber,
-        expirationUnixTimestampSec: BigNumber,
-        feeRecipient: string,
-        signatureData: SignatureData,
-        salt: BigNumber,
-    ): SignedOrder {
-        const ecSignature = signatureData;
-        const exchangeContractAddress = this.getExchangeContractAddressIfExists();
-        const takerOrNullAddress = _.isEmpty(taker) ? constants.NULL_ADDRESS : taker;
-        const signedOrder = {
-            ecSignature,
-            exchangeContractAddress,
-            expirationUnixTimestampSec,
-            feeRecipient,
-            maker,
-            makerFee,
-            makerTokenAddress,
-            makerTokenAmount,
-            salt,
-            taker: takerOrNullAddress,
-            takerFee,
-            takerTokenAddress,
-            takerTokenAmount,
-        };
-        return signedOrder;
-    }
-    public async fillOrderAsync(signedOrder: SignedOrder, fillTakerTokenAmount: BigNumber): Promise<BigNumber> {
-        utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
-
-        const shouldThrowOnInsufficientBalanceOrAllowance = true;
-
-        const txHash = await this._zeroEx.exchange.fillOrderAsync(
-            signedOrder,
-            fillTakerTokenAmount,
-            shouldThrowOnInsufficientBalanceOrAllowance,
-            this._userAddress,
-        );
-        const receipt = await this._showEtherScanLinkAndAwaitTransactionMinedAsync(txHash);
-        const logs: Array<LogWithDecodedArgs<ExchangeContractEventArgs>> = receipt.logs as any;
-        this._zeroEx.exchange.throwLogErrorsAsErrors(logs);
-        const logFill = _.find(logs, { event: 'LogFill' });
-        const args = (logFill.args as any) as LogFillContractEventArgs;
-        const filledTakerTokenAmount = args.filledTakerTokenAmount;
-        return filledTakerTokenAmount;
-    }
-    public async cancelOrderAsync(signedOrder: SignedOrder, cancelTakerTokenAmount: BigNumber): Promise<BigNumber> {
-        const txHash = await this._zeroEx.exchange.cancelOrderAsync(signedOrder, cancelTakerTokenAmount);
-        const receipt = await this._showEtherScanLinkAndAwaitTransactionMinedAsync(txHash);
-        const logs: Array<LogWithDecodedArgs<ExchangeContractEventArgs>> = receipt.logs as any;
-        this._zeroEx.exchange.throwLogErrorsAsErrors(logs);
-        const logCancel = _.find(logs, { event: ExchangeEvents.LogCancel });
-        const args = (logCancel.args as any) as LogCancelContractEventArgs;
-        const cancelledTakerTokenAmount = args.cancelledTakerTokenAmount;
-        return cancelledTakerTokenAmount;
-    }
-    public async getUnavailableTakerAmountAsync(orderHash: string): Promise<BigNumber> {
-        utils.assert(ZeroEx.isValidOrderHash(orderHash), 'Must be valid orderHash');
-        utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
-        const unavailableTakerAmount = await this._zeroEx.exchange.getUnavailableTakerAmountAsync(orderHash);
-        return unavailableTakerAmount;
-    }
-    public getExchangeContractAddressIfExists() {
-        return this._exchangeAddress;
-    }
-    public async validateFillOrderThrowIfInvalidAsync(
-        signedOrder: SignedOrder,
-        fillTakerTokenAmount: BigNumber,
-        takerAddress: string,
-    ): Promise<void> {
-        await this._zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(
-            signedOrder,
-            fillTakerTokenAmount,
-            takerAddress,
-        );
-    }
-    public async validateCancelOrderThrowIfInvalidAsync(
-        order: Order,
-        cancelTakerTokenAmount: BigNumber,
-    ): Promise<void> {
-        await this._zeroEx.exchange.validateCancelOrderThrowIfInvalidAsync(order, cancelTakerTokenAmount);
-    }
-    public isValidAddress(address: string): boolean {
-        const lowercaseAddress = address.toLowerCase();
-        return this._web3Wrapper.isAddress(lowercaseAddress);
-    }
-    public async pollTokenBalanceAsync(token: Token) {
-        utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
-
-        const [currBalance] = await this.getTokenBalanceAndAllowanceAsync(this._userAddress, token.address);
-
-        this._zrxPollIntervalId = intervalUtils.setAsyncExcludingInterval(
-            async () => {
-                const [balance] = await this.getTokenBalanceAndAllowanceAsync(this._userAddress, token.address);
-                if (!balance.eq(currBalance)) {
-                    this._dispatcher.replaceTokenBalanceByAddress(token.address, balance);
-                    intervalUtils.clearAsyncExcludingInterval(this._zrxPollIntervalId);
-                    delete this._zrxPollIntervalId;
-                }
-            },
-            5000,
-            (err: Error) => {
-                utils.consoleLog(`Polling tokenBalance failed: ${err}`);
-                intervalUtils.clearAsyncExcludingInterval(this._zrxPollIntervalId);
-                delete this._zrxPollIntervalId;
-            },
-        );
-    }
-    public async signOrderHashAsync(orderHash: string): Promise<SignatureData> {
-        utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
-        const makerAddress = this._userAddress;
-        // If makerAddress is undefined, this means they have a web3 instance injected into their browser
-        // but no account addresses associated with it.
-        if (_.isUndefined(makerAddress)) {
-            throw new Error('Tried to send a sign request but user has no associated addresses');
-        }
-        const ecSignature = await this._zeroEx.signOrderHashAsync(orderHash, makerAddress);
-        const signatureData = _.extend({}, ecSignature, {
-            hash: orderHash,
-        });
-        this._dispatcher.updateSignatureData(signatureData);
-        return signatureData;
-    }
-    public async mintTestTokensAsync(token: Token) {
-        utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
-
-        const mintableContract = await this._instantiateContractIfExistsAsync(MintableArtifacts, token.address);
-        await mintableContract.mint(constants.MINT_AMOUNT, {
-            from: this._userAddress,
-        });
-        const balanceDelta = constants.MINT_AMOUNT;
-        this._dispatcher.updateTokenBalanceByAddress(token.address, balanceDelta);
-    }
-    public async getBalanceInEthAsync(owner: string): Promise<BigNumber> {
-        const balance = await this._web3Wrapper.getBalanceInEthAsync(owner);
-        return balance;
-    }
-    public async convertEthToWrappedEthTokensAsync(etherTokenAddress: string, amount: BigNumber): Promise<void> {
-        utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
-        utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
-
-        const txHash = await this._zeroEx.etherToken.depositAsync(etherTokenAddress, amount, this._userAddress);
-        await this._showEtherScanLinkAndAwaitTransactionMinedAsync(txHash);
-    }
-    public async convertWrappedEthTokensToEthAsync(etherTokenAddress: string, amount: BigNumber): Promise<void> {
-        utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
-        utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
-
-        const txHash = await this._zeroEx.etherToken.withdrawAsync(etherTokenAddress, amount, this._userAddress);
-        await this._showEtherScanLinkAndAwaitTransactionMinedAsync(txHash);
-    }
-    public async doesContractExistAtAddressAsync(address: string) {
-        const doesContractExist = await this._web3Wrapper.doesContractExistAtAddressAsync(address);
-        return doesContractExist;
-    }
-    public async getCurrentUserTokenBalanceAndAllowanceAsync(tokenAddress: string): Promise<BigNumber[]> {
-        const tokenBalanceAndAllowance = await this.getTokenBalanceAndAllowanceAsync(this._userAddress, tokenAddress);
-        return tokenBalanceAndAllowance;
-    }
-    public async getTokenBalanceAndAllowanceAsync(ownerAddress: string, tokenAddress: string): Promise<BigNumber[]> {
-        utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
-
-        if (_.isEmpty(ownerAddress)) {
-            const zero = new BigNumber(0);
-            return [zero, zero];
-        }
-        let balance = new BigNumber(0);
-        let allowance = new BigNumber(0);
-        if (this._doesUserAddressExist()) {
-            balance = await this._zeroEx.token.getBalanceAsync(tokenAddress, ownerAddress);
-            allowance = await this._zeroEx.token.getProxyAllowanceAsync(tokenAddress, ownerAddress);
-        }
-        return [balance, allowance];
-    }
-    public async updateTokenBalancesAndAllowancesAsync(tokens: Token[]) {
-        const tokenStateByAddress: TokenStateByAddress = {};
-        for (const token of tokens) {
-            let balance = new BigNumber(0);
-            let allowance = new BigNumber(0);
-            if (this._doesUserAddressExist()) {
-                [balance, allowance] = await this.getTokenBalanceAndAllowanceAsync(this._userAddress, token.address);
-            }
-            const tokenState = {
-                balance,
-                allowance,
-            };
-            tokenStateByAddress[token.address] = tokenState;
-        }
-        this._dispatcher.updateTokenStateByAddress(tokenStateByAddress);
-    }
-    public async getUserAccountsAsync() {
-        utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
-        const userAccountsIfExists = await this._zeroEx.getAvailableAddressesAsync();
-        return userAccountsIfExists;
-    }
-    // HACK: When a user is using a Ledger, we simply dispatch the selected userAddress, which
-    // by-passes the web3Wrapper logic for updating the prevUserAddress. We therefore need to
-    // manually update it. This should only be called by the LedgerConfigDialog.
-    public updateWeb3WrapperPrevUserAddress(newUserAddress: string) {
-        this._web3Wrapper.updatePrevUserAddress(newUserAddress);
-    }
-    public destroy() {
-        intervalUtils.clearAsyncExcludingInterval(this._zrxPollIntervalId);
-        this._web3Wrapper.destroy();
-        this._stopWatchingExchangeLogFillEvents();
-    }
-    private async _showEtherScanLinkAndAwaitTransactionMinedAsync(
-        txHash: string,
-    ): Promise<TransactionReceiptWithDecodedLogs> {
-        const etherScanLinkIfExists = utils.getEtherScanLinkIfExists(txHash, this.networkId, EtherscanLinkSuffixes.Tx);
-        this._dispatcher.showFlashMessage(
-            React.createElement(TransactionSubmitted, {
-                etherScanLinkIfExists,
-            }),
-        );
-        const receipt = await this._zeroEx.awaitTransactionMinedAsync(txHash);
-        return receipt;
-    }
-    private _doesUserAddressExist(): boolean {
-        return this._userAddress !== '';
-    }
-    private async _rehydrateStoreWithContractEvents() {
-        // Ensure we are only ever listening to one set of events
-        this._stopWatchingExchangeLogFillEvents();
-
-        if (!this._doesUserAddressExist()) {
-            return; // short-circuit
-        }
-
-        if (!_.isUndefined(this._zeroEx)) {
-            // Since we do not have an index on the `taker` address and want to show
-            // transactions where an account is either the `maker` or `taker`, we loop
-            // through all fill events, and filter/cache them client-side.
-            const filterIndexObj = {};
-            await this._startListeningForExchangeLogFillEventsAsync(filterIndexObj);
-        }
-    }
-    private async _startListeningForExchangeLogFillEventsAsync(indexFilterValues: IndexedFilterValues): Promise<void> {
-        utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
-        utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
-
-        // Fetch historical logs
-        await this._fetchHistoricalExchangeLogFillEventsAsync(indexFilterValues);
-
-        // Start a subscription for new logs
-        this._zeroEx.exchange.subscribe(
-            ExchangeEvents.LogFill,
-            indexFilterValues,
-            async (err: Error, decodedLogEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
-                if (err) {
-                    // Note: it's not entirely clear from the documentation which
-                    // errors will be thrown by `watch`. For now, let's log the error
-                    // to rollbar and stop watching when one occurs
-                    // tslint:disable-next-line:no-floating-promises
-                    errorReporter.reportAsync(err); // fire and forget
-                    return;
-                } else {
-                    const decodedLog = decodedLogEvent.log;
-                    if (!this._doesLogEventInvolveUser(decodedLog)) {
-                        return; // We aren't interested in the fill event
-                    }
-                    this._updateLatestFillsBlockIfNeeded(decodedLog.blockNumber);
-                    const fill = await this._convertDecodedLogToFillAsync(decodedLog);
-                    if (decodedLogEvent.isRemoved) {
-                        tradeHistoryStorage.removeFillFromUser(this._userAddress, this.networkId, fill);
-                    } else {
-                        tradeHistoryStorage.addFillToUser(this._userAddress, this.networkId, fill);
-                    }
-                }
-            },
-        );
-    }
-    private async _fetchHistoricalExchangeLogFillEventsAsync(indexFilterValues: IndexedFilterValues) {
-        const fromBlock = tradeHistoryStorage.getFillsLatestBlock(this._userAddress, this.networkId);
-        const blockRange: BlockRange = {
-            fromBlock,
-            toBlock: 'latest' as BlockParam,
-        };
-        const decodedLogs = await this._zeroEx.exchange.getLogsAsync<LogFillContractEventArgs>(
-            ExchangeEvents.LogFill,
-            blockRange,
-            indexFilterValues,
-        );
-        for (const decodedLog of decodedLogs) {
-            if (!this._doesLogEventInvolveUser(decodedLog)) {
-                continue; // We aren't interested in the fill event
-            }
-            this._updateLatestFillsBlockIfNeeded(decodedLog.blockNumber);
-            const fill = await this._convertDecodedLogToFillAsync(decodedLog);
-            tradeHistoryStorage.addFillToUser(this._userAddress, this.networkId, fill);
-        }
-    }
-    private async _convertDecodedLogToFillAsync(decodedLog: LogWithDecodedArgs<LogFillContractEventArgs>) {
-        const args = decodedLog.args;
-        const blockTimestamp = await this._web3Wrapper.getBlockTimestampAsync(decodedLog.blockHash);
-        const fill = {
-            filledTakerTokenAmount: args.filledTakerTokenAmount,
-            filledMakerTokenAmount: args.filledMakerTokenAmount,
-            logIndex: decodedLog.logIndex,
-            maker: args.maker,
-            orderHash: args.orderHash,
-            taker: args.taker,
-            makerToken: args.makerToken,
-            takerToken: args.takerToken,
-            paidMakerFee: args.paidMakerFee,
-            paidTakerFee: args.paidTakerFee,
-            transactionHash: decodedLog.transactionHash,
-            blockTimestamp,
-        };
-        return fill;
-    }
-    private _doesLogEventInvolveUser(decodedLog: LogWithDecodedArgs<LogFillContractEventArgs>) {
-        const args = decodedLog.args;
-        const isUserMakerOrTaker = args.maker === this._userAddress || args.taker === this._userAddress;
-        return isUserMakerOrTaker;
-    }
-    private _updateLatestFillsBlockIfNeeded(blockNumber: number) {
-        const isBlockPending = _.isNull(blockNumber);
-        if (!isBlockPending) {
-            // Hack: I've observed the behavior where a client won't register certain fill events
-            // and lowering the cache blockNumber fixes the issue. As a quick fix for now, simply
-            // set the cached blockNumber 50 below the one returned. This way, upon refreshing, a user
-            // would still attempt to re-fetch events from the previous 50 blocks, but won't need to
-            // re-fetch all events in all blocks.
-            // TODO: Debug if this is a race condition, and apply a more precise fix
-            const blockNumberToSet =
-                blockNumber - BLOCK_NUMBER_BACK_TRACK < 0 ? 0 : blockNumber - BLOCK_NUMBER_BACK_TRACK;
-            tradeHistoryStorage.setFillsLatestBlock(this._userAddress, this.networkId, blockNumberToSet);
-        }
-    }
-    private _stopWatchingExchangeLogFillEvents(): void {
-        this._zeroEx.exchange.unsubscribeAll();
-    }
-    private async _getTokenRegistryTokensByAddressAsync(): Promise<TokenByAddress> {
-        utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
-        const tokenRegistryTokens = await this._zeroEx.tokenRegistry.getTokensAsync();
-
-        const tokenByAddress: TokenByAddress = {};
-        _.each(tokenRegistryTokens, (t: ZeroExToken, i: number) => {
-            // HACK: For now we have a hard-coded list of iconUrls for the dummyTokens
-            // TODO: Refactor this out and pull the iconUrl directly from the TokenRegistry
-            const iconUrl = configs.ICON_URL_BY_SYMBOL[t.symbol];
-            // HACK: Temporarily we hijack the WETH addresses fetched from the tokenRegistry
-            // so that we can take our time with actually updating it. This ensures that when
-            // we deploy the new WETH page, everyone will re-fill their trackedTokens with the
-            // new canonical WETH.
-            // TODO: Remove this hack once we've updated the TokenRegistries
-            // Airtable task: https://airtable.com/tblFe0Q9JuKJPYbTn/viwsOG2Y97qdIeCIO/recv3VGmIorFzHBVz
-            let address = t.address;
-            if (configs.SHOULD_DEPRECATE_OLD_WETH_TOKEN && t.symbol === 'WETH') {
-                const newEtherTokenAddressIfExists = configs.NEW_WRAPPED_ETHERS[this.networkId];
-                if (!_.isUndefined(newEtherTokenAddressIfExists)) {
-                    address = newEtherTokenAddressIfExists;
-                }
-            }
-            const token: Token = {
-                iconUrl,
-                address,
-                name: t.name,
-                symbol: t.symbol,
-                decimals: t.decimals,
-                isTracked: false,
-                isRegistered: true,
-            };
-            tokenByAddress[token.address] = token;
-        });
-        return tokenByAddress;
-    }
-    private async _onPageLoadInitFireAndForgetAsync() {
-        await Blockchain._onPageLoadAsync(); // wait for page to load
-
-        // Hack: We need to know the networkId the injectedWeb3 is connected to (if it is defined) in
-        // order to properly instantiate the web3Wrapper. Since we must use the async call, we cannot
-        // retrieve it from within the web3Wrapper constructor. This is and should remain the only
-        // call to a web3 instance outside of web3Wrapper in the entire dapp.
-        // In addition, if the user has an injectedWeb3 instance that is disconnected from a backing
-        // Ethereum node, this call will throw. We need to handle this case gracefully
-        const injectedWeb3 = (window as any).web3;
-        let networkIdIfExists: number;
-        if (!_.isUndefined(injectedWeb3)) {
-            try {
-                networkIdIfExists = _.parseInt(await promisify<string>(injectedWeb3.version.getNetwork)());
-            } catch (err) {
-                // Ignore error and proceed with networkId undefined
-            }
-        }
-
-        const provider = await Blockchain._getProviderAsync(injectedWeb3, networkIdIfExists);
-        const networkId = !_.isUndefined(networkIdIfExists)
-            ? networkIdIfExists
-            : configs.IS_MAINNET_ENABLED ? constants.NETWORK_ID_MAINNET : constants.NETWORK_ID_TESTNET;
-        const zeroExConfigs = {
-            networkId,
-        };
-        this._zeroEx = new ZeroEx(provider, zeroExConfigs);
-        this._updateProviderName(injectedWeb3);
-        const shouldPollUserAddress = true;
-        this._web3Wrapper = new Web3Wrapper(this._dispatcher, provider, networkId, shouldPollUserAddress);
-        await this._postInstantiationOrUpdatingProviderZeroExAsync();
-    }
-    // This method should always be run after instantiating or updating the provider
-    // of the ZeroEx instance.
-    private async _postInstantiationOrUpdatingProviderZeroExAsync() {
-        utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
-        this._exchangeAddress = this._zeroEx.exchange.getContractAddress();
-    }
-    private _updateProviderName(injectedWeb3: Web3) {
-        const doesInjectedWeb3Exist = !_.isUndefined(injectedWeb3);
-        const providerName = doesInjectedWeb3Exist
-            ? Blockchain._getNameGivenProvider(injectedWeb3.currentProvider)
-            : constants.PROVIDER_NAME_PUBLIC;
-        this._dispatcher.updateInjectedProviderName(providerName);
-    }
-    private async _fetchTokenInformationAsync() {
-        utils.assert(
-            !_.isUndefined(this.networkId),
-            'Cannot call fetchTokenInformationAsync if disconnected from Ethereum node',
-        );
-
-        this._dispatcher.updateBlockchainIsLoaded(false);
-        this._dispatcher.clearTokenByAddress();
-
-        const tokenRegistryTokensByAddress = await this._getTokenRegistryTokensByAddressAsync();
-
-        // HACK: We need to fetch the userAddress here because otherwise we cannot save the
-        // tracked tokens in localStorage under the users address nor fetch the token
-        // balances and allowances and we need to do this in order not to trigger the blockchain
-        // loading dialog to show up twice. First to load the contracts, and second to load the
-        // balances and allowances.
-        this._userAddress = await this._web3Wrapper.getFirstAccountIfExistsAsync();
-        if (!_.isEmpty(this._userAddress)) {
-            this._dispatcher.updateUserAddress(this._userAddress);
-        }
-
-        let trackedTokensIfExists = trackedTokenStorage.getTrackedTokensIfExists(this._userAddress, this.networkId);
-        const tokenRegistryTokens = _.values(tokenRegistryTokensByAddress);
-        if (_.isUndefined(trackedTokensIfExists)) {
-            trackedTokensIfExists = _.map(configs.DEFAULT_TRACKED_TOKEN_SYMBOLS, symbol => {
-                const token = _.find(tokenRegistryTokens, t => t.symbol === symbol);
-                token.isTracked = true;
-                return token;
-            });
-            _.each(trackedTokensIfExists, token => {
-                trackedTokenStorage.addTrackedTokenToUser(this._userAddress, this.networkId, token);
-            });
-        } else {
-            // Properly set all tokenRegistry tokens `isTracked` to true if they are in the existing trackedTokens array
-            _.each(trackedTokensIfExists, trackedToken => {
-                if (!_.isUndefined(tokenRegistryTokensByAddress[trackedToken.address])) {
-                    tokenRegistryTokensByAddress[trackedToken.address].isTracked = true;
-                }
-            });
-        }
-        const allTokens = _.uniq([...tokenRegistryTokens, ...trackedTokensIfExists]);
-        this._dispatcher.updateTokenByAddress(allTokens);
-
-        // Get balance/allowance for tracked tokens
-        await this.updateTokenBalancesAndAllowancesAsync(trackedTokensIfExists);
-
-        const mostPopularTradingPairTokens: Token[] = [
-            _.find(allTokens, { symbol: configs.DEFAULT_TRACKED_TOKEN_SYMBOLS[0] }),
-            _.find(allTokens, { symbol: configs.DEFAULT_TRACKED_TOKEN_SYMBOLS[1] }),
-        ];
-        this._dispatcher.updateChosenAssetTokenAddress(Side.Deposit, mostPopularTradingPairTokens[0].address);
-        this._dispatcher.updateChosenAssetTokenAddress(Side.Receive, mostPopularTradingPairTokens[1].address);
-        this._dispatcher.updateBlockchainIsLoaded(true);
-    }
-    private async _instantiateContractIfExistsAsync(artifact: any, address?: string): Promise<ContractInstance> {
-        const c = await contract(artifact);
-        const providerObj = this._web3Wrapper.getProviderObj();
-        c.setProvider(providerObj);
-
-        const artifactNetworkConfigs = artifact.networks[this.networkId];
-        let contractAddress;
-        if (!_.isUndefined(address)) {
-            contractAddress = address;
-        } else if (!_.isUndefined(artifactNetworkConfigs)) {
-            contractAddress = artifactNetworkConfigs.address;
-        }
-
-        if (!_.isUndefined(contractAddress)) {
-            const doesContractExist = await this.doesContractExistAtAddressAsync(contractAddress);
-            if (!doesContractExist) {
-                utils.consoleLog(`Contract does not exist: ${artifact.contract_name} at ${contractAddress}`);
-                throw new Error(BlockchainCallErrs.ContractDoesNotExist);
-            }
-        }
-
-        try {
-            const contractInstance = _.isUndefined(address) ? await c.deployed() : await c.at(address);
-            return contractInstance;
-        } catch (err) {
-            const errMsg = `${err}`;
-            utils.consoleLog(`Notice: Error encountered: ${err} ${err.stack}`);
-            if (_.includes(errMsg, 'not been deployed to detected network')) {
-                throw new Error(BlockchainCallErrs.ContractDoesNotExist);
-            } else {
-                await errorReporter.reportAsync(err);
-                throw new Error(BlockchainCallErrs.UnhandledError);
-            }
-        }
-    }
+	public networkId: number;
+	public nodeVersion: string;
+	private _zeroEx: ZeroEx;
+	private _dispatcher: Dispatcher;
+	private _web3Wrapper?: Web3Wrapper;
+	private _exchangeAddress: string;
+	private _userAddress: string;
+	private _cachedProvider: Web3.Provider;
+	private _ledgerSubprovider: LedgerWalletSubprovider;
+	private _zrxPollIntervalId: NodeJS.Timer;
+	private static async _onPageLoadAsync(): Promise<void> {
+		if (document.readyState === 'complete') {
+			return; // Already loaded
+		}
+		return new Promise<void>((resolve, reject) => {
+			window.onload = () => resolve();
+		});
+	}
+	private static _getNameGivenProvider(provider: Web3.Provider): string {
+		if (!_.isUndefined((provider as any).isMetaMask)) {
+			return constants.PROVIDER_NAME_METAMASK;
+		}
+
+		// HACK: We use the fact that Parity Signer's provider is an instance of their
+		// internal `Web3FrameProvider` class.
+		const isParitySigner = _.startsWith(provider.constructor.toString(), 'function Web3FrameProvider');
+		if (isParitySigner) {
+			return constants.PROVIDER_NAME_PARITY_SIGNER;
+		}
+
+		return constants.PROVIDER_NAME_GENERIC;
+	}
+	private static async _getProviderAsync(injectedWeb3: Web3, networkIdIfExists: number) {
+		const doesInjectedWeb3Exist = !_.isUndefined(injectedWeb3);
+		const publicNodeUrlsIfExistsForNetworkId = configs.PUBLIC_NODE_URLS_BY_NETWORK_ID[networkIdIfExists];
+		const isPublicNodeAvailableForNetworkId = !_.isUndefined(publicNodeUrlsIfExistsForNetworkId);
+
+		let provider;
+		if (doesInjectedWeb3Exist && isPublicNodeAvailableForNetworkId) {
+			// We catch all requests involving a users account and send it to the injectedWeb3
+			// instance. All other requests go to the public hosted node.
+			provider = new ProviderEngine();
+			provider.addProvider(new InjectedWeb3Subprovider(injectedWeb3));
+			provider.addProvider(new FilterSubprovider());
+			provider.addProvider(new RedundantRPCSubprovider(publicNodeUrlsIfExistsForNetworkId));
+			provider.start();
+		} else if (doesInjectedWeb3Exist) {
+			// Since no public node for this network, all requests go to injectedWeb3 instance
+			provider = injectedWeb3.currentProvider;
+		} else {
+			// If no injectedWeb3 instance, all requests fallback to our public hosted mainnet/testnet node
+			// We do this so that users can still browse the 0x Portal DApp even if they do not have web3
+			// injected into their browser.
+			provider = new ProviderEngine();
+			provider.addProvider(new FilterSubprovider());
+			const networkId = configs.IS_MAINNET_ENABLED ? constants.NETWORK_ID_MAINNET : constants.NETWORK_ID_TESTNET;
+			provider.addProvider(new RedundantRPCSubprovider(configs.PUBLIC_NODE_URLS_BY_NETWORK_ID[networkId]));
+			provider.start();
+		}
+
+		return provider;
+	}
+	constructor(dispatcher: Dispatcher, isSalePage: boolean = false) {
+		this._dispatcher = dispatcher;
+		this._userAddress = '';
+		// tslint:disable-next-line:no-floating-promises
+		this._onPageLoadInitFireAndForgetAsync();
+	}
+	public async networkIdUpdatedFireAndForgetAsync(newNetworkId: number) {
+		const isConnected = !_.isUndefined(newNetworkId);
+		if (!isConnected) {
+			this.networkId = newNetworkId;
+			this._dispatcher.encounteredBlockchainError(BlockchainErrs.DisconnectedFromEthereumNode);
+			this._dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
+		} else if (this.networkId !== newNetworkId) {
+			this.networkId = newNetworkId;
+			this._dispatcher.encounteredBlockchainError(BlockchainErrs.NoError);
+			await this._fetchTokenInformationAsync();
+			await this._rehydrateStoreWithContractEvents();
+		}
+	}
+	public async userAddressUpdatedFireAndForgetAsync(newUserAddress: string) {
+		if (this._userAddress !== newUserAddress) {
+			this._userAddress = newUserAddress;
+			await this._fetchTokenInformationAsync();
+			await this._rehydrateStoreWithContractEvents();
+		}
+	}
+	public async nodeVersionUpdatedFireAndForgetAsync(nodeVersion: string) {
+		if (this.nodeVersion !== nodeVersion) {
+			this.nodeVersion = nodeVersion;
+		}
+	}
+	public async isAddressInTokenRegistryAsync(tokenAddress: string): Promise<boolean> {
+		utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
+		// HACK: temporarily whitelist the new WETH token address `as if` they were
+		// already in the tokenRegistry.
+		// TODO: Remove this hack once we've updated the TokenRegistries
+		// Airtable task: https://airtable.com/tblFe0Q9JuKJPYbTn/viwsOG2Y97qdIeCIO/recv3VGmIorFzHBVz
+		if (configs.SHOULD_DEPRECATE_OLD_WETH_TOKEN && tokenAddress === configs.NEW_WRAPPED_ETHERS[this.networkId]) {
+			return true;
+		}
+		const tokenIfExists = await this._zeroEx.tokenRegistry.getTokenIfExistsAsync(tokenAddress);
+		return !_.isUndefined(tokenIfExists);
+	}
+	public getLedgerDerivationPathIfExists(): string {
+		if (_.isUndefined(this._ledgerSubprovider)) {
+			return undefined;
+		}
+		const path = this._ledgerSubprovider.getPath();
+		return path;
+	}
+	public updateLedgerDerivationPathIfExists(path: string) {
+		if (_.isUndefined(this._ledgerSubprovider)) {
+			return; // noop
+		}
+		this._ledgerSubprovider.setPath(path);
+	}
+	public updateLedgerDerivationIndex(pathIndex: number) {
+		if (_.isUndefined(this._ledgerSubprovider)) {
+			return; // noop
+		}
+		this._ledgerSubprovider.setPathIndex(pathIndex);
+	}
+	public async providerTypeUpdatedFireAndForgetAsync(providerType: ProviderType) {
+		utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
+		// Should actually be Web3.Provider|ProviderEngine union type but it causes issues
+		// later on in the logic.
+		let provider;
+		switch (providerType) {
+			case ProviderType.Ledger: {
+				const isU2FSupported = await utils.isU2FSupportedAsync();
+				if (!isU2FSupported) {
+					throw new Error('Cannot update providerType to LEDGER without U2F support');
+				}
+
+				// Cache injected provider so that we can switch the user back to it easily
+				this._cachedProvider = this._web3Wrapper.getProviderObj();
+
+				this._dispatcher.updateUserAddress(''); // Clear old userAddress
+
+				provider = new ProviderEngine();
+				const ledgerWalletConfigs = {
+					networkId: this.networkId,
+					ledgerEthereumClientFactoryAsync: ledgerEthereumBrowserClientFactoryAsync,
+				};
+				this._ledgerSubprovider = new LedgerSubprovider(ledgerWalletConfigs);
+				provider.addProvider(this._ledgerSubprovider);
+				provider.addProvider(new FilterSubprovider());
+				const networkId = configs.IS_MAINNET_ENABLED
+					? constants.NETWORK_ID_MAINNET
+					: constants.NETWORK_ID_TESTNET;
+				provider.addProvider(new RedundantRPCSubprovider(configs.PUBLIC_NODE_URLS_BY_NETWORK_ID[networkId]));
+				provider.start();
+				this._web3Wrapper.destroy();
+				const shouldPollUserAddress = false;
+				this._web3Wrapper = new Web3Wrapper(this._dispatcher, provider, this.networkId, shouldPollUserAddress);
+				this._zeroEx.setProvider(provider, networkId);
+				await this._postInstantiationOrUpdatingProviderZeroExAsync();
+				break;
+			}
+
+			case ProviderType.Injected: {
+				if (_.isUndefined(this._cachedProvider)) {
+					return; // Going from injected to injected, so we noop
+				}
+				provider = this._cachedProvider;
+				const shouldPollUserAddress = true;
+				this._web3Wrapper = new Web3Wrapper(this._dispatcher, provider, this.networkId, shouldPollUserAddress);
+				this._zeroEx.setProvider(provider, this.networkId);
+				await this._postInstantiationOrUpdatingProviderZeroExAsync();
+				delete this._ledgerSubprovider;
+				delete this._cachedProvider;
+				break;
+			}
+
+			default:
+				throw utils.spawnSwitchErr('providerType', providerType);
+		}
+
+		await this._fetchTokenInformationAsync();
+	}
+	public async setProxyAllowanceAsync(token: Token, amountInBaseUnits: BigNumber): Promise<void> {
+		utils.assert(this.isValidAddress(token.address), BlockchainCallErrs.TokenAddressIsInvalid);
+		utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
+		utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
+
+		const txHash = await this._zeroEx.token.setProxyAllowanceAsync(
+			token.address,
+			this._userAddress,
+			amountInBaseUnits,
+		);
+		await this._showEtherScanLinkAndAwaitTransactionMinedAsync(txHash);
+		const allowance = amountInBaseUnits;
+		this._dispatcher.replaceTokenAllowanceByAddress(token.address, allowance);
+	}
+	public async transferAsync(token: Token, toAddress: string, amountInBaseUnits: BigNumber): Promise<void> {
+		const txHash = await this._zeroEx.token.transferAsync(
+			token.address,
+			this._userAddress,
+			toAddress,
+			amountInBaseUnits,
+		);
+		await this._showEtherScanLinkAndAwaitTransactionMinedAsync(txHash);
+		const etherScanLinkIfExists = utils.getEtherScanLinkIfExists(txHash, this.networkId, EtherscanLinkSuffixes.Tx);
+		this._dispatcher.showFlashMessage(
+			React.createElement(TokenSendCompleted, {
+				etherScanLinkIfExists,
+				token,
+				toAddress,
+				amountInBaseUnits,
+			}),
+		);
+	}
+	public portalOrderToSignedOrder(
+		maker: string,
+		taker: string,
+		makerTokenAddress: string,
+		takerTokenAddress: string,
+		makerTokenAmount: BigNumber,
+		takerTokenAmount: BigNumber,
+		makerFee: BigNumber,
+		takerFee: BigNumber,
+		expirationUnixTimestampSec: BigNumber,
+		feeRecipient: string,
+		signatureData: SignatureData,
+		salt: BigNumber,
+	): SignedOrder {
+		const ecSignature = signatureData;
+		const exchangeContractAddress = this.getExchangeContractAddressIfExists();
+		const takerOrNullAddress = _.isEmpty(taker) ? constants.NULL_ADDRESS : taker;
+		const signedOrder = {
+			ecSignature,
+			exchangeContractAddress,
+			expirationUnixTimestampSec,
+			feeRecipient,
+			maker,
+			makerFee,
+			makerTokenAddress,
+			makerTokenAmount,
+			salt,
+			taker: takerOrNullAddress,
+			takerFee,
+			takerTokenAddress,
+			takerTokenAmount,
+		};
+		return signedOrder;
+	}
+	public async fillOrderAsync(signedOrder: SignedOrder, fillTakerTokenAmount: BigNumber): Promise<BigNumber> {
+		utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
+
+		const shouldThrowOnInsufficientBalanceOrAllowance = true;
+
+		const txHash = await this._zeroEx.exchange.fillOrderAsync(
+			signedOrder,
+			fillTakerTokenAmount,
+			shouldThrowOnInsufficientBalanceOrAllowance,
+			this._userAddress,
+		);
+		const receipt = await this._showEtherScanLinkAndAwaitTransactionMinedAsync(txHash);
+		const logs: Array<LogWithDecodedArgs<ExchangeContractEventArgs>> = receipt.logs as any;
+		this._zeroEx.exchange.throwLogErrorsAsErrors(logs);
+		const logFill = _.find(logs, { event: 'LogFill' });
+		const args = (logFill.args as any) as LogFillContractEventArgs;
+		const filledTakerTokenAmount = args.filledTakerTokenAmount;
+		return filledTakerTokenAmount;
+	}
+	public async cancelOrderAsync(signedOrder: SignedOrder, cancelTakerTokenAmount: BigNumber): Promise<BigNumber> {
+		const txHash = await this._zeroEx.exchange.cancelOrderAsync(signedOrder, cancelTakerTokenAmount);
+		const receipt = await this._showEtherScanLinkAndAwaitTransactionMinedAsync(txHash);
+		const logs: Array<LogWithDecodedArgs<ExchangeContractEventArgs>> = receipt.logs as any;
+		this._zeroEx.exchange.throwLogErrorsAsErrors(logs);
+		const logCancel = _.find(logs, { event: ExchangeEvents.LogCancel });
+		const args = (logCancel.args as any) as LogCancelContractEventArgs;
+		const cancelledTakerTokenAmount = args.cancelledTakerTokenAmount;
+		return cancelledTakerTokenAmount;
+	}
+	public async getUnavailableTakerAmountAsync(orderHash: string): Promise<BigNumber> {
+		utils.assert(ZeroEx.isValidOrderHash(orderHash), 'Must be valid orderHash');
+		utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
+		const unavailableTakerAmount = await this._zeroEx.exchange.getUnavailableTakerAmountAsync(orderHash);
+		return unavailableTakerAmount;
+	}
+	public getExchangeContractAddressIfExists() {
+		return this._exchangeAddress;
+	}
+	public async validateFillOrderThrowIfInvalidAsync(
+		signedOrder: SignedOrder,
+		fillTakerTokenAmount: BigNumber,
+		takerAddress: string,
+	): Promise<void> {
+		await this._zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(
+			signedOrder,
+			fillTakerTokenAmount,
+			takerAddress,
+		);
+	}
+	public async validateCancelOrderThrowIfInvalidAsync(
+		order: Order,
+		cancelTakerTokenAmount: BigNumber,
+	): Promise<void> {
+		await this._zeroEx.exchange.validateCancelOrderThrowIfInvalidAsync(order, cancelTakerTokenAmount);
+	}
+	public isValidAddress(address: string): boolean {
+		const lowercaseAddress = address.toLowerCase();
+		return this._web3Wrapper.isAddress(lowercaseAddress);
+	}
+	public async pollTokenBalanceAsync(token: Token) {
+		utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
+
+		const [currBalance] = await this.getTokenBalanceAndAllowanceAsync(this._userAddress, token.address);
+
+		this._zrxPollIntervalId = intervalUtils.setAsyncExcludingInterval(
+			async () => {
+				const [balance] = await this.getTokenBalanceAndAllowanceAsync(this._userAddress, token.address);
+				if (!balance.eq(currBalance)) {
+					this._dispatcher.replaceTokenBalanceByAddress(token.address, balance);
+					intervalUtils.clearAsyncExcludingInterval(this._zrxPollIntervalId);
+					delete this._zrxPollIntervalId;
+				}
+			},
+			5000,
+			(err: Error) => {
+				utils.consoleLog(`Polling tokenBalance failed: ${err}`);
+				intervalUtils.clearAsyncExcludingInterval(this._zrxPollIntervalId);
+				delete this._zrxPollIntervalId;
+			},
+		);
+	}
+	public async signOrderHashAsync(orderHash: string): Promise<SignatureData> {
+		utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
+		const makerAddress = this._userAddress;
+		// If makerAddress is undefined, this means they have a web3 instance injected into their browser
+		// but no account addresses associated with it.
+		if (_.isUndefined(makerAddress)) {
+			throw new Error('Tried to send a sign request but user has no associated addresses');
+		}
+		const ecSignature = await this._zeroEx.signOrderHashAsync(orderHash, makerAddress);
+		const signatureData = _.extend({}, ecSignature, {
+			hash: orderHash,
+		});
+		this._dispatcher.updateSignatureData(signatureData);
+		return signatureData;
+	}
+	public async mintTestTokensAsync(token: Token) {
+		utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
+
+		const mintableContract = await this._instantiateContractIfExistsAsync(MintableArtifacts, token.address);
+		await mintableContract.mint(constants.MINT_AMOUNT, {
+			from: this._userAddress,
+		});
+		const balanceDelta = constants.MINT_AMOUNT;
+		this._dispatcher.updateTokenBalanceByAddress(token.address, balanceDelta);
+	}
+	public async getBalanceInEthAsync(owner: string): Promise<BigNumber> {
+		const balance = await this._web3Wrapper.getBalanceInEthAsync(owner);
+		return balance;
+	}
+	public async convertEthToWrappedEthTokensAsync(etherTokenAddress: string, amount: BigNumber): Promise<void> {
+		utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
+		utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
+
+		const txHash = await this._zeroEx.etherToken.depositAsync(etherTokenAddress, amount, this._userAddress);
+		await this._showEtherScanLinkAndAwaitTransactionMinedAsync(txHash);
+	}
+	public async convertWrappedEthTokensToEthAsync(etherTokenAddress: string, amount: BigNumber): Promise<void> {
+		utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
+		utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
+
+		const txHash = await this._zeroEx.etherToken.withdrawAsync(etherTokenAddress, amount, this._userAddress);
+		await this._showEtherScanLinkAndAwaitTransactionMinedAsync(txHash);
+	}
+	public async doesContractExistAtAddressAsync(address: string) {
+		const doesContractExist = await this._web3Wrapper.doesContractExistAtAddressAsync(address);
+		return doesContractExist;
+	}
+	public async getCurrentUserTokenBalanceAndAllowanceAsync(tokenAddress: string): Promise<BigNumber[]> {
+		const tokenBalanceAndAllowance = await this.getTokenBalanceAndAllowanceAsync(this._userAddress, tokenAddress);
+		return tokenBalanceAndAllowance;
+	}
+	public async getTokenBalanceAndAllowanceAsync(ownerAddress: string, tokenAddress: string): Promise<BigNumber[]> {
+		utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
+
+		if (_.isEmpty(ownerAddress)) {
+			const zero = new BigNumber(0);
+			return [zero, zero];
+		}
+		let balance = new BigNumber(0);
+		let allowance = new BigNumber(0);
+		if (this._doesUserAddressExist()) {
+			balance = await this._zeroEx.token.getBalanceAsync(tokenAddress, ownerAddress);
+			allowance = await this._zeroEx.token.getProxyAllowanceAsync(tokenAddress, ownerAddress);
+		}
+		return [balance, allowance];
+	}
+	public async updateTokenBalancesAndAllowancesAsync(tokens: Token[]) {
+		const tokenStateByAddress: TokenStateByAddress = {};
+		for (const token of tokens) {
+			let balance = new BigNumber(0);
+			let allowance = new BigNumber(0);
+			if (this._doesUserAddressExist()) {
+				[balance, allowance] = await this.getTokenBalanceAndAllowanceAsync(this._userAddress, token.address);
+			}
+			const tokenState = {
+				balance,
+				allowance,
+			};
+			tokenStateByAddress[token.address] = tokenState;
+		}
+		this._dispatcher.updateTokenStateByAddress(tokenStateByAddress);
+	}
+	public async getUserAccountsAsync() {
+		utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
+		const userAccountsIfExists = await this._zeroEx.getAvailableAddressesAsync();
+		return userAccountsIfExists;
+	}
+	// HACK: When a user is using a Ledger, we simply dispatch the selected userAddress, which
+	// by-passes the web3Wrapper logic for updating the prevUserAddress. We therefore need to
+	// manually update it. This should only be called by the LedgerConfigDialog.
+	public updateWeb3WrapperPrevUserAddress(newUserAddress: string) {
+		this._web3Wrapper.updatePrevUserAddress(newUserAddress);
+	}
+	public destroy() {
+		intervalUtils.clearAsyncExcludingInterval(this._zrxPollIntervalId);
+		this._web3Wrapper.destroy();
+		this._stopWatchingExchangeLogFillEvents();
+	}
+	private async _showEtherScanLinkAndAwaitTransactionMinedAsync(
+		txHash: string,
+	): Promise<TransactionReceiptWithDecodedLogs> {
+		const etherScanLinkIfExists = utils.getEtherScanLinkIfExists(txHash, this.networkId, EtherscanLinkSuffixes.Tx);
+		this._dispatcher.showFlashMessage(
+			React.createElement(TransactionSubmitted, {
+				etherScanLinkIfExists,
+			}),
+		);
+		const receipt = await this._zeroEx.awaitTransactionMinedAsync(txHash);
+		return receipt;
+	}
+	private _doesUserAddressExist(): boolean {
+		return this._userAddress !== '';
+	}
+	private async _rehydrateStoreWithContractEvents() {
+		// Ensure we are only ever listening to one set of events
+		this._stopWatchingExchangeLogFillEvents();
+
+		if (!this._doesUserAddressExist()) {
+			return; // short-circuit
+		}
+
+		if (!_.isUndefined(this._zeroEx)) {
+			// Since we do not have an index on the `taker` address and want to show
+			// transactions where an account is either the `maker` or `taker`, we loop
+			// through all fill events, and filter/cache them client-side.
+			const filterIndexObj = {};
+			await this._startListeningForExchangeLogFillEventsAsync(filterIndexObj);
+		}
+	}
+	private async _startListeningForExchangeLogFillEventsAsync(indexFilterValues: IndexedFilterValues): Promise<void> {
+		utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
+		utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
+
+		// Fetch historical logs
+		await this._fetchHistoricalExchangeLogFillEventsAsync(indexFilterValues);
+
+		// Start a subscription for new logs
+		this._zeroEx.exchange.subscribe(
+			ExchangeEvents.LogFill,
+			indexFilterValues,
+			async (err: Error, decodedLogEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
+				if (err) {
+					// Note: it's not entirely clear from the documentation which
+					// errors will be thrown by `watch`. For now, let's log the error
+					// to rollbar and stop watching when one occurs
+					// tslint:disable-next-line:no-floating-promises
+					errorReporter.reportAsync(err); // fire and forget
+					return;
+				} else {
+					const decodedLog = decodedLogEvent.log;
+					if (!this._doesLogEventInvolveUser(decodedLog)) {
+						return; // We aren't interested in the fill event
+					}
+					this._updateLatestFillsBlockIfNeeded(decodedLog.blockNumber);
+					const fill = await this._convertDecodedLogToFillAsync(decodedLog);
+					if (decodedLogEvent.isRemoved) {
+						tradeHistoryStorage.removeFillFromUser(this._userAddress, this.networkId, fill);
+					} else {
+						tradeHistoryStorage.addFillToUser(this._userAddress, this.networkId, fill);
+					}
+				}
+			},
+		);
+	}
+	private async _fetchHistoricalExchangeLogFillEventsAsync(indexFilterValues: IndexedFilterValues) {
+		const fromBlock = tradeHistoryStorage.getFillsLatestBlock(this._userAddress, this.networkId);
+		const blockRange: BlockRange = {
+			fromBlock,
+			toBlock: 'latest' as BlockParam,
+		};
+		const decodedLogs = await this._zeroEx.exchange.getLogsAsync<LogFillContractEventArgs>(
+			ExchangeEvents.LogFill,
+			blockRange,
+			indexFilterValues,
+		);
+		for (const decodedLog of decodedLogs) {
+			if (!this._doesLogEventInvolveUser(decodedLog)) {
+				continue; // We aren't interested in the fill event
+			}
+			this._updateLatestFillsBlockIfNeeded(decodedLog.blockNumber);
+			const fill = await this._convertDecodedLogToFillAsync(decodedLog);
+			tradeHistoryStorage.addFillToUser(this._userAddress, this.networkId, fill);
+		}
+	}
+	private async _convertDecodedLogToFillAsync(decodedLog: LogWithDecodedArgs<LogFillContractEventArgs>) {
+		const args = decodedLog.args;
+		const blockTimestamp = await this._web3Wrapper.getBlockTimestampAsync(decodedLog.blockHash);
+		const fill = {
+			filledTakerTokenAmount: args.filledTakerTokenAmount,
+			filledMakerTokenAmount: args.filledMakerTokenAmount,
+			logIndex: decodedLog.logIndex,
+			maker: args.maker,
+			orderHash: args.orderHash,
+			taker: args.taker,
+			makerToken: args.makerToken,
+			takerToken: args.takerToken,
+			paidMakerFee: args.paidMakerFee,
+			paidTakerFee: args.paidTakerFee,
+			transactionHash: decodedLog.transactionHash,
+			blockTimestamp,
+		};
+		return fill;
+	}
+	private _doesLogEventInvolveUser(decodedLog: LogWithDecodedArgs<LogFillContractEventArgs>) {
+		const args = decodedLog.args;
+		const isUserMakerOrTaker = args.maker === this._userAddress || args.taker === this._userAddress;
+		return isUserMakerOrTaker;
+	}
+	private _updateLatestFillsBlockIfNeeded(blockNumber: number) {
+		const isBlockPending = _.isNull(blockNumber);
+		if (!isBlockPending) {
+			// Hack: I've observed the behavior where a client won't register certain fill events
+			// and lowering the cache blockNumber fixes the issue. As a quick fix for now, simply
+			// set the cached blockNumber 50 below the one returned. This way, upon refreshing, a user
+			// would still attempt to re-fetch events from the previous 50 blocks, but won't need to
+			// re-fetch all events in all blocks.
+			// TODO: Debug if this is a race condition, and apply a more precise fix
+			const blockNumberToSet =
+				blockNumber - BLOCK_NUMBER_BACK_TRACK < 0 ? 0 : blockNumber - BLOCK_NUMBER_BACK_TRACK;
+			tradeHistoryStorage.setFillsLatestBlock(this._userAddress, this.networkId, blockNumberToSet);
+		}
+	}
+	private _stopWatchingExchangeLogFillEvents(): void {
+		this._zeroEx.exchange.unsubscribeAll();
+	}
+	private async _getTokenRegistryTokensByAddressAsync(): Promise<TokenByAddress> {
+		utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
+		const tokenRegistryTokens = await this._zeroEx.tokenRegistry.getTokensAsync();
+
+		const tokenByAddress: TokenByAddress = {};
+		_.each(tokenRegistryTokens, (t: ZeroExToken, i: number) => {
+			// HACK: For now we have a hard-coded list of iconUrls for the dummyTokens
+			// TODO: Refactor this out and pull the iconUrl directly from the TokenRegistry
+			const iconUrl = configs.ICON_URL_BY_SYMBOL[t.symbol];
+			// HACK: Temporarily we hijack the WETH addresses fetched from the tokenRegistry
+			// so that we can take our time with actually updating it. This ensures that when
+			// we deploy the new WETH page, everyone will re-fill their trackedTokens with the
+			// new canonical WETH.
+			// TODO: Remove this hack once we've updated the TokenRegistries
+			// Airtable task: https://airtable.com/tblFe0Q9JuKJPYbTn/viwsOG2Y97qdIeCIO/recv3VGmIorFzHBVz
+			let address = t.address;
+			if (configs.SHOULD_DEPRECATE_OLD_WETH_TOKEN && t.symbol === 'WETH') {
+				const newEtherTokenAddressIfExists = configs.NEW_WRAPPED_ETHERS[this.networkId];
+				if (!_.isUndefined(newEtherTokenAddressIfExists)) {
+					address = newEtherTokenAddressIfExists;
+				}
+			}
+			const token: Token = {
+				iconUrl,
+				address,
+				name: t.name,
+				symbol: t.symbol,
+				decimals: t.decimals,
+				isTracked: false,
+				isRegistered: true,
+			};
+			tokenByAddress[token.address] = token;
+		});
+		return tokenByAddress;
+	}
+	private async _onPageLoadInitFireAndForgetAsync() {
+		await Blockchain._onPageLoadAsync(); // wait for page to load
+
+		// Hack: We need to know the networkId the injectedWeb3 is connected to (if it is defined) in
+		// order to properly instantiate the web3Wrapper. Since we must use the async call, we cannot
+		// retrieve it from within the web3Wrapper constructor. This is and should remain the only
+		// call to a web3 instance outside of web3Wrapper in the entire dapp.
+		// In addition, if the user has an injectedWeb3 instance that is disconnected from a backing
+		// Ethereum node, this call will throw. We need to handle this case gracefully
+		const injectedWeb3 = (window as any).web3;
+		let networkIdIfExists: number;
+		if (!_.isUndefined(injectedWeb3)) {
+			try {
+				networkIdIfExists = _.parseInt(await promisify<string>(injectedWeb3.version.getNetwork)());
+			} catch (err) {
+				// Ignore error and proceed with networkId undefined
+			}
+		}
+
+		const provider = await Blockchain._getProviderAsync(injectedWeb3, networkIdIfExists);
+		const networkId = !_.isUndefined(networkIdIfExists)
+			? networkIdIfExists
+			: configs.IS_MAINNET_ENABLED ? constants.NETWORK_ID_MAINNET : constants.NETWORK_ID_TESTNET;
+		const zeroExConfigs = {
+			networkId,
+		};
+		this._zeroEx = new ZeroEx(provider, zeroExConfigs);
+		this._updateProviderName(injectedWeb3);
+		const shouldPollUserAddress = true;
+		this._web3Wrapper = new Web3Wrapper(this._dispatcher, provider, networkId, shouldPollUserAddress);
+		await this._postInstantiationOrUpdatingProviderZeroExAsync();
+	}
+	// This method should always be run after instantiating or updating the provider
+	// of the ZeroEx instance.
+	private async _postInstantiationOrUpdatingProviderZeroExAsync() {
+		utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
+		this._exchangeAddress = this._zeroEx.exchange.getContractAddress();
+	}
+	private _updateProviderName(injectedWeb3: Web3) {
+		const doesInjectedWeb3Exist = !_.isUndefined(injectedWeb3);
+		const providerName = doesInjectedWeb3Exist
+			? Blockchain._getNameGivenProvider(injectedWeb3.currentProvider)
+			: constants.PROVIDER_NAME_PUBLIC;
+		this._dispatcher.updateInjectedProviderName(providerName);
+	}
+	private async _fetchTokenInformationAsync() {
+		utils.assert(
+			!_.isUndefined(this.networkId),
+			'Cannot call fetchTokenInformationAsync if disconnected from Ethereum node',
+		);
+
+		this._dispatcher.updateBlockchainIsLoaded(false);
+		this._dispatcher.clearTokenByAddress();
+
+		const tokenRegistryTokensByAddress = await this._getTokenRegistryTokensByAddressAsync();
+
+		// HACK: We need to fetch the userAddress here because otherwise we cannot save the
+		// tracked tokens in localStorage under the users address nor fetch the token
+		// balances and allowances and we need to do this in order not to trigger the blockchain
+		// loading dialog to show up twice. First to load the contracts, and second to load the
+		// balances and allowances.
+		this._userAddress = await this._web3Wrapper.getFirstAccountIfExistsAsync();
+		if (!_.isEmpty(this._userAddress)) {
+			this._dispatcher.updateUserAddress(this._userAddress);
+		}
+
+		let trackedTokensIfExists = trackedTokenStorage.getTrackedTokensIfExists(this._userAddress, this.networkId);
+		const tokenRegistryTokens = _.values(tokenRegistryTokensByAddress);
+		if (_.isUndefined(trackedTokensIfExists)) {
+			trackedTokensIfExists = _.map(configs.DEFAULT_TRACKED_TOKEN_SYMBOLS, symbol => {
+				const token = _.find(tokenRegistryTokens, t => t.symbol === symbol);
+				token.isTracked = true;
+				return token;
+			});
+			_.each(trackedTokensIfExists, token => {
+				trackedTokenStorage.addTrackedTokenToUser(this._userAddress, this.networkId, token);
+			});
+		} else {
+			// Properly set all tokenRegistry tokens `isTracked` to true if they are in the existing trackedTokens array
+			_.each(trackedTokensIfExists, trackedToken => {
+				if (!_.isUndefined(tokenRegistryTokensByAddress[trackedToken.address])) {
+					tokenRegistryTokensByAddress[trackedToken.address].isTracked = true;
+				}
+			});
+		}
+		const allTokens = _.uniq([...tokenRegistryTokens, ...trackedTokensIfExists]);
+		this._dispatcher.updateTokenByAddress(allTokens);
+
+		// Get balance/allowance for tracked tokens
+		await this.updateTokenBalancesAndAllowancesAsync(trackedTokensIfExists);
+
+		const mostPopularTradingPairTokens: Token[] = [
+			_.find(allTokens, { symbol: configs.DEFAULT_TRACKED_TOKEN_SYMBOLS[0] }),
+			_.find(allTokens, { symbol: configs.DEFAULT_TRACKED_TOKEN_SYMBOLS[1] }),
+		];
+		this._dispatcher.updateChosenAssetTokenAddress(Side.Deposit, mostPopularTradingPairTokens[0].address);
+		this._dispatcher.updateChosenAssetTokenAddress(Side.Receive, mostPopularTradingPairTokens[1].address);
+		this._dispatcher.updateBlockchainIsLoaded(true);
+	}
+	private async _instantiateContractIfExistsAsync(artifact: any, address?: string): Promise<ContractInstance> {
+		const c = await contract(artifact);
+		const providerObj = this._web3Wrapper.getProviderObj();
+		c.setProvider(providerObj);
+
+		const artifactNetworkConfigs = artifact.networks[this.networkId];
+		let contractAddress;
+		if (!_.isUndefined(address)) {
+			contractAddress = address;
+		} else if (!_.isUndefined(artifactNetworkConfigs)) {
+			contractAddress = artifactNetworkConfigs.address;
+		}
+
+		if (!_.isUndefined(contractAddress)) {
+			const doesContractExist = await this.doesContractExistAtAddressAsync(contractAddress);
+			if (!doesContractExist) {
+				utils.consoleLog(`Contract does not exist: ${artifact.contract_name} at ${contractAddress}`);
+				throw new Error(BlockchainCallErrs.ContractDoesNotExist);
+			}
+		}
+
+		try {
+			const contractInstance = _.isUndefined(address) ? await c.deployed() : await c.at(address);
+			return contractInstance;
+		} catch (err) {
+			const errMsg = `${err}`;
+			utils.consoleLog(`Notice: Error encountered: ${err} ${err.stack}`);
+			if (_.includes(errMsg, 'not been deployed to detected network')) {
+				throw new Error(BlockchainCallErrs.ContractDoesNotExist);
+			} else {
+				await errorReporter.reportAsync(err);
+				throw new Error(BlockchainCallErrs.UnhandledError);
+			}
+		}
+	}
 } // tslint:disable:max-file-line-count
diff --git a/packages/website/ts/components/dialogs/blockchain_err_dialog.tsx b/packages/website/ts/components/dialogs/blockchain_err_dialog.tsx
index f555ca6b1..e0f61a29b 100644
--- a/packages/website/ts/components/dialogs/blockchain_err_dialog.tsx
+++ b/packages/website/ts/components/dialogs/blockchain_err_dialog.tsx
@@ -9,150 +9,150 @@ import { configs } from 'ts/utils/configs';
 import { constants } from 'ts/utils/constants';
 
 interface BlockchainErrDialogProps {
-    blockchain: Blockchain;
-    blockchainErr: BlockchainErrs;
-    isOpen: boolean;
-    userAddress: string;
-    toggleDialogFn: (isOpen: boolean) => void;
-    networkId: number;
+	blockchain: Blockchain;
+	blockchainErr: BlockchainErrs;
+	isOpen: boolean;
+	userAddress: string;
+	toggleDialogFn: (isOpen: boolean) => void;
+	networkId: number;
 }
 
 export class BlockchainErrDialog extends React.Component<BlockchainErrDialogProps, undefined> {
-    public render() {
-        const dialogActions = [
-            <FlatButton
-                key="blockchainErrOk"
-                label="Ok"
-                primary={true}
-                onTouchTap={this.props.toggleDialogFn.bind(this.props.toggleDialogFn, false)}
-            />,
-        ];
+	public render() {
+		const dialogActions = [
+			<FlatButton
+				key="blockchainErrOk"
+				label="Ok"
+				primary={true}
+				onTouchTap={this.props.toggleDialogFn.bind(this.props.toggleDialogFn, false)}
+			/>,
+		];
 
-        const hasWalletAddress = this.props.userAddress !== '';
-        return (
-            <Dialog
-                title={this._getTitle(hasWalletAddress)}
-                titleStyle={{ fontWeight: 100 }}
-                actions={dialogActions}
-                open={this.props.isOpen}
-                contentStyle={{ width: 400 }}
-                onRequestClose={this.props.toggleDialogFn.bind(this.props.toggleDialogFn, false)}
-                autoScrollBodyContent={true}
-            >
-                <div className="pt2" style={{ color: colors.grey700 }}>
-                    {this._renderExplanation(hasWalletAddress)}
-                </div>
-            </Dialog>
-        );
-    }
-    private _getTitle(hasWalletAddress: boolean) {
-        if (this.props.blockchainErr === BlockchainErrs.AContractNotDeployedOnNetwork) {
-            return '0x smart contracts not found';
-        } else if (!hasWalletAddress) {
-            return 'Enable wallet communication';
-        } else if (this.props.blockchainErr === BlockchainErrs.DisconnectedFromEthereumNode) {
-            return 'Disconnected from Ethereum network';
-        } else {
-            return 'Unexpected error';
-        }
-    }
-    private _renderExplanation(hasWalletAddress: boolean) {
-        if (this.props.blockchainErr === BlockchainErrs.AContractNotDeployedOnNetwork) {
-            return this._renderContractsNotDeployedExplanation();
-        } else if (!hasWalletAddress) {
-            return this._renderNoWalletFoundExplanation();
-        } else if (this.props.blockchainErr === BlockchainErrs.DisconnectedFromEthereumNode) {
-            return this._renderDisconnectedFromNode();
-        } else {
-            return this._renderUnexpectedErrorExplanation();
-        }
-    }
-    private _renderDisconnectedFromNode() {
-        return (
-            <div>
-                You were disconnected from the backing Ethereum node. If using{' '}
-                <a href={constants.URL_METAMASK_CHROME_STORE} target="_blank">
-                    Metamask
-                </a>{' '}
-                or{' '}
-                <a href={constants.URL_MIST_DOWNLOAD} target="_blank">
-                    Mist
-                </a>{' '}
-                try refreshing the page. If using a locally hosted Ethereum node, make sure it's still running.
-            </div>
-        );
-    }
-    private _renderUnexpectedErrorExplanation() {
-        return <div>We encountered an unexpected error. Please try refreshing the page.</div>;
-    }
-    private _renderNoWalletFoundExplanation() {
-        return (
-            <div>
-                <div>
-                    We were unable to access an Ethereum wallet you control. In order to interact with the 0x portal
-                    dApp, we need a way to interact with one of your Ethereum wallets. There are two easy ways you can
-                    enable us to do that:
-                </div>
-                <h4>1. Metamask chrome extension</h4>
-                <div>
-                    You can install the{' '}
-                    <a href={constants.URL_METAMASK_CHROME_STORE} target="_blank">
-                        Metamask
-                    </a>{' '}
-                    Chrome extension Ethereum wallet. Once installed and set up, refresh this page.
-                    <div className="pt1">
-                        <span className="bold">Note:</span> If you already have Metamask installed, make sure it is
-                        unlocked.
-                    </div>
-                </div>
-                <h4>Parity Signer</h4>
-                <div>
-                    The{' '}
-                    <a href={constants.URL_PARITY_CHROME_STORE} target="_blank">
-                        Parity Signer Chrome extension
-                    </a>{' '}
-                    lets you connect to a locally running Parity node. Make sure you have started your local Parity node
-                    with {configs.IS_MAINNET_ENABLED && '`parity ui` or'} `parity --chain kovan ui` in order to connect
-                    to {configs.IS_MAINNET_ENABLED ? 'mainnet or Kovan respectively.' : 'Kovan.'}
-                </div>
-                <div className="pt2">
-                    <span className="bold">Note:</span> If you have done one of the above steps and are still seeing
-                    this message, we might still be unable to retrieve an Ethereum address by calling
-                    `web3.eth.accounts`. Make sure you have created at least one Ethereum address.
-                </div>
-            </div>
-        );
-    }
-    private _renderContractsNotDeployedExplanation() {
-        return (
-            <div>
-                <div>
-                    The 0x smart contracts are not deployed on the Ethereum network you are currently connected to
-                    (network Id: {this.props.networkId}). In order to use the 0x portal dApp, please connect to the{' '}
-                    {constants.TESTNET_NAME} testnet (network Id: {constants.NETWORK_ID_TESTNET})
-                    {configs.IS_MAINNET_ENABLED
-                        ? ` or ${constants.MAINNET_NAME} (network Id: ${constants.NETWORK_ID_MAINNET}).`
-                        : `.`}
-                </div>
-                <h4>Metamask</h4>
-                <div>
-                    If you are using{' '}
-                    <a href={constants.URL_METAMASK_CHROME_STORE} target="_blank">
-                        Metamask
-                    </a>, you can switch networks in the top left corner of the extension popover.
-                </div>
-                <h4>Parity Signer</h4>
-                <div>
-                    If using the{' '}
-                    <a href={constants.URL_PARITY_CHROME_STORE} target="_blank">
-                        Parity Signer Chrome extension
-                    </a>, make sure to start your local Parity node with{' '}
-                    {configs.IS_MAINNET_ENABLED
-                        ? '`parity ui` or `parity --chain Kovan ui` in order to connect to mainnet \
+		const hasWalletAddress = this.props.userAddress !== '';
+		return (
+			<Dialog
+				title={this._getTitle(hasWalletAddress)}
+				titleStyle={{ fontWeight: 100 }}
+				actions={dialogActions}
+				open={this.props.isOpen}
+				contentStyle={{ width: 400 }}
+				onRequestClose={this.props.toggleDialogFn.bind(this.props.toggleDialogFn, false)}
+				autoScrollBodyContent={true}
+			>
+				<div className="pt2" style={{ color: colors.grey700 }}>
+					{this._renderExplanation(hasWalletAddress)}
+				</div>
+			</Dialog>
+		);
+	}
+	private _getTitle(hasWalletAddress: boolean) {
+		if (this.props.blockchainErr === BlockchainErrs.AContractNotDeployedOnNetwork) {
+			return '0x smart contracts not found';
+		} else if (!hasWalletAddress) {
+			return 'Enable wallet communication';
+		} else if (this.props.blockchainErr === BlockchainErrs.DisconnectedFromEthereumNode) {
+			return 'Disconnected from Ethereum network';
+		} else {
+			return 'Unexpected error';
+		}
+	}
+	private _renderExplanation(hasWalletAddress: boolean) {
+		if (this.props.blockchainErr === BlockchainErrs.AContractNotDeployedOnNetwork) {
+			return this._renderContractsNotDeployedExplanation();
+		} else if (!hasWalletAddress) {
+			return this._renderNoWalletFoundExplanation();
+		} else if (this.props.blockchainErr === BlockchainErrs.DisconnectedFromEthereumNode) {
+			return this._renderDisconnectedFromNode();
+		} else {
+			return this._renderUnexpectedErrorExplanation();
+		}
+	}
+	private _renderDisconnectedFromNode() {
+		return (
+			<div>
+				You were disconnected from the backing Ethereum node. If using{' '}
+				<a href={constants.URL_METAMASK_CHROME_STORE} target="_blank">
+					Metamask
+				</a>{' '}
+				or{' '}
+				<a href={constants.URL_MIST_DOWNLOAD} target="_blank">
+					Mist
+				</a>{' '}
+				try refreshing the page. If using a locally hosted Ethereum node, make sure it's still running.
+			</div>
+		);
+	}
+	private _renderUnexpectedErrorExplanation() {
+		return <div>We encountered an unexpected error. Please try refreshing the page.</div>;
+	}
+	private _renderNoWalletFoundExplanation() {
+		return (
+			<div>
+				<div>
+					We were unable to access an Ethereum wallet you control. In order to interact with the 0x portal
+					dApp, we need a way to interact with one of your Ethereum wallets. There are two easy ways you can
+					enable us to do that:
+				</div>
+				<h4>1. Metamask chrome extension</h4>
+				<div>
+					You can install the{' '}
+					<a href={constants.URL_METAMASK_CHROME_STORE} target="_blank">
+						Metamask
+					</a>{' '}
+					Chrome extension Ethereum wallet. Once installed and set up, refresh this page.
+					<div className="pt1">
+						<span className="bold">Note:</span> If you already have Metamask installed, make sure it is
+						unlocked.
+					</div>
+				</div>
+				<h4>Parity Signer</h4>
+				<div>
+					The{' '}
+					<a href={constants.URL_PARITY_CHROME_STORE} target="_blank">
+						Parity Signer Chrome extension
+					</a>{' '}
+					lets you connect to a locally running Parity node. Make sure you have started your local Parity node
+					with {configs.IS_MAINNET_ENABLED && '`parity ui` or'} `parity --chain kovan ui` in order to connect
+					to {configs.IS_MAINNET_ENABLED ? 'mainnet or Kovan respectively.' : 'Kovan.'}
+				</div>
+				<div className="pt2">
+					<span className="bold">Note:</span> If you have done one of the above steps and are still seeing
+					this message, we might still be unable to retrieve an Ethereum address by calling
+					`web3.eth.accounts`. Make sure you have created at least one Ethereum address.
+				</div>
+			</div>
+		);
+	}
+	private _renderContractsNotDeployedExplanation() {
+		return (
+			<div>
+				<div>
+					The 0x smart contracts are not deployed on the Ethereum network you are currently connected to
+					(network Id: {this.props.networkId}). In order to use the 0x portal dApp, please connect to the{' '}
+					{constants.TESTNET_NAME} testnet (network Id: {constants.NETWORK_ID_TESTNET})
+					{configs.IS_MAINNET_ENABLED
+						? ` or ${constants.MAINNET_NAME} (network Id: ${constants.NETWORK_ID_MAINNET}).`
+						: `.`}
+				</div>
+				<h4>Metamask</h4>
+				<div>
+					If you are using{' '}
+					<a href={constants.URL_METAMASK_CHROME_STORE} target="_blank">
+						Metamask
+					</a>, you can switch networks in the top left corner of the extension popover.
+				</div>
+				<h4>Parity Signer</h4>
+				<div>
+					If using the{' '}
+					<a href={constants.URL_PARITY_CHROME_STORE} target="_blank">
+						Parity Signer Chrome extension
+					</a>, make sure to start your local Parity node with{' '}
+					{configs.IS_MAINNET_ENABLED
+						? '`parity ui` or `parity --chain Kovan ui` in order to connect to mainnet \
                          or Kovan respectively.'
-                        : '`parity --chain kovan ui` in order to connect to Kovan.'}
-                </div>
-            </div>
-        );
-    }
+						: '`parity --chain kovan ui` in order to connect to Kovan.'}
+				</div>
+			</div>
+		);
+	}
 }
diff --git a/packages/website/ts/components/dialogs/eth_weth_conversion_dialog.tsx b/packages/website/ts/components/dialogs/eth_weth_conversion_dialog.tsx
index 661cc1d8c..45ba5cc9e 100644
--- a/packages/website/ts/components/dialogs/eth_weth_conversion_dialog.tsx
+++ b/packages/website/ts/components/dialogs/eth_weth_conversion_dialog.tsx
@@ -8,156 +8,156 @@ import { Side, Token, TokenState } from 'ts/types';
 import { colors } from 'ts/utils/colors';
 
 interface EthWethConversionDialogProps {
-    direction: Side;
-    onComplete: (direction: Side, value: BigNumber) => void;
-    onCancelled: () => void;
-    isOpen: boolean;
-    token: Token;
-    tokenState: TokenState;
-    etherBalance: BigNumber;
+	direction: Side;
+	onComplete: (direction: Side, value: BigNumber) => void;
+	onCancelled: () => void;
+	isOpen: boolean;
+	token: Token;
+	tokenState: TokenState;
+	etherBalance: BigNumber;
 }
 
 interface EthWethConversionDialogState {
-    value?: BigNumber;
-    shouldShowIncompleteErrs: boolean;
-    hasErrors: boolean;
+	value?: BigNumber;
+	shouldShowIncompleteErrs: boolean;
+	hasErrors: boolean;
 }
 
 export class EthWethConversionDialog extends React.Component<
-    EthWethConversionDialogProps,
-    EthWethConversionDialogState
+	EthWethConversionDialogProps,
+	EthWethConversionDialogState
 > {
-    constructor() {
-        super();
-        this.state = {
-            shouldShowIncompleteErrs: false,
-            hasErrors: false,
-        };
-    }
-    public render() {
-        const convertDialogActions = [
-            <FlatButton key="cancel" label="Cancel" onTouchTap={this._onCancel.bind(this)} />,
-            <FlatButton key="convert" label="Convert" primary={true} onTouchTap={this._onConvertClick.bind(this)} />,
-        ];
-        const title = this.props.direction === Side.Deposit ? 'Wrap ETH' : 'Unwrap WETH';
-        return (
-            <Dialog
-                title={title}
-                titleStyle={{ fontWeight: 100 }}
-                actions={convertDialogActions}
-                contentStyle={{ width: 448 }}
-                open={this.props.isOpen}
-            >
-                {this._renderConversionDialogBody()}
-            </Dialog>
-        );
-    }
-    private _renderConversionDialogBody() {
-        const explanation =
-            this.props.direction === Side.Deposit
-                ? 'Convert your Ether into a tokenized, tradable form.'
-                : "Convert your Wrapped Ether back into it's native form.";
-        const isWrappedVersion = this.props.direction === Side.Receive;
-        return (
-            <div>
-                <div className="pb2">{explanation}</div>
-                <div className="mx-auto" style={{ maxWidth: 312 }}>
-                    <div className="flex">
-                        {this._renderCurrency(isWrappedVersion)}
-                        <div style={{ paddingTop: 68 }}>
-                            <i style={{ fontSize: 28, color: colors.darkBlue }} className="zmdi zmdi-arrow-right" />
-                        </div>
-                        {this._renderCurrency(!isWrappedVersion)}
-                    </div>
-                    <div className="pt2 mx-auto" style={{ width: 245 }}>
-                        {this.props.direction === Side.Receive ? (
-                            <TokenAmountInput
-                                token={this.props.token}
-                                tokenState={this.props.tokenState}
-                                shouldShowIncompleteErrs={this.state.shouldShowIncompleteErrs}
-                                shouldCheckBalance={true}
-                                shouldCheckAllowance={false}
-                                onChange={this._onValueChange.bind(this)}
-                                amount={this.state.value}
-                                onVisitBalancesPageClick={this.props.onCancelled}
-                            />
-                        ) : (
-                            <EthAmountInput
-                                balance={this.props.etherBalance}
-                                amount={this.state.value}
-                                onChange={this._onValueChange.bind(this)}
-                                shouldCheckBalance={true}
-                                shouldShowIncompleteErrs={this.state.shouldShowIncompleteErrs}
-                                onVisitBalancesPageClick={this.props.onCancelled}
-                            />
-                        )}
-                        <div className="pt1" style={{ fontSize: 12 }}>
-                            <div className="left">1 ETH = 1 WETH</div>
-                            {this.props.direction === Side.Receive && (
-                                <div
-                                    className="right"
-                                    onClick={this._onMaxClick.bind(this)}
-                                    style={{
-                                        color: colors.darkBlue,
-                                        textDecoration: 'underline',
-                                        cursor: 'pointer',
-                                    }}
-                                >
-                                    Max
-                                </div>
-                            )}
-                        </div>
-                    </div>
-                </div>
-            </div>
-        );
-    }
-    private _renderCurrency(isWrappedVersion: boolean) {
-        const name = isWrappedVersion ? 'Wrapped Ether' : 'Ether';
-        const iconUrl = isWrappedVersion ? '/images/token_icons/ether_erc20.png' : '/images/ether.png';
-        const symbol = isWrappedVersion ? 'WETH' : 'ETH';
-        return (
-            <div className="mx-auto pt2">
-                <div className="center" style={{ color: colors.darkBlue }}>
-                    {name}
-                </div>
-                <div className="center py2">
-                    <img src={iconUrl} style={{ width: 60 }} />
-                </div>
-                <div className="center" style={{ fontSize: 12 }}>
-                    ({symbol})
-                </div>
-            </div>
-        );
-    }
-    private _onMaxClick() {
-        this.setState({
-            value: this.props.tokenState.balance,
-        });
-    }
-    private _onValueChange(isValid: boolean, amount?: BigNumber) {
-        this.setState({
-            value: amount,
-            hasErrors: !isValid,
-        });
-    }
-    private _onConvertClick() {
-        if (this.state.hasErrors) {
-            this.setState({
-                shouldShowIncompleteErrs: true,
-            });
-        } else {
-            const value = this.state.value;
-            this.setState({
-                value: undefined,
-            });
-            this.props.onComplete(this.props.direction, value);
-        }
-    }
-    private _onCancel() {
-        this.setState({
-            value: undefined,
-        });
-        this.props.onCancelled();
-    }
+	constructor() {
+		super();
+		this.state = {
+			shouldShowIncompleteErrs: false,
+			hasErrors: false,
+		};
+	}
+	public render() {
+		const convertDialogActions = [
+			<FlatButton key="cancel" label="Cancel" onTouchTap={this._onCancel.bind(this)} />,
+			<FlatButton key="convert" label="Convert" primary={true} onTouchTap={this._onConvertClick.bind(this)} />,
+		];
+		const title = this.props.direction === Side.Deposit ? 'Wrap ETH' : 'Unwrap WETH';
+		return (
+			<Dialog
+				title={title}
+				titleStyle={{ fontWeight: 100 }}
+				actions={convertDialogActions}
+				contentStyle={{ width: 448 }}
+				open={this.props.isOpen}
+			>
+				{this._renderConversionDialogBody()}
+			</Dialog>
+		);
+	}
+	private _renderConversionDialogBody() {
+		const explanation =
+			this.props.direction === Side.Deposit
+				? 'Convert your Ether into a tokenized, tradable form.'
+				: "Convert your Wrapped Ether back into it's native form.";
+		const isWrappedVersion = this.props.direction === Side.Receive;
+		return (
+			<div>
+				<div className="pb2">{explanation}</div>
+				<div className="mx-auto" style={{ maxWidth: 312 }}>
+					<div className="flex">
+						{this._renderCurrency(isWrappedVersion)}
+						<div style={{ paddingTop: 68 }}>
+							<i style={{ fontSize: 28, color: colors.darkBlue }} className="zmdi zmdi-arrow-right" />
+						</div>
+						{this._renderCurrency(!isWrappedVersion)}
+					</div>
+					<div className="pt2 mx-auto" style={{ width: 245 }}>
+						{this.props.direction === Side.Receive ? (
+							<TokenAmountInput
+								token={this.props.token}
+								tokenState={this.props.tokenState}
+								shouldShowIncompleteErrs={this.state.shouldShowIncompleteErrs}
+								shouldCheckBalance={true}
+								shouldCheckAllowance={false}
+								onChange={this._onValueChange.bind(this)}
+								amount={this.state.value}
+								onVisitBalancesPageClick={this.props.onCancelled}
+							/>
+						) : (
+							<EthAmountInput
+								balance={this.props.etherBalance}
+								amount={this.state.value}
+								onChange={this._onValueChange.bind(this)}
+								shouldCheckBalance={true}
+								shouldShowIncompleteErrs={this.state.shouldShowIncompleteErrs}
+								onVisitBalancesPageClick={this.props.onCancelled}
+							/>
+						)}
+						<div className="pt1" style={{ fontSize: 12 }}>
+							<div className="left">1 ETH = 1 WETH</div>
+							{this.props.direction === Side.Receive && (
+								<div
+									className="right"
+									onClick={this._onMaxClick.bind(this)}
+									style={{
+										color: colors.darkBlue,
+										textDecoration: 'underline',
+										cursor: 'pointer',
+									}}
+								>
+									Max
+								</div>
+							)}
+						</div>
+					</div>
+				</div>
+			</div>
+		);
+	}
+	private _renderCurrency(isWrappedVersion: boolean) {
+		const name = isWrappedVersion ? 'Wrapped Ether' : 'Ether';
+		const iconUrl = isWrappedVersion ? '/images/token_icons/ether_erc20.png' : '/images/ether.png';
+		const symbol = isWrappedVersion ? 'WETH' : 'ETH';
+		return (
+			<div className="mx-auto pt2">
+				<div className="center" style={{ color: colors.darkBlue }}>
+					{name}
+				</div>
+				<div className="center py2">
+					<img src={iconUrl} style={{ width: 60 }} />
+				</div>
+				<div className="center" style={{ fontSize: 12 }}>
+					({symbol})
+				</div>
+			</div>
+		);
+	}
+	private _onMaxClick() {
+		this.setState({
+			value: this.props.tokenState.balance,
+		});
+	}
+	private _onValueChange(isValid: boolean, amount?: BigNumber) {
+		this.setState({
+			value: amount,
+			hasErrors: !isValid,
+		});
+	}
+	private _onConvertClick() {
+		if (this.state.hasErrors) {
+			this.setState({
+				shouldShowIncompleteErrs: true,
+			});
+		} else {
+			const value = this.state.value;
+			this.setState({
+				value: undefined,
+			});
+			this.props.onComplete(this.props.direction, value);
+		}
+	}
+	private _onCancel() {
+		this.setState({
+			value: undefined,
+		});
+		this.props.onCancelled();
+	}
 }
diff --git a/packages/website/ts/components/dialogs/ledger_config_dialog.tsx b/packages/website/ts/components/dialogs/ledger_config_dialog.tsx
index 60db93c52..8b7760a1a 100644
--- a/packages/website/ts/components/dialogs/ledger_config_dialog.tsx
+++ b/packages/website/ts/components/dialogs/ledger_config_dialog.tsx
@@ -17,245 +17,245 @@ import { utils } from 'ts/utils/utils';
 const VALID_ETHEREUM_DERIVATION_PATH_PREFIX = `44'/60'`;
 
 enum LedgerSteps {
-    CONNECT,
-    SELECT_ADDRESS,
+	CONNECT,
+	SELECT_ADDRESS,
 }
 
 interface LedgerConfigDialogProps {
-    isOpen: boolean;
-    toggleDialogFn: (isOpen: boolean) => void;
-    dispatcher: Dispatcher;
-    blockchain: Blockchain;
-    networkId: number;
+	isOpen: boolean;
+	toggleDialogFn: (isOpen: boolean) => void;
+	dispatcher: Dispatcher;
+	blockchain: Blockchain;
+	networkId: number;
 }
 
 interface LedgerConfigDialogState {
-    didConnectFail: boolean;
-    stepIndex: LedgerSteps;
-    userAddresses: string[];
-    addressBalances: BigNumber[];
-    derivationPath: string;
-    derivationErrMsg: string;
+	didConnectFail: boolean;
+	stepIndex: LedgerSteps;
+	userAddresses: string[];
+	addressBalances: BigNumber[];
+	derivationPath: string;
+	derivationErrMsg: string;
 }
 
 export class LedgerConfigDialog extends React.Component<LedgerConfigDialogProps, LedgerConfigDialogState> {
-    constructor(props: LedgerConfigDialogProps) {
-        super(props);
-        this.state = {
-            didConnectFail: false,
-            stepIndex: LedgerSteps.CONNECT,
-            userAddresses: [],
-            addressBalances: [],
-            derivationPath: configs.DEFAULT_DERIVATION_PATH,
-            derivationErrMsg: '',
-        };
-    }
-    public render() {
-        const dialogActions = [
-            <FlatButton key="ledgerConnectCancel" label="Cancel" onTouchTap={this._onClose.bind(this)} />,
-        ];
-        const dialogTitle =
-            this.state.stepIndex === LedgerSteps.CONNECT ? 'Connect to your Ledger' : 'Select desired address';
-        return (
-            <Dialog
-                title={dialogTitle}
-                titleStyle={{ fontWeight: 100 }}
-                actions={dialogActions}
-                open={this.props.isOpen}
-                onRequestClose={this._onClose.bind(this)}
-                autoScrollBodyContent={true}
-                bodyStyle={{ paddingBottom: 0 }}
-            >
-                <div style={{ color: colors.grey700, paddingTop: 1 }}>
-                    {this.state.stepIndex === LedgerSteps.CONNECT && this._renderConnectStep()}
-                    {this.state.stepIndex === LedgerSteps.SELECT_ADDRESS && this._renderSelectAddressStep()}
-                </div>
-            </Dialog>
-        );
-    }
-    private _renderConnectStep() {
-        return (
-            <div>
-                <div className="h4 pt3">Follow these instructions before proceeding:</div>
-                <ol>
-                    <li className="pb1">Connect your Ledger Nano S & Open the Ethereum application</li>
-                    <li className="pb1">Verify that Browser Support is enabled in Settings</li>
-                    <li className="pb1">
-                        If no Browser Support is found in settings, verify that you have{' '}
-                        <a href="https://www.ledgerwallet.com/apps/manager" target="_blank">
-                            Firmware >1.2
-                        </a>
-                    </li>
-                </ol>
-                <div className="center pb3">
-                    <LifeCycleRaisedButton
-                        isPrimary={true}
-                        labelReady="Connect to Ledger"
-                        labelLoading="Connecting..."
-                        labelComplete="Connected!"
-                        onClickAsyncFn={this._onConnectLedgerClickAsync.bind(this, true)}
-                    />
-                    {this.state.didConnectFail && (
-                        <div className="pt2 left-align" style={{ color: colors.red200 }}>
-                            Failed to connect. Follow the instructions and try again.
-                        </div>
-                    )}
-                </div>
-            </div>
-        );
-    }
-    private _renderSelectAddressStep() {
-        return (
-            <div>
-                <div>
-                    <Table bodyStyle={{ height: 300 }} onRowSelection={this._onAddressSelected.bind(this)}>
-                        <TableHeader displaySelectAll={false}>
-                            <TableRow>
-                                <TableHeaderColumn colSpan={2}>Address</TableHeaderColumn>
-                                <TableHeaderColumn>Balance</TableHeaderColumn>
-                            </TableRow>
-                        </TableHeader>
-                        <TableBody>{this._renderAddressTableRows()}</TableBody>
-                    </Table>
-                </div>
-                <div className="flex pt2" style={{ height: 100 }}>
-                    <div className="overflow-hidden" style={{ width: 180 }}>
-                        <TextField
-                            floatingLabelFixed={true}
-                            floatingLabelStyle={{ color: colors.grey }}
-                            floatingLabelText="Update path derivation (advanced)"
-                            value={this.state.derivationPath}
-                            errorText={this.state.derivationErrMsg}
-                            onChange={this._onDerivationPathChanged.bind(this)}
-                        />
-                    </div>
-                    <div className="pl2" style={{ paddingTop: 28 }}>
-                        <LifeCycleRaisedButton
-                            labelReady="Update"
-                            labelLoading="Updating..."
-                            labelComplete="Updated!"
-                            onClickAsyncFn={this._onFetchAddressesForDerivationPathAsync.bind(this)}
-                        />
-                    </div>
-                </div>
-            </div>
-        );
-    }
-    private _renderAddressTableRows() {
-        const rows = _.map(this.state.userAddresses, (userAddress: string, i: number) => {
-            const balance = this.state.addressBalances[i];
-            const addressTooltipId = `address-${userAddress}`;
-            const balanceTooltipId = `balance-${userAddress}`;
-            const networkName = constants.NETWORK_NAME_BY_ID[this.props.networkId];
-            // We specifically prefix kovan ETH.
-            // TODO: We should probably add prefixes for all networks
-            const isKovanNetwork = networkName === 'Kovan';
-            const balanceString = `${balance.toString()} ${isKovanNetwork ? 'Kovan ' : ''}ETH`;
-            return (
-                <TableRow key={userAddress} style={{ height: 40 }}>
-                    <TableRowColumn colSpan={2}>
-                        <div data-tip={true} data-for={addressTooltipId}>
-                            {userAddress}
-                        </div>
-                        <ReactTooltip id={addressTooltipId}>{userAddress}</ReactTooltip>
-                    </TableRowColumn>
-                    <TableRowColumn>
-                        <div data-tip={true} data-for={balanceTooltipId}>
-                            {balanceString}
-                        </div>
-                        <ReactTooltip id={balanceTooltipId}>{balanceString}</ReactTooltip>
-                    </TableRowColumn>
-                </TableRow>
-            );
-        });
-        return rows;
-    }
-    private _onClose() {
-        this.setState({
-            didConnectFail: false,
-        });
-        const isOpen = false;
-        this.props.toggleDialogFn(isOpen);
-    }
-    private _onAddressSelected(selectedRowIndexes: number[]) {
-        const selectedRowIndex = selectedRowIndexes[0];
-        this.props.blockchain.updateLedgerDerivationIndex(selectedRowIndex);
-        const selectedAddress = this.state.userAddresses[selectedRowIndex];
-        const selectAddressBalance = this.state.addressBalances[selectedRowIndex];
-        this.props.dispatcher.updateUserAddress(selectedAddress);
-        this.props.blockchain.updateWeb3WrapperPrevUserAddress(selectedAddress);
-        this.props.dispatcher.updateUserEtherBalance(selectAddressBalance);
-        this.setState({
-            stepIndex: LedgerSteps.CONNECT,
-        });
-        const isOpen = false;
-        this.props.toggleDialogFn(isOpen);
-    }
-    private async _onFetchAddressesForDerivationPathAsync(): Promise<boolean> {
-        const currentlySetPath = this.props.blockchain.getLedgerDerivationPathIfExists();
-        let didSucceed;
-        if (currentlySetPath === this.state.derivationPath) {
-            didSucceed = true;
-            return didSucceed;
-        }
-        this.props.blockchain.updateLedgerDerivationPathIfExists(this.state.derivationPath);
-        didSucceed = await this._fetchAddressesAndBalancesAsync();
-        if (!didSucceed) {
-            this.setState({
-                derivationErrMsg: 'Failed to connect to Ledger.',
-            });
-        }
-        return didSucceed;
-    }
-    private async _fetchAddressesAndBalancesAsync() {
-        let userAddresses: string[];
-        const addressBalances: BigNumber[] = [];
-        try {
-            userAddresses = await this._getUserAddressesAsync();
-            for (const address of userAddresses) {
-                const balance = await this.props.blockchain.getBalanceInEthAsync(address);
-                addressBalances.push(balance);
-            }
-        } catch (err) {
-            utils.consoleLog(`Ledger error: ${JSON.stringify(err)}`);
-            this.setState({
-                didConnectFail: true,
-            });
-            return false;
-        }
-        this.setState({
-            userAddresses,
-            addressBalances,
-        });
-        return true;
-    }
-    private _onDerivationPathChanged(e: any, derivationPath: string) {
-        let derivationErrMsg = '';
-        if (!_.startsWith(derivationPath, VALID_ETHEREUM_DERIVATION_PATH_PREFIX)) {
-            derivationErrMsg = 'Must be valid Ethereum path.';
-        }
+	constructor(props: LedgerConfigDialogProps) {
+		super(props);
+		this.state = {
+			didConnectFail: false,
+			stepIndex: LedgerSteps.CONNECT,
+			userAddresses: [],
+			addressBalances: [],
+			derivationPath: configs.DEFAULT_DERIVATION_PATH,
+			derivationErrMsg: '',
+		};
+	}
+	public render() {
+		const dialogActions = [
+			<FlatButton key="ledgerConnectCancel" label="Cancel" onTouchTap={this._onClose.bind(this)} />,
+		];
+		const dialogTitle =
+			this.state.stepIndex === LedgerSteps.CONNECT ? 'Connect to your Ledger' : 'Select desired address';
+		return (
+			<Dialog
+				title={dialogTitle}
+				titleStyle={{ fontWeight: 100 }}
+				actions={dialogActions}
+				open={this.props.isOpen}
+				onRequestClose={this._onClose.bind(this)}
+				autoScrollBodyContent={true}
+				bodyStyle={{ paddingBottom: 0 }}
+			>
+				<div style={{ color: colors.grey700, paddingTop: 1 }}>
+					{this.state.stepIndex === LedgerSteps.CONNECT && this._renderConnectStep()}
+					{this.state.stepIndex === LedgerSteps.SELECT_ADDRESS && this._renderSelectAddressStep()}
+				</div>
+			</Dialog>
+		);
+	}
+	private _renderConnectStep() {
+		return (
+			<div>
+				<div className="h4 pt3">Follow these instructions before proceeding:</div>
+				<ol>
+					<li className="pb1">Connect your Ledger Nano S & Open the Ethereum application</li>
+					<li className="pb1">Verify that Browser Support is enabled in Settings</li>
+					<li className="pb1">
+						If no Browser Support is found in settings, verify that you have{' '}
+						<a href="https://www.ledgerwallet.com/apps/manager" target="_blank">
+							Firmware >1.2
+						</a>
+					</li>
+				</ol>
+				<div className="center pb3">
+					<LifeCycleRaisedButton
+						isPrimary={true}
+						labelReady="Connect to Ledger"
+						labelLoading="Connecting..."
+						labelComplete="Connected!"
+						onClickAsyncFn={this._onConnectLedgerClickAsync.bind(this, true)}
+					/>
+					{this.state.didConnectFail && (
+						<div className="pt2 left-align" style={{ color: colors.red200 }}>
+							Failed to connect. Follow the instructions and try again.
+						</div>
+					)}
+				</div>
+			</div>
+		);
+	}
+	private _renderSelectAddressStep() {
+		return (
+			<div>
+				<div>
+					<Table bodyStyle={{ height: 300 }} onRowSelection={this._onAddressSelected.bind(this)}>
+						<TableHeader displaySelectAll={false}>
+							<TableRow>
+								<TableHeaderColumn colSpan={2}>Address</TableHeaderColumn>
+								<TableHeaderColumn>Balance</TableHeaderColumn>
+							</TableRow>
+						</TableHeader>
+						<TableBody>{this._renderAddressTableRows()}</TableBody>
+					</Table>
+				</div>
+				<div className="flex pt2" style={{ height: 100 }}>
+					<div className="overflow-hidden" style={{ width: 180 }}>
+						<TextField
+							floatingLabelFixed={true}
+							floatingLabelStyle={{ color: colors.grey }}
+							floatingLabelText="Update path derivation (advanced)"
+							value={this.state.derivationPath}
+							errorText={this.state.derivationErrMsg}
+							onChange={this._onDerivationPathChanged.bind(this)}
+						/>
+					</div>
+					<div className="pl2" style={{ paddingTop: 28 }}>
+						<LifeCycleRaisedButton
+							labelReady="Update"
+							labelLoading="Updating..."
+							labelComplete="Updated!"
+							onClickAsyncFn={this._onFetchAddressesForDerivationPathAsync.bind(this)}
+						/>
+					</div>
+				</div>
+			</div>
+		);
+	}
+	private _renderAddressTableRows() {
+		const rows = _.map(this.state.userAddresses, (userAddress: string, i: number) => {
+			const balance = this.state.addressBalances[i];
+			const addressTooltipId = `address-${userAddress}`;
+			const balanceTooltipId = `balance-${userAddress}`;
+			const networkName = constants.NETWORK_NAME_BY_ID[this.props.networkId];
+			// We specifically prefix kovan ETH.
+			// TODO: We should probably add prefixes for all networks
+			const isKovanNetwork = networkName === 'Kovan';
+			const balanceString = `${balance.toString()} ${isKovanNetwork ? 'Kovan ' : ''}ETH`;
+			return (
+				<TableRow key={userAddress} style={{ height: 40 }}>
+					<TableRowColumn colSpan={2}>
+						<div data-tip={true} data-for={addressTooltipId}>
+							{userAddress}
+						</div>
+						<ReactTooltip id={addressTooltipId}>{userAddress}</ReactTooltip>
+					</TableRowColumn>
+					<TableRowColumn>
+						<div data-tip={true} data-for={balanceTooltipId}>
+							{balanceString}
+						</div>
+						<ReactTooltip id={balanceTooltipId}>{balanceString}</ReactTooltip>
+					</TableRowColumn>
+				</TableRow>
+			);
+		});
+		return rows;
+	}
+	private _onClose() {
+		this.setState({
+			didConnectFail: false,
+		});
+		const isOpen = false;
+		this.props.toggleDialogFn(isOpen);
+	}
+	private _onAddressSelected(selectedRowIndexes: number[]) {
+		const selectedRowIndex = selectedRowIndexes[0];
+		this.props.blockchain.updateLedgerDerivationIndex(selectedRowIndex);
+		const selectedAddress = this.state.userAddresses[selectedRowIndex];
+		const selectAddressBalance = this.state.addressBalances[selectedRowIndex];
+		this.props.dispatcher.updateUserAddress(selectedAddress);
+		this.props.blockchain.updateWeb3WrapperPrevUserAddress(selectedAddress);
+		this.props.dispatcher.updateUserEtherBalance(selectAddressBalance);
+		this.setState({
+			stepIndex: LedgerSteps.CONNECT,
+		});
+		const isOpen = false;
+		this.props.toggleDialogFn(isOpen);
+	}
+	private async _onFetchAddressesForDerivationPathAsync(): Promise<boolean> {
+		const currentlySetPath = this.props.blockchain.getLedgerDerivationPathIfExists();
+		let didSucceed;
+		if (currentlySetPath === this.state.derivationPath) {
+			didSucceed = true;
+			return didSucceed;
+		}
+		this.props.blockchain.updateLedgerDerivationPathIfExists(this.state.derivationPath);
+		didSucceed = await this._fetchAddressesAndBalancesAsync();
+		if (!didSucceed) {
+			this.setState({
+				derivationErrMsg: 'Failed to connect to Ledger.',
+			});
+		}
+		return didSucceed;
+	}
+	private async _fetchAddressesAndBalancesAsync() {
+		let userAddresses: string[];
+		const addressBalances: BigNumber[] = [];
+		try {
+			userAddresses = await this._getUserAddressesAsync();
+			for (const address of userAddresses) {
+				const balance = await this.props.blockchain.getBalanceInEthAsync(address);
+				addressBalances.push(balance);
+			}
+		} catch (err) {
+			utils.consoleLog(`Ledger error: ${JSON.stringify(err)}`);
+			this.setState({
+				didConnectFail: true,
+			});
+			return false;
+		}
+		this.setState({
+			userAddresses,
+			addressBalances,
+		});
+		return true;
+	}
+	private _onDerivationPathChanged(e: any, derivationPath: string) {
+		let derivationErrMsg = '';
+		if (!_.startsWith(derivationPath, VALID_ETHEREUM_DERIVATION_PATH_PREFIX)) {
+			derivationErrMsg = 'Must be valid Ethereum path.';
+		}
 
-        this.setState({
-            derivationPath,
-            derivationErrMsg,
-        });
-    }
-    private async _onConnectLedgerClickAsync() {
-        const didSucceed = await this._fetchAddressesAndBalancesAsync();
-        if (didSucceed) {
-            this.setState({
-                stepIndex: LedgerSteps.SELECT_ADDRESS,
-            });
-        }
-        return didSucceed;
-    }
-    private async _getUserAddressesAsync(): Promise<string[]> {
-        let userAddresses: string[];
-        userAddresses = await this.props.blockchain.getUserAccountsAsync();
+		this.setState({
+			derivationPath,
+			derivationErrMsg,
+		});
+	}
+	private async _onConnectLedgerClickAsync() {
+		const didSucceed = await this._fetchAddressesAndBalancesAsync();
+		if (didSucceed) {
+			this.setState({
+				stepIndex: LedgerSteps.SELECT_ADDRESS,
+			});
+		}
+		return didSucceed;
+	}
+	private async _getUserAddressesAsync(): Promise<string[]> {
+		let userAddresses: string[];
+		userAddresses = await this.props.blockchain.getUserAccountsAsync();
 
-        if (_.isEmpty(userAddresses)) {
-            throw new Error('No addresses retrieved.');
-        }
-        return userAddresses;
-    }
+		if (_.isEmpty(userAddresses)) {
+			throw new Error('No addresses retrieved.');
+		}
+		return userAddresses;
+	}
 }
diff --git a/packages/website/ts/components/dialogs/portal_disclaimer_dialog.tsx b/packages/website/ts/components/dialogs/portal_disclaimer_dialog.tsx
index 3ecc454a0..1c5efc978 100644
--- a/packages/website/ts/components/dialogs/portal_disclaimer_dialog.tsx
+++ b/packages/website/ts/components/dialogs/portal_disclaimer_dialog.tsx
@@ -4,33 +4,33 @@ import * as React from 'react';
 import { colors } from 'ts/utils/colors';
 
 interface PortalDisclaimerDialogProps {
-    isOpen: boolean;
-    onToggleDialog: () => void;
+	isOpen: boolean;
+	onToggleDialog: () => void;
 }
 
 export function PortalDisclaimerDialog(props: PortalDisclaimerDialogProps) {
-    return (
-        <Dialog
-            title="0x Portal Disclaimer"
-            titleStyle={{ fontWeight: 100 }}
-            actions={[<FlatButton key="portalAgree" label="I Agree" onTouchTap={props.onToggleDialog} />]}
-            open={props.isOpen}
-            onRequestClose={props.onToggleDialog}
-            autoScrollBodyContent={true}
-            modal={true}
-        >
-            <div className="pt2" style={{ color: colors.grey700 }}>
-                <div>
-                    0x Portal is a free software-based tool intended to help users to buy and sell ERC20-compatible
-                    blockchain tokens through the 0x protocol on a purely peer-to-peer basis. 0x portal is not a
-                    regulated marketplace, exchange or intermediary of any kind, and therefore, you should only use 0x
-                    portal to exchange tokens that are not securities, commodity interests, or any other form of
-                    regulated instrument. 0x has not attempted to screen or otherwise limit the tokens that you may
-                    enter in 0x Portal. By clicking “I Agree” below, you understand that you are solely responsible for
-                    using 0x Portal and buying and selling tokens using 0x Portal in compliance with all applicable laws
-                    and regulations.
-                </div>
-            </div>
-        </Dialog>
-    );
+	return (
+		<Dialog
+			title="0x Portal Disclaimer"
+			titleStyle={{ fontWeight: 100 }}
+			actions={[<FlatButton key="portalAgree" label="I Agree" onTouchTap={props.onToggleDialog} />]}
+			open={props.isOpen}
+			onRequestClose={props.onToggleDialog}
+			autoScrollBodyContent={true}
+			modal={true}
+		>
+			<div className="pt2" style={{ color: colors.grey700 }}>
+				<div>
+					0x Portal is a free software-based tool intended to help users to buy and sell ERC20-compatible
+					blockchain tokens through the 0x protocol on a purely peer-to-peer basis. 0x portal is not a
+					regulated marketplace, exchange or intermediary of any kind, and therefore, you should only use 0x
+					portal to exchange tokens that are not securities, commodity interests, or any other form of
+					regulated instrument. 0x has not attempted to screen or otherwise limit the tokens that you may
+					enter in 0x Portal. By clicking “I Agree” below, you understand that you are solely responsible for
+					using 0x Portal and buying and selling tokens using 0x Portal in compliance with all applicable laws
+					and regulations.
+				</div>
+			</div>
+		</Dialog>
+	);
 }
diff --git a/packages/website/ts/components/dialogs/send_dialog.tsx b/packages/website/ts/components/dialogs/send_dialog.tsx
index b3dbce598..b9022cd9b 100644
--- a/packages/website/ts/components/dialogs/send_dialog.tsx
+++ b/packages/website/ts/components/dialogs/send_dialog.tsx
@@ -8,110 +8,110 @@ import { TokenAmountInput } from 'ts/components/inputs/token_amount_input';
 import { Token, TokenState } from 'ts/types';
 
 interface SendDialogProps {
-    onComplete: (recipient: string, value: BigNumber) => void;
-    onCancelled: () => void;
-    isOpen: boolean;
-    token: Token;
-    tokenState: TokenState;
+	onComplete: (recipient: string, value: BigNumber) => void;
+	onCancelled: () => void;
+	isOpen: boolean;
+	token: Token;
+	tokenState: TokenState;
 }
 
 interface SendDialogState {
-    value?: BigNumber;
-    recipient: string;
-    shouldShowIncompleteErrs: boolean;
-    isAmountValid: boolean;
+	value?: BigNumber;
+	recipient: string;
+	shouldShowIncompleteErrs: boolean;
+	isAmountValid: boolean;
 }
 
 export class SendDialog extends React.Component<SendDialogProps, SendDialogState> {
-    constructor() {
-        super();
-        this.state = {
-            recipient: '',
-            shouldShowIncompleteErrs: false,
-            isAmountValid: false,
-        };
-    }
-    public render() {
-        const transferDialogActions = [
-            <FlatButton key="cancelTransfer" label="Cancel" onTouchTap={this._onCancel.bind(this)} />,
-            <FlatButton
-                key="sendTransfer"
-                disabled={this._hasErrors()}
-                label="Send"
-                primary={true}
-                onTouchTap={this._onSendClick.bind(this)}
-            />,
-        ];
-        return (
-            <Dialog
-                title="I want to send"
-                titleStyle={{ fontWeight: 100 }}
-                actions={transferDialogActions}
-                open={this.props.isOpen}
-            >
-                {this._renderSendDialogBody()}
-            </Dialog>
-        );
-    }
-    private _renderSendDialogBody() {
-        return (
-            <div className="mx-auto" style={{ maxWidth: 300 }}>
-                <div style={{ height: 80 }}>
-                    <AddressInput
-                        initialAddress={this.state.recipient}
-                        updateAddress={this._onRecipientChange.bind(this)}
-                        isRequired={true}
-                        label={'Recipient address'}
-                        hintText={'Address'}
-                    />
-                </div>
-                <TokenAmountInput
-                    label="Amount to send"
-                    token={this.props.token}
-                    tokenState={this.props.tokenState}
-                    shouldShowIncompleteErrs={this.state.shouldShowIncompleteErrs}
-                    shouldCheckBalance={true}
-                    shouldCheckAllowance={false}
-                    onChange={this._onValueChange.bind(this)}
-                    amount={this.state.value}
-                    onVisitBalancesPageClick={this.props.onCancelled}
-                />
-            </div>
-        );
-    }
-    private _onRecipientChange(recipient?: string) {
-        this.setState({
-            shouldShowIncompleteErrs: false,
-            recipient,
-        });
-    }
-    private _onValueChange(isValid: boolean, amount?: BigNumber) {
-        this.setState({
-            isAmountValid: isValid,
-            value: amount,
-        });
-    }
-    private _onSendClick() {
-        if (this._hasErrors()) {
-            this.setState({
-                shouldShowIncompleteErrs: true,
-            });
-        } else {
-            const value = this.state.value;
-            this.setState({
-                recipient: undefined,
-                value: undefined,
-            });
-            this.props.onComplete(this.state.recipient, value);
-        }
-    }
-    private _onCancel() {
-        this.setState({
-            value: undefined,
-        });
-        this.props.onCancelled();
-    }
-    private _hasErrors() {
-        return _.isUndefined(this.state.recipient) || _.isUndefined(this.state.value) || !this.state.isAmountValid;
-    }
+	constructor() {
+		super();
+		this.state = {
+			recipient: '',
+			shouldShowIncompleteErrs: false,
+			isAmountValid: false,
+		};
+	}
+	public render() {
+		const transferDialogActions = [
+			<FlatButton key="cancelTransfer" label="Cancel" onTouchTap={this._onCancel.bind(this)} />,
+			<FlatButton
+				key="sendTransfer"
+				disabled={this._hasErrors()}
+				label="Send"
+				primary={true}
+				onTouchTap={this._onSendClick.bind(this)}
+			/>,
+		];
+		return (
+			<Dialog
+				title="I want to send"
+				titleStyle={{ fontWeight: 100 }}
+				actions={transferDialogActions}
+				open={this.props.isOpen}
+			>
+				{this._renderSendDialogBody()}
+			</Dialog>
+		);
+	}
+	private _renderSendDialogBody() {
+		return (
+			<div className="mx-auto" style={{ maxWidth: 300 }}>
+				<div style={{ height: 80 }}>
+					<AddressInput
+						initialAddress={this.state.recipient}
+						updateAddress={this._onRecipientChange.bind(this)}
+						isRequired={true}
+						label={'Recipient address'}
+						hintText={'Address'}
+					/>
+				</div>
+				<TokenAmountInput
+					label="Amount to send"
+					token={this.props.token}
+					tokenState={this.props.tokenState}
+					shouldShowIncompleteErrs={this.state.shouldShowIncompleteErrs}
+					shouldCheckBalance={true}
+					shouldCheckAllowance={false}
+					onChange={this._onValueChange.bind(this)}
+					amount={this.state.value}
+					onVisitBalancesPageClick={this.props.onCancelled}
+				/>
+			</div>
+		);
+	}
+	private _onRecipientChange(recipient?: string) {
+		this.setState({
+			shouldShowIncompleteErrs: false,
+			recipient,
+		});
+	}
+	private _onValueChange(isValid: boolean, amount?: BigNumber) {
+		this.setState({
+			isAmountValid: isValid,
+			value: amount,
+		});
+	}
+	private _onSendClick() {
+		if (this._hasErrors()) {
+			this.setState({
+				shouldShowIncompleteErrs: true,
+			});
+		} else {
+			const value = this.state.value;
+			this.setState({
+				recipient: undefined,
+				value: undefined,
+			});
+			this.props.onComplete(this.state.recipient, value);
+		}
+	}
+	private _onCancel() {
+		this.setState({
+			value: undefined,
+		});
+		this.props.onCancelled();
+	}
+	private _hasErrors() {
+		return _.isUndefined(this.state.recipient) || _.isUndefined(this.state.value) || !this.state.isAmountValid;
+	}
 }
diff --git a/packages/website/ts/components/dialogs/track_token_confirmation_dialog.tsx b/packages/website/ts/components/dialogs/track_token_confirmation_dialog.tsx
index 3f29d46f8..b1804e95c 100644
--- a/packages/website/ts/components/dialogs/track_token_confirmation_dialog.tsx
+++ b/packages/website/ts/components/dialogs/track_token_confirmation_dialog.tsx
@@ -9,94 +9,94 @@ import { Dispatcher } from 'ts/redux/dispatcher';
 import { Token, TokenByAddress } from 'ts/types';
 
 interface TrackTokenConfirmationDialogProps {
-    tokens: Token[];
-    tokenByAddress: TokenByAddress;
-    isOpen: boolean;
-    onToggleDialog: (didConfirmTokenTracking: boolean) => void;
-    dispatcher: Dispatcher;
-    networkId: number;
-    blockchain: Blockchain;
-    userAddress: string;
+	tokens: Token[];
+	tokenByAddress: TokenByAddress;
+	isOpen: boolean;
+	onToggleDialog: (didConfirmTokenTracking: boolean) => void;
+	dispatcher: Dispatcher;
+	networkId: number;
+	blockchain: Blockchain;
+	userAddress: string;
 }
 
 interface TrackTokenConfirmationDialogState {
-    isAddingTokenToTracked: boolean;
+	isAddingTokenToTracked: boolean;
 }
 
 export class TrackTokenConfirmationDialog extends React.Component<
-    TrackTokenConfirmationDialogProps,
-    TrackTokenConfirmationDialogState
+	TrackTokenConfirmationDialogProps,
+	TrackTokenConfirmationDialogState
 > {
-    constructor(props: TrackTokenConfirmationDialogProps) {
-        super(props);
-        this.state = {
-            isAddingTokenToTracked: false,
-        };
-    }
-    public render() {
-        const tokens = this.props.tokens;
-        return (
-            <Dialog
-                title="Tracking confirmation"
-                titleStyle={{ fontWeight: 100 }}
-                actions={[
-                    <FlatButton
-                        key="trackNo"
-                        label="No"
-                        onTouchTap={this._onTrackConfirmationRespondedAsync.bind(this, false)}
-                    />,
-                    <FlatButton
-                        key="trackYes"
-                        label="Yes"
-                        onTouchTap={this._onTrackConfirmationRespondedAsync.bind(this, true)}
-                    />,
-                ]}
-                open={this.props.isOpen}
-                onRequestClose={this.props.onToggleDialog.bind(this, false)}
-                autoScrollBodyContent={true}
-            >
-                <div className="pt2">
-                    <TrackTokenConfirmation
-                        tokens={tokens}
-                        networkId={this.props.networkId}
-                        tokenByAddress={this.props.tokenByAddress}
-                        isAddingTokenToTracked={this.state.isAddingTokenToTracked}
-                    />
-                </div>
-            </Dialog>
-        );
-    }
-    private async _onTrackConfirmationRespondedAsync(didUserAcceptTracking: boolean) {
-        if (!didUserAcceptTracking) {
-            this.props.onToggleDialog(didUserAcceptTracking);
-            return;
-        }
-        this.setState({
-            isAddingTokenToTracked: true,
-        });
-        for (const token of this.props.tokens) {
-            const newTokenEntry = {
-                ...token,
-            };
+	constructor(props: TrackTokenConfirmationDialogProps) {
+		super(props);
+		this.state = {
+			isAddingTokenToTracked: false,
+		};
+	}
+	public render() {
+		const tokens = this.props.tokens;
+		return (
+			<Dialog
+				title="Tracking confirmation"
+				titleStyle={{ fontWeight: 100 }}
+				actions={[
+					<FlatButton
+						key="trackNo"
+						label="No"
+						onTouchTap={this._onTrackConfirmationRespondedAsync.bind(this, false)}
+					/>,
+					<FlatButton
+						key="trackYes"
+						label="Yes"
+						onTouchTap={this._onTrackConfirmationRespondedAsync.bind(this, true)}
+					/>,
+				]}
+				open={this.props.isOpen}
+				onRequestClose={this.props.onToggleDialog.bind(this, false)}
+				autoScrollBodyContent={true}
+			>
+				<div className="pt2">
+					<TrackTokenConfirmation
+						tokens={tokens}
+						networkId={this.props.networkId}
+						tokenByAddress={this.props.tokenByAddress}
+						isAddingTokenToTracked={this.state.isAddingTokenToTracked}
+					/>
+				</div>
+			</Dialog>
+		);
+	}
+	private async _onTrackConfirmationRespondedAsync(didUserAcceptTracking: boolean) {
+		if (!didUserAcceptTracking) {
+			this.props.onToggleDialog(didUserAcceptTracking);
+			return;
+		}
+		this.setState({
+			isAddingTokenToTracked: true,
+		});
+		for (const token of this.props.tokens) {
+			const newTokenEntry = {
+				...token,
+			};
 
-            newTokenEntry.isTracked = true;
-            trackedTokenStorage.addTrackedTokenToUser(this.props.userAddress, this.props.networkId, newTokenEntry);
-            this.props.dispatcher.updateTokenByAddress([newTokenEntry]);
+			newTokenEntry.isTracked = true;
+			trackedTokenStorage.addTrackedTokenToUser(this.props.userAddress, this.props.networkId, newTokenEntry);
+			this.props.dispatcher.updateTokenByAddress([newTokenEntry]);
 
-            const [balance, allowance] = await this.props.blockchain.getCurrentUserTokenBalanceAndAllowanceAsync(
-                token.address,
-            );
-            this.props.dispatcher.updateTokenStateByAddress({
-                [token.address]: {
-                    balance,
-                    allowance,
-                },
-            });
-        }
+			const [balance, allowance] = await this.props.blockchain.getCurrentUserTokenBalanceAndAllowanceAsync(
+				token.address,
+			);
+			this.props.dispatcher.updateTokenStateByAddress({
+				[token.address]: {
+					balance,
+					allowance,
+				},
+			});
+		}
 
-        this.setState({
-            isAddingTokenToTracked: false,
-        });
-        this.props.onToggleDialog(didUserAcceptTracking);
-    }
+		this.setState({
+			isAddingTokenToTracked: false,
+		});
+		this.props.onToggleDialog(didUserAcceptTracking);
+	}
 }
diff --git a/packages/website/ts/components/dialogs/u2f_not_supported_dialog.tsx b/packages/website/ts/components/dialogs/u2f_not_supported_dialog.tsx
index 098e3e26d..2ea51d07b 100644
--- a/packages/website/ts/components/dialogs/u2f_not_supported_dialog.tsx
+++ b/packages/website/ts/components/dialogs/u2f_not_supported_dialog.tsx
@@ -5,42 +5,42 @@ import { colors } from 'ts/utils/colors';
 import { constants } from 'ts/utils/constants';
 
 interface U2fNotSupportedDialogProps {
-    isOpen: boolean;
-    onToggleDialog: () => void;
+	isOpen: boolean;
+	onToggleDialog: () => void;
 }
 
 export function U2fNotSupportedDialog(props: U2fNotSupportedDialogProps) {
-    return (
-        <Dialog
-            title="U2F Not Supported"
-            titleStyle={{ fontWeight: 100 }}
-            actions={[<FlatButton key="u2fNo" label="Ok" onTouchTap={props.onToggleDialog.bind(this)} />]}
-            open={props.isOpen}
-            onRequestClose={props.onToggleDialog.bind(this)}
-            autoScrollBodyContent={true}
-        >
-            <div className="pt2" style={{ color: colors.grey700 }}>
-                <div>
-                    It looks like your browser does not support U2F connections required for us to communicate with your
-                    hardware wallet. Please use a browser that supports U2F connections and try again.
-                </div>
-                <div>
-                    <ul>
-                        <li className="pb1">Chrome version 38 or later</li>
-                        <li className="pb1">Opera version 40 of later</li>
-                        <li>
-                            Firefox with{' '}
-                            <a
-                                href={constants.URL_FIREFOX_U2F_ADDON}
-                                target="_blank"
-                                style={{ textDecoration: 'underline' }}
-                            >
-                                this extension
-                            </a>.
-                        </li>
-                    </ul>
-                </div>
-            </div>
-        </Dialog>
-    );
+	return (
+		<Dialog
+			title="U2F Not Supported"
+			titleStyle={{ fontWeight: 100 }}
+			actions={[<FlatButton key="u2fNo" label="Ok" onTouchTap={props.onToggleDialog.bind(this)} />]}
+			open={props.isOpen}
+			onRequestClose={props.onToggleDialog.bind(this)}
+			autoScrollBodyContent={true}
+		>
+			<div className="pt2" style={{ color: colors.grey700 }}>
+				<div>
+					It looks like your browser does not support U2F connections required for us to communicate with your
+					hardware wallet. Please use a browser that supports U2F connections and try again.
+				</div>
+				<div>
+					<ul>
+						<li className="pb1">Chrome version 38 or later</li>
+						<li className="pb1">Opera version 40 of later</li>
+						<li>
+							Firefox with{' '}
+							<a
+								href={constants.URL_FIREFOX_U2F_ADDON}
+								target="_blank"
+								style={{ textDecoration: 'underline' }}
+							>
+								this extension
+							</a>.
+						</li>
+					</ul>
+				</div>
+			</div>
+		</Dialog>
+	);
 }
diff --git a/packages/website/ts/components/dialogs/wrapped_eth_section_notice_dialog.tsx b/packages/website/ts/components/dialogs/wrapped_eth_section_notice_dialog.tsx
index 9e91ff12d..98436eb50 100644
--- a/packages/website/ts/components/dialogs/wrapped_eth_section_notice_dialog.tsx
+++ b/packages/website/ts/components/dialogs/wrapped_eth_section_notice_dialog.tsx
@@ -4,30 +4,30 @@ import { colors } from 'material-ui/styles';
 import * as React from 'react';
 
 interface WrappedEthSectionNoticeDialogProps {
-    isOpen: boolean;
-    onToggleDialog: () => void;
+	isOpen: boolean;
+	onToggleDialog: () => void;
 }
 
 export function WrappedEthSectionNoticeDialog(props: WrappedEthSectionNoticeDialogProps) {
-    return (
-        <Dialog
-            title="Dedicated Wrapped Ether Section"
-            titleStyle={{ fontWeight: 100 }}
-            actions={[
-                <FlatButton key="acknowledgeWrapEthSection" label="Sounds good" onTouchTap={props.onToggleDialog} />,
-            ]}
-            open={props.isOpen}
-            onRequestClose={props.onToggleDialog}
-            autoScrollBodyContent={true}
-            modal={true}
-        >
-            <div className="pt2" style={{ color: colors.grey700 }}>
-                <div>
-                    We have recently updated the Wrapped Ether token (WETH) used by 0x Portal. Don't worry, unwrapping
-                    Ether tied to the old Wrapped Ether token can be done at any time by clicking on the "Wrap ETH"
-                    section in the menu to the left.
-                </div>
-            </div>
-        </Dialog>
-    );
+	return (
+		<Dialog
+			title="Dedicated Wrapped Ether Section"
+			titleStyle={{ fontWeight: 100 }}
+			actions={[
+				<FlatButton key="acknowledgeWrapEthSection" label="Sounds good" onTouchTap={props.onToggleDialog} />,
+			]}
+			open={props.isOpen}
+			onRequestClose={props.onToggleDialog}
+			autoScrollBodyContent={true}
+			modal={true}
+		>
+			<div className="pt2" style={{ color: colors.grey700 }}>
+				<div>
+					We have recently updated the Wrapped Ether token (WETH) used by 0x Portal. Don't worry, unwrapping
+					Ether tied to the old Wrapped Ether token can be done at any time by clicking on the "Wrap ETH"
+					section in the menu to the left.
+				</div>
+			</div>
+		</Dialog>
+	);
 }
diff --git a/packages/website/ts/components/eth_weth_conversion_button.tsx b/packages/website/ts/components/eth_weth_conversion_button.tsx
index 300e71f1f..af1b33eef 100644
--- a/packages/website/ts/components/eth_weth_conversion_button.tsx
+++ b/packages/website/ts/components/eth_weth_conversion_button.tsx
@@ -12,115 +12,115 @@ import { errorReporter } from 'ts/utils/error_reporter';
 import { utils } from 'ts/utils/utils';
 
 interface EthWethConversionButtonProps {
-    direction: Side;
-    ethToken: Token;
-    ethTokenState: TokenState;
-    dispatcher: Dispatcher;
-    blockchain: Blockchain;
-    userEtherBalance: BigNumber;
-    isOutdatedWrappedEther: boolean;
-    onConversionSuccessful?: () => void;
-    isDisabled?: boolean;
+	direction: Side;
+	ethToken: Token;
+	ethTokenState: TokenState;
+	dispatcher: Dispatcher;
+	blockchain: Blockchain;
+	userEtherBalance: BigNumber;
+	isOutdatedWrappedEther: boolean;
+	onConversionSuccessful?: () => void;
+	isDisabled?: boolean;
 }
 
 interface EthWethConversionButtonState {
-    isEthConversionDialogVisible: boolean;
-    isEthConversionHappening: boolean;
+	isEthConversionDialogVisible: boolean;
+	isEthConversionHappening: boolean;
 }
 
 export class EthWethConversionButton extends React.Component<
-    EthWethConversionButtonProps,
-    EthWethConversionButtonState
+	EthWethConversionButtonProps,
+	EthWethConversionButtonState
 > {
-    public static defaultProps: Partial<EthWethConversionButtonProps> = {
-        isDisabled: false,
-        onConversionSuccessful: _.noop,
-    };
-    public constructor(props: EthWethConversionButtonProps) {
-        super(props);
-        this.state = {
-            isEthConversionDialogVisible: false,
-            isEthConversionHappening: false,
-        };
-    }
-    public render() {
-        const labelStyle = this.state.isEthConversionHappening ? { fontSize: 10 } : {};
-        let callToActionLabel;
-        let inProgressLabel;
-        if (this.props.direction === Side.Deposit) {
-            callToActionLabel = 'Wrap';
-            inProgressLabel = 'Wrapping...';
-        } else {
-            callToActionLabel = 'Unwrap';
-            inProgressLabel = 'Unwrapping...';
-        }
-        return (
-            <div>
-                <RaisedButton
-                    style={{ width: '100%' }}
-                    labelStyle={labelStyle}
-                    disabled={this.props.isDisabled || this.state.isEthConversionHappening}
-                    label={this.state.isEthConversionHappening ? inProgressLabel : callToActionLabel}
-                    onClick={this._toggleConversionDialog.bind(this)}
-                />
-                <EthWethConversionDialog
-                    direction={this.props.direction}
-                    isOpen={this.state.isEthConversionDialogVisible}
-                    onComplete={this._onConversionAmountSelectedAsync.bind(this)}
-                    onCancelled={this._toggleConversionDialog.bind(this)}
-                    etherBalance={this.props.userEtherBalance}
-                    token={this.props.ethToken}
-                    tokenState={this.props.ethTokenState}
-                />
-            </div>
-        );
-    }
-    private _toggleConversionDialog() {
-        this.setState({
-            isEthConversionDialogVisible: !this.state.isEthConversionDialogVisible,
-        });
-    }
-    private async _onConversionAmountSelectedAsync(direction: Side, value: BigNumber) {
-        this.setState({
-            isEthConversionHappening: true,
-        });
-        this._toggleConversionDialog();
-        const token = this.props.ethToken;
-        const tokenState = this.props.ethTokenState;
-        let balance = tokenState.balance;
-        try {
-            if (direction === Side.Deposit) {
-                await this.props.blockchain.convertEthToWrappedEthTokensAsync(token.address, value);
-                const ethAmount = ZeroEx.toUnitAmount(value, constants.DECIMAL_PLACES_ETH);
-                this.props.dispatcher.showFlashMessage(`Successfully wrapped ${ethAmount.toString()} ETH to WETH`);
-                balance = balance.plus(value);
-            } else {
-                await this.props.blockchain.convertWrappedEthTokensToEthAsync(token.address, value);
-                const tokenAmount = ZeroEx.toUnitAmount(value, token.decimals);
-                this.props.dispatcher.showFlashMessage(`Successfully unwrapped ${tokenAmount.toString()} WETH to ETH`);
-                balance = balance.minus(value);
-            }
-            if (!this.props.isOutdatedWrappedEther) {
-                this.props.dispatcher.replaceTokenBalanceByAddress(token.address, balance);
-            }
-            this.props.onConversionSuccessful();
-        } catch (err) {
-            const errMsg = `${err}`;
-            if (_.includes(errMsg, BlockchainCallErrs.UserHasNoAssociatedAddresses)) {
-                this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
-            } else if (!_.includes(errMsg, 'User denied transaction')) {
-                utils.consoleLog(`Unexpected error encountered: ${err}`);
-                utils.consoleLog(err.stack);
-                const errorMsg =
-                    direction === Side.Deposit
-                        ? 'Failed to wrap your ETH. Please try again.'
-                        : 'Failed to unwrap your WETH. Please try again.';
-                this.props.dispatcher.showFlashMessage(errorMsg);
-                await errorReporter.reportAsync(err);
-            }
-        }
-        this.setState({
-            isEthConversionHappening: false,
-        });
-    }
+	public static defaultProps: Partial<EthWethConversionButtonProps> = {
+		isDisabled: false,
+		onConversionSuccessful: _.noop,
+	};
+	public constructor(props: EthWethConversionButtonProps) {
+		super(props);
+		this.state = {
+			isEthConversionDialogVisible: false,
+			isEthConversionHappening: false,
+		};
+	}
+	public render() {
+		const labelStyle = this.state.isEthConversionHappening ? { fontSize: 10 } : {};
+		let callToActionLabel;
+		let inProgressLabel;
+		if (this.props.direction === Side.Deposit) {
+			callToActionLabel = 'Wrap';
+			inProgressLabel = 'Wrapping...';
+		} else {
+			callToActionLabel = 'Unwrap';
+			inProgressLabel = 'Unwrapping...';
+		}
+		return (
+			<div>
+				<RaisedButton
+					style={{ width: '100%' }}
+					labelStyle={labelStyle}
+					disabled={this.props.isDisabled || this.state.isEthConversionHappening}
+					label={this.state.isEthConversionHappening ? inProgressLabel : callToActionLabel}
+					onClick={this._toggleConversionDialog.bind(this)}
+				/>
+				<EthWethConversionDialog
+					direction={this.props.direction}
+					isOpen={this.state.isEthConversionDialogVisible}
+					onComplete={this._onConversionAmountSelectedAsync.bind(this)}
+					onCancelled={this._toggleConversionDialog.bind(this)}
+					etherBalance={this.props.userEtherBalance}
+					token={this.props.ethToken}
+					tokenState={this.props.ethTokenState}
+				/>
+			</div>
+		);
+	}
+	private _toggleConversionDialog() {
+		this.setState({
+			isEthConversionDialogVisible: !this.state.isEthConversionDialogVisible,
+		});
+	}
+	private async _onConversionAmountSelectedAsync(direction: Side, value: BigNumber) {
+		this.setState({
+			isEthConversionHappening: true,
+		});
+		this._toggleConversionDialog();
+		const token = this.props.ethToken;
+		const tokenState = this.props.ethTokenState;
+		let balance = tokenState.balance;
+		try {
+			if (direction === Side.Deposit) {
+				await this.props.blockchain.convertEthToWrappedEthTokensAsync(token.address, value);
+				const ethAmount = ZeroEx.toUnitAmount(value, constants.DECIMAL_PLACES_ETH);
+				this.props.dispatcher.showFlashMessage(`Successfully wrapped ${ethAmount.toString()} ETH to WETH`);
+				balance = balance.plus(value);
+			} else {
+				await this.props.blockchain.convertWrappedEthTokensToEthAsync(token.address, value);
+				const tokenAmount = ZeroEx.toUnitAmount(value, token.decimals);
+				this.props.dispatcher.showFlashMessage(`Successfully unwrapped ${tokenAmount.toString()} WETH to ETH`);
+				balance = balance.minus(value);
+			}
+			if (!this.props.isOutdatedWrappedEther) {
+				this.props.dispatcher.replaceTokenBalanceByAddress(token.address, balance);
+			}
+			this.props.onConversionSuccessful();
+		} catch (err) {
+			const errMsg = `${err}`;
+			if (_.includes(errMsg, BlockchainCallErrs.UserHasNoAssociatedAddresses)) {
+				this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
+			} else if (!_.includes(errMsg, 'User denied transaction')) {
+				utils.consoleLog(`Unexpected error encountered: ${err}`);
+				utils.consoleLog(err.stack);
+				const errorMsg =
+					direction === Side.Deposit
+						? 'Failed to wrap your ETH. Please try again.'
+						: 'Failed to unwrap your WETH. Please try again.';
+				this.props.dispatcher.showFlashMessage(errorMsg);
+				await errorReporter.reportAsync(err);
+			}
+		}
+		this.setState({
+			isEthConversionHappening: false,
+		});
+	}
 }
diff --git a/packages/website/ts/components/eth_wrappers.tsx b/packages/website/ts/components/eth_wrappers.tsx
index d074ec787..1593d51f0 100644
--- a/packages/website/ts/components/eth_wrappers.tsx
+++ b/packages/website/ts/components/eth_wrappers.tsx
@@ -10,13 +10,13 @@ import { Blockchain } from 'ts/blockchain';
 import { EthWethConversionButton } from 'ts/components/eth_weth_conversion_button';
 import { Dispatcher } from 'ts/redux/dispatcher';
 import {
-    EtherscanLinkSuffixes,
-    OutdatedWrappedEtherByNetworkId,
-    Side,
-    Token,
-    TokenByAddress,
-    TokenState,
-    TokenStateByAddress,
+	EtherscanLinkSuffixes,
+	OutdatedWrappedEtherByNetworkId,
+	Side,
+	Token,
+	TokenByAddress,
+	TokenState,
+	TokenStateByAddress,
 } from 'ts/types';
 import { colors } from 'ts/utils/colors';
 import { configs } from 'ts/utils/configs';
@@ -30,345 +30,345 @@ const ETHER_ICON_PATH = '/images/ether.png';
 const OUTDATED_WETH_ICON_PATH = '/images/wrapped_eth_gray.png';
 
 interface OutdatedWETHAddressToIsStateLoaded {
-    [address: string]: boolean;
+	[address: string]: boolean;
 }
 interface OutdatedWETHStateByAddress {
-    [address: string]: TokenState;
+	[address: string]: TokenState;
 }
 
 interface EthWrappersProps {
-    networkId: number;
-    blockchain: Blockchain;
-    dispatcher: Dispatcher;
-    tokenByAddress: TokenByAddress;
-    tokenStateByAddress: TokenStateByAddress;
-    userAddress: string;
-    userEtherBalance: BigNumber;
+	networkId: number;
+	blockchain: Blockchain;
+	dispatcher: Dispatcher;
+	tokenByAddress: TokenByAddress;
+	tokenStateByAddress: TokenStateByAddress;
+	userAddress: string;
+	userEtherBalance: BigNumber;
 }
 
 interface EthWrappersState {
-    outdatedWETHAddressToIsStateLoaded: OutdatedWETHAddressToIsStateLoaded;
-    outdatedWETHStateByAddress: OutdatedWETHStateByAddress;
+	outdatedWETHAddressToIsStateLoaded: OutdatedWETHAddressToIsStateLoaded;
+	outdatedWETHStateByAddress: OutdatedWETHStateByAddress;
 }
 
 export class EthWrappers extends React.Component<EthWrappersProps, EthWrappersState> {
-    constructor(props: EthWrappersProps) {
-        super(props);
-        const outdatedWETHAddresses = this._getOutdatedWETHAddresses();
-        const outdatedWETHAddressToIsStateLoaded: OutdatedWETHAddressToIsStateLoaded = {};
-        const outdatedWETHStateByAddress: OutdatedWETHStateByAddress = {};
-        _.each(outdatedWETHAddresses, outdatedWETHAddress => {
-            outdatedWETHAddressToIsStateLoaded[outdatedWETHAddress] = false;
-            outdatedWETHStateByAddress[outdatedWETHAddress] = {
-                balance: new BigNumber(0),
-                allowance: new BigNumber(0),
-            };
-        });
-        this.state = {
-            outdatedWETHAddressToIsStateLoaded,
-            outdatedWETHStateByAddress,
-        };
-    }
-    public componentDidMount() {
-        window.scrollTo(0, 0);
-        // tslint:disable-next-line:no-floating-promises
-        this._fetchOutdatedWETHStateAsync();
-    }
-    public render() {
-        const tokens = _.values(this.props.tokenByAddress);
-        const etherToken = _.find(tokens, { symbol: 'WETH' });
-        const etherTokenState = this.props.tokenStateByAddress[etherToken.address];
-        const wethBalance = ZeroEx.toUnitAmount(etherTokenState.balance, constants.DECIMAL_PLACES_ETH);
-        const isBidirectional = true;
-        const etherscanUrl = utils.getEtherScanLinkIfExists(
-            etherToken.address,
-            this.props.networkId,
-            EtherscanLinkSuffixes.Address,
-        );
-        const tokenLabel = this._renderToken('Wrapped Ether', etherToken.address, configs.ICON_URL_BY_SYMBOL.WETH);
-        return (
-            <div className="clearfix lg-px4 md-px4 sm-px2" style={{ minHeight: 600 }}>
-                <div className="relative">
-                    <h3>ETH Wrapper</h3>
-                    <div className="absolute" style={{ top: 0, right: 0 }}>
-                        <a target="_blank" href={constants.URL_WETH_IO} style={{ color: colors.grey }}>
-                            <div className="flex">
-                                <div>About Wrapped ETH</div>
-                                <div className="pl1">
-                                    <i className="zmdi zmdi-open-in-new" />
-                                </div>
-                            </div>
-                        </a>
-                    </div>
-                </div>
-                <Divider />
-                <div>
-                    <div className="py2">Wrap ETH into an ERC20-compliant Ether token. 1 ETH = 1 WETH.</div>
-                    <div>
-                        <Table selectable={false} style={{ backgroundColor: colors.grey50 }}>
-                            <TableHeader displaySelectAll={false} adjustForCheckbox={false}>
-                                <TableRow>
-                                    <TableHeaderColumn>ETH Token</TableHeaderColumn>
-                                    <TableHeaderColumn>Balance</TableHeaderColumn>
-                                    <TableHeaderColumn className="center">
-                                        {this._renderActionColumnTitle(isBidirectional)}
-                                    </TableHeaderColumn>
-                                </TableRow>
-                            </TableHeader>
-                            <TableBody displayRowCheckbox={false}>
-                                <TableRow key="ETH">
-                                    <TableRowColumn className="py1">
-                                        <div className="flex">
-                                            <img
-                                                style={{
-                                                    width: ICON_DIMENSION,
-                                                    height: ICON_DIMENSION,
-                                                }}
-                                                src={ETHER_ICON_PATH}
-                                            />
-                                            <div className="ml2 sm-hide xs-hide" style={{ marginTop: 12 }}>
-                                                ETH
-                                            </div>
-                                        </div>
-                                    </TableRowColumn>
-                                    <TableRowColumn>
-                                        {this.props.userEtherBalance.toFixed(PRECISION)} ETH
-                                    </TableRowColumn>
-                                    <TableRowColumn>
-                                        <EthWethConversionButton
-                                            isOutdatedWrappedEther={false}
-                                            direction={Side.Deposit}
-                                            ethToken={etherToken}
-                                            ethTokenState={etherTokenState}
-                                            dispatcher={this.props.dispatcher}
-                                            blockchain={this.props.blockchain}
-                                            userEtherBalance={this.props.userEtherBalance}
-                                        />
-                                    </TableRowColumn>
-                                </TableRow>
-                                <TableRow key="WETH">
-                                    <TableRowColumn className="py1">
-                                        {this._renderTokenLink(tokenLabel, etherscanUrl)}
-                                    </TableRowColumn>
-                                    <TableRowColumn>{wethBalance.toFixed(PRECISION)} WETH</TableRowColumn>
-                                    <TableRowColumn>
-                                        <EthWethConversionButton
-                                            isOutdatedWrappedEther={false}
-                                            direction={Side.Receive}
-                                            ethToken={etherToken}
-                                            ethTokenState={etherTokenState}
-                                            dispatcher={this.props.dispatcher}
-                                            blockchain={this.props.blockchain}
-                                            userEtherBalance={this.props.userEtherBalance}
-                                        />
-                                    </TableRowColumn>
-                                </TableRow>
-                            </TableBody>
-                        </Table>
-                    </div>
-                </div>
-                <div>
-                    <h4>Outdated WETH</h4>
-                    <Divider />
-                    <div className="pt2" style={{ lineHeight: 1.5 }}>
-                        The{' '}
-                        <a href="https://blog.0xproject.com/canonical-weth-a9aa7d0279dd" target="_blank">
-                            canonical WETH
-                        </a>{' '}
-                        contract is updated when necessary. Unwrap outdated WETH in order to
 retrieve your ETH and move
-                        it to the updated WETH token.
-                    </div>
-                    <div>
-                        <Table selectable={false} style={{ backgroundColor: colors.grey50 }}>
-                            <TableHeader displaySelectAll={false} adjustForCheckbox={false}>
-                                <TableRow>
-                                    <TableHeaderColumn>WETH Version</TableHeaderColumn>
-                                    <TableHeaderColumn>Balance</TableHeaderColumn>
-                                    <TableHeaderColumn className="center">
-                                        {this._renderActionColumnTitle(!isBidirectional)}
-                                    </TableHeaderColumn>
-                                </TableRow>
-                            </TableHeader>
-                            <TableBody displayRowCheckbox={false}>
-                                {this._renderOutdatedWeths(etherToken, etherTokenState)}
-                            </TableBody>
-                        </Table>
-                    </div>
-                </div>
-            </div>
-        );
-    }
-    private _renderActionColumnTitle(isBidirectional: boolean) {
-        let iconClass = 'zmdi-long-arrow-right';
-        let leftSymbol = 'WETH';
-        let rightSymbol = 'ETH';
-        if (isBidirectional) {
-            iconClass = 'zmdi-swap';
-            leftSymbol = 'ETH';
-            rightSymbol = 'WETH';
-        }
-        return (
-            <div className="flex mx-auto" style={{ width: 85 }}>
-                <div style={{ paddingTop: 3 }}>{leftSymbol}</div>
-                <div className="px1">
-                    <i style={{ fontSize: 18 }} className={`zmdi ${iconClass}`} />
-                </div>
-                <div style={{ paddingTop: 3 }}>{rightSymbol}</div>
-            </div>
-        );
-    }
-    private _renderOutdatedWeths(etherToken: Token, etherTokenState: TokenState) {
-        const rows = _.map(
-            configs.OUTDATED_WRAPPED_ETHERS,
-            (outdatedWETHByNetworkId: OutdatedWrappedEtherByNetworkId) => {
-                const outdatedWETHIfExists = outdatedWETHByNetworkId[this.props.networkId];
-                if (_.isUndefined(outdatedWETHIfExists)) {
-                    return null; // noop
-                }
-                const timestampMsRange = outdatedWETHIfExists.timestampMsRange;
-                let dateRange: string;
-                if (!_.isUndefined(timestampMsRange)) {
-                    const startMoment = moment(timestampMsRange.startTimestampMs);
-                    const endMoment = moment(timestampMsRange.endTimestampMs);
-                    dateRange = `${startMoment.format(DATE_FORMAT)}-${endMoment.format(DATE_FORMAT)}`;
-                } else {
-                    dateRange = '-';
-                }
-                const outdatedEtherToken = {
-                    ...etherToken,
-                    address: outdatedWETHIfExists.address,
-                };
-                const isStateLoaded = this.state.outdatedWETHAddressToIsStateLoaded[outdatedWETHIfExists.address];
-                const outdatedEtherTokenState = this.state.outdatedWETHStateByAddress[outdatedWETHIfExists.address];
-                const balanceInEthIfExists = isStateLoaded
-                    ? ZeroEx.toUnitAmount(outdatedEtherTokenState.balance, constants.DECIMAL_PLACES_ETH).toFixed(
-                          PRECISION,
-                      )
-                    : undefined;
-                const onConversionSuccessful = this._onOutdatedConversionSuccessfulAsync.bind(
-                    this,
-                    outdatedWETHIfExists.address,
-                );
-                const etherscanUrl = utils.getEtherScanLinkIfExists(
-                    outdatedWETHIfExists.address,
-                    this.props.networkId,
-                    EtherscanLinkSuffixes.Address,
-                );
-                const tokenLabel = this._renderToken(dateRange, outdatedEtherToken.address, OUTDATED_WETH_ICON_PATH);
-                return (
-                    <TableRow key={`weth-${outdatedWETHIfExists.address}`}>
-                        <TableRowColumn className="py1">
-                            {this._renderTokenLink(tokenLabel, etherscanUrl)}
-                        </TableRowColumn>
-                        <TableRowColumn>
-                            {isStateLoaded ? (
-                                `${balanceInEthIfExists} WETH`
-                            ) : (
-                                <i className="zmdi zmdi-spinner zmdi-hc-spin" />
-                            )}
-                        </TableRowColumn>
-                        <TableRowColumn>
-                            <EthWethConversionButton
-                                isDisabled={!isStateLoaded}
-                                isOutdatedWrappedEther={true}
-                                direction={Side.Receive}
-                                ethToken={outdatedEtherToken}
-                                ethTokenState={outdatedEtherTokenState}
-                                dispatcher={this.props.dispatcher}
-                                blockchain={this.props.blockchain}
-                                userEtherBalance={this.props.userEtherBalance}
-                                onConversionSuccessful={onConversionSuccessful}
-                            />
-                        </TableRowColumn>
-                    </TableRow>
-                );
-            },
-        );
-        return rows;
-    }
-    private _renderTokenLink(tokenLabel: React.ReactNode, etherscanUrl: string) {
-        return (
-            <span>
-                {_.isUndefined(etherscanUrl) ? (
-                    tokenLabel
-                ) : (
-                    <a href={etherscanUrl} target="_blank" style={{ textDecoration: 'none' }}>
-                        {tokenLabel}
-                    </a>
-                )}
-            </span>
-        );
-    }
-    private _renderToken(name: string, address: string, imgPath: string) {
-        const tooltipId = `tooltip-${address}`;
-        return (
-            <div className="flex">
-                <img style={{ width: ICON_DIMENSION, height: ICON_DIMENSION }} src={imgPath} />
-                <div className="ml2 sm-hide xs-hide" style={{ marginTop: 12 }}>
-                    <span data-tip={true} data-for={tooltipId}>
-                        {name}
-                    </span>
-                    <ReactTooltip id={tooltipId}>{address}</ReactTooltip>
-                </div>
-            </div>
-        );
-    }
-    private async _onOutdatedConversionSuccessfulAsync(outdatedWETHAddress: string) {
-        this.setState({
-            outdatedWETHAddressToIsStateLoaded: {
-                ...this.state.outdatedWETHAddressToIsStateLoaded,
-                [outdatedWETHAddress]: false,
-            },
-        });
-        const [balance, allowance] = await this.props.blockchain.getTokenBalanceAndAllowanceAsync(
-            this.props.userAddress,
-            outdatedWETHAddress,
-        );
-        this.setState({
-            outdatedWETHAddressToIsStateLoaded: {
-                ...this.state.outdatedWETHAddressToIsStateLoaded,
-                [outdatedWETHAddress]: true,
-            },
-            outdatedWETHStateByAddress: {
-                ...this.state.outdatedWETHStateByAddress,
-                [outdatedWETHAddress]: {
-                    balance,
-                    allowance,
-                },
-            },
-        });
-    }
-    private async _fetchOutdatedWETHStateAsync() {
-        const outdatedWETHAddresses = this._getOutdatedWETHAddresses();
-        const outdatedWETHAddressToIsStateLoaded: OutdatedWETHAddressToIsStateLoaded = {};
-        const outdatedWETHStateByAddress: OutdatedWETHStateByAddress = {};
-        for (const address of outdatedWETHAddresses) {
-            const [balance, allowance] = await this.props.blockchain.getTokenBalanceAndAllowanceAsync(
-                this.props.userAddress,
-                address,
-            );
-            outdatedWETHStateByAddress[address] = {
-                balance,
-                allowance,
-            };
-            outdatedWETHAddressToIsStateLoaded[address] = true;
-        }
-        this.setState({
-            outdatedWETHStateByAddress,
-            outdatedWETHAddressToIsStateLoaded,
-        });
-    }
-    private _getOutdatedWETHAddresses(): string[] {
-        const outdatedWETHAddresses = _.compact(
-            _.map(configs.OUTDATED_WRAPPED_ETHERS, outdatedWrappedEtherByNetwork => {
-                const outdatedWrappedEtherIfExists = outdatedWrappedEtherByNetwork[this.props.networkId];
-                if (_.isUndefined(outdatedWrappedEtherIfExists)) {
-                    return undefined;
-                }
-                const address = outdatedWrappedEtherIfExists.address;
-                return address;
-            }),
-        );
-        return outdatedWETHAddresses;
-    }
+	constructor(props: EthWrappersProps) {
+		super(props);
+		const outdatedWETHAddresses = this._getOutdatedWETHAddresses();
+		const outdatedWETHAddressToIsStateLoaded: OutdatedWETHAddressToIsStateLoaded = {};
+		const outdatedWETHStateByAddress: OutdatedWETHStateByAddress = {};
+		_.each(outdatedWETHAddresses, outdatedWETHAddress => {
+			outdatedWETHAddressToIsStateLoaded[outdatedWETHAddress] = false;
+			outdatedWETHStateByAddress[outdatedWETHAddress] = {
+				balance: new BigNumber(0),
+				allowance: new BigNumber(0),
+			};
+		});
+		this.state = {
+			outdatedWETHAddressToIsStateLoaded,
+			outdatedWETHStateByAddress,
+		};
+	}
+	public componentDidMount() {
+		window.scrollTo(0, 0);
+		// tslint:disable-next-line:no-floating-promises
+		this._fetchOutdatedWETHStateAsync();
+	}
+	public render() {
+		const tokens = _.values(this.props.tokenByAddress);
+		const etherToken = _.find(tokens, { symbol: 'WETH' });
+		const etherTokenState = this.props.tokenStateByAddress[etherToken.address];
+		const wethBalance = ZeroEx.toUnitAmount(etherTokenState.balance, constants.DECIMAL_PLACES_ETH);
+		const isBidirectional = true;
+		const etherscanUrl = utils.getEtherScanLinkIfExists(
+			etherToken.address,
+			this.props.networkId,
+			EtherscanLinkSuffixes.Address,
+		);
+		const tokenLabel = this._renderToken('Wrapped Ether', etherToken.address, configs.ICON_URL_BY_SYMBOL.WETH);
+		return (
+			<div className="clearfix lg-px4 md-px4 sm-px2" style={{ minHeight: 600 }}>
+				<div className="relative">
+					<h3>ETH Wrapper</h3>
+					<div className="absolute" style={{ top: 0, right: 0 }}>
+						<a target="_blank" href={constants.URL_WETH_IO} style={{ color: colors.grey }}>
+							<div className="flex">
+								<div>About Wrapped ETH</div>
+								<div className="pl1">
+									<i className="zmdi zmdi-open-in-new" />
+								</div>
+							</div>
+						</a>
+					</div>
+				</div>
+				<Divider />
+				<div>
+					<div className="py2">Wrap ETH into an ERC20-compliant Ether token. 1 ETH = 1 WETH.</div>
+					<div>
+						<Table selectable={false} style={{ backgroundColor: colors.grey50 }}>
+							<TableHeader displaySelectAll={false} adjustForCheckbox={false}>
+								<TableRow>
+									<TableHeaderColumn>ETH Token</TableHeaderColumn>
+									<TableHeaderColumn>Balance</TableHeaderColumn>
+									<TableHeaderColumn className="center">
+										{this._renderActionColumnTitle(isBidirectional)}
+									</TableHeaderColumn>
+								</TableRow>
+							</TableHeader>
+							<TableBody displayRowCheckbox={false}>
+								<TableRow key="ETH">
+									<TableRowColumn className="py1">
+										<div className="flex">
+											<img
+												style={{
+													width: ICON_DIMENSION,
+													height: ICON_DIMENSION,
+												}}
+												src={ETHER_ICON_PATH}
+											/>
+											<div className="ml2 sm-hide xs-hide" style={{ marginTop: 12 }}>
+												ETH
+											</div>
+										</div>
+									</TableRowColumn>
+									<TableRowColumn>
+										{this.props.userEtherBalance.toFixed(PRECISION)} ETH
+									</TableRowColumn>
+									<TableRowColumn>
+										<EthWethConversionButton
+											isOutdatedWrappedEther={false}
+											direction={Side.Deposit}
+											ethToken={etherToken}
+											ethTokenState={etherTokenState}
+											dispatcher={this.props.dispatcher}
+											blockchain={this.props.blockchain}
+											userEtherBalance={this.props.userEtherBalance}
+										/>
+									</TableRowColumn>
+								</TableRow>
+								<TableRow key="WETH">
+									<TableRowColumn className="py1">
+										{this._renderTokenLink(tokenLabel, etherscanUrl)}
+									</TableRowColumn>
+									<TableRowColumn>{wethBalance.toFixed(PRECISION)} WETH</TableRowColumn>
+									<TableRowColumn>
+										<EthWethConversionButton
+											isOutdatedWrappedEther={false}
+											direction={Side.Receive}
+											ethToken={etherToken}
+											ethTokenState={etherTokenState}
+											dispatcher={this.props.dispatcher}
+											blockchain={this.props.blockchain}
+											userEtherBalance={this.props.userEtherBalance}
+										/>
+									</TableRowColumn>
+								</TableRow>
+							</TableBody>
+						</Table>
+					</div>
+				</div>
+				<div>
+					<h4>Outdated WETH</h4>
+					<Divider />
+					<div className="pt2" style={{ lineHeight: 1.5 }}>
+						The{' '}
+						<a href="https://blog.0xproject.com/canonical-weth-a9aa7d0279dd" target="_blank">
+							canonical WETH
+						</a>{' '}
+						contract is updated when necessary. Unwrap outdated WETH in order to
 retrieve your ETH and move
+						it to the updated WETH token.
+					</div>
+					<div>
+						<Table selectable={false} style={{ backgroundColor: colors.grey50 }}>
+							<TableHeader displaySelectAll={false} adjustForCheckbox={false}>
+								<TableRow>
+									<TableHeaderColumn>WETH Version</TableHeaderColumn>
+									<TableHeaderColumn>Balance</TableHeaderColumn>
+									<TableHeaderColumn className="center">
+										{this._renderActionColumnTitle(!isBidirectional)}
+									</TableHeaderColumn>
+								</TableRow>
+							</TableHeader>
+							<TableBody displayRowCheckbox={false}>
+								{this._renderOutdatedWeths(etherToken, etherTokenState)}
+							</TableBody>
+						</Table>
+					</div>
+				</div>
+			</div>
+		);
+	}
+	private _renderActionColumnTitle(isBidirectional: boolean) {
+		let iconClass = 'zmdi-long-arrow-right';
+		let leftSymbol = 'WETH';
+		let rightSymbol = 'ETH';
+		if (isBidirectional) {
+			iconClass = 'zmdi-swap';
+			leftSymbol = 'ETH';
+			rightSymbol = 'WETH';
+		}
+		return (
+			<div className="flex mx-auto" style={{ width: 85 }}>
+				<div style={{ paddingTop: 3 }}>{leftSymbol}</div>
+				<div className="px1">
+					<i style={{ fontSize: 18 }} className={`zmdi ${iconClass}`} />
+				</div>
+				<div style={{ paddingTop: 3 }}>{rightSymbol}</div>
+			</div>
+		);
+	}
+	private _renderOutdatedWeths(etherToken: Token, etherTokenState: TokenState) {
+		const rows = _.map(
+			configs.OUTDATED_WRAPPED_ETHERS,
+			(outdatedWETHByNetworkId: OutdatedWrappedEtherByNetworkId) => {
+				const outdatedWETHIfExists = outdatedWETHByNetworkId[this.props.networkId];
+				if (_.isUndefined(outdatedWETHIfExists)) {
+					return null; // noop
+				}
+				const timestampMsRange = outdatedWETHIfExists.timestampMsRange;
+				let dateRange: string;
+				if (!_.isUndefined(timestampMsRange)) {
+					const startMoment = moment(timestampMsRange.startTimestampMs);
+					const endMoment = moment(timestampMsRange.endTimestampMs);
+					dateRange = `${startMoment.format(DATE_FORMAT)}-${endMoment.format(DATE_FORMAT)}`;
+				} else {
+					dateRange = '-';
+				}
+				const outdatedEtherToken = {
+					...etherToken,
+					address: outdatedWETHIfExists.address,
+				};
+				const isStateLoaded = this.state.outdatedWETHAddressToIsStateLoaded[outdatedWETHIfExists.address];
+				const outdatedEtherTokenState = this.state.outdatedWETHStateByAddress[outdatedWETHIfExists.address];
+				const balanceInEthIfExists = isStateLoaded
+					? ZeroEx.toUnitAmount(outdatedEtherTokenState.balance, constants.DECIMAL_PLACES_ETH).toFixed(
+							PRECISION,
+						)
+					: undefined;
+				const onConversionSuccessful = this._onOutdatedConversionSuccessfulAsync.bind(
+					this,
+					outdatedWETHIfExists.address,
+				);
+				const etherscanUrl = utils.getEtherScanLinkIfExists(
+					outdatedWETHIfExists.address,
+					this.props.networkId,
+					EtherscanLinkSuffixes.Address,
+				);
+				const tokenLabel = this._renderToken(dateRange, outdatedEtherToken.address, OUTDATED_WETH_ICON_PATH);
+				return (
+					<TableRow key={`weth-${outdatedWETHIfExists.address}`}>
+						<TableRowColumn className="py1">
+							{this._renderTokenLink(tokenLabel, etherscanUrl)}
+						</TableRowColumn>
+						<TableRowColumn>
+							{isStateLoaded ? (
+								`${balanceInEthIfExists} WETH`
+							) : (
+								<i className="zmdi zmdi-spinner zmdi-hc-spin" />
+							)}
+						</TableRowColumn>
+						<TableRowColumn>
+							<EthWethConversionButton
+								isDisabled={!isStateLoaded}
+								isOutdatedWrappedEther={true}
+								direction={Side.Receive}
+								ethToken={outdatedEtherToken}
+								ethTokenState={outdatedEtherTokenState}
+								dispatcher={this.props.dispatcher}
+								blockchain={this.props.blockchain}
+								userEtherBalance={this.props.userEtherBalance}
+								onConversionSuccessful={onConversionSuccessful}
+							/>
+						</TableRowColumn>
+					</TableRow>
+				);
+			},
+		);
+		return rows;
+	}
+	private _renderTokenLink(tokenLabel: React.ReactNode, etherscanUrl: string) {
+		return (
+			<span>
+				{_.isUndefined(etherscanUrl) ? (
+					tokenLabel
+				) : (
+					<a href={etherscanUrl} target="_blank" style={{ textDecoration: 'none' }}>
+						{tokenLabel}
+					</a>
+				)}
+			</span>
+		);
+	}
+	private _renderToken(name: string, address: string, imgPath: string) {
+		const tooltipId = `tooltip-${address}`;
+		return (
+			<div className="flex">
+				<img style={{ width: ICON_DIMENSION, height: ICON_DIMENSION }} src={imgPath} />
+				<div className="ml2 sm-hide xs-hide" style={{ marginTop: 12 }}>
+					<span data-tip={true} data-for={tooltipId}>
+						{name}
+					</span>
+					<ReactTooltip id={tooltipId}>{address}</ReactTooltip>
+				</div>
+			</div>
+		);
+	}
+	private async _onOutdatedConversionSuccessfulAsync(outdatedWETHAddress: string) {
+		this.setState({
+			outdatedWETHAddressToIsStateLoaded: {
+				...this.state.outdatedWETHAddressToIsStateLoaded,
+				[outdatedWETHAddress]: false,
+			},
+		});
+		const [balance, allowance] = await this.props.blockchain.getTokenBalanceAndAllowanceAsync(
+			this.props.userAddress,
+			outdatedWETHAddress,
+		);
+		this.setState({
+			outdatedWETHAddressToIsStateLoaded: {
+				...this.state.outdatedWETHAddressToIsStateLoaded,
+				[outdatedWETHAddress]: true,
+			},
+			outdatedWETHStateByAddress: {
+				...this.state.outdatedWETHStateByAddress,
+				[outdatedWETHAddress]: {
+					balance,
+					allowance,
+				},
+			},
+		});
+	}
+	private async _fetchOutdatedWETHStateAsync() {
+		const outdatedWETHAddresses = this._getOutdatedWETHAddresses();
+		const outdatedWETHAddressToIsStateLoaded: OutdatedWETHAddressToIsStateLoaded = {};
+		const outdatedWETHStateByAddress: OutdatedWETHStateByAddress = {};
+		for (const address of outdatedWETHAddresses) {
+			const [balance, allowance] = await this.props.blockchain.getTokenBalanceAndAllowanceAsync(
+				this.props.userAddress,
+				address,
+			);
+			outdatedWETHStateByAddress[address] = {
+				balance,
+				allowance,
+			};
+			outdatedWETHAddressToIsStateLoaded[address] = true;
+		}
+		this.setState({
+			outdatedWETHStateByAddress,
+			outdatedWETHAddressToIsStateLoaded,
+		});
+	}
+	private _getOutdatedWETHAddresses(): string[] {
+		const outdatedWETHAddresses = _.compact(
+			_.map(configs.OUTDATED_WRAPPED_ETHERS, outdatedWrappedEtherByNetwork => {
+				const outdatedWrappedEtherIfExists = outdatedWrappedEtherByNetwork[this.props.networkId];
+				if (_.isUndefined(outdatedWrappedEtherIfExists)) {
+					return undefined;
+				}
+				const address = outdatedWrappedEtherIfExists.address;
+				return address;
+			}),
+		);
+		return outdatedWETHAddresses;
+	}
 } // tslint:disable:max-file-line-count
diff --git a/packages/website/ts/components/fill_order.tsx b/packages/website/ts/components/fill_order.tsx
index 1a150e9ee..249ee419e 100644
--- a/packages/website/ts/components/fill_order.tsx
+++ b/packages/website/ts/components/fill_order.tsx
@@ -26,665 +26,665 @@ import { errorReporter } from 'ts/utils/error_reporter';
 import { utils } from 'ts/utils/utils';
 
 interface FillOrderProps {
-    blockchain: Blockchain;
-    blockchainErr: BlockchainErrs;
-    orderFillAmount: BigNumber;
-    isOrderInUrl: boolean;
-    networkId: number;
-    userAddress: string;
-    tokenByAddress: TokenByAddress;
-    tokenStateByAddress: TokenStateByAddress;
-    initialOrder: Order;
-    dispatcher: Dispatcher;
+	blockchain: Blockchain;
+	blockchainErr: BlockchainErrs;
+	orderFillAmount: BigNumber;
+	isOrderInUrl: boolean;
+	networkId: number;
+	userAddress: string;
+	tokenByAddress: TokenByAddress;
+	tokenStateByAddress: TokenStateByAddress;
+	initialOrder: Order;
+	dispatcher: Dispatcher;
 }
 
 interface FillOrderState {
-    didOrderValidationRun: boolean;
-    areAllInvolvedTokensTracked: boolean;
-    globalErrMsg: string;
-    orderJSON: string;
-    orderJSONErrMsg: string;
-    parsedOrder: Order;
-    didFillOrderSucceed: boolean;
-    didCancelOrderSucceed: boolean;
-    unavailableTakerAmount: BigNumber;
-    isMakerTokenAddressInRegistry: boolean;
-    isTakerTokenAddressInRegistry: boolean;
-    isFillWarningDialogOpen: boolean;
-    isFilling: boolean;
-    isCancelling: boolean;
-    isConfirmingTokenTracking: boolean;
-    tokensToTrack: Token[];
+	didOrderValidationRun: boolean;
+	areAllInvolvedTokensTracked: boolean;
+	globalErrMsg: string;
+	orderJSON: string;
+	orderJSONErrMsg: string;
+	parsedOrder: Order;
+	didFillOrderSucceed: boolean;
+	didCancelOrderSucceed: boolean;
+	unavailableTakerAmount: BigNumber;
+	isMakerTokenAddressInRegistry: boolean;
+	isTakerTokenAddressInRegistry: boolean;
+	isFillWarningDialogOpen: boolean;
+	isFilling: boolean;
+	isCancelling: boolean;
+	isConfirmingTokenTracking: boolean;
+	tokensToTrack: Token[];
 }
 
 export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
-    private _validator: SchemaValidator;
-    constructor(props: FillOrderProps) {
-        super(props);
-        this.state = {
-            globalErrMsg: '',
-            didOrderValidationRun: false,
-            areAllInvolvedTokensTracked: false,
-            didFillOrderSucceed: false,
-            didCancelOrderSucceed: false,
-            orderJSON: _.isUndefined(this.props.initialOrder) ? '' : JSON.stringify(this.props.initialOrder),
-            orderJSONErrMsg: '',
-            parsedOrder: this.props.initialOrder,
-            unavailableTakerAmount: new BigNumber(0),
-            isMakerTokenAddressInRegistry: false,
-            isTakerTokenAddressInRegistry: false,
-            isFillWarningDialogOpen: false,
-            isFilling: false,
-            isCancelling: false,
-            isConfirmingTokenTracking: false,
-            tokensToTrack: [],
-        };
-        this._validator = new SchemaValidator();
-    }
-    public componentWillMount() {
-        if (!_.isEmpty(this.state.orderJSON)) {
-            // tslint:disable-next-line:no-floating-promises
-            this._validateFillOrderFireAndForgetAsync(this.state.orderJSON);
-        }
-    }
-    public componentDidMount() {
-        window.scrollTo(0, 0);
-    }
-    public render() {
-        return (
-            <div className="clearfix lg-px4 md-px4 sm-px2" style={{ minHeight: 600 }}>
-                <h3>Fill an order</h3>
-                <Divider />
-                <div>
-                    {!this.props.isOrderInUrl && (
-                        <div>
-                            <div className="pt2 pb2">Paste an order JSON snippet below to begin</div>
-                            <div className="pb2">Order JSON</div>
-                            <FillOrderJSON
-                                blockchain={this.props.blockchain}
-                                tokenByAddress={this.props.tokenByAddress}
-                                networkId={this.props.networkId}
-                                orderJSON={this.state.orderJSON}
-                                onFillOrderJSONChanged={this._onFillOrderJSONChanged.bind(this)}
-                            />
-                            {this._renderOrderJsonNotices()}
-                        </div>
-                    )}
-                    <div>
-                        {!_.isUndefined(this.state.parsedOrder) &&
-                            this.state.didOrderValidationRun &&
-                            this.state.areAllInvolvedTokensTracked &&
-                            this._renderVisualOrder()}
-                    </div>
-                    {this.props.isOrderInUrl && (
-                        <div className="pt2">
-                            <Card
-                                style={{
-                                    boxShadow: 'none',
-                                    backgroundColor: 'none',
-                                    border: '1px solid #eceaea',
-                                }}
-                            >
-                                <CardHeader title="Order JSON" actAsExpander={true} showExpandableButton={true} />
-                                <CardText expandable={true}>
-                                    <FillOrderJSON
-                                        blockchain={this.props.blockchain}
-                                        tokenByAddress={this.props.tokenByAddress}
-                                        networkId={this.props.networkId}
-                                        orderJSON={this.state.orderJSON}
-                                        onFillOrderJSONChanged={this._onFillOrderJSONChanged.bind(this)}
-                                    />
-                                </CardText>
-                            </Card>
-                            {this._renderOrderJsonNotices()}
-                        </div>
-                    )}
-                </div>
-                <FillWarningDialog
-                    isOpen={this.state.isFillWarningDialogOpen}
-                    onToggleDialog={this._onFillWarningClosed.bind(this)}
-                />
-                <TrackTokenConfirmationDialog
-                    userAddress={this.props.userAddress}
-                    networkId={this.props.networkId}
-                    blockchain={this.props.blockchain}
-                    tokenByAddress={this.props.tokenByAddress}
-                    dispatcher={this.props.dispatcher}
-                    tokens={this.state.tokensToTrack}
-                    isOpen={this.state.isConfirmingTokenTracking}
-                    onToggleDialog={this._onToggleTrackConfirmDialog.bind(this)}
-                />
-            </div>
-        );
-    }
-    private _renderOrderJsonNotices() {
-        return (
-            <div>
-                {!_.isUndefined(this.props.initialOrder) &&
-                    !this.state.didOrderValidationRun && (
-                        <div className="pt2">
-                            <span className="pr1">
-                                <i className="zmdi zmdi-spinner zmdi-hc-spin" />
-                            </span>
-                            <span>Validating order...</span>
-                        </div>
-                    )}
-                {!_.isEmpty(this.state.orderJSONErrMsg) && (
-                    <Alert type={AlertTypes.ERROR} message={this.state.orderJSONErrMsg} />
-                )}
-            </div>
-        );
-    }
-    private _renderVisualOrder() {
-        const takerTokenAddress = this.state.parsedOrder.taker.token.address;
-        const takerToken = this.props.tokenByAddress[takerTokenAddress];
-        const orderTakerAmount = new BigNumber(this.state.parsedOrder.taker.amount);
-        const orderMakerAmount = new BigNumber(this.state.parsedOrder.maker.amount);
-        const takerAssetToken = {
-            amount: orderTakerAmount.minus(this.state.unavailableTakerAmount),
-            symbol: takerToken.symbol,
-        };
-        const fillToken = this.props.tokenByAddress[takerToken.address];
-        const fillTokenState = this.props.tokenStateByAddress[takerToken.address];
-        const makerTokenAddress = this.state.parsedOrder.maker.token.address;
-        const makerToken = this.props.tokenByAddress[makerTokenAddress];
-        const makerAssetToken = {
-            amount: orderMakerAmount.times(takerAssetToken.amount).div(orderTakerAmount),
-            symbol: makerToken.symbol,
-        };
-        const fillAssetToken = {
-            amount: this.props.orderFillAmount,
-            symbol: takerToken.symbol,
-        };
-        const orderTaker = !_.isEmpty(this.state.parsedOrder.taker.address)
-            ? this.state.parsedOrder.taker.address
-            : this.props.userAddress;
-        const parsedOrderExpiration = new BigNumber(this.state.parsedOrder.expiration);
-        const exchangeRate = orderMakerAmount.div(orderTakerAmount);
+	private _validator: SchemaValidator;
+	constructor(props: FillOrderProps) {
+		super(props);
+		this.state = {
+			globalErrMsg: '',
+			didOrderValidationRun: false,
+			areAllInvolvedTokensTracked: false,
+			didFillOrderSucceed: false,
+			didCancelOrderSucceed: false,
+			orderJSON: _.isUndefined(this.props.initialOrder) ? '' : JSON.stringify(this.props.initialOrder),
+			orderJSONErrMsg: '',
+			parsedOrder: this.props.initialOrder,
+			unavailableTakerAmount: new BigNumber(0),
+			isMakerTokenAddressInRegistry: false,
+			isTakerTokenAddressInRegistry: false,
+			isFillWarningDialogOpen: false,
+			isFilling: false,
+			isCancelling: false,
+			isConfirmingTokenTracking: false,
+			tokensToTrack: [],
+		};
+		this._validator = new SchemaValidator();
+	}
+	public componentWillMount() {
+		if (!_.isEmpty(this.state.orderJSON)) {
+			// tslint:disable-next-line:no-floating-promises
+			this._validateFillOrderFireAndForgetAsync(this.state.orderJSON);
+		}
+	}
+	public componentDidMount() {
+		window.scrollTo(0, 0);
+	}
+	public render() {
+		return (
+			<div className="clearfix lg-px4 md-px4 sm-px2" style={{ minHeight: 600 }}>
+				<h3>Fill an order</h3>
+				<Divider />
+				<div>
+					{!this.props.isOrderInUrl && (
+						<div>
+							<div className="pt2 pb2">Paste an order JSON snippet below to begin</div>
+							<div className="pb2">Order JSON</div>
+							<FillOrderJSON
+								blockchain={this.props.blockchain}
+								tokenByAddress={this.props.tokenByAddress}
+								networkId={this.props.networkId}
+								orderJSON={this.state.orderJSON}
+								onFillOrderJSONChanged={this._onFillOrderJSONChanged.bind(this)}
+							/>
+							{this._renderOrderJsonNotices()}
+						</div>
+					)}
+					<div>
+						{!_.isUndefined(this.state.parsedOrder) &&
+							this.state.didOrderValidationRun &&
+							this.state.areAllInvolvedTokensTracked &&
+							this._renderVisualOrder()}
+					</div>
+					{this.props.isOrderInUrl && (
+						<div className="pt2">
+							<Card
+								style={{
+									boxShadow: 'none',
+									backgroundColor: 'none',
+									border: '1px solid #eceaea',
+								}}
+							>
+								<CardHeader title="Order JSON" actAsExpander={true} showExpandableButton={true} />
+								<CardText expandable={true}>
+									<FillOrderJSON
+										blockchain={this.props.blockchain}
+										tokenByAddress={this.props.tokenByAddress}
+										networkId={this.props.networkId}
+										orderJSON={this.state.orderJSON}
+										onFillOrderJSONChanged={this._onFillOrderJSONChanged.bind(this)}
+									/>
+								</CardText>
+							</Card>
+							{this._renderOrderJsonNotices()}
+						</div>
+					)}
+				</div>
+				<FillWarningDialog
+					isOpen={this.state.isFillWarningDialogOpen}
+					onToggleDialog={this._onFillWarningClosed.bind(this)}
+				/>
+				<TrackTokenConfirmationDialog
+					userAddress={this.props.userAddress}
+					networkId={this.props.networkId}
+					blockchain={this.props.blockchain}
+					tokenByAddress={this.props.tokenByAddress}
+					dispatcher={this.props.dispatcher}
+					tokens={this.state.tokensToTrack}
+					isOpen={this.state.isConfirmingTokenTracking}
+					onToggleDialog={this._onToggleTrackConfirmDialog.bind(this)}
+				/>
+			</div>
+		);
+	}
+	private _renderOrderJsonNotices() {
+		return (
+			<div>
+				{!_.isUndefined(this.props.initialOrder) &&
+					!this.state.didOrderValidationRun && (
+						<div className="pt2">
+							<span className="pr1">
+								<i className="zmdi zmdi-spinner zmdi-hc-spin" />
+							</span>
+							<span>Validating order...</span>
+						</div>
+					)}
+				{!_.isEmpty(this.state.orderJSONErrMsg) && (
+					<Alert type={AlertTypes.ERROR} message={this.state.orderJSONErrMsg} />
+				)}
+			</div>
+		);
+	}
+	private _renderVisualOrder() {
+		const takerTokenAddress = this.state.parsedOrder.taker.token.address;
+		const takerToken = this.props.tokenByAddress[takerTokenAddress];
+		const orderTakerAmount = new BigNumber(this.state.parsedOrder.taker.amount);
+		const orderMakerAmount = new BigNumber(this.state.parsedOrder.maker.amount);
+		const takerAssetToken = {
+			amount: orderTakerAmount.minus(this.state.unavailableTakerAmount),
+			symbol: takerToken.symbol,
+		};
+		const fillToken = this.props.tokenByAddress[takerToken.address];
+		const fillTokenState = this.props.tokenStateByAddress[takerToken.address];
+		const makerTokenAddress = this.state.parsedOrder.maker.token.address;
+		const makerToken = this.props.tokenByAddress[makerTokenAddress];
+		const makerAssetToken = {
+			amount: orderMakerAmount.times(takerAssetToken.amount).div(orderTakerAmount),
+			symbol: makerToken.symbol,
+		};
+		const fillAssetToken = {
+			amount: this.props.orderFillAmount,
+			symbol: takerToken.symbol,
+		};
+		const orderTaker = !_.isEmpty(this.state.parsedOrder.taker.address)
+			? this.state.parsedOrder.taker.address
+			: this.props.userAddress;
+		const parsedOrderExpiration = new BigNumber(this.state.parsedOrder.expiration);
+		const exchangeRate = orderMakerAmount.div(orderTakerAmount);
 
-        let orderReceiveAmount = 0;
-        if (!_.isUndefined(this.props.orderFillAmount)) {
-            const orderReceiveAmountBigNumber = exchangeRate.mul(this.props.orderFillAmount);
-            orderReceiveAmount = this._formatCurrencyAmount(orderReceiveAmountBigNumber, makerToken.decimals);
-        }
-        const isUserMaker =
-            !_.isUndefined(this.state.parsedOrder) && this.state.parsedOrder.maker.address === this.props.userAddress;
-        const expiryDate = utils.convertToReadableDateTimeFromUnixTimestamp(parsedOrderExpiration);
-        return (
-            <div className="pt3 pb1">
-                <div className="clearfix pb2" style={{ width: '100%' }}>
-                    <div className="inline left">Order details</div>
-                    <div className="inline right" style={{ minWidth: 208 }}>
-                        <div className="col col-4 pl2" style={{ color: colors.grey }}>
-                            Maker:
-                        </div>
-                        <div className="col col-2 pr1">
-                            <Identicon address={this.state.parsedOrder.maker.address} diameter={23} />
-                        </div>
-                        <div className="col col-6">
-                            <EthereumAddress
-                                address={this.state.parsedOrder.maker.address}
-                                networkId={this.props.networkId}
-                            />
-                        </div>
-                    </div>
-                </div>
-                <div className="lg-px4 md-px4 sm-px0">
-                    <div className="lg-px4 md-px4 sm-px1 pt1">
-                        <VisualOrder
-                            orderTakerAddress={orderTaker}
-                            orderMakerAddress={this.state.parsedOrder.maker.address}
-                            makerAssetToken={makerAssetToken}
-                            takerAssetToken={takerAssetToken}
-                            tokenByAddress={this.props.tokenByAddress}
-                            makerToken={makerToken}
-                            takerToken={takerToken}
-                            networkId={this.props.networkId}
-                            isMakerTokenAddressInRegistry={this.state.isMakerTokenAddressInRegistry}
-                            isTakerTokenAddressInRegistry={this.state.isTakerTokenAddressInRegistry}
-                        />
-                        <div className="center pt3 pb2">Expires: {expiryDate} UTC</div>
-                    </div>
-                </div>
-                {!isUserMaker && (
-                    <div className="clearfix mx-auto relative" style={{ width: 235, height: 108 }}>
-                        <TokenAmountInput
-                            label="Fill amount"
-                            onChange={this._onFillAmountChange.bind(this)}
-                            shouldShowIncompleteErrs={false}
-                            token={fillToken}
-                            tokenState={fillTokenState}
-                            amount={fillAssetToken.amount}
-                            shouldCheckBalance={true}
-                            shouldCheckAllowance={true}
-                        />
-                        <div
-                            className="absolute sm-hide xs-hide"
-                            style={{
-                                color: colors.grey400,
-                                right: -247,
-                                top: 39,
-                                width: 242,
-                            }}
-                        >
-                            = {accounting.formatNumber(orderReceiveAmount, 6)} {makerToken.symbol}
-                        </div>
-                    </div>
-                )}
-                <div>
-                    {isUserMaker ? (
-                        <div>
-                            <RaisedButton
-                                style={{ width: '100%' }}
-                                disabled={this.state.isCancelling}
-                                label={this.state.isCancelling ? 'Cancelling order...' : 'Cancel order'}
-                                onClick={this._onCancelOrderClickFireAndForgetAsync.bind(this)}
-                            />
-                            {this.state.didCancelOrderSucceed && (
-                                <Alert type={AlertTypes.SUCCESS} message={this._renderCancelSuccessMsg()} />
-                            )}
-                        </div>
-                    ) : (
-                        <div>
-                            <RaisedButton
-                                style={{ width: '100%' }}
-                                disabled={this.state.isFilling}
-                                label={this.state.isFilling ? 'Filling order...' : 'Fill order'}
-                                onClick={this._onFillOrderClick.bind(this)}
-                            />
-                            {!_.isEmpty(this.state.globalErrMsg) && (
-                                <Alert type={AlertTypes.ERROR} message={this.state.globalErrMsg} />
-                            )}
-                            {this.state.didFillOrderSucceed && (
-                                <Alert type={AlertTypes.SUCCESS} message={this._renderFillSuccessMsg()} />
-                            )}
-                        </div>
-                    )}
-                </div>
-            </div>
-        );
-    }
-    private _renderFillSuccessMsg() {
-        return (
-            <div>
-                Order successfully filled. See the trade details in your{' '}
-                <Link to={`${WebsitePaths.Portal}/trades`} style={{ color: colors.white }}>
-                    trade history
-                </Link>
-            </div>
-        );
-    }
-    private _renderCancelSuccessMsg() {
-        return <div>Order successfully cancelled.</div>;
-    }
-    private _onFillOrderClick() {
-        if (!this.state.isMakerTokenAddressInRegistry || !this.state.isTakerTokenAddressInRegistry) {
-            this.setState({
-                isFillWarningDialogOpen: true,
-            });
-        } else {
-            // tslint:disable-next-line:no-floating-promises
-            this._onFillOrderClickFireAndForgetAsync();
-        }
-    }
-    private _onFillWarningClosed(didUserCancel: boolean) {
-        this.setState({
-            isFillWarningDialogOpen: false,
-        });
-        if (!didUserCancel) {
-            // tslint:disable-next-line:no-floating-promises
-            this._onFillOrderClickFireAndForgetAsync();
-        }
-    }
-    private _onFillAmountChange(isValid: boolean, amount?: BigNumber) {
-        this.props.dispatcher.updateOrderFillAmount(amount);
-    }
-    private _onFillOrderJSONChanged(event: any) {
-        const orderJSON = event.target.value;
-        this.setState({
-            didOrderValidationRun: _.isEmpty(orderJSON) && _.isEmpty(this.state.orderJSONErrMsg),
-            didFillOrderSucceed: false,
-        });
-        // tslint:disable-next-line:no-floating-promises
-        this._validateFillOrderFireAndForgetAsync(orderJSON);
-    }
-    private async _checkForUntrackedTokensAndAskToAdd() {
-        if (!_.isEmpty(this.state.orderJSONErrMsg)) {
-            return;
-        }
+		let orderReceiveAmount = 0;
+		if (!_.isUndefined(this.props.orderFillAmount)) {
+			const orderReceiveAmountBigNumber = exchangeRate.mul(this.props.orderFillAmount);
+			orderReceiveAmount = this._formatCurrencyAmount(orderReceiveAmountBigNumber, makerToken.decimals);
+		}
+		const isUserMaker =
+			!_.isUndefined(this.state.parsedOrder) && this.state.parsedOrder.maker.address === this.props.userAddress;
+		const expiryDate = utils.convertToReadableDateTimeFromUnixTimestamp(parsedOrderExpiration);
+		return (
+			<div className="pt3 pb1">
+				<div className="clearfix pb2" style={{ width: '100%' }}>
+					<div className="inline left">Order details</div>
+					<div className="inline right" style={{ minWidth: 208 }}>
+						<div className="col col-4 pl2" style={{ color: colors.grey }}>
+							Maker:
+						</div>
+						<div className="col col-2 pr1">
+							<Identicon address={this.state.parsedOrder.maker.address} diameter={23} />
+						</div>
+						<div className="col col-6">
+							<EthereumAddress
+								address={this.state.parsedOrder.maker.address}
+								networkId={this.props.networkId}
+							/>
+						</div>
+					</div>
+				</div>
+				<div className="lg-px4 md-px4 sm-px0">
+					<div className="lg-px4 md-px4 sm-px1 pt1">
+						<VisualOrder
+							orderTakerAddress={orderTaker}
+							orderMakerAddress={this.state.parsedOrder.maker.address}
+							makerAssetToken={makerAssetToken}
+							takerAssetToken={takerAssetToken}
+							tokenByAddress={this.props.tokenByAddress}
+							makerToken={makerToken}
+							takerToken={takerToken}
+							networkId={this.props.networkId}
+							isMakerTokenAddressInRegistry={this.state.isMakerTokenAddressInRegistry}
+							isTakerTokenAddressInRegistry={this.state.isTakerTokenAddressInRegistry}
+						/>
+						<div className="center pt3 pb2">Expires: {expiryDate} UTC</div>
+					</div>
+				</div>
+				{!isUserMaker && (
+					<div className="clearfix mx-auto relative" style={{ width: 235, height: 108 }}>
+						<TokenAmountInput
+							label="Fill amount"
+							onChange={this._onFillAmountChange.bind(this)}
+							shouldShowIncompleteErrs={false}
+							token={fillToken}
+							tokenState={fillTokenState}
+							amount={fillAssetToken.amount}
+							shouldCheckBalance={true}
+							shouldCheckAllowance={true}
+						/>
+						<div
+							className="absolute sm-hide xs-hide"
+							style={{
+								color: colors.grey400,
+								right: -247,
+								top: 39,
+								width: 242,
+							}}
+						>
+							= {accounting.formatNumber(orderReceiveAmount, 6)} {makerToken.symbol}
+						</div>
+					</div>
+				)}
+				<div>
+					{isUserMaker ? (
+						<div>
+							<RaisedButton
+								style={{ width: '100%' }}
+								disabled={this.state.isCancelling}
+								label={this.state.isCancelling ? 'Cancelling order...' : 'Cancel order'}
+								onClick={this._onCancelOrderClickFireAndForgetAsync.bind(this)}
+							/>
+							{this.state.didCancelOrderSucceed && (
+								<Alert type={AlertTypes.SUCCESS} message={this._renderCancelSuccessMsg()} />
+							)}
+						</div>
+					) : (
+						<div>
+							<RaisedButton
+								style={{ width: '100%' }}
+								disabled={this.state.isFilling}
+								label={this.state.isFilling ? 'Filling order...' : 'Fill order'}
+								onClick={this._onFillOrderClick.bind(this)}
+							/>
+							{!_.isEmpty(this.state.globalErrMsg) && (
+								<Alert type={AlertTypes.ERROR} message={this.state.globalErrMsg} />
+							)}
+							{this.state.didFillOrderSucceed && (
+								<Alert type={AlertTypes.SUCCESS} message={this._renderFillSuccessMsg()} />
+							)}
+						</div>
+					)}
+				</div>
+			</div>
+		);
+	}
+	private _renderFillSuccessMsg() {
+		return (
+			<div>
+				Order successfully filled. See the trade details in your{' '}
+				<Link to={`${WebsitePaths.Portal}/trades`} style={{ color: colors.white }}>
+					trade history
+				</Link>
+			</div>
+		);
+	}
+	private _renderCancelSuccessMsg() {
+		return <div>Order successfully cancelled.</div>;
+	}
+	private _onFillOrderClick() {
+		if (!this.state.isMakerTokenAddressInRegistry || !this.state.isTakerTokenAddressInRegistry) {
+			this.setState({
+				isFillWarningDialogOpen: true,
+			});
+		} else {
+			// tslint:disable-next-line:no-floating-promises
+			this._onFillOrderClickFireAndForgetAsync();
+		}
+	}
+	private _onFillWarningClosed(didUserCancel: boolean) {
+		this.setState({
+			isFillWarningDialogOpen: false,
+		});
+		if (!didUserCancel) {
+			// tslint:disable-next-line:no-floating-promises
+			this._onFillOrderClickFireAndForgetAsync();
+		}
+	}
+	private _onFillAmountChange(isValid: boolean, amount?: BigNumber) {
+		this.props.dispatcher.updateOrderFillAmount(amount);
+	}
+	private _onFillOrderJSONChanged(event: any) {
+		const orderJSON = event.target.value;
+		this.setState({
+			didOrderValidationRun: _.isEmpty(orderJSON) && _.isEmpty(this.state.orderJSONErrMsg),
+			didFillOrderSucceed: false,
+		});
+		// tslint:disable-next-line:no-floating-promises
+		this._validateFillOrderFireAndForgetAsync(orderJSON);
+	}
+	private async _checkForUntrackedTokensAndAskToAdd() {
+		if (!_.isEmpty(this.state.orderJSONErrMsg)) {
+			return;
+		}
 
-        const makerTokenIfExists = this.props.tokenByAddress[this.state.parsedOrder.maker.token.address];
-        const takerTokenIfExists = this.props.tokenByAddress[this.state.parsedOrder.taker.token.address];
+		const makerTokenIfExists = this.props.tokenByAddress[this.state.parsedOrder.maker.token.address];
+		const takerTokenIfExists = this.props.tokenByAddress[this.state.parsedOrder.taker.token.address];
 
-        const tokensToTrack = [];
-        const isUnseenMakerToken = _.isUndefined(makerTokenIfExists);
-        const isMakerTokenTracked = !_.isUndefined(makerTokenIfExists) && makerTokenIfExists.isTracked;
-        if (isUnseenMakerToken) {
-            tokensToTrack.push({
-                ...this.state.parsedOrder.maker.token,
-                iconUrl: undefined,
-                isTracked: false,
-                isRegistered: false,
-            });
-        } else if (!isMakerTokenTracked) {
-            tokensToTrack.push(makerTokenIfExists);
-        }
-        const isUnseenTakerToken = _.isUndefined(takerTokenIfExists);
-        const isTakerTokenTracked = !_.isUndefined(takerTokenIfExists) && takerTokenIfExists.isTracked;
-        if (isUnseenTakerToken) {
-            tokensToTrack.push({
-                ...this.state.parsedOrder.taker.token,
-                iconUrl: undefined,
-                isTracked: false,
-                isRegistered: false,
-            });
-        } else if (!isTakerTokenTracked) {
-            tokensToTrack.push(takerTokenIfExists);
-        }
-        if (!_.isEmpty(tokensToTrack)) {
-            this.setState({
-                isConfirmingTokenTracking: true,
-                tokensToTrack,
-            });
-        } else {
-            this.setState({
-                areAllInvolvedTokensTracked: true,
-            });
-        }
-    }
-    private async _validateFillOrderFireAndForgetAsync(orderJSON: string) {
-        let orderJSONErrMsg = '';
-        let parsedOrder: Order;
-        try {
-            const order = JSON.parse(orderJSON);
-            const validationResult = this._validator.validate(order, orderSchema);
-            if (validationResult.errors.length > 0) {
-                orderJSONErrMsg = 'Submitted order JSON is not a valid order';
-                utils.consoleLog(`Unexpected order JSON validation error: ${validationResult.errors.join(', ')}`);
-                return;
-            }
-            parsedOrder = order;
+		const tokensToTrack = [];
+		const isUnseenMakerToken = _.isUndefined(makerTokenIfExists);
+		const isMakerTokenTracked = !_.isUndefined(makerTokenIfExists) && makerTokenIfExists.isTracked;
+		if (isUnseenMakerToken) {
+			tokensToTrack.push({
+				...this.state.parsedOrder.maker.token,
+				iconUrl: undefined,
+				isTracked: false,
+				isRegistered: false,
+			});
+		} else if (!isMakerTokenTracked) {
+			tokensToTrack.push(makerTokenIfExists);
+		}
+		const isUnseenTakerToken = _.isUndefined(takerTokenIfExists);
+		const isTakerTokenTracked = !_.isUndefined(takerTokenIfExists) && takerTokenIfExists.isTracked;
+		if (isUnseenTakerToken) {
+			tokensToTrack.push({
+				...this.state.parsedOrder.taker.token,
+				iconUrl: undefined,
+				isTracked: false,
+				isRegistered: false,
+			});
+		} else if (!isTakerTokenTracked) {
+			tokensToTrack.push(takerTokenIfExists);
+		}
+		if (!_.isEmpty(tokensToTrack)) {
+			this.setState({
+				isConfirmingTokenTracking: true,
+				tokensToTrack,
+			});
+		} else {
+			this.setState({
+				areAllInvolvedTokensTracked: true,
+			});
+		}
+	}
+	private async _validateFillOrderFireAndForgetAsync(orderJSON: string) {
+		let orderJSONErrMsg = '';
+		let parsedOrder: Order;
+		try {
+			const order = JSON.parse(orderJSON);
+			const validationResult = this._validator.validate(order, orderSchema);
+			if (validationResult.errors.length > 0) {
+				orderJSONErrMsg = 'Submitted order JSON is not a valid order';
+				utils.consoleLog(`Unexpected order JSON validation error: ${validationResult.errors.join(', ')}`);
+				return;
+			}
+			parsedOrder = order;
 
-            const exchangeContractAddr = this.props.blockchain.getExchangeContractAddressIfExists();
-            const makerAmount = new BigNumber(parsedOrder.maker.amount);
-            const takerAmount = new BigNumber(parsedOrder.taker.amount);
-            const expiration = new BigNumber(parsedOrder.expiration);
-            const salt = new BigNumber(parsedOrder.salt);
-            const parsedMakerFee = new BigNumber(parsedOrder.maker.feeAmount);
-            const parsedTakerFee = new BigNumber(parsedOrder.taker.feeAmount);
+			const exchangeContractAddr = this.props.blockchain.getExchangeContractAddressIfExists();
+			const makerAmount = new BigNumber(parsedOrder.maker.amount);
+			const takerAmount = new BigNumber(parsedOrder.taker.amount);
+			const expiration = new BigNumber(parsedOrder.expiration);
+			const salt = new BigNumber(parsedOrder.salt);
+			const parsedMakerFee = new BigNumber(parsedOrder.maker.feeAmount);
+			const parsedTakerFee = new BigNumber(parsedOrder.taker.feeAmount);
 
-            const zeroExOrder: ZeroExOrder = {
-                exchangeContractAddress: parsedOrder.exchangeContract,
-                expirationUnixTimestampSec: expiration,
-                feeRecipient: parsedOrder.feeRecipient,
-                maker: parsedOrder.maker.address,
-                makerFee: parsedMakerFee,
-                makerTokenAddress: parsedOrder.maker.token.address,
-                makerTokenAmount: makerAmount,
-                salt,
-                taker: _.isEmpty(parsedOrder.taker.address) ? constants.NULL_ADDRESS : parsedOrder.taker.address,
-                takerFee: parsedTakerFee,
-                takerTokenAddress: parsedOrder.taker.token.address,
-                takerTokenAmount: takerAmount,
-            };
-            const orderHash = ZeroEx.getOrderHashHex(zeroExOrder);
+			const zeroExOrder: ZeroExOrder = {
+				exchangeContractAddress: parsedOrder.exchangeContract,
+				expirationUnixTimestampSec: expiration,
+				feeRecipient: parsedOrder.feeRecipient,
+				maker: parsedOrder.maker.address,
+				makerFee: parsedMakerFee,
+				makerTokenAddress: parsedOrder.maker.token.address,
+				makerTokenAmount: makerAmount,
+				salt,
+				taker: _.isEmpty(parsedOrder.taker.address) ? constants.NULL_ADDRESS : parsedOrder.taker.address,
+				takerFee: parsedTakerFee,
+				takerTokenAddress: parsedOrder.taker.token.address,
+				takerTokenAmount: takerAmount,
+			};
+			const orderHash = ZeroEx.getOrderHashHex(zeroExOrder);
 
-            const signature = parsedOrder.signature;
-            const isValidSignature = ZeroEx.isValidSignature(signature.hash, signature, parsedOrder.maker.address);
-            if (this.props.networkId !== parsedOrder.networkId) {
-                orderJSONErrMsg = `This order was made on another Ethereum network
+			const signature = parsedOrder.signature;
+			const isValidSignature = ZeroEx.isValidSignature(signature.hash, signature, parsedOrder.maker.address);
+			if (this.props.networkId !== parsedOrder.networkId) {
+				orderJSONErrMsg = `This order was made on another Ethereum network
                                    (id: ${parsedOrder.networkId}). Connect to this network to fill.`;
-                parsedOrder = undefined;
-            } else if (exchangeContractAddr !== parsedOrder.exchangeContract) {
-                orderJSONErrMsg = 'This order was made using a deprecated 0x Exchange contract.';
-                parsedOrder = undefined;
-            } else if (orderHash !== signature.hash) {
-                orderJSONErrMsg = 'Order hash does not match supplied plaintext values';
-                parsedOrder = undefined;
-            } else if (!isValidSignature) {
-                orderJSONErrMsg = 'Order signature is invalid';
-                parsedOrder = undefined;
-            } else {
-                // Update user supplied order cache so that if they navigate away from fill view
-                // e.g to set a token allowance, when they come back, the fill order persists
-                this.props.dispatcher.updateUserSuppliedOrderCache(parsedOrder);
-            }
-        } catch (err) {
-            utils.consoleLog(`Validate order err: ${err}`);
-            if (!_.isEmpty(orderJSON)) {
-                orderJSONErrMsg = 'Submitted order JSON is not valid JSON';
-            }
-            this.setState({
-                didOrderValidationRun: true,
-                orderJSON,
-                orderJSONErrMsg,
-                parsedOrder,
-            });
-            return;
-        }
+				parsedOrder = undefined;
+			} else if (exchangeContractAddr !== parsedOrder.exchangeContract) {
+				orderJSONErrMsg = 'This order was made using a deprecated 0x Exchange contract.';
+				parsedOrder = undefined;
+			} else if (orderHash !== signature.hash) {
+				orderJSONErrMsg = 'Order hash does not match supplied plaintext values';
+				parsedOrder = undefined;
+			} else if (!isValidSignature) {
+				orderJSONErrMsg = 'Order signature is invalid';
+				parsedOrder = undefined;
+			} else {
+				// Update user supplied order cache so that if they navigate away from fill view
+				// e.g to set a token allowance, when they come back, the fill order persists
+				this.props.dispatcher.updateUserSuppliedOrderCache(parsedOrder);
+			}
+		} catch (err) {
+			utils.consoleLog(`Validate order err: ${err}`);
+			if (!_.isEmpty(orderJSON)) {
+				orderJSONErrMsg = 'Submitted order JSON is not valid JSON';
+			}
+			this.setState({
+				didOrderValidationRun: true,
+				orderJSON,
+				orderJSONErrMsg,
+				parsedOrder,
+			});
+			return;
+		}
 
-        let unavailableTakerAmount = new BigNumber(0);
-        if (!_.isEmpty(orderJSONErrMsg)) {
-            // Clear cache entry if user updates orderJSON to invalid entry
-            this.props.dispatcher.updateUserSuppliedOrderCache(undefined);
-        } else {
-            const orderHash = parsedOrder.signature.hash;
-            unavailableTakerAmount = await this.props.blockchain.getUnavailableTakerAmountAsync(orderHash);
-            const isMakerTokenAddressInRegistry = await this.props.blockchain.isAddressInTokenRegistryAsync(
-                parsedOrder.maker.token.address,
-            );
-            const isTakerTokenAddressInRegistry = await this.props.blockchain.isAddressInTokenRegistryAsync(
-                parsedOrder.taker.token.address,
-            );
-            this.setState({
-                isMakerTokenAddressInRegistry,
-                isTakerTokenAddressInRegistry,
-            });
-        }
+		let unavailableTakerAmount = new BigNumber(0);
+		if (!_.isEmpty(orderJSONErrMsg)) {
+			// Clear cache entry if user updates orderJSON to invalid entry
+			this.props.dispatcher.updateUserSuppliedOrderCache(undefined);
+		} else {
+			const orderHash = parsedOrder.signature.hash;
+			unavailableTakerAmount = await this.props.blockchain.getUnavailableTakerAmountAsync(orderHash);
+			const isMakerTokenAddressInRegistry = await this.props.blockchain.isAddressInTokenRegistryAsync(
+				parsedOrder.maker.token.address,
+			);
+			const isTakerTokenAddressInRegistry = await this.props.blockchain.isAddressInTokenRegistryAsync(
+				parsedOrder.taker.token.address,
+			);
+			this.setState({
+				isMakerTokenAddressInRegistry,
+				isTakerTokenAddressInRegistry,
+			});
+		}
 
-        this.setState({
-            didOrderValidationRun: true,
-            orderJSON,
-            orderJSONErrMsg,
-            parsedOrder,
-            unavailableTakerAmount,
-        });
+		this.setState({
+			didOrderValidationRun: true,
+			orderJSON,
+			orderJSONErrMsg,
+			parsedOrder,
+			unavailableTakerAmount,
+		});
 
-        await this._checkForUntrackedTokensAndAskToAdd();
-    }
-    private async _onFillOrderClickFireAndForgetAsync(): Promise<void> {
-        if (this.props.blockchainErr !== BlockchainErrs.NoError || _.isEmpty(this.props.userAddress)) {
-            this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
-            return;
-        }
+		await this._checkForUntrackedTokensAndAskToAdd();
+	}
+	private async _onFillOrderClickFireAndForgetAsync(): Promise<void> {
+		if (this.props.blockchainErr !== BlockchainErrs.NoError || _.isEmpty(this.props.userAddress)) {
+			this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
+			return;
+		}
 
-        this.setState({
-            isFilling: true,
-            didFillOrderSucceed: false,
-        });
+		this.setState({
+			isFilling: true,
+			didFillOrderSucceed: false,
+		});
 
-        const parsedOrder = this.state.parsedOrder;
-        const takerFillAmount = this.props.orderFillAmount;
+		const parsedOrder = this.state.parsedOrder;
+		const takerFillAmount = this.props.orderFillAmount;
 
-        if (_.isUndefined(this.props.userAddress)) {
-            this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
-            this.setState({
-                isFilling: false,
-            });
-            return;
-        }
-        let globalErrMsg = '';
+		if (_.isUndefined(this.props.userAddress)) {
+			this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
+			this.setState({
+				isFilling: false,
+			});
+			return;
+		}
+		let globalErrMsg = '';
 
-        if (_.isUndefined(takerFillAmount)) {
-            globalErrMsg = 'You must specify a fill amount';
-        }
+		if (_.isUndefined(takerFillAmount)) {
+			globalErrMsg = 'You must specify a fill amount';
+		}
 
-        const signedOrder = this.props.blockchain.portalOrderToSignedOrder(
-            parsedOrder.maker.address,
-            parsedOrder.taker.address,
-            parsedOrder.maker.token.address,
-            parsedOrder.taker.token.address,
-            new BigNumber(parsedOrder.maker.amount),
-            new BigNumber(parsedOrder.taker.amount),
-            new BigNumber(parsedOrder.maker.feeAmount),
-            new BigNumber(parsedOrder.taker.feeAmount),
-            new BigNumber(this.state.parsedOrder.expiration),
-            parsedOrder.feeRecipient,
-            parsedOrder.signature,
-            new BigNumber(parsedOrder.salt),
-        );
-        if (_.isEmpty(globalErrMsg)) {
-            try {
-                await this.props.blockchain.validateFillOrderThrowIfInvalidAsync(
-                    signedOrder,
-                    takerFillAmount,
-                    this.props.userAddress,
-                );
-            } catch (err) {
-                globalErrMsg = utils.zeroExErrToHumanReadableErrMsg(err.message, parsedOrder.taker.address);
-            }
-        }
-        if (!_.isEmpty(globalErrMsg)) {
-            this.setState({
-                isFilling: false,
-                globalErrMsg,
-            });
-            return;
-        }
-        try {
-            const orderFilledAmount: BigNumber = await this.props.blockchain.fillOrderAsync(
-                signedOrder,
-                this.props.orderFillAmount,
-            );
-            // After fill completes, let's update the token balances
-            const makerToken = this.props.tokenByAddress[parsedOrder.maker.token.address];
-            const takerToken = this.props.tokenByAddress[parsedOrder.taker.token.address];
-            const tokens = [makerToken, takerToken];
-            await this.props.blockchain.updateTokenBalancesAndAllowancesAsync(tokens);
-            this.setState({
-                isFilling: false,
-                didFillOrderSucceed: true,
-                globalErrMsg: '',
-                unavailableTakerAmount: this.state.unavailableTakerAmount.plus(orderFilledAmount),
-            });
-            return;
-        } catch (err) {
-            this.setState({
-                isFilling: false,
-            });
-            const errMsg = `${err}`;
-            if (_.includes(errMsg, 'User denied transaction signature')) {
-                return;
-            }
-            globalErrMsg = 'Failed to fill order, please refresh and try again';
-            utils.consoleLog(`${err}`);
-            this.setState({
-                globalErrMsg,
-            });
-            await errorReporter.reportAsync(err);
-            return;
-        }
-    }
-    private async _onCancelOrderClickFireAndForgetAsync(): Promise<void> {
-        if (this.props.blockchainErr !== BlockchainErrs.NoError || _.isEmpty(this.props.userAddress)) {
-            this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
-            return;
-        }
+		const signedOrder = this.props.blockchain.portalOrderToSignedOrder(
+			parsedOrder.maker.address,
+			parsedOrder.taker.address,
+			parsedOrder.maker.token.address,
+			parsedOrder.taker.token.address,
+			new BigNumber(parsedOrder.maker.amount),
+			new BigNumber(parsedOrder.taker.amount),
+			new BigNumber(parsedOrder.maker.feeAmount),
+			new BigNumber(parsedOrder.taker.feeAmount),
+			new BigNumber(this.state.parsedOrder.expiration),
+			parsedOrder.feeRecipient,
+			parsedOrder.signature,
+			new BigNumber(parsedOrder.salt),
+		);
+		if (_.isEmpty(globalErrMsg)) {
+			try {
+				await this.props.blockchain.validateFillOrderThrowIfInvalidAsync(
+					signedOrder,
+					takerFillAmount,
+					this.props.userAddress,
+				);
+			} catch (err) {
+				globalErrMsg = utils.zeroExErrToHumanReadableErrMsg(err.message, parsedOrder.taker.address);
+			}
+		}
+		if (!_.isEmpty(globalErrMsg)) {
+			this.setState({
+				isFilling: false,
+				globalErrMsg,
+			});
+			return;
+		}
+		try {
+			const orderFilledAmount: BigNumber = await this.props.blockchain.fillOrderAsync(
+				signedOrder,
+				this.props.orderFillAmount,
+			);
+			// After fill completes, let's update the token balances
+			const makerToken = this.props.tokenByAddress[parsedOrder.maker.token.address];
+			const takerToken = this.props.tokenByAddress[parsedOrder.taker.token.address];
+			const tokens = [makerToken, takerToken];
+			await this.props.blockchain.updateTokenBalancesAndAllowancesAsync(tokens);
+			this.setState({
+				isFilling: false,
+				didFillOrderSucceed: true,
+				globalErrMsg: '',
+				unavailableTakerAmount: this.state.unavailableTakerAmount.plus(orderFilledAmount),
+			});
+			return;
+		} catch (err) {
+			this.setState({
+				isFilling: false,
+			});
+			const errMsg = `${err}`;
+			if (_.includes(errMsg, 'User denied transaction signature')) {
+				return;
+			}
+			globalErrMsg = 'Failed to fill order, please refresh and try again';
+			utils.consoleLog(`${err}`);
+			this.setState({
+				globalErrMsg,
+			});
+			await errorReporter.reportAsync(err);
+			return;
+		}
+	}
+	private async _onCancelOrderClickFireAndForgetAsync(): Promise<void> {
+		if (this.props.blockchainErr !== BlockchainErrs.NoError || _.isEmpty(this.props.userAddress)) {
+			this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
+			return;
+		}
 
-        this.setState({
-            isCancelling: true,
-            didCancelOrderSucceed: false,
-        });
+		this.setState({
+			isCancelling: true,
+			didCancelOrderSucceed: false,
+		});
 
-        const parsedOrder = this.state.parsedOrder;
-        const orderHash = parsedOrder.signature.hash;
-        const takerAddress = this.props.userAddress;
+		const parsedOrder = this.state.parsedOrder;
+		const orderHash = parsedOrder.signature.hash;
+		const takerAddress = this.props.userAddress;
 
-        if (_.isUndefined(takerAddress)) {
-            this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
-            this.setState({
-                isFilling: false,
-            });
-            return;
-        }
-        let globalErrMsg = '';
+		if (_.isUndefined(takerAddress)) {
+			this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
+			this.setState({
+				isFilling: false,
+			});
+			return;
+		}
+		let globalErrMsg = '';
 
-        const takerTokenAmount = new BigNumber(parsedOrder.taker.amount);
+		const takerTokenAmount = new BigNumber(parsedOrder.taker.amount);
 
-        const signedOrder = this.props.blockchain.portalOrderToSignedOrder(
-            parsedOrder.maker.address,
-            parsedOrder.taker.address,
-            parsedOrder.maker.token.address,
-            parsedOrder.taker.token.address,
-            new BigNumber(parsedOrder.maker.amount),
-            takerTokenAmount,
-            new BigNumber(parsedOrder.maker.feeAmount),
-            new BigNumber(parsedOrder.taker.feeAmount),
-            new BigNumber(this.state.parsedOrder.expiration),
-            parsedOrder.feeRecipient,
-            parsedOrder.signature,
-            new BigNumber(parsedOrder.salt),
-        );
-        const unavailableTakerAmount = await this.props.blockchain.getUnavailableTakerAmountAsync(orderHash);
-        const availableTakerTokenAmount = takerTokenAmount.minus(unavailableTakerAmount);
-        try {
-            await this.props.blockchain.validateCancelOrderThrowIfInvalidAsync(signedOrder, availableTakerTokenAmount);
-        } catch (err) {
-            globalErrMsg = utils.zeroExErrToHumanReadableErrMsg(err.message, parsedOrder.taker.address);
-        }
-        if (!_.isEmpty(globalErrMsg)) {
-            this.setState({
-                isCancelling: false,
-                globalErrMsg,
-            });
-            return;
-        }
-        try {
-            await this.props.blockchain.cancelOrderAsync(signedOrder, availableTakerTokenAmount);
-            this.setState({
-                isCancelling: false,
-                didCancelOrderSucceed: true,
-                globalErrMsg: '',
-                unavailableTakerAmount: takerTokenAmount,
-            });
-            return;
-        } catch (err) {
-            this.setState({
-                isCancelling: false,
-            });
-            const errMsg = `${err}`;
-            if (_.includes(errMsg, 'User denied transaction signature')) {
-                return;
-            }
-            globalErrMsg = 'Failed to cancel order, please refresh and try again';
-            utils.consoleLog(`${err}`);
-            this.setState({
-                globalErrMsg,
-            });
-            await errorReporter.reportAsync(err);
-            return;
-        }
-    }
-    private _formatCurrencyAmount(amount: BigNumber, decimals: number): number {
-        const unitAmount = ZeroEx.toUnitAmount(amount, decimals);
-        const roundedUnitAmount = Math.round(unitAmount.toNumber() * 100000) / 100000;
-        return roundedUnitAmount;
-    }
-    private _onToggleTrackConfirmDialog(didConfirmTokenTracking: boolean) {
-        if (!didConfirmTokenTracking) {
-            this.setState({
-                orderJSON: '',
-                orderJSONErrMsg: '',
-                parsedOrder: undefined,
-            });
-        } else {
-            this.setState({
-                areAllInvolvedTokensTracked: true,
-            });
-        }
-        this.setState({
-            isConfirmingTokenTracking: !this.state.isConfirmingTokenTracking,
-            tokensToTrack: [],
-        });
-    }
+		const signedOrder = this.props.blockchain.portalOrderToSignedOrder(
+			parsedOrder.maker.address,
+			parsedOrder.taker.address,
+			parsedOrder.maker.token.address,
+			parsedOrder.taker.token.address,
+			new BigNumber(parsedOrder.maker.amount),
+			takerTokenAmount,
+			new BigNumber(parsedOrder.maker.feeAmount),
+			new BigNumber(parsedOrder.taker.feeAmount),
+			new BigNumber(this.state.parsedOrder.expiration),
+			parsedOrder.feeRecipient,
+			parsedOrder.signature,
+			new BigNumber(parsedOrder.salt),
+		);
+		const unavailableTakerAmount = await this.props.blockchain.getUnavailableTakerAmountAsync(orderHash);
+		const availableTakerTokenAmount = takerTokenAmount.minus(unavailableTakerAmount);
+		try {
+			await this.props.blockchain.validateCancelOrderThrowIfInvalidAsync(signedOrder, availableTakerTokenAmount);
+		} catch (err) {
+			globalErrMsg = utils.zeroExErrToHumanReadableErrMsg(err.message, parsedOrder.taker.address);
+		}
+		if (!_.isEmpty(globalErrMsg)) {
+			this.setState({
+				isCancelling: false,
+				globalErrMsg,
+			});
+			return;
+		}
+		try {
+			await this.props.blockchain.cancelOrderAsync(signedOrder, availableTakerTokenAmount);
+			this.setState({
+				isCancelling: false,
+				didCancelOrderSucceed: true,
+				globalErrMsg: '',
+				unavailableTakerAmount: takerTokenAmount,
+			});
+			return;
+		} catch (err) {
+			this.setState({
+				isCancelling: false,
+			});
+			const errMsg = `${err}`;
+			if (_.includes(errMsg, 'User denied transaction signature')) {
+				return;
+			}
+			globalErrMsg = 'Failed to cancel order, please refresh and try again';
+			utils.consoleLog(`${err}`);
+			this.setState({
+				globalErrMsg,
+			});
+			await errorReporter.reportAsync(err);
+			return;
+		}
+	}
+	private _formatCurrencyAmount(amount: BigNumber, decimals: number): number {
+		const unitAmount = ZeroEx.toUnitAmount(amount, decimals);
+		const roundedUnitAmount = Math.round(unitAmount.toNumber() * 100000) / 100000;
+		return roundedUnitAmount;
+	}
+	private _onToggleTrackConfirmDialog(didConfirmTokenTracking: boolean) {
+		if (!didConfirmTokenTracking) {
+			this.setState({
+				orderJSON: '',
+				orderJSONErrMsg: '',
+				parsedOrder: undefined,
+			});
+		} else {
+			this.setState({
+				areAllInvolvedTokensTracked: true,
+			});
+		}
+		this.setState({
+			isConfirmingTokenTracking: !this.state.isConfirmingTokenTracking,
+			tokensToTrack: [],
+		});
+	}
 } // tslint:disable:max-file-line-count
diff --git a/packages/website/ts/components/fill_order_json.tsx b/packages/website/ts/components/fill_order_json.tsx
index f8e43481a..3446b8a39 100644
--- a/packages/website/ts/components/fill_order_json.tsx
+++ b/packages/website/ts/components/fill_order_json.tsx
@@ -10,71 +10,71 @@ import { constants } from 'ts/utils/constants';
 import { utils } from 'ts/utils/utils';
 
 interface FillOrderJSONProps {
-    blockchain: Blockchain;
-    tokenByAddress: TokenByAddress;
-    networkId: number;
-    orderJSON: string;
-    onFillOrderJSONChanged: (event: any) => void;
+	blockchain: Blockchain;
+	tokenByAddress: TokenByAddress;
+	networkId: number;
+	orderJSON: string;
+	onFillOrderJSONChanged: (event: any) => void;
 }
 
 interface FillOrderJSONState {}
 
 export class FillOrderJSON extends React.Component<FillOrderJSONProps, FillOrderJSONState> {
-    public render() {
-        const tokenAddresses = _.keys(this.props.tokenByAddress);
-        const exchangeContract = this.props.blockchain.getExchangeContractAddressIfExists();
-        const hintSideToAssetToken = {
-            [Side.Deposit]: {
-                amount: new BigNumber(35),
-                address: tokenAddresses[0],
-            },
-            [Side.Receive]: {
-                amount: new BigNumber(89),
-                address: tokenAddresses[1],
-            },
-        };
-        const hintOrderExpiryTimestamp = utils.initialOrderExpiryUnixTimestampSec();
-        const hintSignatureData = {
-            hash: '0xf965a9978a0381ab58f5a2408ad967c...',
-            r: '0xf01103f759e2289a28593eaf22e5820032...',
-            s: '937862111edcba395f8a9e0cc1b2c5e12320...',
-            v: 27,
-        };
-        const hintSalt = ZeroEx.generatePseudoRandomSalt();
-        const feeRecipient = constants.NULL_ADDRESS;
-        const hintOrder = utils.generateOrder(
-            this.props.networkId,
-            exchangeContract,
-            hintSideToAssetToken,
-            hintOrderExpiryTimestamp,
-            '',
-            '',
-            constants.MAKER_FEE,
-            constants.TAKER_FEE,
-            feeRecipient,
-            hintSignatureData,
-            this.props.tokenByAddress,
-            hintSalt,
-        );
-        const hintOrderJSON = `${JSON.stringify(hintOrder, null, '\t').substring(0, 500)}...`;
-        return (
-            <div>
-                <Paper className="p1 overflow-hidden" style={{ height: 164 }}>
-                    <TextField
-                        id="orderJSON"
-                        hintStyle={{ bottom: 0, top: 0 }}
-                        fullWidth={true}
-                        value={this.props.orderJSON}
-                        onChange={this.props.onFillOrderJSONChanged.bind(this)}
-                        hintText={hintOrderJSON}
-                        multiLine={true}
-                        rows={6}
-                        rowsMax={6}
-                        underlineStyle={{ display: 'none' }}
-                        textareaStyle={{ marginTop: 0 }}
-                    />
-                </Paper>
-            </div>
-        );
-    }
+	public render() {
+		const tokenAddresses = _.keys(this.props.tokenByAddress);
+		const exchangeContract = this.props.blockchain.getExchangeContractAddressIfExists();
+		const hintSideToAssetToken = {
+			[Side.Deposit]: {
+				amount: new BigNumber(35),
+				address: tokenAddresses[0],
+			},
+			[Side.Receive]: {
+				amount: new BigNumber(89),
+				address: tokenAddresses[1],
+			},
+		};
+		const hintOrderExpiryTimestamp = utils.initialOrderExpiryUnixTimestampSec();
+		const hintSignatureData = {
+			hash: '0xf965a9978a0381ab58f5a2408ad967c...',
+			r: '0xf01103f759e2289a28593eaf22e5820032...',
+			s: '937862111edcba395f8a9e0cc1b2c5e12320...',
+			v: 27,
+		};
+		const hintSalt = ZeroEx.generatePseudoRandomSalt();
+		const feeRecipient = constants.NULL_ADDRESS;
+		const hintOrder = utils.generateOrder(
+			this.props.networkId,
+			exchangeContract,
+			hintSideToAssetToken,
+			hintOrderExpiryTimestamp,
+			'',
+			'',
+			constants.MAKER_FEE,
+			constants.TAKER_FEE,
+			feeRecipient,
+			hintSignatureData,
+			this.props.tokenByAddress,
+			hintSalt,
+		);
+		const hintOrderJSON = `${JSON.stringify(hintOrder, null, '\t').substring(0, 500)}...`;
+		return (
+			<div>
+				<Paper className="p1 overflow-hidden" style={{ height: 164 }}>
+					<TextField
+						id="orderJSON"
+						hintStyle={{ bottom: 0, top: 0 }}
+						fullWidth={true}
+						value={this.props.orderJSON}
+						onChange={this.props.onFillOrderJSONChanged.bind(this)}
+						hintText={hintOrderJSON}
+						multiLine={true}
+						rows={6}
+						rowsMax={6}
+						underlineStyle={{ display: 'none' }}
+						textareaStyle={{ marginTop: 0 }}
+					/>
+				</Paper>
+			</div>
+		);
+	}
 }
diff --git a/packages/website/ts/components/fill_warning_dialog.tsx b/packages/website/ts/components/fill_warning_dialog.tsx
index 165d21b34..40b04723d 100644
--- a/packages/website/ts/components/fill_warning_dialog.tsx
+++ b/packages/website/ts/components/fill_warning_dialog.tsx
@@ -4,42 +4,42 @@ import * as React from 'react';
 import { colors } from 'ts/utils/colors';
 
 interface FillWarningDialogProps {
-    isOpen: boolean;
-    onToggleDialog: (didUserCancel: boolean) => void;
+	isOpen: boolean;
+	onToggleDialog: (didUserCancel: boolean) => void;
 }
 
 export function FillWarningDialog(props: FillWarningDialogProps) {
-    const didCancel = true;
-    return (
-        <Dialog
-            title="Warning"
-            titleStyle={{ fontWeight: 100, color: colors.red500 }}
-            actions={[
-                <FlatButton
-                    key="fillWarningCancel"
-                    label="Cancel"
-                    onTouchTap={props.onToggleDialog.bind(this, didCancel)}
-                />,
-                <FlatButton
-                    key="fillWarningContinue"
-                    label="Fill Order"
-                    onTouchTap={props.onToggleDialog.bind(this, !didCancel)}
-                />,
-            ]}
-            open={props.isOpen}
-            onRequestClose={props.onToggleDialog.bind(this)}
-            autoScrollBodyContent={true}
-            modal={true}
-        >
-            <div className="pt2" style={{ color: colors.grey700 }}>
-                <div>
-                    At least one of the tokens in this order was not found in the token registry smart contract and may
-                    be counterfeit. It is your responsibility to verify the token addresses on Etherscan (
-                    <a href="https://0xproject.com/wiki#Verifying-Custom-Tokens" target="_blank">
-                        See this how-to guide
-                    </a>) before filling an order. <b>This action may result in the loss of funds</b>.
-                </div>
-            </div>
-        </Dialog>
-    );
+	const didCancel = true;
+	return (
+		<Dialog
+			title="Warning"
+			titleStyle={{ fontWeight: 100, color: colors.red500 }}
+			actions={[
+				<FlatButton
+					key="fillWarningCancel"
+					label="Cancel"
+					onTouchTap={props.onToggleDialog.bind(this, didCancel)}
+				/>,
+				<FlatButton
+					key="fillWarningContinue"
+					label="Fill Order"
+					onTouchTap={props.onToggleDialog.bind(this, !didCancel)}
+				/>,
+			]}
+			open={props.isOpen}
+			onRequestClose={props.onToggleDialog.bind(this)}
+			autoScrollBodyContent={true}
+			modal={true}
+		>
+			<div className="pt2" style={{ color: colors.grey700 }}>
+				<div>
+					At least one of the tokens in this order was not found in the token registry smart contract and may
+					be counterfeit. It is your responsibility to verify the token addresses on Etherscan (
+					<a href="https://0xproject.com/wiki#Verifying-Custom-Tokens" target="_blank">
+						See this how-to guide
+					</a>) before filling an order. <b>This action may result in the loss of funds</b>.
+				</div>
+			</div>
+		</Dialog>
+	);
 }
diff --git a/packages/website/ts/components/flash_messages/token_send_completed.tsx b/packages/website/ts/components/flash_messages/token_send_completed.tsx
index 18f371624..07fca1ddc 100644
--- a/packages/website/ts/components/flash_messages/token_send_completed.tsx
+++ b/packages/website/ts/components/flash_messages/token_send_completed.tsx
@@ -7,28 +7,28 @@ import { colors } from 'ts/utils/colors';
 import { utils } from 'ts/utils/utils';
 
 interface TokenSendCompletedProps {
-    etherScanLinkIfExists?: string;
-    token: Token;
-    toAddress: string;
-    amountInBaseUnits: BigNumber;
+	etherScanLinkIfExists?: string;
+	token: Token;
+	toAddress: string;
+	amountInBaseUnits: BigNumber;
 }
 
 interface TokenSendCompletedState {}
 
 export class TokenSendCompleted extends React.Component<TokenSendCompletedProps, TokenSendCompletedState> {
-    public render() {
-        const etherScanLink = !_.isUndefined(this.props.etherScanLinkIfExists) && (
-            <a style={{ color: colors.white }} href={`${this.props.etherScanLinkIfExists}`} target="_blank">
-                Verify on Etherscan
-            </a>
-        );
-        const amountInUnits = ZeroEx.toUnitAmount(this.props.amountInBaseUnits, this.props.token.decimals);
-        const truncatedAddress = utils.getAddressBeginAndEnd(this.props.toAddress);
-        return (
-            <div>
-                {`Sent ${amountInUnits} ${this.props.token.symbol} to ${truncatedAddress}: `}
-                {etherScanLink}
-            </div>
-        );
-    }
+	public render() {
+		const etherScanLink = !_.isUndefined(this.props.etherScanLinkIfExists) && (
+			<a style={{ color: colors.white }} href={`${this.props.etherScanLinkIfExists}`} target="_blank">
+				Verify on Etherscan
+			</a>
+		);
+		const amountInUnits = ZeroEx.toUnitAmount(this.props.amountInBaseUnits, this.props.token.decimals);
+		const truncatedAddress = utils.getAddressBeginAndEnd(this.props.toAddress);
+		return (
+			<div>
+				{`Sent ${amountInUnits} ${this.props.token.symbol} to ${truncatedAddress}: `}
+				{etherScanLink}
+			</div>
+		);
+	}
 }
diff --git a/packages/website/ts/components/flash_messages/transaction_submitted.tsx b/packages/website/ts/components/flash_messages/transaction_submitted.tsx
index 862e382dd..14464b923 100644
--- a/packages/website/ts/components/flash_messages/transaction_submitted.tsx
+++ b/packages/website/ts/components/flash_messages/transaction_submitted.tsx
@@ -3,24 +3,24 @@ import * as React from 'react';
 import { colors } from 'ts/utils/colors';
 
 interface TransactionSubmittedProps {
-    etherScanLinkIfExists?: string;
+	etherScanLinkIfExists?: string;
 }
 
 interface TransactionSubmittedState {}
 
 export class TransactionSubmitted extends React.Component<TransactionSubmittedProps, TransactionSubmittedState> {
-    public render() {
-        if (_.isUndefined(this.props.etherScanLinkIfExists)) {
-            return <div>Transaction submitted to the network</div>;
-        } else {
-            return (
-                <div>
-                    Transaction submitted to the network:{' '}
-                    <a style={{ color: colors.white }} href={`${this.props.etherScanLinkIfExists}`} target="_blank">
-                        Verify on Etherscan
-                    </a>
-                </div>
-            );
-        }
-    }
+	public render() {
+		if (_.isUndefined(this.props.etherScanLinkIfExists)) {
+			return <div>Transaction submitted to the network</div>;
+		} else {
+			return (
+				<div>
+					Transaction submitted to the network:{' '}
+					<a style={{ color: colors.white }} href={`${this.props.etherScanLinkIfExists}`} target="_blank">
+						Verify on Etherscan
+					</a>
+				</div>
+			);
+		}
+	}
 }
diff --git a/packages/website/ts/components/footer.tsx b/packages/website/ts/components/footer.tsx
index a0f1a0c96..3a342591c 100644
--- a/packages/website/ts/components/footer.tsx
+++ b/packages/website/ts/components/footer.tsx
@@ -6,106 +6,106 @@ import { colors } from 'ts/utils/colors';
 import { constants } from 'ts/utils/constants';
 
 interface MenuItemsBySection {
-    [sectionName: string]: FooterMenuItem[];
+	[sectionName: string]: FooterMenuItem[];
 }
 
 interface FooterMenuItem {
-    title: string;
-    path?: string;
-    isExternal?: boolean;
+	title: string;
+	path?: string;
+	isExternal?: boolean;
 }
 
 enum Sections {
-    Documentation = 'Documentation',
-    Community = 'Community',
-    Organization = 'Organization',
+	Documentation = 'Documentation',
+	Community = 'Community',
+	Organization = 'Organization',
 }
 
 const ICON_DIMENSION = 16;
 const menuItemsBySection: MenuItemsBySection = {
-    Documentation: [
-        {
-            title: '0x.js',
-            path: WebsitePaths.ZeroExJs,
-        },
-        {
-            title: '0x Smart Contracts',
-            path: WebsitePaths.SmartContracts,
-        },
-        {
-            title: '0x Connect',
-            path: WebsitePaths.Connect,
-        },
-        {
-            title: 'Whitepaper',
-            path: WebsitePaths.Whitepaper,
-            isExternal: true,
-        },
-        {
-            title: 'Wiki',
-            path: WebsitePaths.Wiki,
-        },
-        {
-            title: 'FAQ',
-            path: WebsitePaths.FAQ,
-        },
-    ],
-    Community: [
-        {
-            title: 'Rocket.chat',
-            isExternal: true,
-            path: constants.URL_ZEROEX_CHAT,
-        },
-        {
-            title: 'Blog',
-            isExternal: true,
-            path: constants.URL_BLOG,
-        },
-        {
-            title: 'Twitter',
-            isExternal: true,
-            path: constants.URL_TWITTER,
-        },
-        {
-            title: 'Reddit',
-            isExternal: true,
-            path: constants.URL_REDDIT,
-        },
-        {
-            title: 'Forum',
-            isExternal: true,
-            path: constants.URL_DISCOURSE_FORUM,
-        },
-    ],
-    Organization: [
-        {
-            title: 'About',
-            isExternal: false,
-            path: WebsitePaths.About,
-        },
-        {
-            title: 'Careers',
-            isExternal: true,
-            path: constants.URL_ANGELLIST,
-        },
-        {
-            title: 'Contact',
-            isExternal: true,
-            path: 'mailto:team@0xproject.com',
-        },
-    ],
+	Documentation: [
+		{
+			title: '0x.js',
+			path: WebsitePaths.ZeroExJs,
+		},
+		{
+			title: '0x Smart Contracts',
+			path: WebsitePaths.SmartContracts,
+		},
+		{
+			title: '0x Connect',
+			path: WebsitePaths.Connect,
+		},
+		{
+			title: 'Whitepaper',
+			path: WebsitePaths.Whitepaper,
+			isExternal: true,
+		},
+		{
+			title: 'Wiki',
+			path: WebsitePaths.Wiki,
+		},
+		{
+			title: 'FAQ',
+			path: WebsitePaths.FAQ,
+		},
+	],
+	Community: [
+		{
+			title: 'Rocket.chat',
+			isExternal: true,
+			path: constants.URL_ZEROEX_CHAT,
+		},
+		{
+			title: 'Blog',
+			isExternal: true,
+			path: constants.URL_BLOG,
+		},
+		{
+			title: 'Twitter',
+			isExternal: true,
+			path: constants.URL_TWITTER,
+		},
+		{
+			title: 'Reddit',
+			isExternal: true,
+			path: constants.URL_REDDIT,
+		},
+		{
+			title: 'Forum',
+			isExternal: true,
+			path: constants.URL_DISCOURSE_FORUM,
+		},
+	],
+	Organization: [
+		{
+			title: 'About',
+			isExternal: false,
+			path: WebsitePaths.About,
+		},
+		{
+			title: 'Careers',
+			isExternal: true,
+			path: constants.URL_ANGELLIST,
+		},
+		{
+			title: 'Contact',
+			isExternal: true,
+			path: 'mailto:team@0xproject.com',
+		},
+	],
 };
 const linkStyle = {
-    color: colors.white,
-    cursor: 'pointer',
+	color: colors.white,
+	cursor: 'pointer',
 };
 
 const titleToIcon: { [title: string]: string } = {
-    'Rocket.chat': 'rocketchat.png',
-    Blog: 'medium.png',
-    Twitter: 'twitter.png',
-    Reddit: 'reddit.png',
-    Forum: 'discourse.png',
+	'Rocket.chat': 'rocketchat.png',
+	Blog: 'medium.png',
+	Twitter: 'twitter.png',
+	Reddit: 'reddit.png',
+	Forum: 'discourse.png',
 };
 
 export interface FooterProps {}
@@ -113,100 +113,100 @@ export interface FooterProps {}
 interface FooterState {}
 
 export class Footer extends React.Component<FooterProps, FooterState> {
-    public render() {
-        return (
-            <div className="relative pb4 pt2" style={{ backgroundColor: colors.darkerGrey }}>
-                <div className="mx-auto max-width-4 md-px2 lg-px0 py4 clearfix" style={{ color: colors.white }}>
-                    <div className="col lg-col-4 md-col-4 col-12 left">
-                        <div className="sm-mx-auto" style={{ width: 148 }}>
-                            <div>
-                                <img src="/images/protocol_logo_white.png" height="30" />
-                            </div>
-                            <div
-                                style={{
-                                    fontSize: 11,
-                                    color: colors.grey,
-                                    paddingLeft: 37,
-                                    paddingTop: 2,
-                                }}
-                            >
-                                © ZeroEx, Intl.
-                            </div>
-                        </div>
-                    </div>
-                    <div className="col lg-col-8 md-col-8 col-12 lg-pl4 md-pl4">
-                        <div className="col lg-col-4 md-col-4 col-12">
-                            <div className="lg-right md-right sm-center">
-                                {this._renderHeader(Sections.Documentation)}
-                                {_.map(menuItemsBySection[Sections.Documentation], this._renderMenuItem.bind(this))}
-                            </div>
-                        </div>
-                        <div className="col lg-col-4 md-col-4 col-12 lg-pr2 md-pr2">
-                            <div className="lg-right md-right sm-center">
-                                {this._renderHeader(Sections.Community)}
-                                {_.map(menuItemsBySection[Sections.Community], this._renderMenuItem.bind(this))}
-                            </div>
-                        </div>
-                        <div className="col lg-col-4 md-col-4 col-12">
-                            <div className="lg-right md-right sm-center">
-                                {this._renderHeader(Sections.Organization)}
-                                {_.map(menuItemsBySection[Sections.Organization], this._renderMenuItem.bind(this))}
-                            </div>
-                        </div>
-                    </div>
-                </div>
-            </div>
-        );
-    }
-    private _renderIcon(fileName: string) {
-        return (
-            <div style={{ height: ICON_DIMENSION, width: ICON_DIMENSION }}>
-                <img src={`/images/social/${fileName}`} style={{ width: ICON_DIMENSION }} />
-            </div>
-        );
-    }
-    private _renderMenuItem(item: FooterMenuItem) {
-        const iconIfExists = titleToIcon[item.title];
-        return (
-            <div key={item.title} className="sm-center" style={{ fontSize: 13, paddingTop: 25 }}>
-                {item.isExternal ? (
-                    <a className="text-decoration-none" style={linkStyle} target="_blank" href={item.path}>
-                        {!_.isUndefined(iconIfExists) ? (
-                            <div className="sm-mx-auto" style={{ width: 65 }}>
-                                <div className="flex">
-                                    <div className="pr1">{this._renderIcon(iconIfExists)}</div>
-                                    <div>{item.title}</div>
-                                </div>
-                            </div>
-                        ) : (
-                            item.title
-                        )}
-                    </a>
-                ) : (
-                    <Link to={item.path} style={linkStyle} className="text-decoration-none">
-                        <div>
-                            {!_.isUndefined(iconIfExists) && (
-                                <div className="pr1">{this._renderIcon(iconIfExists)}</div>
-                            )}
-                            {item.title}
-                        </div>
-                    </Link>
-                )}
-            </div>
-        );
-    }
-    private _renderHeader(title: string) {
-        const headerStyle = {
-            textTransform: 'uppercase',
-            color: colors.grey400,
-            letterSpacing: 2,
-            fontFamily: 'Roboto Mono',
-            fontSize: 13,
-        };
-        return (
-            <div className="lg-pb2 md-pb2 sm-pt4" style={headerStyle}>
-                {title}
-            </div>
-        );
-    }
+	public render() {
+		return (
+			<div className="relative pb4 pt2" style={{ backgroundColor: colors.darkerGrey }}>
+				<div className="mx-auto max-width-4 md-px2 lg-px0 py4 clearfix" style={{ color: colors.white }}>
+					<div className="col lg-col-4 md-col-4 col-12 left">
+						<div className="sm-mx-auto" style={{ width: 148 }}>
+							<div>
+								<img src="/images/protocol_logo_white.png" height="30" />
+							</div>
+							<div
+								style={{
+									fontSize: 11,
+									color: colors.grey,
+									paddingLeft: 37,
+									paddingTop: 2,
+								}}
+							>
+								© ZeroEx, Intl.
+							</div>
+						</div>
+					</div>
+					<div className="col lg-col-8 md-col-8 col-12 lg-pl4 md-pl4">
+						<div className="col lg-col-4 md-col-4 col-12">
+							<div className="lg-right md-right sm-center">
+								{this._renderHeader(Sections.Documentation)}
+								{_.map(menuItemsBySection[Sections.Documentation], this._renderMenuItem.bind(this))}
+							</div>
+						</div>
+						<div className="col lg-col-4 md-col-4 col-12 lg-pr2 md-pr2">
+							<div className="lg-right md-right sm-center">
+								{this._renderHeader(Sections.Community)}
+								{_.map(menuItemsBySection[Sections.Community], this._renderMenuItem.bind(this))}
+							</div>
+						</div>
+						<div className="col lg-col-4 md-col-4 col-12">
+							<div className="lg-right md-right sm-center">
+								{this._renderHeader(Sections.Organization)}
+								{_.map(menuItemsBySection[Sections.Organization], this._renderMenuItem.bind(this))}
+							</div>
+						</div>
+					</div>
+				</div>
+			</div>
+		);
+	}
+	private _renderIcon(fileName: string) {
+		return (
+			<div style={{ height: ICON_DIMENSION, width: ICON_DIMENSION }}>
+				<img src={`/images/social/${fileName}`} style={{ width: ICON_DIMENSION }} />
+			</div>
+		);
+	}
+	private _renderMenuItem(item: FooterMenuItem) {
+		const iconIfExists = titleToIcon[item.title];
+		return (
+			<div key={item.title} className="sm-center" style={{ fontSize: 13, paddingTop: 25 }}>
+				{item.isExternal ? (
+					<a className="text-decoration-none" style={linkStyle} target="_blank" href={item.path}>
+						{!_.isUndefined(iconIfExists) ? (
+							<div className="sm-mx-auto" style={{ width: 65 }}>
+								<div className="flex">
+									<div className="pr1">{this._renderIcon(iconIfExists)}</div>
+									<div>{item.title}</div>
+								</div>
+							</div>
+						) : (
+							item.title
+						)}
+					</a>
+				) : (
+					<Link to={item.path} style={linkStyle} className="text-decoration-none">
+						<div>
+							{!_.isUndefined(iconIfExists) && (
+								<div className="pr1">{this._renderIcon(iconIfExists)}</div>
+							)}
+							{item.title}
+						</div>
+					</Link>
+				)}
+			</div>
+		);
+	}
+	private _renderHeader(title: string) {
+		const headerStyle = {
+			textTransform: 'uppercase',
+			color: colors.grey400,
+			letterSpacing: 2,
+			fontFamily: 'Roboto Mono',
+			fontSize: 13,
+		};
+		return (
+			<div className="lg-pb2 md-pb2 sm-pt4" style={headerStyle}>
+				{title}
+			</div>
+		);
+	}
 }
diff --git a/packages/website/ts/components/generate_order/asset_picker.tsx b/packages/website/ts/components/generate_order/asset_picker.tsx
index df7d87cfd..5eed2fabf 100644
--- a/packages/website/ts/components/generate_order/asset_picker.tsx
+++ b/packages/website/ts/components/generate_order/asset_picker.tsx
@@ -13,264 +13,264 @@ import { DialogConfigs, Token, TokenByAddress, TokenState, TokenVisibility } fro
 const TOKEN_ICON_DIMENSION = 100;
 const TILE_DIMENSION = 146;
 enum AssetViews {
-    ASSET_PICKER = 'ASSET_PICKER',
-    NEW_TOKEN_FORM = 'NEW_TOKEN_FORM',
-    CONFIRM_TRACK_TOKEN = 'CONFIRM_TRACK_TOKEN',
+	ASSET_PICKER = 'ASSET_PICKER',
+	NEW_TOKEN_FORM = 'NEW_TOKEN_FORM',
+	CONFIRM_TRACK_TOKEN = 'CONFIRM_TRACK_TOKEN',
 }
 
 interface AssetPickerProps {
-    userAddress: string;
-    blockchain: Blockchain;
-    dispatcher: Dispatcher;
-    networkId: number;
-    isOpen: boolean;
-    currentTokenAddress: string;
-    onTokenChosen: (tokenAddress: string) => void;
-    tokenByAddress: TokenByAddress;
-    tokenVisibility?: TokenVisibility;
+	userAddress: string;
+	blockchain: Blockchain;
+	dispatcher: Dispatcher;
+	networkId: number;
+	isOpen: boolean;
+	currentTokenAddress: string;
+	onTokenChosen: (tokenAddress: string) => void;
+	tokenByAddress: TokenByAddress;
+	tokenVisibility?: TokenVisibility;
 }
 
 interface AssetPickerState {
-    assetView: AssetViews;
-    hoveredAddress: string | undefined;
-    chosenTrackTokenAddress: string;
-    isAddingTokenToTracked: boolean;
+	assetView: AssetViews;
+	hoveredAddress: string | undefined;
+	chosenTrackTokenAddress: string;
+	isAddingTokenToTracked: boolean;
 }
 
 export class AssetPicker extends React.Component<AssetPickerProps, AssetPickerState> {
-    public static defaultProps: Partial<AssetPickerProps> = {
-        tokenVisibility: TokenVisibility.ALL,
-    };
-    private _dialogConfigsByAssetView: { [assetView: string]: DialogConfigs };
-    constructor(props: AssetPickerProps) {
-        super(props);
-        this.state = {
-            assetView: AssetViews.ASSET_PICKER,
-            hoveredAddress: undefined,
-            chosenTrackTokenAddress: undefined,
-            isAddingTokenToTracked: false,
-        };
-        this._dialogConfigsByAssetView = {
-            [AssetViews.ASSET_PICKER]: {
-                title: 'Select token',
-                isModal: false,
-                actions: [],
-            },
-            [AssetViews.NEW_TOKEN_FORM]: {
-                title: 'Add an ERC20 token',
-                isModal: false,
-                actions: [],
-            },
-            [AssetViews.CONFIRM_TRACK_TOKEN]: {
-                title: 'Tracking confirmation',
-                isModal: true,
-                actions: [
-                    <FlatButton
-                        key="noTracking"
-                        label="No"
-                        onTouchTap={this._onTrackConfirmationRespondedAsync.bind(this, false)}
-                    />,
-                    <FlatButton
-                        key="yesTrack"
-                        label="Yes"
-                        onTouchTap={this._onTrackConfirmationRespondedAsync.bind(this, true)}
-                    />,
-                ],
-            },
-        };
-    }
-    public render() {
-        const dialogConfigs: DialogConfigs = this._dialogConfigsByAssetView[this.state.assetView];
-        return (
-            <Dialog
-                title={dialogConfigs.title}
-                titleStyle={{ fontWeight: 100 }}
-                modal={dialogConfigs.isModal}
-                open={this.props.isOpen}
-                actions={dialogConfigs.actions}
-                onRequestClose={this._onCloseDialog.bind(this)}
-            >
-                {this.state.assetView === AssetViews.ASSET_PICKER && this._renderAssetPicker()}
-                {this.state.assetView === AssetViews.NEW_TOKEN_FORM && (
-                    <NewTokenForm
-                        blockchain={this.props.blockchain}
-                        onNewTokenSubmitted={this._onNewTokenSubmitted.bind(this)}
-                        tokenByAddress={this.props.tokenByAddress}
-                    />
-                )}
-                {this.state.assetView === AssetViews.CONFIRM_TRACK_TOKEN && this._renderConfirmTrackToken()}
-            </Dialog>
-        );
-    }
-    private _renderConfirmTrackToken() {
-        const token = this.props.tokenByAddress[this.state.chosenTrackTokenAddress];
-        return (
-            <TrackTokenConfirmation
-                tokens={[token]}
-                tokenByAddress={this.props.tokenByAddress}
-                networkId={this.props.networkId}
-                isAddingTokenToTracked={this.state.isAddingTokenToTracked}
-            />
-        );
-    }
-    private _renderAssetPicker() {
-        return (
-            <div
-                className="clearfix flex flex-wrap"
-                style={{
-                    overflowY: 'auto',
-                    maxWidth: 720,
-                    maxHeight: 356,
-                    marginBottom: 10,
-                }}
-            >
-                {this._renderGridTiles()}
-            </div>
-        );
-    }
-    private _renderGridTiles() {
-        let isHovered;
-        let tileStyles;
-        const gridTiles = _.map(this.props.tokenByAddress, (token: Token, address: string) => {
-            if (
-                (this.props.tokenVisibility === TokenVisibility.TRACKED && !token.isTracked) ||
-                (this.props.tokenVisibility === TokenVisibility.UNTRACKED && token.isTracked)
-            ) {
-                return null; // Skip
-            }
-            isHovered = this.state.hoveredAddress === address;
-            tileStyles = {
-                cursor: 'pointer',
-                opacity: isHovered ? 0.6 : 1,
-            };
-            return (
-                <div
-                    key={address}
-                    style={{
-                        width: TILE_DIMENSION,
-                        height: TILE_DIMENSION,
-                        ...tileStyles,
-                    }}
-                    className="p2 mx-auto"
-                    onClick={this._onChooseToken.bind(this, address)}
-                    onMouseEnter={this._onToggleHover.bind(this, address, true)}
-                    onMouseLeave={this._onToggleHover.bind(this, address, false)}
-                >
-                    <div className="p1 center">
-                        <TokenIcon token={token} diameter={TOKEN_ICON_DIMENSION} />
-                    </div>
-                    <div className="center">{token.name}</div>
-                </div>
-            );
-        });
-        const otherTokenKey = 'otherToken';
-        isHovered = this.state.hoveredAddress === otherTokenKey;
-        tileStyles = {
-            cursor: 'pointer',
-            opacity: isHovered ? 0.6 : 1,
-        };
-        if (this.props.tokenVisibility !== TokenVisibility.TRACKED) {
-            gridTiles.push(
-                <div
-                    key={otherTokenKey}
-                    style={{
-                        width: TILE_DIMENSION,
-                        height: TILE_DIMENSION,
-                        ...tileStyles,
-                    }}
-                    className="p2 mx-auto"
-                    onClick={this._onCustomAssetChosen.bind(this)}
-                    onMouseEnter={this._onToggleHover.bind(this, otherTokenKey, true)}
-                    onMouseLeave={this._onToggleHover.bind(this, otherTokenKey, false)}
-                >
-                    <div className="p1 center">
-                        <i
-                            style={{ fontSize: 105, paddingLeft: 1, paddingRight: 1 }}
-                            className="zmdi zmdi-plus-circle"
-                        />
-                    </div>
-                    <div className="center">Other ERC20 Token</div>
-                </div>,
-            );
-        }
-        return gridTiles;
-    }
-    private _onToggleHover(address: string, isHovered: boolean) {
-        const hoveredAddress = isHovered ? address : undefined;
-        this.setState({
-            hoveredAddress,
-        });
-    }
-    private _onCloseDialog() {
-        this.setState({
-            assetView: AssetViews.ASSET_PICKER,
-        });
-        this.props.onTokenChosen(this.props.currentTokenAddress);
-    }
-    private _onChooseToken(tokenAddress: string) {
-        const token = this.props.tokenByAddress[tokenAddress];
-        if (token.isTracked) {
-            this.props.onTokenChosen(tokenAddress);
-        } else {
-            this.setState({
-                assetView: AssetViews.CONFIRM_TRACK_TOKEN,
-                chosenTrackTokenAddress: tokenAddress,
-            });
-        }
-    }
-    private _onCustomAssetChosen() {
-        this.setState({
-            assetView: AssetViews.NEW_TOKEN_FORM,
-        });
-    }
-    private _onNewTokenSubmitted(newToken: Token, newTokenState: TokenState) {
-        this.props.dispatcher.updateTokenStateByAddress({
-            [newToken.address]: newTokenState,
-        });
-        trackedTokenStorage.addTrackedTokenToUser(this.props.userAddress, this.props.networkId, newToken);
-        this.props.dispatcher.addTokenToTokenByAddress(newToken);
-        this.setState({
-            assetView: AssetViews.ASSET_PICKER,
-        });
-        this.props.onTokenChosen(newToken.address);
-    }
-    private async _onTrackConfirmationRespondedAsync(didUserAcceptTracking: boolean) {
-        if (!didUserAcceptTracking) {
-            this.setState({
-                isAddingTokenToTracked: false,
-                assetView: AssetViews.ASSET_PICKER,
-                chosenTrackTokenAddress: undefined,
-            });
-            this._onCloseDialog();
-            return;
-        }
-        this.setState({
-            isAddingTokenToTracked: true,
-        });
-        const tokenAddress = this.state.chosenTrackTokenAddress;
-        const token = this.props.tokenByAddress[tokenAddress];
-        const newTokenEntry = {
-            ...token,
-        };
+	public static defaultProps: Partial<AssetPickerProps> = {
+		tokenVisibility: TokenVisibility.ALL,
+	};
+	private _dialogConfigsByAssetView: { [assetView: string]: DialogConfigs };
+	constructor(props: AssetPickerProps) {
+		super(props);
+		this.state = {
+			assetView: AssetViews.ASSET_PICKER,
+			hoveredAddress: undefined,
+			chosenTrackTokenAddress: undefined,
+			isAddingTokenToTracked: false,
+		};
+		this._dialogConfigsByAssetView = {
+			[AssetViews.ASSET_PICKER]: {
+				title: 'Select token',
+				isModal: false,
+				actions: [],
+			},
+			[AssetViews.NEW_TOKEN_FORM]: {
+				title: 'Add an ERC20 token',
+				isModal: false,
+				actions: [],
+			},
+			[AssetViews.CONFIRM_TRACK_TOKEN]: {
+				title: 'Tracking confirmation',
+				isModal: true,
+				actions: [
+					<FlatButton
+						key="noTracking"
+						label="No"
+						onTouchTap={this._onTrackConfirmationRespondedAsync.bind(this, false)}
+					/>,
+					<FlatButton
+						key="yesTrack"
+						label="Yes"
+						onTouchTap={this._onTrackConfirmationRespondedAsync.bind(this, true)}
+					/>,
+				],
+			},
+		};
+	}
+	public render() {
+		const dialogConfigs: DialogConfigs = this._dialogConfigsByAssetView[this.state.assetView];
+		return (
+			<Dialog
+				title={dialogConfigs.title}
+				titleStyle={{ fontWeight: 100 }}
+				modal={dialogConfigs.isModal}
+				open={this.props.isOpen}
+				actions={dialogConfigs.actions}
+				onRequestClose={this._onCloseDialog.bind(this)}
+			>
+				{this.state.assetView === AssetViews.ASSET_PICKER && this._renderAssetPicker()}
+				{this.state.assetView === AssetViews.NEW_TOKEN_FORM && (
+					<NewTokenForm
+						blockchain={this.props.blockchain}
+						onNewTokenSubmitted={this._onNewTokenSubmitted.bind(this)}
+						tokenByAddress={this.props.tokenByAddress}
+					/>
+				)}
+				{this.state.assetView === AssetViews.CONFIRM_TRACK_TOKEN && this._renderConfirmTrackToken()}
+			</Dialog>
+		);
+	}
+	private _renderConfirmTrackToken() {
+		const token = this.props.tokenByAddress[this.state.chosenTrackTokenAddress];
+		return (
+			<TrackTokenConfirmation
+				tokens={[token]}
+				tokenByAddress={this.props.tokenByAddress}
+				networkId={this.props.networkId}
+				isAddingTokenToTracked={this.state.isAddingTokenToTracked}
+			/>
+		);
+	}
+	private _renderAssetPicker() {
+		return (
+			<div
+				className="clearfix flex flex-wrap"
+				style={{
+					overflowY: 'auto',
+					maxWidth: 720,
+					maxHeight: 356,
+					marginBottom: 10,
+				}}
+			>
+				{this._renderGridTiles()}
+			</div>
+		);
+	}
+	private _renderGridTiles() {
+		let isHovered;
+		let tileStyles;
+		const gridTiles = _.map(this.props.tokenByAddress, (token: Token, address: string) => {
+			if (
+				(this.props.tokenVisibility === TokenVisibility.TRACKED && !token.isTracked) ||
+				(this.props.tokenVisibility === TokenVisibility.UNTRACKED && token.isTracked)
+			) {
+				return null; // Skip
+			}
+			isHovered = this.state.hoveredAddress === address;
+			tileStyles = {
+				cursor: 'pointer',
+				opacity: isHovered ? 0.6 : 1,
+			};
+			return (
+				<div
+					key={address}
+					style={{
+						width: TILE_DIMENSION,
+						height: TILE_DIMENSION,
+						...tileStyles,
+					}}
+					className="p2 mx-auto"
+					onClick={this._onChooseToken.bind(this, address)}
+					onMouseEnter={this._onToggleHover.bind(this, address, true)}
+					onMouseLeave={this._onToggleHover.bind(this, address, false)}
+				>
+					<div className="p1 center">
+						<TokenIcon token={token} diameter={TOKEN_ICON_DIMENSION} />
+					</div>
+					<div className="center">{token.name}</div>
+				</div>
+			);
+		});
+		const otherTokenKey = 'otherToken';
+		isHovered = this.state.hoveredAddress === otherTokenKey;
+		tileStyles = {
+			cursor: 'pointer',
+			opacity: isHovered ? 0.6 : 1,
+		};
+		if (this.props.tokenVisibility !== TokenVisibility.TRACKED) {
+			gridTiles.push(
+				<div
+					key={otherTokenKey}
+					style={{
+						width: TILE_DIMENSION,
+						height: TILE_DIMENSION,
+						...tileStyles,
+					}}
+					className="p2 mx-auto"
+					onClick={this._onCustomAssetChosen.bind(this)}
+					onMouseEnter={this._onToggleHover.bind(this, otherTokenKey, true)}
+					onMouseLeave={this._onToggleHover.bind(this, otherTokenKey, false)}
+				>
+					<div className="p1 center">
+						<i
+							style={{ fontSize: 105, paddingLeft: 1, paddingRight: 1 }}
+							className="zmdi zmdi-plus-circle"
+						/>
+					</div>
+					<div className="center">Other ERC20 Token</div>
+				</div>,
+			);
+		}
+		return gridTiles;
+	}
+	private _onToggleHover(address: string, isHovered: boolean) {
+		const hoveredAddress = isHovered ? address : undefined;
+		this.setState({
+			hoveredAddress,
+		});
+	}
+	private _onCloseDialog() {
+		this.setState({
+			assetView: AssetViews.ASSET_PICKER,
+		});
+		this.props.onTokenChosen(this.props.currentTokenAddress);
+	}
+	private _onChooseToken(tokenAddress: string) {
+		const token = this.props.tokenByAddress[tokenAddress];
+		if (token.isTracked) {
+			this.props.onTokenChosen(tokenAddress);
+		} else {
+			this.setState({
+				assetView: AssetViews.CONFIRM_TRACK_TOKEN,
+				chosenTrackTokenAddress: tokenAddress,
+			});
+		}
+	}
+	private _onCustomAssetChosen() {
+		this.setState({
+			assetView: AssetViews.NEW_TOKEN_FORM,
+		});
+	}
+	private _onNewTokenSubmitted(newToken: Token, newTokenState: TokenState) {
+		this.props.dispatcher.updateTokenStateByAddress({
+			[newToken.address]: newTokenState,
+		});
+		trackedTokenStorage.addTrackedTokenToUser(this.props.userAddress, this.props.networkId, newToken);
+		this.props.dispatcher.addTokenToTokenByAddress(newToken);
+		this.setState({
+			assetView: AssetViews.ASSET_PICKER,
+		});
+		this.props.onTokenChosen(newToken.address);
+	}
+	private async _onTrackConfirmationRespondedAsync(didUserAcceptTracking: boolean) {
+		if (!didUserAcceptTracking) {
+			this.setState({
+				isAddingTokenToTracked: false,
+				assetView: AssetViews.ASSET_PICKER,
+				chosenTrackTokenAddress: undefined,
+			});
+			this._onCloseDialog();
+			return;
+		}
+		this.setState({
+			isAddingTokenToTracked: true,
+		});
+		const tokenAddress = this.state.chosenTrackTokenAddress;
+		const token = this.props.tokenByAddress[tokenAddress];
+		const newTokenEntry = {
+			...token,
+		};
 
-        newTokenEntry.isTracked = true;
-        trackedTokenStorage.addTrackedTokenToUser(this.props.userAddress, this.props.networkId, newTokenEntry);
+		newTokenEntry.isTracked = true;
+		trackedTokenStorage.addTrackedTokenToUser(this.props.userAddress, this.props.networkId, newTokenEntry);
 
-        const [balance, allowance] = await this.props.blockchain.getCurrentUserTokenBalanceAndAllowanceAsync(
-            token.address,
-        );
-        this.props.dispatcher.updateTokenStateByAddress({
-            [token.address]: {
-                balance,
-                allowance,
-            },
-        });
-        this.props.dispatcher.updateTokenByAddress([newTokenEntry]);
-        this.setState({
-            isAddingTokenToTracked: false,
-            assetView: AssetViews.ASSET_PICKER,
-            chosenTrackTokenAddress: undefined,
-        });
-        this.props.onTokenChosen(tokenAddress);
-    }
+		const [balance, allowance] = await this.props.blockchain.getCurrentUserTokenBalanceAndAllowanceAsync(
+			token.address,
+		);
+		this.props.dispatcher.updateTokenStateByAddress({
+			[token.address]: {
+				balance,
+				allowance,
+			},
+		});
+		this.props.dispatcher.updateTokenByAddress([newTokenEntry]);
+		this.setState({
+			isAddingTokenToTracked: false,
+			assetView: AssetViews.ASSET_PICKER,
+			chosenTrackTokenAddress: undefined,
+		});
+		this.props.onTokenChosen(tokenAddress);
+	}
 }
diff --git a/packages/website/ts/components/generate_order/generate_order_form.tsx b/packages/website/ts/components/generate_order/generate_order_form.tsx
index 3ae0d48a7..b10b2d609 100644
--- a/packages/website/ts/components/generate_order/generate_order_form.tsx
+++ b/packages/website/ts/components/generate_order/generate_order_form.tsx
@@ -19,335 +19,335 @@ import { Dispatcher } from 'ts/redux/dispatcher';
 import { orderSchema } from 'ts/schemas/order_schema';
 import { SchemaValidator } from 'ts/schemas/validator';
 import {
-    AlertTypes,
-    BlockchainErrs,
-    HashData,
-    Side,
-    SideToAssetToken,
-    SignatureData,
-    Token,
-    TokenByAddress,
-    TokenStateByAddress,
+	AlertTypes,
+	BlockchainErrs,
+	HashData,
+	Side,
+	SideToAssetToken,
+	SignatureData,
+	Token,
+	TokenByAddress,
+	TokenStateByAddress,
 } from 'ts/types';
 import { colors } from 'ts/utils/colors';
 import { errorReporter } from 'ts/utils/error_reporter';
 import { utils } from 'ts/utils/utils';
 
 enum SigningState {
-    UNSIGNED,
-    SIGNING,
-    SIGNED,
+	UNSIGNED,
+	SIGNING,
+	SIGNED,
 }
 
 interface GenerateOrderFormProps {
-    blockchain: Blockchain;
-    blockchainErr: BlockchainErrs;
-    blockchainIsLoaded: boolean;
-    dispatcher: Dispatcher;
-    hashData: HashData;
-    orderExpiryTimestamp: BigNumber;
-    networkId: number;
-    userAddress: string;
-    orderSignatureData: SignatureData;
-    orderTakerAddress: string;
-    orderSalt: BigNumber;
-    sideToAssetToken: SideToAssetToken;
-    tokenByAddress: TokenByAddress;
-    tokenStateByAddress: TokenStateByAddress;
+	blockchain: Blockchain;
+	blockchainErr: BlockchainErrs;
+	blockchainIsLoaded: boolean;
+	dispatcher: Dispatcher;
+	hashData: HashData;
+	orderExpiryTimestamp: BigNumber;
+	networkId: number;
+	userAddress: string;
+	orderSignatureData: SignatureData;
+	orderTakerAddress: string;
+	orderSalt: BigNumber;
+	sideToAssetToken: SideToAssetToken;
+	tokenByAddress: TokenByAddress;
+	tokenStateByAddress: TokenStateByAddress;
 }
 
 interface GenerateOrderFormState {
-    globalErrMsg: string;
-    shouldShowIncompleteErrs: boolean;
-    signingState: SigningState;
+	globalErrMsg: string;
+	shouldShowIncompleteErrs: boolean;
+	signingState: SigningState;
 }
 
 export class GenerateOrderForm extends React.Component<GenerateOrderFormProps, GenerateOrderFormState> {
-    private _validator: SchemaValidator;
-    constructor(props: GenerateOrderFormProps) {
-        super(props);
-        this.state = {
-            globalErrMsg: '',
-            shouldShowIncompleteErrs: false,
-            signingState: SigningState.UNSIGNED,
-        };
-        this._validator = new SchemaValidator();
-    }
-    public componentDidMount() {
-        window.scrollTo(0, 0);
-    }
-    public render() {
-        const dispatcher = this.props.dispatcher;
-        const depositTokenAddress = this.props.sideToAssetToken[Side.Deposit].address;
-        const depositToken = this.props.tokenByAddress[depositTokenAddress];
-        const depositTokenState = this.props.tokenStateByAddress[depositTokenAddress];
-        const receiveTokenAddress = this.props.sideToAssetToken[Side.Receive].address;
-        const receiveToken = this.props.tokenByAddress[receiveTokenAddress];
-        const receiveTokenState = this.props.tokenStateByAddress[receiveTokenAddress];
-        const takerExplanation =
-            'If a taker is specified, only they are<br> \
+	private _validator: SchemaValidator;
+	constructor(props: GenerateOrderFormProps) {
+		super(props);
+		this.state = {
+			globalErrMsg: '',
+			shouldShowIncompleteErrs: false,
+			signingState: SigningState.UNSIGNED,
+		};
+		this._validator = new SchemaValidator();
+	}
+	public componentDidMount() {
+		window.scrollTo(0, 0);
+	}
+	public render() {
+		const dispatcher = this.props.dispatcher;
+		const depositTokenAddress = this.props.sideToAssetToken[Side.Deposit].address;
+		const depositToken = this.props.tokenByAddress[depositTokenAddress];
+		const depositTokenState = this.props.tokenStateByAddress[depositTokenAddress];
+		const receiveTokenAddress = this.props.sideToAssetToken[Side.Receive].address;
+		const receiveToken = this.props.tokenByAddress[receiveTokenAddress];
+		const receiveTokenState = this.props.tokenStateByAddress[receiveTokenAddress];
+		const takerExplanation =
+			'If a taker is specified, only they are<br> \
                                   allowed to fill this order. If no taker is<br> \
                                   specified, anyone is able to fill it.';
-        const exchangeContractIfExists = this.props.blockchain.getExchangeContractAddressIfExists();
-        return (
-            <div className="clearfix mb2 lg-px4 md-px4 sm-px2">
-                <h3>Generate an order</h3>
-                <Divider />
-                <div className="mx-auto" style={{ maxWidth: 580 }}>
-                    <div className="pt3">
-                        <div className="mx-auto clearfix">
-                            <div className="lg-col md-col lg-col-5 md-col-5 sm-col sm-col-5 sm-pb2">
-                                <TokenInput
-                                    userAddress={this.props.userAddress}
-                                    blockchain={this.props.blockchain}
-                                    blockchainErr={this.props.blockchainErr}
-                                    dispatcher={this.props.dispatcher}
-                                    label="Selling"
-                                    side={Side.Deposit}
-                                    networkId={this.props.networkId}
-                                    assetToken={this.props.sideToAssetToken[Side.Deposit]}
-                                    updateChosenAssetToken={dispatcher.updateChosenAssetToken.bind(dispatcher)}
-                                    tokenByAddress={this.props.tokenByAddress}
-                                />
-                                <TokenAmountInput
-                                    label="Sell amount"
-                                    token={depositToken}
-                                    tokenState={depositTokenState}
-                                    amount={this.props.sideToAssetToken[Side.Deposit].amount}
-                                    onChange={this._onTokenAmountChange.bind(this, depositToken, Side.Deposit)}
-                                    shouldShowIncompleteErrs={this.state.shouldShowIncompleteErrs}
-                                    shouldCheckBalance={true}
-                                    shouldCheckAllowance={true}
-                                />
-                            </div>
-                            <div className="lg-col md-col lg-col-2 md-col-2 sm-col sm-col-2 xs-hide">
-                                <div className="p1">
-                                    <SwapIcon swapTokensFn={dispatcher.swapAssetTokenSymbols.bind(dispatcher)} />
-                                </div>
-                            </div>
-                            <div className="lg-col md-col lg-col-5 md-col-5 sm-col sm-col-5 sm-pb2">
-                                <TokenInput
-                                    userAddress={this.props.userAddress}
-                                    blockchain={this.props.blockchain}
-                                    blockchainErr={this.props.blockchainErr}
-                                    dispatcher={this.props.dispatcher}
-                                    label="Buying"
-                                    side={Side.Receive}
-                                    networkId={this.props.networkId}
-                                    assetToken={this.props.sideToAssetToken[Side.Receive]}
-                                    updateChosenAssetToken={dispatcher.updateChosenAssetToken.bind(dispatcher)}
-                                    tokenByAddress={this.props.tokenByAddress}
-                                />
-                                <TokenAmountInput
-                                    label="Receive amount"
-                                    token={receiveToken}
-                                    tokenState={receiveTokenState}
-                                    amount={this.props.sideToAssetToken[Side.Receive].amount}
-                                    onChange={this._onTokenAmountChange.bind(this, receiveToken, Side.Receive)}
-                                    shouldShowIncompleteErrs={this.state.shouldShowIncompleteErrs}
-                                    shouldCheckBalance={false}
-                                    shouldCheckAllowance={false}
-                                />
-                            </div>
-                        </div>
-                    </div>
-                    <div className="pt1 sm-pb2 lg-px4 md-px4">
-                        <div className="lg-px3 md-px3">
-                            <div style={{ fontSize: 12, color: colors.grey }}>Expiration</div>
-                            <ExpirationInput
-                                orderExpiryTimestamp={this.props.orderExpiryTimestamp}
-                                updateOrderExpiry={dispatcher.updateOrderExpiry.bind(dispatcher)}
-                            />
-                        </div>
-                    </div>
-                    <div className="pt1 flex mx-auto">
-                        <IdenticonAddressInput
-                            label="Taker"
-                            initialAddress={this.props.orderTakerAddress}
-                            updateOrderAddress={this._updateOrderAddress.bind(this)}
-                        />
-                        <div className="pt3">
-                            <div className="pl1">
-                                <HelpTooltip explanation={takerExplanation} />
-                            </div>
-                        </div>
-                    </div>
-                    <div>
-                        <HashInput
-                            blockchain={this.props.blockchain}
-                            blockchainIsLoaded={this.props.blockchainIsLoaded}
-                            hashData={this.props.hashData}
-                            label="Order Hash"
-                        />
-                    </div>
-                    <div className="pt2">
-                        <div className="center">
-                            <LifeCycleRaisedButton
-                                labelReady="Sign hash"
-                                labelLoading="Signing..."
-                                labelComplete="Hash signed!"
-                                onClickAsyncFn={this._onSignClickedAsync.bind(this)}
-                            />
-                        </div>
-                        {this.state.globalErrMsg !== '' && (
-                            <Alert type={AlertTypes.ERROR} message={this.state.globalErrMsg} />
-                        )}
-                    </div>
-                </div>
-                <Dialog
-                    title="Order JSON"
-                    titleStyle={{ fontWeight: 100 }}
-                    modal={false}
-                    open={this.state.signingState === SigningState.SIGNED}
-                    onRequestClose={this._onCloseOrderJSONDialog.bind(this)}
-                >
-                    <OrderJSON
-                        exchangeContractIfExists={exchangeContractIfExists}
-                        orderExpiryTimestamp={this.props.orderExpiryTimestamp}
-                        orderSignatureData={this.props.orderSignatureData}
-                        orderTakerAddress={this.props.orderTakerAddress}
-                        orderMakerAddress={this.props.userAddress}
-                        orderSalt={this.props.orderSalt}
-                        orderMakerFee={this.props.hashData.makerFee}
-                        orderTakerFee={this.props.hashData.takerFee}
-                        orderFeeRecipient={this.props.hashData.feeRecipientAddress}
-                        networkId={this.props.networkId}
-                        sideToAssetToken={this.props.sideToAssetToken}
-                        tokenByAddress={this.props.tokenByAddress}
-                    />
-                </Dialog>
-            </div>
-        );
-    }
-    private _onTokenAmountChange(token: Token, side: Side, isValid: boolean, amount?: BigNumber) {
-        this.props.dispatcher.updateChosenAssetToken(side, {
-            address: token.address,
-            amount,
-        });
-    }
-    private _onCloseOrderJSONDialog() {
-        // Upon closing the order JSON dialog, we update the orderSalt stored in the Redux store
-        // with a new value so that if a user signs the identical order again, the newly signed
-        // orderHash will not collide with the previously generated orderHash.
-        this.props.dispatcher.updateOrderSalt(ZeroEx.generatePseudoRandomSalt());
-        this.setState({
-            signingState: SigningState.UNSIGNED,
-        });
-    }
-    private async _onSignClickedAsync(): Promise<boolean> {
-        if (this.props.blockchainErr !== BlockchainErrs.NoError) {
-            this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
-            return false;
-        }
+		const exchangeContractIfExists = this.props.blockchain.getExchangeContractAddressIfExists();
+		return (
+			<div className="clearfix mb2 lg-px4 md-px4 sm-px2">
+				<h3>Generate an order</h3>
+				<Divider />
+				<div className="mx-auto" style={{ maxWidth: 580 }}>
+					<div className="pt3">
+						<div className="mx-auto clearfix">
+							<div className="lg-col md-col lg-col-5 md-col-5 sm-col sm-col-5 sm-pb2">
+								<TokenInput
+									userAddress={this.props.userAddress}
+									blockchain={this.props.blockchain}
+									blockchainErr={this.props.blockchainErr}
+									dispatcher={this.props.dispatcher}
+									label="Selling"
+									side={Side.Deposit}
+									networkId={this.props.networkId}
+									assetToken={this.props.sideToAssetToken[Side.Deposit]}
+									updateChosenAssetToken={dispatcher.updateChosenAssetToken.bind(dispatcher)}
+									tokenByAddress={this.props.tokenByAddress}
+								/>
+								<TokenAmountInput
+									label="Sell amount"
+									token={depositToken}
+									tokenState={depositTokenState}
+									amount={this.props.sideToAssetToken[Side.Deposit].amount}
+									onChange={this._onTokenAmountChange.bind(this, depositToken, Side.Deposit)}
+									shouldShowIncompleteErrs={this.state.shouldShowIncompleteErrs}
+									shouldCheckBalance={true}
+									shouldCheckAllowance={true}
+								/>
+							</div>
+							<div className="lg-col md-col lg-col-2 md-col-2 sm-col sm-col-2 xs-hide">
+								<div className="p1">
+									<SwapIcon swapTokensFn={dispatcher.swapAssetTokenSymbols.bind(dispatcher)} />
+								</div>
+							</div>
+							<div className="lg-col md-col lg-col-5 md-col-5 sm-col sm-col-5 sm-pb2">
+								<TokenInput
+									userAddress={this.props.userAddress}
+									blockchain={this.props.blockchain}
+									blockchainErr={this.props.blockchainErr}
+									dispatcher={this.props.dispatcher}
+									label="Buying"
+									side={Side.Receive}
+									networkId={this.props.networkId}
+									assetToken={this.props.sideToAssetToken[Side.Receive]}
+									updateChosenAssetToken={dispatcher.updateChosenAssetToken.bind(dispatcher)}
+									tokenByAddress={this.props.tokenByAddress}
+								/>
+								<TokenAmountInput
+									label="Receive amount"
+									token={receiveToken}
+									tokenState={receiveTokenState}
+									amount={this.props.sideToAssetToken[Side.Receive].amount}
+									onChange={this._onTokenAmountChange.bind(this, receiveToken, Side.Receive)}
+									shouldShowIncompleteErrs={this.state.shouldShowIncompleteErrs}
+									shouldCheckBalance={false}
+									shouldCheckAllowance={false}
+								/>
+							</div>
+						</div>
+					</div>
+					<div className="pt1 sm-pb2 lg-px4 md-px4">
+						<div className="lg-px3 md-px3">
+							<div style={{ fontSize: 12, color: colors.grey }}>Expiration</div>
+							<ExpirationInput
+								orderExpiryTimestamp={this.props.orderExpiryTimestamp}
+								updateOrderExpiry={dispatcher.updateOrderExpiry.bind(dispatcher)}
+							/>
+						</div>
+					</div>
+					<div className="pt1 flex mx-auto">
+						<IdenticonAddressInput
+							label="Taker"
+							initialAddress={this.props.orderTakerAddress}
+							updateOrderAddress={this._updateOrderAddress.bind(this)}
+						/>
+						<div className="pt3">
+							<div className="pl1">
+								<HelpTooltip explanation={takerExplanation} />
+							</div>
+						</div>
+					</div>
+					<div>
+						<HashInput
+							blockchain={this.props.blockchain}
+							blockchainIsLoaded={this.props.blockchainIsLoaded}
+							hashData={this.props.hashData}
+							label="Order Hash"
+						/>
+					</div>
+					<div className="pt2">
+						<div className="center">
+							<LifeCycleRaisedButton
+								labelReady="Sign hash"
+								labelLoading="Signing..."
+								labelComplete="Hash signed!"
+								onClickAsyncFn={this._onSignClickedAsync.bind(this)}
+							/>
+						</div>
+						{this.state.globalErrMsg !== '' && (
+							<Alert type={AlertTypes.ERROR} message={this.state.globalErrMsg} />
+						)}
+					</div>
+				</div>
+				<Dialog
+					title="Order JSON"
+					titleStyle={{ fontWeight: 100 }}
+					modal={false}
+					open={this.state.signingState === SigningState.SIGNED}
+					onRequestClose={this._onCloseOrderJSONDialog.bind(this)}
+				>
+					<OrderJSON
+						exchangeContractIfExists={exchangeContractIfExists}
+						orderExpiryTimestamp={this.props.orderExpiryTimestamp}
+						orderSignatureData={this.props.orderSignatureData}
+						orderTakerAddress={this.props.orderTakerAddress}
+						orderMakerAddress={this.props.userAddress}
+						orderSalt={this.props.orderSalt}
+						orderMakerFee={this.props.hashData.makerFee}
+						orderTakerFee={this.props.hashData.takerFee}
+						orderFeeRecipient={this.props.hashData.feeRecipientAddress}
+						networkId={this.props.networkId}
+						sideToAssetToken={this.props.sideToAssetToken}
+						tokenByAddress={this.props.tokenByAddress}
+					/>
+				</Dialog>
+			</div>
+		);
+	}
+	private _onTokenAmountChange(token: Token, side: Side, isValid: boolean, amount?: BigNumber) {
+		this.props.dispatcher.updateChosenAssetToken(side, {
+			address: token.address,
+			amount,
+		});
+	}
+	private _onCloseOrderJSONDialog() {
+		// Upon closing the order JSON dialog, we update the orderSalt stored in the Redux store
+		// with a new value so that if a user signs the identical order again, the newly signed
+		// orderHash will not collide with the previously generated orderHash.
+		this.props.dispatcher.updateOrderSalt(ZeroEx.generatePseudoRandomSalt());
+		this.setState({
+			signingState: SigningState.UNSIGNED,
+		});
+	}
+	private async _onSignClickedAsync(): Promise<boolean> {
+		if (this.props.blockchainErr !== BlockchainErrs.NoError) {
+			this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
+			return false;
+		}
 
-        // Check if all required inputs were supplied
-        const debitToken = this.props.sideToAssetToken[Side.Deposit];
-        const debitBalance = this.props.tokenStateByAddress[debitToken.address].balance;
-        const debitAllowance = this.props.tokenStateByAddress[debitToken.address].allowance;
-        const receiveAmount = this.props.sideToAssetToken[Side.Receive].amount;
-        if (
-            !_.isUndefined(debitToken.amount) &&
-            !_.isUndefined(receiveAmount) &&
-            debitToken.amount.gt(0) &&
-            receiveAmount.gt(0) &&
-            this.props.userAddress !== '' &&
-            debitBalance.gte(debitToken.amount) &&
-            debitAllowance.gte(debitToken.amount)
-        ) {
-            const didSignSuccessfully = await this._signTransactionAsync();
-            if (didSignSuccessfully) {
-                this.setState({
-                    globalErrMsg: '',
-                    shouldShowIncompleteErrs: false,
-                });
-            }
-            return didSignSuccessfully;
-        } else {
-            let globalErrMsg = 'You must fix the above errors in order to generate a valid order';
-            if (this.props.userAddress === '') {
-                globalErrMsg = 'You must enable wallet communication';
-                this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
-            }
-            this.setState({
-                globalErrMsg,
-                shouldShowIncompleteErrs: true,
-            });
-            return false;
-        }
-    }
-    private async _signTransactionAsync(): Promise<boolean> {
-        this.setState({
-            signingState: SigningState.SIGNING,
-        });
-        const exchangeContractAddr = this.props.blockchain.getExchangeContractAddressIfExists();
-        if (_.isUndefined(exchangeContractAddr)) {
-            this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
-            this.setState({
-                signingState: SigningState.UNSIGNED,
-            });
-            return false;
-        }
-        const hashData = this.props.hashData;
+		// Check if all required inputs were supplied
+		const debitToken = this.props.sideToAssetToken[Side.Deposit];
+		const debitBalance = this.props.tokenStateByAddress[debitToken.address].balance;
+		const debitAllowance = this.props.tokenStateByAddress[debitToken.address].allowance;
+		const receiveAmount = this.props.sideToAssetToken[Side.Receive].amount;
+		if (
+			!_.isUndefined(debitToken.amount) &&
+			!_.isUndefined(receiveAmount) &&
+			debitToken.amount.gt(0) &&
+			receiveAmount.gt(0) &&
+			this.props.userAddress !== '' &&
+			debitBalance.gte(debitToken.amount) &&
+			debitAllowance.gte(debitToken.amount)
+		) {
+			const didSignSuccessfully = await this._signTransactionAsync();
+			if (didSignSuccessfully) {
+				this.setState({
+					globalErrMsg: '',
+					shouldShowIncompleteErrs: false,
+				});
+			}
+			return didSignSuccessfully;
+		} else {
+			let globalErrMsg = 'You must fix the above errors in order to generate a valid order';
+			if (this.props.userAddress === '') {
+				globalErrMsg = 'You must enable wallet communication';
+				this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
+			}
+			this.setState({
+				globalErrMsg,
+				shouldShowIncompleteErrs: true,
+			});
+			return false;
+		}
+	}
+	private async _signTransactionAsync(): Promise<boolean> {
+		this.setState({
+			signingState: SigningState.SIGNING,
+		});
+		const exchangeContractAddr = this.props.blockchain.getExchangeContractAddressIfExists();
+		if (_.isUndefined(exchangeContractAddr)) {
+			this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
+			this.setState({
+				signingState: SigningState.UNSIGNED,
+			});
+			return false;
+		}
+		const hashData = this.props.hashData;
 
-        const zeroExOrder: Order = {
-            exchangeContractAddress: exchangeContractAddr,
-            expirationUnixTimestampSec: hashData.orderExpiryTimestamp,
-            feeRecipient: hashData.feeRecipientAddress,
-            maker: hashData.orderMakerAddress,
-            makerFee: hashData.makerFee,
-            makerTokenAddress: hashData.depositTokenContractAddr,
-            makerTokenAmount: hashData.depositAmount,
-            salt: hashData.orderSalt,
-            taker: hashData.orderTakerAddress,
-            takerFee: hashData.takerFee,
-            takerTokenAddress: hashData.receiveTokenContractAddr,
-            takerTokenAmount: hashData.receiveAmount,
-        };
-        const orderHash = ZeroEx.getOrderHashHex(zeroExOrder);
+		const zeroExOrder: Order = {
+			exchangeContractAddress: exchangeContractAddr,
+			expirationUnixTimestampSec: hashData.orderExpiryTimestamp,
+			feeRecipient: hashData.feeRecipientAddress,
+			maker: hashData.orderMakerAddress,
+			makerFee: hashData.makerFee,
+			makerTokenAddress: hashData.depositTokenContractAddr,
+			makerTokenAmount: hashData.depositAmount,
+			salt: hashData.orderSalt,
+			taker: hashData.orderTakerAddress,
+			takerFee: hashData.takerFee,
+			takerTokenAddress: hashData.receiveTokenContractAddr,
+			takerTokenAmount: hashData.receiveAmount,
+		};
+		const orderHash = ZeroEx.getOrderHashHex(zeroExOrder);
 
-        let globalErrMsg = '';
-        try {
-            const signatureData = await this.props.blockchain.signOrderHashAsync(orderHash);
-            const order = utils.generateOrder(
-                this.props.networkId,
-                exchangeContractAddr,
-                this.props.sideToAssetToken,
-                hashData.orderExpiryTimestamp,
-                this.props.orderTakerAddress,
-                this.props.userAddress,
-                hashData.makerFee,
-                hashData.takerFee,
-                hashData.feeRecipientAddress,
-                signatureData,
-                this.props.tokenByAddress,
-                hashData.orderSalt,
-            );
-            const validationResult = this._validator.validate(order, orderSchema);
-            if (validationResult.errors.length > 0) {
-                globalErrMsg = 'Order signing failed. Please refresh and try again';
-                utils.consoleLog(`Unexpected error occured: Order validation failed:
+		let globalErrMsg = '';
+		try {
+			const signatureData = await this.props.blockchain.signOrderHashAsync(orderHash);
+			const order = utils.generateOrder(
+				this.props.networkId,
+				exchangeContractAddr,
+				this.props.sideToAssetToken,
+				hashData.orderExpiryTimestamp,
+				this.props.orderTakerAddress,
+				this.props.userAddress,
+				hashData.makerFee,
+				hashData.takerFee,
+				hashData.feeRecipientAddress,
+				signatureData,
+				this.props.tokenByAddress,
+				hashData.orderSalt,
+			);
+			const validationResult = this._validator.validate(order, orderSchema);
+			if (validationResult.errors.length > 0) {
+				globalErrMsg = 'Order signing failed. Please refresh and try again';
+				utils.consoleLog(`Unexpected error occured: Order validation failed:
                                   ${validationResult.errors}`);
-            }
-        } catch (err) {
-            const errMsg = `${err}`;
-            if (utils.didUserDenyWeb3Request(errMsg)) {
-                globalErrMsg = 'User denied sign request';
-            } else {
-                globalErrMsg = 'An unexpected error occured. Please try refreshing the page';
-                utils.consoleLog(`Unexpected error occured: ${err}`);
-                utils.consoleLog(err.stack);
-                await errorReporter.reportAsync(err);
-            }
-        }
-        this.setState({
-            signingState: globalErrMsg === '' ? SigningState.SIGNED : SigningState.UNSIGNED,
-            globalErrMsg,
-        });
-        return globalErrMsg === '';
-    }
-    private _updateOrderAddress(address?: string): void {
-        if (!_.isUndefined(address)) {
-            this.props.dispatcher.updateOrderTakerAddress(address);
-        }
-    }
+			}
+		} catch (err) {
+			const errMsg = `${err}`;
+			if (utils.didUserDenyWeb3Request(errMsg)) {
+				globalErrMsg = 'User denied sign request';
+			} else {
+				globalErrMsg = 'An unexpected error occured. Please try refreshing the page';
+				utils.consoleLog(`Unexpected error occured: ${err}`);
+				utils.consoleLog(err.stack);
+				await errorReporter.reportAsync(err);
+			}
+		}
+		this.setState({
+			signingState: globalErrMsg === '' ? SigningState.SIGNED : SigningState.UNSIGNED,
+			globalErrMsg,
+		});
+		return globalErrMsg === '';
+	}
+	private _updateOrderAddress(address?: string): void {
+		if (!_.isUndefined(address)) {
+			this.props.dispatcher.updateOrderTakerAddress(address);
+		}
+	}
 }
diff --git a/packages/website/ts/components/generate_order/new_token_form.tsx b/packages/website/ts/components/generate_order/new_token_form.tsx
index 63645be9a..d61aac92a 100644
--- a/packages/website/ts/components/generate_order/new_token_form.tsx
+++ b/packages/website/ts/components/generate_order/new_token_form.tsx
@@ -11,227 +11,227 @@ import { AlertTypes, Token, TokenByAddress, TokenState } from 'ts/types';
 import { colors } from 'ts/utils/colors';
 
 interface NewTokenFormProps {
-    blockchain: Blockchain;
-    tokenByAddress: TokenByAddress;
-    onNewTokenSubmitted: (token: Token, tokenState: TokenState) => void;
+	blockchain: Blockchain;
+	tokenByAddress: TokenByAddress;
+	onNewTokenSubmitted: (token: Token, tokenState: TokenState) => void;
 }
 
 interface NewTokenFormState {
-    globalErrMsg: string;
-    name: string;
-    nameErrText: string;
-    symbol: string;
-    symbolErrText: string;
-    address: string;
-    shouldShowAddressIncompleteErr: boolean;
-    decimals: string;
-    decimalsErrText: string;
+	globalErrMsg: string;
+	name: string;
+	nameErrText: string;
+	symbol: string;
+	symbolErrText: string;
+	address: string;
+	shouldShowAddressIncompleteErr: boolean;
+	decimals: string;
+	decimalsErrText: string;
 }
 
 export class NewTokenForm extends React.Component<NewTokenFormProps, NewTokenFormState> {
-    constructor(props: NewTokenFormProps) {
-        super(props);
-        this.state = {
-            address: '',
-            globalErrMsg: '',
-            name: '',
-            nameErrText: '',
-            shouldShowAddressIncompleteErr: false,
-            symbol: '',
-            symbolErrText: '',
-            decimals: '18',
-            decimalsErrText: '',
-        };
-    }
-    public render() {
-        return (
-            <div className="mx-auto pb2" style={{ width: 256 }}>
-                <div>
-                    <TextField
-                        floatingLabelFixed={true}
-                        floatingLabelStyle={{ color: colors.grey }}
-                        floatingLabelText={<RequiredLabel label="Name" />}
-                        value={this.state.name}
-                        errorText={this.state.nameErrText}
-                        onChange={this._onTokenNameChanged.bind(this)}
-                    />
-                </div>
-                <div>
-                    <TextField
-                        floatingLabelFixed={true}
-                        floatingLabelStyle={{ color: colors.grey }}
-                        floatingLabelText={<RequiredLabel label="Symbol" />}
-                        value={this.state.symbol}
-                        errorText={this.state.symbolErrText}
-                        onChange={this._onTokenSymbolChanged.bind(this)}
-                    />
-                </div>
-                <div>
-                    <AddressInput
-                        isRequired={true}
-                        label="Contract address"
-                        initialAddress=""
-                        shouldShowIncompleteErrs={this.state.shouldShowAddressIncompleteErr}
-                        updateAddress={this._onTokenAddressChanged.bind(this)}
-                    />
-                </div>
-                <div>
-                    <TextField
-                        floatingLabelFixed={true}
-                        floatingLabelStyle={{ color: colors.grey }}
-                        floatingLabelText={<RequiredLabel label="Decimals" />}
-                        value={this.state.decimals}
-                        errorText={this.state.decimalsErrText}
-                        onChange={this._onTokenDecimalsChanged.bind(this)}
-                    />
-                </div>
-                <div className="pt2 mx-auto" style={{ width: 120 }}>
-                    <LifeCycleRaisedButton
-                        labelReady="Add"
-                        labelLoading="Adding..."
-                        labelComplete="Added!"
-                        onClickAsyncFn={this._onAddNewTokenClickAsync.bind(this)}
-                    />
-                </div>
-                {this.state.globalErrMsg !== '' && <Alert type={AlertTypes.ERROR} message={this.state.globalErrMsg} />}
-            </div>
-        );
-    }
-    private async _onAddNewTokenClickAsync() {
-        // Trigger validation of name and symbol
-        this._onTokenNameChanged(undefined, this.state.name);
-        this._onTokenSymbolChanged(undefined, this.state.symbol);
-        this._onTokenDecimalsChanged(undefined, this.state.decimals);
+	constructor(props: NewTokenFormProps) {
+		super(props);
+		this.state = {
+			address: '',
+			globalErrMsg: '',
+			name: '',
+			nameErrText: '',
+			shouldShowAddressIncompleteErr: false,
+			symbol: '',
+			symbolErrText: '',
+			decimals: '18',
+			decimalsErrText: '',
+		};
+	}
+	public render() {
+		return (
+			<div className="mx-auto pb2" style={{ width: 256 }}>
+				<div>
+					<TextField
+						floatingLabelFixed={true}
+						floatingLabelStyle={{ color: colors.grey }}
+						floatingLabelText={<RequiredLabel label="Name" />}
+						value={this.state.name}
+						errorText={this.state.nameErrText}
+						onChange={this._onTokenNameChanged.bind(this)}
+					/>
+				</div>
+				<div>
+					<TextField
+						floatingLabelFixed={true}
+						floatingLabelStyle={{ color: colors.grey }}
+						floatingLabelText={<RequiredLabel label="Symbol" />}
+						value={this.state.symbol}
+						errorText={this.state.symbolErrText}
+						onChange={this._onTokenSymbolChanged.bind(this)}
+					/>
+				</div>
+				<div>
+					<AddressInput
+						isRequired={true}
+						label="Contract address"
+						initialAddress=""
+						shouldShowIncompleteErrs={this.state.shouldShowAddressIncompleteErr}
+						updateAddress={this._onTokenAddressChanged.bind(this)}
+					/>
+				</div>
+				<div>
+					<TextField
+						floatingLabelFixed={true}
+						floatingLabelStyle={{ color: colors.grey }}
+						floatingLabelText={<RequiredLabel label="Decimals" />}
+						value={this.state.decimals}
+						errorText={this.state.decimalsErrText}
+						onChange={this._onTokenDecimalsChanged.bind(this)}
+					/>
+				</div>
+				<div className="pt2 mx-auto" style={{ width: 120 }}>
+					<LifeCycleRaisedButton
+						labelReady="Add"
+						labelLoading="Adding..."
+						labelComplete="Added!"
+						onClickAsyncFn={this._onAddNewTokenClickAsync.bind(this)}
+					/>
+				</div>
+				{this.state.globalErrMsg !== '' && <Alert type={AlertTypes.ERROR} message={this.state.globalErrMsg} />}
+			</div>
+		);
+	}
+	private async _onAddNewTokenClickAsync() {
+		// Trigger validation of name and symbol
+		this._onTokenNameChanged(undefined, this.state.name);
+		this._onTokenSymbolChanged(undefined, this.state.symbol);
+		this._onTokenDecimalsChanged(undefined, this.state.decimals);
 
-        const isAddressIncomplete = this.state.address === '';
-        let doesContractExist = false;
-        if (!isAddressIncomplete) {
-            doesContractExist = await this.props.blockchain.doesContractExistAtAddressAsync(this.state.address);
-        }
+		const isAddressIncomplete = this.state.address === '';
+		let doesContractExist = false;
+		if (!isAddressIncomplete) {
+			doesContractExist = await this.props.blockchain.doesContractExistAtAddressAsync(this.state.address);
+		}
 
-        let hasBalanceAllowanceErr = false;
-        let balance = new BigNumber(0);
-        let allowance = new BigNumber(0);
-        if (doesContractExist) {
-            try {
-                [balance, allowance] = await this.props.blockchain.getCurrentUserTokenBalanceAndAllowanceAsync(
-                    this.state.address,
-                );
-            } catch (err) {
-                hasBalanceAllowanceErr = true;
-            }
-        }
+		let hasBalanceAllowanceErr = false;
+		let balance = new BigNumber(0);
+		let allowance = new BigNumber(0);
+		if (doesContractExist) {
+			try {
+				[balance, allowance] = await this.props.blockchain.getCurrentUserTokenBalanceAndAllowanceAsync(
+					this.state.address,
+				);
+			} catch (err) {
+				hasBalanceAllowanceErr = true;
+			}
+		}
 
-        let globalErrMsg = '';
-        if (
-            this.state.nameErrText !== '' ||
-            this.state.symbolErrText !== '' ||
-            this.state.decimalsErrText !== '' ||
-            isAddressIncomplete
-        ) {
-            globalErrMsg = 'Please fix the above issues';
-        } else if (!doesContractExist) {
-            globalErrMsg = 'No contract found at supplied address';
-        } else if (hasBalanceAllowanceErr) {
-            globalErrMsg = 'Unsuccessful call to `balanceOf` and/or `allowance` on supplied contract address';
-        } else if (!isAddressIncomplete && !_.isUndefined(this.props.tokenByAddress[this.state.address])) {
-            globalErrMsg = 'A token already exists with this address';
-        }
+		let globalErrMsg = '';
+		if (
+			this.state.nameErrText !== '' ||
+			this.state.symbolErrText !== '' ||
+			this.state.decimalsErrText !== '' ||
+			isAddressIncomplete
+		) {
+			globalErrMsg = 'Please fix the above issues';
+		} else if (!doesContractExist) {
+			globalErrMsg = 'No contract found at supplied address';
+		} else if (hasBalanceAllowanceErr) {
+			globalErrMsg = 'Unsuccessful call to `balanceOf` and/or `allowance` on supplied contract address';
+		} else if (!isAddressIncomplete && !_.isUndefined(this.props.tokenByAddress[this.state.address])) {
+			globalErrMsg = 'A token already exists with this address';
+		}
 
-        if (globalErrMsg !== '') {
-            this.setState({
-                globalErrMsg,
-                shouldShowAddressIncompleteErr: isAddressIncomplete,
-            });
-            return;
-        }
+		if (globalErrMsg !== '') {
+			this.setState({
+				globalErrMsg,
+				shouldShowAddressIncompleteErr: isAddressIncomplete,
+			});
+			return;
+		}
 
-        const newToken: Token = {
-            address: this.state.address,
-            decimals: _.parseInt(this.state.decimals),
-            iconUrl: undefined,
-            name: this.state.name,
-            symbol: this.state.symbol.toUpperCase(),
-            isTracked: true,
-            isRegistered: false,
-        };
-        const newTokenState: TokenState = {
-            balance,
-            allowance,
-        };
-        this.props.onNewTokenSubmitted(newToken, newTokenState);
-    }
-    private _onTokenNameChanged(e: any, name: string) {
-        let nameErrText = '';
-        const maxLength = 30;
-        const tokens = _.values(this.props.tokenByAddress);
-        const tokenWithNameIfExists = _.find(tokens, { name });
-        const tokenWithNameExists = !_.isUndefined(tokenWithNameIfExists);
-        if (name === '') {
-            nameErrText = 'Name is required';
-        } else if (!this._isValidName(name)) {
-            nameErrText = 'Name should only contain letters, digits and spaces';
-        } else if (name.length > maxLength) {
-            nameErrText = `Max length is ${maxLength}`;
-        } else if (tokenWithNameExists) {
-            nameErrText = 'Token with this name already exists';
-        }
+		const newToken: Token = {
+			address: this.state.address,
+			decimals: _.parseInt(this.state.decimals),
+			iconUrl: undefined,
+			name: this.state.name,
+			symbol: this.state.symbol.toUpperCase(),
+			isTracked: true,
+			isRegistered: false,
+		};
+		const newTokenState: TokenState = {
+			balance,
+			allowance,
+		};
+		this.props.onNewTokenSubmitted(newToken, newTokenState);
+	}
+	private _onTokenNameChanged(e: any, name: string) {
+		let nameErrText = '';
+		const maxLength = 30;
+		const tokens = _.values(this.props.tokenByAddress);
+		const tokenWithNameIfExists = _.find(tokens, { name });
+		const tokenWithNameExists = !_.isUndefined(tokenWithNameIfExists);
+		if (name === '') {
+			nameErrText = 'Name is required';
+		} else if (!this._isValidName(name)) {
+			nameErrText = 'Name should only contain letters, digits and spaces';
+		} else if (name.length > maxLength) {
+			nameErrText = `Max length is ${maxLength}`;
+		} else if (tokenWithNameExists) {
+			nameErrText = 'Token with this name already exists';
+		}
 
-        this.setState({
-            name,
-            nameErrText,
-        });
-    }
-    private _onTokenSymbolChanged(e: any, symbol: string) {
-        let symbolErrText = '';
-        const maxLength = 5;
-        const tokens = _.values(this.props.tokenByAddress);
-        const tokenWithSymbolExists = !_.isUndefined(_.find(tokens, { symbol }));
-        if (symbol === '') {
-            symbolErrText = 'Symbol is required';
-        } else if (!this._isAlphanumeric(symbol)) {
-            symbolErrText = 'Can only include alphanumeric characters';
-        } else if (symbol.length > maxLength) {
-            symbolErrText = `Max length is ${maxLength}`;
-        } else if (tokenWithSymbolExists) {
-            symbolErrText = 'Token with symbol already exists';
-        }
+		this.setState({
+			name,
+			nameErrText,
+		});
+	}
+	private _onTokenSymbolChanged(e: any, symbol: string) {
+		let symbolErrText = '';
+		const maxLength = 5;
+		const tokens = _.values(this.props.tokenByAddress);
+		const tokenWithSymbolExists = !_.isUndefined(_.find(tokens, { symbol }));
+		if (symbol === '') {
+			symbolErrText = 'Symbol is required';
+		} else if (!this._isAlphanumeric(symbol)) {
+			symbolErrText = 'Can only include alphanumeric characters';
+		} else if (symbol.length > maxLength) {
+			symbolErrText = `Max length is ${maxLength}`;
+		} else if (tokenWithSymbolExists) {
+			symbolErrText = 'Token with symbol already exists';
+		}
 
-        this.setState({
-            symbol,
-            symbolErrText,
-        });
-    }
-    private _onTokenDecimalsChanged(e: any, decimals: string) {
-        let decimalsErrText = '';
-        const maxLength = 2;
-        if (decimals === '') {
-            decimalsErrText = 'Decimals is required';
-        } else if (!this._isInteger(decimals)) {
-            decimalsErrText = 'Must be an integer';
-        } else if (decimals.length > maxLength) {
-            decimalsErrText = `Max length is ${maxLength}`;
-        }
+		this.setState({
+			symbol,
+			symbolErrText,
+		});
+	}
+	private _onTokenDecimalsChanged(e: any, decimals: string) {
+		let decimalsErrText = '';
+		const maxLength = 2;
+		if (decimals === '') {
+			decimalsErrText = 'Decimals is required';
+		} else if (!this._isInteger(decimals)) {
+			decimalsErrText = 'Must be an integer';
+		} else if (decimals.length > maxLength) {
+			decimalsErrText = `Max length is ${maxLength}`;
+		}
 
-        this.setState({
-            decimals,
-            decimalsErrText,
-        });
-    }
-    private _onTokenAddressChanged(address?: string) {
-        if (!_.isUndefined(address)) {
-            this.setState({
-                address,
-            });
-        }
-    }
-    private _isValidName(input: string) {
-        return /^[a-z0-9 ]+$/i.test(input);
-    }
-    private _isInteger(input: string) {
-        return /^[0-9]+$/i.test(input);
-    }
-    private _isAlphanumeric(input: string) {
-        return /^[a-zA-Z0-9]+$/i.test(input);
-    }
+		this.setState({
+			decimals,
+			decimalsErrText,
+		});
+	}
+	private _onTokenAddressChanged(address?: string) {
+		if (!_.isUndefined(address)) {
+			this.setState({
+				address,
+			});
+		}
+	}
+	private _isValidName(input: string) {
+		return /^[a-z0-9 ]+$/i.test(input);
+	}
+	private _isInteger(input: string) {
+		return /^[0-9]+$/i.test(input);
+	}
+	private _isAlphanumeric(input: string) {
+		return /^[a-zA-Z0-9]+$/i.test(input);
+	}
 }
diff --git a/packages/website/ts/components/inputs/address_input.tsx b/packages/website/ts/components/inputs/address_input.tsx
index dd4131140..236bf9a00 100644
--- a/packages/website/ts/components/inputs/address_input.tsx
+++ b/packages/website/ts/components/inputs/address_input.tsx
@@ -6,66 +6,66 @@ import { RequiredLabel } from 'ts/components/ui/required_label';
 import { colors } from 'ts/utils/colors';
 
 interface AddressInputProps {
-    disabled?: boolean;
-    initialAddress: string;
-    isRequired?: boolean;
-    hintText?: string;
-    shouldHideLabel?: boolean;
-    label?: string;
-    shouldShowIncompleteErrs?: boolean;
-    updateAddress: (address?: string) => void;
+	disabled?: boolean;
+	initialAddress: string;
+	isRequired?: boolean;
+	hintText?: string;
+	shouldHideLabel?: boolean;
+	label?: string;
+	shouldShowIncompleteErrs?: boolean;
+	updateAddress: (address?: string) => void;
 }
 
 interface AddressInputState {
-    address: string;
-    errMsg: string;
+	address: string;
+	errMsg: string;
 }
 
 export class AddressInput extends React.Component<AddressInputProps, AddressInputState> {
-    constructor(props: AddressInputProps) {
-        super(props);
-        this.state = {
-            address: this.props.initialAddress,
-            errMsg: '',
-        };
-    }
-    public componentWillReceiveProps(nextProps: AddressInputProps) {
-        if (nextProps.shouldShowIncompleteErrs && this.props.isRequired && this.state.address === '') {
-            this.setState({
-                errMsg: 'Address is required',
-            });
-        }
-    }
-    public render() {
-        const label = this.props.isRequired ? <RequiredLabel label={this.props.label} /> : this.props.label;
-        const labelDisplay = this.props.shouldHideLabel ? 'hidden' : 'block';
-        const hintText = this.props.hintText ? this.props.hintText : '';
-        return (
-            <div className="overflow-hidden">
-                <TextField
-                    id={`address-field-${this.props.label}`}
-                    disabled={_.isUndefined(this.props.disabled) ? false : this.props.disabled}
-                    fullWidth={true}
-                    hintText={hintText}
-                    floatingLabelFixed={true}
-                    floatingLabelStyle={{ color: colors.grey, display: labelDisplay }}
-                    floatingLabelText={label}
-                    errorText={this.state.errMsg}
-                    value={this.state.address}
-                    onChange={this._onOrderTakerAddressUpdated.bind(this)}
-                />
-            </div>
-        );
-    }
-    private _onOrderTakerAddressUpdated(e: any) {
-        const address = e.target.value.toLowerCase();
-        const isValidAddress = addressUtils.isAddress(address) || address === '';
-        const errMsg = isValidAddress ? '' : 'Invalid ethereum address';
-        this.setState({
-            address,
-            errMsg,
-        });
-        const addressIfValid = isValidAddress ? address : undefined;
-        this.props.updateAddress(addressIfValid);
-    }
+	constructor(props: AddressInputProps) {
+		super(props);
+		this.state = {
+			address: this.props.initialAddress,
+			errMsg: '',
+		};
+	}
+	public componentWillReceiveProps(nextProps: AddressInputProps) {
+		if (nextProps.shouldShowIncompleteErrs && this.props.isRequired && this.state.address === '') {
+			this.setState({
+				errMsg: 'Address is required',
+			});
+		}
+	}
+	public render() {
+		const label = this.props.isRequired ? <RequiredLabel label={this.props.label} /> : this.props.label;
+		const labelDisplay = this.props.shouldHideLabel ? 'hidden' : 'block';
+		const hintText = this.props.hintText ? this.props.hintText : '';
+		return (
+			<div className="overflow-hidden">
+				<TextField
+					id={`address-field-${this.props.label}`}
+					disabled={_.isUndefined(this.props.disabled) ? false : this.props.disabled}
+					fullWidth={true}
+					hintText={hintText}
+					floatingLabelFixed={true}
+					floatingLabelStyle={{ color: colors.grey, display: labelDisplay }}
+					floatingLabelText={label}
+					errorText={this.state.errMsg}
+					value={this.state.address}
+					onChange={this._onOrderTakerAddressUpdated.bind(this)}
+				/>
+			</div>
+		);
+	}
+	private _onOrderTakerAddressUpdated(e: any) {
+		const address = e.target.value.toLowerCase();
+		const isValidAddress = addressUtils.isAddress(address) || address === '';
+		const errMsg = isValidAddress ? '' : 'Invalid ethereum address';
+		this.setState({
+			address,
+			errMsg,
+		});
+		const addressIfValid = isValidAddress ? address : undefined;
+		this.props.updateAddress(addressIfValid);
+	}
 }
diff --git a/packages/website/ts/components/inputs/allowance_toggle.tsx b/packages/website/ts/components/inputs/allowance_toggle.tsx
index da46db4f4..245784824 100644
--- a/packages/website/ts/components/inputs/allowance_toggle.tsx
+++ b/packages/website/ts/components/inputs/allowance_toggle.tsx
@@ -11,83 +11,83 @@ import { utils } from 'ts/utils/utils';
 const DEFAULT_ALLOWANCE_AMOUNT_IN_BASE_UNITS = new BigNumber(2).pow(256).minus(1);
 
 interface AllowanceToggleProps {
-    blockchain: Blockchain;
-    dispatcher: Dispatcher;
-    onErrorOccurred: (errType: BalanceErrs) => void;
-    token: Token;
-    tokenState: TokenState;
-    userAddress: string;
+	blockchain: Blockchain;
+	dispatcher: Dispatcher;
+	onErrorOccurred: (errType: BalanceErrs) => void;
+	token: Token;
+	tokenState: TokenState;
+	userAddress: string;
 }
 
 interface AllowanceToggleState {
-    isSpinnerVisible: boolean;
-    prevAllowance: BigNumber;
+	isSpinnerVisible: boolean;
+	prevAllowance: BigNumber;
 }
 
 export class AllowanceToggle extends React.Component<AllowanceToggleProps, AllowanceToggleState> {
-    constructor(props: AllowanceToggleProps) {
-        super(props);
-        this.state = {
-            isSpinnerVisible: false,
-            prevAllowance: props.tokenState.allowance,
-        };
-    }
-    public componentWillReceiveProps(nextProps: AllowanceToggleProps) {
-        if (!nextProps.tokenState.allowance.eq(this.state.prevAllowance)) {
-            this.setState({
-                isSpinnerVisible: false,
-                prevAllowance: nextProps.tokenState.allowance,
-            });
-        }
-    }
-    public render() {
-        return (
-            <div className="flex">
-                <div>
-                    <Toggle
-                        disabled={this.state.isSpinnerVisible}
-                        toggled={this._isAllowanceSet()}
-                        onToggle={this._onToggleAllowanceAsync.bind(this)}
-                    />
-                </div>
-                {this.state.isSpinnerVisible && (
-                    <div className="pl1" style={{ paddingTop: 3 }}>
-                        <i className="zmdi zmdi-spinner zmdi-hc-spin" />
-                    </div>
-                )}
-            </div>
-        );
-    }
-    private async _onToggleAllowanceAsync(): Promise<void> {
-        if (this.props.userAddress === '') {
-            this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
-        }
+	constructor(props: AllowanceToggleProps) {
+		super(props);
+		this.state = {
+			isSpinnerVisible: false,
+			prevAllowance: props.tokenState.allowance,
+		};
+	}
+	public componentWillReceiveProps(nextProps: AllowanceToggleProps) {
+		if (!nextProps.tokenState.allowance.eq(this.state.prevAllowance)) {
+			this.setState({
+				isSpinnerVisible: false,
+				prevAllowance: nextProps.tokenState.allowance,
+			});
+		}
+	}
+	public render() {
+		return (
+			<div className="flex">
+				<div>
+					<Toggle
+						disabled={this.state.isSpinnerVisible}
+						toggled={this._isAllowanceSet()}
+						onToggle={this._onToggleAllowanceAsync.bind(this)}
+					/>
+				</div>
+				{this.state.isSpinnerVisible && (
+					<div className="pl1" style={{ paddingTop: 3 }}>
+						<i className="zmdi zmdi-spinner zmdi-hc-spin" />
+					</div>
+				)}
+			</div>
+		);
+	}
+	private async _onToggleAllowanceAsync(): Promise<void> {
+		if (this.props.userAddress === '') {
+			this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
+		}
 
-        this.setState({
-            isSpinnerVisible: true,
-        });
+		this.setState({
+			isSpinnerVisible: true,
+		});
 
-        let newAllowanceAmountInBaseUnits = new BigNumber(0);
-        if (!this._isAllowanceSet()) {
-            newAllowanceAmountInBaseUnits = DEFAULT_ALLOWANCE_AMOUNT_IN_BASE_UNITS;
-        }
-        try {
-            await this.props.blockchain.setProxyAllowanceAsync(this.props.token, newAllowanceAmountInBaseUnits);
-        } catch (err) {
-            this.setState({
-                isSpinnerVisible: false,
-            });
-            const errMsg = `${err}`;
-            if (_.includes(errMsg, 'User denied transaction')) {
-                return;
-            }
-            utils.consoleLog(`Unexpected error encountered: ${err}`);
-            utils.consoleLog(err.stack);
-            this.props.onErrorOccurred(BalanceErrs.allowanceSettingFailed);
-            await errorReporter.reportAsync(err);
-        }
-    }
-    private _isAllowanceSet() {
-        return !this.props.tokenState.allowance.eq(0);
-    }
+		let newAllowanceAmountInBaseUnits = new BigNumber(0);
+		if (!this._isAllowanceSet()) {
+			newAllowanceAmountInBaseUnits = DEFAULT_ALLOWANCE_AMOUNT_IN_BASE_UNITS;
+		}
+		try {
+			await this.props.blockchain.setProxyAllowanceAsync(this.props.token, newAllowanceAmountInBaseUnits);
+		} catch (err) {
+			this.setState({
+				isSpinnerVisible: false,
+			});
+			const errMsg = `${err}`;
+			if (_.includes(errMsg, 'User denied transaction')) {
+				return;
+			}
+			utils.consoleLog(`Unexpected error encountered: ${err}`);
+			utils.consoleLog(err.stack);
+			this.props.onErrorOccurred(BalanceErrs.allowanceSettingFailed);
+			await errorReporter.reportAsync(err);
+		}
+	}
+	private _isAllowanceSet() {
+		return !this.props.tokenState.allowance.eq(0);
+	}
 }
diff --git a/packages/website/ts/components/inputs/balance_bounded_input.tsx b/packages/website/ts/components/inputs/balance_bounded_input.tsx
index ddc434b51..5cc91994e 100644
--- a/packages/website/ts/components/inputs/balance_bounded_input.tsx
+++ b/packages/website/ts/components/inputs/balance_bounded_input.tsx
@@ -9,143 +9,143 @@ import { colors } from 'ts/utils/colors';
 import { utils } from 'ts/utils/utils';
 
 interface BalanceBoundedInputProps {
-    label?: string;
-    balance: BigNumber;
-    amount?: BigNumber;
-    onChange: ValidatedBigNumberCallback;
-    shouldShowIncompleteErrs?: boolean;
-    shouldCheckBalance: boolean;
-    validate?: (amount: BigNumber) => InputErrMsg;
-    onVisitBalancesPageClick?: () => void;
-    shouldHideVisitBalancesLink?: boolean;
+	label?: string;
+	balance: BigNumber;
+	amount?: BigNumber;
+	onChange: ValidatedBigNumberCallback;
+	shouldShowIncompleteErrs?: boolean;
+	shouldCheckBalance: boolean;
+	validate?: (amount: BigNumber) => InputErrMsg;
+	onVisitBalancesPageClick?: () => void;
+	shouldHideVisitBalancesLink?: boolean;
 }
 
 interface BalanceBoundedInputState {
-    errMsg: InputErrMsg;
-    amountString: string;
+	errMsg: InputErrMsg;
+	amountString: string;
 }
 
 export class BalanceBoundedInput extends React.Component<BalanceBoundedInputProps, BalanceBoundedInputState> {
-    public static defaultProps: Partial<BalanceBoundedInputProps> = {
-        shouldShowIncompleteErrs: false,
-        shouldHideVisitBalancesLink: false,
-    };
-    constructor(props: BalanceBoundedInputProps) {
-        super(props);
-        const amountString = this.props.amount ? this.props.amount.toString() : '';
-        this.state = {
-            errMsg: this._validate(amountString, props.balance),
-            amountString,
-        };
-    }
-    public componentWillReceiveProps(nextProps: BalanceBoundedInputProps) {
-        if (nextProps === this.props) {
-            return;
-        }
-        const isCurrentAmountNumeric = utils.isNumeric(this.state.amountString);
-        if (!_.isUndefined(nextProps.amount)) {
-            let shouldResetState = false;
-            if (!isCurrentAmountNumeric) {
-                shouldResetState = true;
-            } else {
-                const currentAmount = new BigNumber(this.state.amountString);
-                if (!currentAmount.eq(nextProps.amount) || !nextProps.balance.eq(this.props.balance)) {
-                    shouldResetState = true;
-                }
-            }
-            if (shouldResetState) {
-                const amountString = nextProps.amount.toString();
-                this.setState({
-                    errMsg: this._validate(amountString, nextProps.balance),
-                    amountString,
-                });
-            }
-        } else if (isCurrentAmountNumeric) {
-            const amountString = '';
-            this.setState({
-                errMsg: this._validate(amountString, nextProps.balance),
-                amountString,
-            });
-        }
-    }
-    public render() {
-        let errorText = this.state.errMsg;
-        if (this.props.shouldShowIncompleteErrs && this.state.amountString === '') {
-            errorText = 'This field is required';
-        }
-        let label: React.ReactNode | string = '';
-        if (!_.isUndefined(this.props.label)) {
-            label = <RequiredLabel label={this.props.label} />;
-        }
-        return (
-            <TextField
-                fullWidth={true}
-                floatingLabelText={label}
-                floatingLabelFixed={true}
-                floatingLabelStyle={{ color: colors.grey, width: 206 }}
-                errorText={errorText}
-                value={this.state.amountString}
-                hintText={<span style={{ textTransform: 'capitalize' }}>amount</span>}
-                onChange={this._onValueChange.bind(this)}
-                underlineStyle={{ width: 'calc(100% + 50px)' }}
-            />
-        );
-    }
-    private _onValueChange(e: any, amountString: string) {
-        const errMsg = this._validate(amountString, this.props.balance);
-        this.setState(
-            {
-                amountString,
-                errMsg,
-            },
-            () => {
-                const isValid = _.isUndefined(errMsg);
-                if (utils.isNumeric(amountString)) {
-                    this.props.onChange(isValid, new BigNumber(amountString));
-                } else {
-                    this.props.onChange(isValid);
-                }
-            },
-        );
-    }
-    private _validate(amountString: string, balance: BigNumber): InputErrMsg {
-        if (!utils.isNumeric(amountString)) {
-            return amountString !== '' ? 'Must be a number' : '';
-        }
-        const amount = new BigNumber(amountString);
-        if (amount.eq(0)) {
-            return 'Cannot be zero';
-        }
-        if (this.props.shouldCheckBalance && amount.gt(balance)) {
-            return <span>Insufficient balance. {this._renderIncreaseBalanceLink()}</span>;
-        }
-        const errMsg = _.isUndefined(this.props.validate) ? undefined : this.props.validate(amount);
-        return errMsg;
-    }
-    private _renderIncreaseBalanceLink() {
-        if (this.props.shouldHideVisitBalancesLink) {
-            return null;
-        }
+	public static defaultProps: Partial<BalanceBoundedInputProps> = {
+		shouldShowIncompleteErrs: false,
+		shouldHideVisitBalancesLink: false,
+	};
+	constructor(props: BalanceBoundedInputProps) {
+		super(props);
+		const amountString = this.props.amount ? this.props.amount.toString() : '';
+		this.state = {
+			errMsg: this._validate(amountString, props.balance),
+			amountString,
+		};
+	}
+	public componentWillReceiveProps(nextProps: BalanceBoundedInputProps) {
+		if (nextProps === this.props) {
+			return;
+		}
+		const isCurrentAmountNumeric = utils.isNumeric(this.state.amountString);
+		if (!_.isUndefined(nextProps.amount)) {
+			let shouldResetState = false;
+			if (!isCurrentAmountNumeric) {
+				shouldResetState = true;
+			} else {
+				const currentAmount = new BigNumber(this.state.amountString);
+				if (!currentAmount.eq(nextProps.amount) || !nextProps.balance.eq(this.props.balance)) {
+					shouldResetState = true;
+				}
+			}
+			if (shouldResetState) {
+				const amountString = nextProps.amount.toString();
+				this.setState({
+					errMsg: this._validate(amountString, nextProps.balance),
+					amountString,
+				});
+			}
+		} else if (isCurrentAmountNumeric) {
+			const amountString = '';
+			this.setState({
+				errMsg: this._validate(amountString, nextProps.balance),
+				amountString,
+			});
+		}
+	}
+	public render() {
+		let errorText = this.state.errMsg;
+		if (this.props.shouldShowIncompleteErrs && this.state.amountString === '') {
+			errorText = 'This field is required';
+		}
+		let label: React.ReactNode | string = '';
+		if (!_.isUndefined(this.props.label)) {
+			label = <RequiredLabel label={this.props.label} />;
+		}
+		return (
+			<TextField
+				fullWidth={true}
+				floatingLabelText={label}
+				floatingLabelFixed={true}
+				floatingLabelStyle={{ color: colors.grey, width: 206 }}
+				errorText={errorText}
+				value={this.state.amountString}
+				hintText={<span style={{ textTransform: 'capitalize' }}>amount</span>}
+				onChange={this._onValueChange.bind(this)}
+				underlineStyle={{ width: 'calc(100% + 50px)' }}
+			/>
+		);
+	}
+	private _onValueChange(e: any, amountString: string) {
+		const errMsg = this._validate(amountString, this.props.balance);
+		this.setState(
+			{
+				amountString,
+				errMsg,
+			},
+			() => {
+				const isValid = _.isUndefined(errMsg);
+				if (utils.isNumeric(amountString)) {
+					this.props.onChange(isValid, new BigNumber(amountString));
+				} else {
+					this.props.onChange(isValid);
+				}
+			},
+		);
+	}
+	private _validate(amountString: string, balance: BigNumber): InputErrMsg {
+		if (!utils.isNumeric(amountString)) {
+			return amountString !== '' ? 'Must be a number' : '';
+		}
+		const amount = new BigNumber(amountString);
+		if (amount.eq(0)) {
+			return 'Cannot be zero';
+		}
+		if (this.props.shouldCheckBalance && amount.gt(balance)) {
+			return <span>Insufficient balance. {this._renderIncreaseBalanceLink()}</span>;
+		}
+		const errMsg = _.isUndefined(this.props.validate) ? undefined : this.props.validate(amount);
+		return errMsg;
+	}
+	private _renderIncreaseBalanceLink() {
+		if (this.props.shouldHideVisitBalancesLink) {
+			return null;
+		}
 
-        const increaseBalanceText = 'Increase balance';
-        const linkStyle = {
-            cursor: 'pointer',
-            color: colors.darkestGrey,
-            textDecoration: 'underline',
-            display: 'inline',
-        };
-        if (_.isUndefined(this.props.onVisitBalancesPageClick)) {
-            return (
-                <Link to={`${WebsitePaths.Portal}/balances`} style={linkStyle}>
-                    {increaseBalanceText}
-                </Link>
-            );
-        } else {
-            return (
-                <div onClick={this.props.onVisitBalancesPageClick} style={linkStyle}>
-                    {increaseBalanceText}
-                </div>
-            );
-        }
-    }
+		const increaseBalanceText = 'Increase balance';
+		const linkStyle = {
+			cursor: 'pointer',
+			color: colors.darkestGrey,
+			textDecoration: 'underline',
+			display: 'inline',
+		};
+		if (_.isUndefined(this.props.onVisitBalancesPageClick)) {
+			return (
+				<Link to={`${WebsitePaths.Portal}/balances`} style={linkStyle}>
+					{increaseBalanceText}
+				</Link>
+			);
+		} else {
+			return (
+				<div onClick={this.props.onVisitBalancesPageClick} style={linkStyle}>
+					{increaseBalanceText}
+				</div>
+			);
+		}
+	}
 }
diff --git a/packages/website/ts/components/inputs/eth_amount_input.tsx b/packages/website/ts/components/inputs/eth_amount_input.tsx
index a66f92c8c..7f9747094 100644
--- a/packages/website/ts/components/inputs/eth_amount_input.tsx
+++ b/packages/website/ts/components/inputs/eth_amount_input.tsx
@@ -7,43 +7,43 @@ import { ValidatedBigNumberCallback } from 'ts/types';
 import { constants } from 'ts/utils/constants';
 
 interface EthAmountInputProps {
-    label?: string;
-    balance: BigNumber;
-    amount?: BigNumber;
-    onChange: ValidatedBigNumberCallback;
-    shouldShowIncompleteErrs: boolean;
-    onVisitBalancesPageClick?: () => void;
-    shouldCheckBalance: boolean;
-    shouldHideVisitBalancesLink?: boolean;
+	label?: string;
+	balance: BigNumber;
+	amount?: BigNumber;
+	onChange: ValidatedBigNumberCallback;
+	shouldShowIncompleteErrs: boolean;
+	onVisitBalancesPageClick?: () => void;
+	shouldCheckBalance: boolean;
+	shouldHideVisitBalancesLink?: boolean;
 }
 
 interface EthAmountInputState {}
 
 export class EthAmountInput extends React.Component<EthAmountInputProps, EthAmountInputState> {
-    public render() {
-        const amount = this.props.amount
-            ? ZeroEx.toUnitAmount(this.props.amount, constants.DECIMAL_PLACES_ETH)
-            : undefined;
-        return (
-            <div className="flex overflow-hidden" style={{ height: 63 }}>
-                <BalanceBoundedInput
-                    label={this.props.label}
-                    balance={this.props.balance}
-                    amount={amount}
-                    onChange={this._onChange.bind(this)}
-                    shouldCheckBalance={this.props.shouldCheckBalance}
-                    shouldShowIncompleteErrs={this.props.shouldShowIncompleteErrs}
-                    onVisitBalancesPageClick={this.props.onVisitBalancesPageClick}
-                    shouldHideVisitBalancesLink={this.props.shouldHideVisitBalancesLink}
-                />
-                <div style={{ paddingTop: _.isUndefined(this.props.label) ? 15 : 40 }}>ETH</div>
-            </div>
-        );
-    }
-    private _onChange(isValid: boolean, amount?: BigNumber) {
-        const baseUnitAmountIfExists = _.isUndefined(amount)
-            ? undefined
-            : ZeroEx.toBaseUnitAmount(amount, constants.DECIMAL_PLACES_ETH);
-        this.props.onChange(isValid, baseUnitAmountIfExists);
-    }
+	public render() {
+		const amount = this.props.amount
+			? ZeroEx.toUnitAmount(this.props.amount, constants.DECIMAL_PLACES_ETH)
+			: undefined;
+		return (
+			<div className="flex overflow-hidden" style={{ height: 63 }}>
+				<BalanceBoundedInput
+					label={this.props.label}
+					balance={this.props.balance}
+					amount={amount}
+					onChange={this._onChange.bind(this)}
+					shouldCheckBalance={this.props.shouldCheckBalance}
+					shouldShowIncompleteErrs={this.props.shouldShowIncompleteErrs}
+					onVisitBalancesPageClick={this.props.onVisitBalancesPageClick}
+					shouldHideVisitBalancesLink={this.props.shouldHideVisitBalancesLink}
+				/>
+				<div style={{ paddingTop: _.isUndefined(this.props.label) ? 15 : 40 }}>ETH</div>
+			</div>
+		);
+	}
+	private _onChange(isValid: boolean, amount?: BigNumber) {
+		const baseUnitAmountIfExists = _.isUndefined(amount)
+			? undefined
+			: ZeroEx.toBaseUnitAmount(amount, constants.DECIMAL_PLACES_ETH);
+		this.props.onChange(isValid, baseUnitAmountIfExists);
+	}
 }
diff --git a/packages/website/ts/components/inputs/expiration_input.tsx b/packages/website/ts/components/inputs/expiration_input.tsx
index e473648d2..cb4ed7bd0 100644
--- a/packages/website/ts/components/inputs/expiration_input.tsx
+++ b/packages/website/ts/components/inputs/expiration_input.tsx
@@ -7,94 +7,94 @@ import * as React from 'react';
 import { utils } from 'ts/utils/utils';
 
 interface ExpirationInputProps {
-    orderExpiryTimestamp: BigNumber;
-    updateOrderExpiry: (unixTimestampSec: BigNumber) => void;
+	orderExpiryTimestamp: BigNumber;
+	updateOrderExpiry: (unixTimestampSec: BigNumber) => void;
 }
 
 interface ExpirationInputState {
-    dateMoment: moment.Moment;
-    timeMoment: moment.Moment;
+	dateMoment: moment.Moment;
+	timeMoment: moment.Moment;
 }
 
 export class ExpirationInput extends React.Component<ExpirationInputProps, ExpirationInputState> {
-    private _earliestPickableMoment: moment.Moment;
-    constructor(props: ExpirationInputProps) {
-        super(props);
-        // Set the earliest pickable date to today at 00:00, so users can only pick the current or later dates
-        this._earliestPickableMoment = moment().startOf('day');
-        const expirationMoment = utils.convertToMomentFromUnixTimestamp(props.orderExpiryTimestamp);
-        const initialOrderExpiryTimestamp = utils.initialOrderExpiryUnixTimestampSec();
-        const didUserSetExpiry = !initialOrderExpiryTimestamp.eq(props.orderExpiryTimestamp);
-        this.state = {
-            dateMoment: didUserSetExpiry ? expirationMoment : undefined,
-            timeMoment: didUserSetExpiry ? expirationMoment : undefined,
-        };
-    }
-    public render() {
-        const date = this.state.dateMoment ? this.state.dateMoment.toDate() : undefined;
-        const time = this.state.timeMoment ? this.state.timeMoment.toDate() : undefined;
-        return (
-            <div className="clearfix">
-                <div className="col col-6 overflow-hidden pr3 flex relative">
-                    <DatePicker
-                        className="overflow-hidden"
-                        hintText="Date"
-                        mode="landscape"
-                        autoOk={true}
-                        value={date}
-                        onChange={this._onDateChanged.bind(this)}
-                        shouldDisableDate={this._shouldDisableDate.bind(this)}
-                    />
-                    <div className="absolute" style={{ fontSize: 20, right: 40, top: 13, pointerEvents: 'none' }}>
-                        <i className="zmdi zmdi-calendar" />
-                    </div>
-                </div>
-                <div className="col col-5 overflow-hidden flex relative">
-                    <TimePicker
-                        className="overflow-hidden"
-                        hintText="Time"
-                        autoOk={true}
-                        value={time}
-                        onChange={this._onTimeChanged.bind(this)}
-                    />
-                    <div className="absolute" style={{ fontSize: 20, right: 9, top: 13, pointerEvents: 'none' }}>
-                        <i className="zmdi zmdi-time" />
-                    </div>
-                </div>
-                <div onClick={this._clearDates.bind(this)} className="col col-1 pt2" style={{ textAlign: 'right' }}>
-                    <i style={{ fontSize: 16, cursor: 'pointer' }} className="zmdi zmdi-close" />
-                </div>
-            </div>
-        );
-    }
-    private _shouldDisableDate(date: Date): boolean {
-        return moment(date)
-            .startOf('day')
-            .isBefore(this._earliestPickableMoment);
-    }
-    private _clearDates() {
-        this.setState({
-            dateMoment: undefined,
-            timeMoment: undefined,
-        });
-        const defaultDateTime = utils.initialOrderExpiryUnixTimestampSec();
-        this.props.updateOrderExpiry(defaultDateTime);
-    }
-    private _onDateChanged(e: any, date: Date) {
-        const dateMoment = moment(date);
-        this.setState({
-            dateMoment,
-        });
-        const timestamp = utils.convertToUnixTimestampSeconds(dateMoment, this.state.timeMoment);
-        this.props.updateOrderExpiry(timestamp);
-    }
-    private _onTimeChanged(e: any, time: Date) {
-        const timeMoment = moment(time);
-        this.setState({
-            timeMoment,
-        });
-        const dateMoment = _.isUndefined(this.state.dateMoment) ? moment() : this.state.dateMoment;
-        const timestamp = utils.convertToUnixTimestampSeconds(dateMoment, timeMoment);
-        this.props.updateOrderExpiry(timestamp);
-    }
+	private _earliestPickableMoment: moment.Moment;
+	constructor(props: ExpirationInputProps) {
+		super(props);
+		// Set the earliest pickable date to today at 00:00, so users can only pick the current or later dates
+		this._earliestPickableMoment = moment().startOf('day');
+		const expirationMoment = utils.convertToMomentFromUnixTimestamp(props.orderExpiryTimestamp);
+		const initialOrderExpiryTimestamp = utils.initialOrderExpiryUnixTimestampSec();
+		const didUserSetExpiry = !initialOrderExpiryTimestamp.eq(props.orderExpiryTimestamp);
+		this.state = {
+			dateMoment: didUserSetExpiry ? expirationMoment : undefined,
+			timeMoment: didUserSetExpiry ? expirationMoment : undefined,
+		};
+	}
+	public render() {
+		const date = this.state.dateMoment ? this.state.dateMoment.toDate() : undefined;
+		const time = this.state.timeMoment ? this.state.timeMoment.toDate() : undefined;
+		return (
+			<div className="clearfix">
+				<div className="col col-6 overflow-hidden pr3 flex relative">
+					<DatePicker
+						className="overflow-hidden"
+						hintText="Date"
+						mode="landscape"
+						autoOk={true}
+						value={date}
+						onChange={this._onDateChanged.bind(this)}
+						shouldDisableDate={this._shouldDisableDate.bind(this)}
+					/>
+					<div className="absolute" style={{ fontSize: 20, right: 40, top: 13, pointerEvents: 'none' }}>
+						<i className="zmdi zmdi-calendar" />
+					</div>
+				</div>
+				<div className="col col-5 overflow-hidden flex relative">
+					<TimePicker
+						className="overflow-hidden"
+						hintText="Time"
+						autoOk={true}
+						value={time}
+						onChange={this._onTimeChanged.bind(this)}
+					/>
+					<div className="absolute" style={{ fontSize: 20, right: 9, top: 13, pointerEvents: 'none' }}>
+						<i className="zmdi zmdi-time" />
+					</div>
+				</div>
+				<div onClick={this._clearDates.bind(this)} className="col col-1 pt2" style={{ textAlign: 'right' }}>
+					<i style={{ fontSize: 16, cursor: 'pointer' }} className="zmdi zmdi-close" />
+				</div>
+			</div>
+		);
+	}
+	private _shouldDisableDate(date: Date): boolean {
+		return moment(date)
+			.startOf('day')
+			.isBefore(this._earliestPickableMoment);
+	}
+	private _clearDates() {
+		this.setState({
+			dateMoment: undefined,
+			timeMoment: undefined,
+		});
+		const defaultDateTime = utils.initialOrderExpiryUnixTimestampSec();
+		this.props.updateOrderExpiry(defaultDateTime);
+	}
+	private _onDateChanged(e: any, date: Date) {
+		const dateMoment = moment(date);
+		this.setState({
+			dateMoment,
+		});
+		const timestamp = utils.convertToUnixTimestampSeconds(dateMoment, this.state.timeMoment);
+		this.props.updateOrderExpiry(timestamp);
+	}
+	private _onTimeChanged(e: any, time: Date) {
+		const timeMoment = moment(time);
+		this.setState({
+			timeMoment,
+		});
+		const dateMoment = _.isUndefined(this.state.dateMoment) ? moment() : this.state.dateMoment;
+		const timestamp = utils.convertToUnixTimestampSeconds(dateMoment, timeMoment);
+		this.props.updateOrderExpiry(timestamp);
+	}
 }
diff --git a/packages/website/ts/components/inputs/hash_input.tsx b/packages/website/ts/components/inputs/hash_input.tsx
index 5a3d34fe6..36d7e6140 100644
--- a/packages/website/ts/components/inputs/hash_input.tsx
+++ b/packages/website/ts/components/inputs/hash_input.tsx
@@ -8,55 +8,55 @@ import { HashData, Styles } from 'ts/types';
 import { constants } from 'ts/utils/constants';
 
 const styles: Styles = {
-    textField: {
-        overflow: 'hidden',
-        paddingTop: 8,
-        textOverflow: 'ellipsis',
-        whiteSpace: 'nowrap',
-    },
+	textField: {
+		overflow: 'hidden',
+		paddingTop: 8,
+		textOverflow: 'ellipsis',
+		whiteSpace: 'nowrap',
+	},
 };
 
 interface HashInputProps {
-    blockchain: Blockchain;
-    blockchainIsLoaded: boolean;
-    hashData: HashData;
-    label: string;
+	blockchain: Blockchain;
+	blockchainIsLoaded: boolean;
+	hashData: HashData;
+	label: string;
 }
 
 interface HashInputState {}
 
 export class HashInput extends React.Component<HashInputProps, HashInputState> {
-    public render() {
-        const msgHashHex = this.props.blockchainIsLoaded ? this._generateMessageHashHex() : '';
-        return (
-            <div>
-                <FakeTextField label={this.props.label}>
-                    <div style={styles.textField} data-tip={true} data-for="hashTooltip">
-                        {msgHashHex}
-                    </div>
-                </FakeTextField>
-                <ReactTooltip id="hashTooltip">{msgHashHex}</ReactTooltip>
-            </div>
-        );
-    }
-    private _generateMessageHashHex() {
-        const exchangeContractAddress = this.props.blockchain.getExchangeContractAddressIfExists();
-        const hashData = this.props.hashData;
-        const order: Order = {
-            exchangeContractAddress,
-            expirationUnixTimestampSec: hashData.orderExpiryTimestamp,
-            feeRecipient: hashData.feeRecipientAddress,
-            maker: _.isEmpty(hashData.orderMakerAddress) ? constants.NULL_ADDRESS : hashData.orderMakerAddress,
-            makerFee: hashData.makerFee,
-            makerTokenAddress: hashData.depositTokenContractAddr,
-            makerTokenAmount: hashData.depositAmount,
-            salt: hashData.orderSalt,
-            taker: hashData.orderTakerAddress,
-            takerFee: hashData.takerFee,
-            takerTokenAddress: hashData.receiveTokenContractAddr,
-            takerTokenAmount: hashData.receiveAmount,
-        };
-        const orderHash = ZeroEx.getOrderHashHex(order);
-        return orderHash;
-    }
+	public render() {
+		const msgHashHex = this.props.blockchainIsLoaded ? this._generateMessageHashHex() : '';
+		return (
+			<div>
+				<FakeTextField label={this.props.label}>
+					<div style={styles.textField} data-tip={true} data-for="hashTooltip">
+						{msgHashHex}
+					</div>
+				</FakeTextField>
+				<ReactTooltip id="hashTooltip">{msgHashHex}</ReactTooltip>
+			</div>
+		);
+	}
+	private _generateMessageHashHex() {
+		const exchangeContractAddress = this.props.blockchain.getExchangeContractAddressIfExists();
+		const hashData = this.props.hashData;
+		const order: Order = {
+			exchangeContractAddress,
+			expirationUnixTimestampSec: hashData.orderExpiryTimestamp,
+			feeRecipient: hashData.feeRecipientAddress,
+			maker: _.isEmpty(hashData.orderMakerAddress) ? constants.NULL_ADDRESS : hashData.orderMakerAddress,
+			makerFee: hashData.makerFee,
+			makerTokenAddress: hashData.depositTokenContractAddr,
+			makerTokenAmount: hashData.depositAmount,
+			salt: hashData.orderSalt,
+			taker: hashData.orderTakerAddress,
+			takerFee: hashData.takerFee,
+			takerTokenAddress: hashData.receiveTokenContractAddr,
+			takerTokenAmount: hashData.receiveAmount,
+		};
+		const orderHash = ZeroEx.getOrderHashHex(order);
+		return orderHash;
+	}
 }
diff --git a/packages/website/ts/components/inputs/identicon_address_input.tsx b/packages/website/ts/components/inputs/identicon_address_input.tsx
index 4cf9af64d..f14cb4e9c 100644
--- a/packages/website/ts/components/inputs/identicon_address_input.tsx
+++ b/packages/website/ts/components/inputs/identicon_address_input.tsx
@@ -6,48 +6,48 @@ import { InputLabel } from 'ts/components/ui/input_label';
 import { RequiredLabel } from 'ts/components/ui/required_label';
 
 interface IdenticonAddressInputProps {
-    initialAddress: string;
-    isRequired?: boolean;
-    label: string;
-    updateOrderAddress: (address?: string) => void;
+	initialAddress: string;
+	isRequired?: boolean;
+	label: string;
+	updateOrderAddress: (address?: string) => void;
 }
 
 interface IdenticonAddressInputState {
-    address: string;
+	address: string;
 }
 
 export class IdenticonAddressInput extends React.Component<IdenticonAddressInputProps, IdenticonAddressInputState> {
-    constructor(props: IdenticonAddressInputProps) {
-        super(props);
-        this.state = {
-            address: props.initialAddress,
-        };
-    }
-    public render() {
-        const label = this.props.isRequired ? <RequiredLabel label={this.props.label} /> : this.props.label;
-        return (
-            <div className="relative" style={{ width: '100%' }}>
-                <InputLabel text={label} />
-                <div className="flex">
-                    <div className="col col-1 pb1 pr1" style={{ paddingTop: 13 }}>
-                        <Identicon address={this.state.address} diameter={26} />
-                    </div>
-                    <div className="col col-11 pb1 pl1" style={{ height: 65 }}>
-                        <AddressInput
-                            hintText="e.g 0x75bE4F78AA3699B3A348c84bDB2a96c3Db..."
-                            shouldHideLabel={true}
-                            initialAddress={this.props.initialAddress}
-                            updateAddress={this._updateAddress.bind(this)}
-                        />
-                    </div>
-                </div>
-            </div>
-        );
-    }
-    private _updateAddress(address?: string): void {
-        this.setState({
-            address,
-        });
-        this.props.updateOrderAddress(address);
-    }
+	constructor(props: IdenticonAddressInputProps) {
+		super(props);
+		this.state = {
+			address: props.initialAddress,
+		};
+	}
+	public render() {
+		const label = this.props.isRequired ? <RequiredLabel label={this.props.label} /> : this.props.label;
+		return (
+			<div className="relative" style={{ width: '100%' }}>
+				<InputLabel text={label} />
+				<div className="flex">
+					<div className="col col-1 pb1 pr1" style={{ paddingTop: 13 }}>
+						<Identicon address={this.state.address} diameter={26} />
+					</div>
+					<div className="col col-11 pb1 pl1" style={{ height: 65 }}>
+						<AddressInput
+							hintText="e.g 0x75bE4F78AA3699B3A348c84bDB2a96c3Db..."
+							shouldHideLabel={true}
+							initialAddress={this.props.initialAddress}
+							updateAddress={this._updateAddress.bind(this)}
+						/>
+					</div>
+				</div>
+			</div>
+		);
+	}
+	private _updateAddress(address?: string): void {
+		this.setState({
+			address,
+		});
+		this.props.updateOrderAddress(address);
+	}
 }
diff --git a/packages/website/ts/components/inputs/token_amount_input.tsx b/packages/website/ts/components/inputs/token_amount_input.tsx
index 63966d759..0a71b2c00 100644
--- a/packages/website/ts/components/inputs/token_amount_input.tsx
+++ b/packages/website/ts/components/inputs/token_amount_input.tsx
@@ -8,63 +8,63 @@ import { InputErrMsg, Token, TokenState, ValidatedBigNumberCallback, WebsitePath
 import { colors } from 'ts/utils/colors';
 
 interface TokenAmountInputProps {
-    token: Token;
-    tokenState: TokenState;
-    label?: string;
-    amount?: BigNumber;
-    shouldShowIncompleteErrs: boolean;
-    shouldCheckBalance: boolean;
-    shouldCheckAllowance: boolean;
-    onChange: ValidatedBigNumberCallback;
-    onVisitBalancesPageClick?: () => void;
+	token: Token;
+	tokenState: TokenState;
+	label?: string;
+	amount?: BigNumber;
+	shouldShowIncompleteErrs: boolean;
+	shouldCheckBalance: boolean;
+	shouldCheckAllowance: boolean;
+	onChange: ValidatedBigNumberCallback;
+	onVisitBalancesPageClick?: () => void;
 }
 
 interface TokenAmountInputState {}
 
 export class TokenAmountInput extends React.Component<TokenAmountInputProps, TokenAmountInputState> {
-    public render() {
-        const amount = this.props.amount
-            ? ZeroEx.toUnitAmount(this.props.amount, this.props.token.decimals)
-            : undefined;
-        const hasLabel = !_.isUndefined(this.props.label);
-        return (
-            <div className="flex overflow-hidden" style={{ height: hasLabel ? 84 : 62 }}>
-                <BalanceBoundedInput
-                    label={this.props.label}
-                    amount={amount}
-                    balance={ZeroEx.toUnitAmount(this.props.tokenState.balance, this.props.token.decimals)}
-                    onChange={this._onChange.bind(this)}
-                    validate={this._validate.bind(this)}
-                    shouldCheckBalance={this.props.shouldCheckBalance}
-                    shouldShowIncompleteErrs={this.props.shouldShowIncompleteErrs}
-                    onVisitBalancesPageClick={this.props.onVisitBalancesPageClick}
-                />
-                <div style={{ paddingTop: hasLabel ? 39 : 14 }}>{this.props.token.symbol}</div>
-            </div>
-        );
-    }
-    private _onChange(isValid: boolean, amount?: BigNumber) {
-        let baseUnitAmount;
-        if (!_.isUndefined(amount)) {
-            baseUnitAmount = ZeroEx.toBaseUnitAmount(amount, this.props.token.decimals);
-        }
-        this.props.onChange(isValid, baseUnitAmount);
-    }
-    private _validate(amount: BigNumber): InputErrMsg {
-        if (this.props.shouldCheckAllowance && amount.gt(this.props.tokenState.allowance)) {
-            return (
-                <span>
-                    Insufficient allowance.{' '}
-                    <Link
-                        to={`${WebsitePaths.Portal}/balances`}
-                        style={{ cursor: 'pointer', color: colors.darkestGrey }}
-                    >
-                        Set allowance
-                    </Link>
-                </span>
-            );
-        } else {
-            return undefined;
-        }
-    }
+	public render() {
+		const amount = this.props.amount
+			? ZeroEx.toUnitAmount(this.props.amount, this.props.token.decimals)
+			: undefined;
+		const hasLabel = !_.isUndefined(this.props.label);
+		return (
+			<div className="flex overflow-hidden" style={{ height: hasLabel ? 84 : 62 }}>
+				<BalanceBoundedInput
+					label={this.props.label}
+					amount={amount}
+					balance={ZeroEx.toUnitAmount(this.props.tokenState.balance, this.props.token.decimals)}
+					onChange={this._onChange.bind(this)}
+					validate={this._validate.bind(this)}
+					shouldCheckBalance={this.props.shouldCheckBalance}
+					shouldShowIncompleteErrs={this.props.shouldShowIncompleteErrs}
+					onVisitBalancesPageClick={this.props.onVisitBalancesPageClick}
+				/>
+				<div style={{ paddingTop: hasLabel ? 39 : 14 }}>{this.props.token.symbol}</div>
+			</div>
+		);
+	}
+	private _onChange(isValid: boolean, amount?: BigNumber) {
+		let baseUnitAmount;
+		if (!_.isUndefined(amount)) {
+			baseUnitAmount = ZeroEx.toBaseUnitAmount(amount, this.props.token.decimals);
+		}
+		this.props.onChange(isValid, baseUnitAmount);
+	}
+	private _validate(amount: BigNumber): InputErrMsg {
+		if (this.props.shouldCheckAllowance && amount.gt(this.props.tokenState.allowance)) {
+			return (
+				<span>
+					Insufficient allowance.{' '}
+					<Link
+						to={`${WebsitePaths.Portal}/balances`}
+						style={{ cursor: 'pointer', color: colors.darkestGrey }}
+					>
+						Set allowance
+					</Link>
+				</span>
+			);
+		} else {
+			return undefined;
+		}
+	}
 }
diff --git a/packages/website/ts/components/inputs/token_input.tsx b/packages/website/ts/components/inputs/token_input.tsx
index 5df19b28c..3aceacb22 100644
--- a/packages/website/ts/components/inputs/token_input.tsx
+++ b/packages/website/ts/components/inputs/token_input.tsx
@@ -12,93 +12,93 @@ import { colors } from 'ts/utils/colors';
 const TOKEN_ICON_DIMENSION = 80;
 
 interface TokenInputProps {
-    blockchain: Blockchain;
-    blockchainErr: BlockchainErrs;
-    dispatcher: Dispatcher;
-    label: string;
-    side: Side;
-    networkId: number;
-    assetToken: AssetToken;
-    updateChosenAssetToken: (side: Side, token: AssetToken) => void;
-    tokenByAddress: TokenByAddress;
-    userAddress: string;
+	blockchain: Blockchain;
+	blockchainErr: BlockchainErrs;
+	dispatcher: Dispatcher;
+	label: string;
+	side: Side;
+	networkId: number;
+	assetToken: AssetToken;
+	updateChosenAssetToken: (side: Side, token: AssetToken) => void;
+	tokenByAddress: TokenByAddress;
+	userAddress: string;
 }
 
 interface TokenInputState {
-    isHoveringIcon: boolean;
-    isPickerOpen: boolean;
-    trackCandidateTokenIfExists?: Token;
+	isHoveringIcon: boolean;
+	isPickerOpen: boolean;
+	trackCandidateTokenIfExists?: Token;
 }
 
 export class TokenInput extends React.Component<TokenInputProps, TokenInputState> {
-    constructor(props: TokenInputProps) {
-        super(props);
-        this.state = {
-            isHoveringIcon: false,
-            isPickerOpen: false,
-        };
-    }
-    public render() {
-        const token = this.props.tokenByAddress[this.props.assetToken.address];
-        const iconStyles = {
-            cursor: 'pointer',
-            opacity: this.state.isHoveringIcon ? 0.5 : 1,
-        };
-        return (
-            <div className="relative">
-                <div className="pb1">
-                    <InputLabel text={this.props.label} />
-                </div>
-                <Paper
-                    zDepth={1}
-                    style={{ cursor: 'pointer' }}
-                    onMouseEnter={this._onToggleHover.bind(this, true)}
-                    onMouseLeave={this._onToggleHover.bind(this, false)}
-                    onClick={this._onAssetClicked.bind(this)}
-                >
-                    <div className="mx-auto pt2" style={{ width: TOKEN_ICON_DIMENSION, ...iconStyles }}>
-                        <TokenIcon token={token} diameter={TOKEN_ICON_DIMENSION} />
-                    </div>
-                    <div className="py1 center" style={{ color: colors.grey }}>
-                        {token.name}
-                    </div>
-                </Paper>
-                <AssetPicker
-                    userAddress={this.props.userAddress}
-                    networkId={this.props.networkId}
-                    blockchain={this.props.blockchain}
-                    dispatcher={this.props.dispatcher}
-                    isOpen={this.state.isPickerOpen}
-                    currentTokenAddress={this.props.assetToken.address}
-                    onTokenChosen={this._onTokenChosen.bind(this)}
-                    tokenByAddress={this.props.tokenByAddress}
-                />
-            </div>
-        );
-    }
-    private _onTokenChosen(tokenAddress: string) {
-        const assetToken: AssetToken = {
-            address: tokenAddress,
-            amount: this.props.assetToken.amount,
-        };
-        this.props.updateChosenAssetToken(this.props.side, assetToken);
-        this.setState({
-            isPickerOpen: false,
-        });
-    }
-    private _onToggleHover(isHoveringIcon: boolean) {
-        this.setState({
-            isHoveringIcon,
-        });
-    }
-    private _onAssetClicked() {
-        if (this.props.blockchainErr !== BlockchainErrs.NoError) {
-            this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
-            return;
-        }
+	constructor(props: TokenInputProps) {
+		super(props);
+		this.state = {
+			isHoveringIcon: false,
+			isPickerOpen: false,
+		};
+	}
+	public render() {
+		const token = this.props.tokenByAddress[this.props.assetToken.address];
+		const iconStyles = {
+			cursor: 'pointer',
+			opacity: this.state.isHoveringIcon ? 0.5 : 1,
+		};
+		return (
+			<div className="relative">
+				<div className="pb1">
+					<InputLabel text={this.props.label} />
+				</div>
+				<Paper
+					zDepth={1}
+					style={{ cursor: 'pointer' }}
+					onMouseEnter={this._onToggleHover.bind(this, true)}
+					onMouseLeave={this._onToggleHover.bind(this, false)}
+					onClick={this._onAssetClicked.bind(this)}
+				>
+					<div className="mx-auto pt2" style={{ width: TOKEN_ICON_DIMENSION, ...iconStyles }}>
+						<TokenIcon token={token} diameter={TOKEN_ICON_DIMENSION} />
+					</div>
+					<div className="py1 center" style={{ color: colors.grey }}>
+						{token.name}
+					</div>
+				</Paper>
+				<AssetPicker
+					userAddress={this.props.userAddress}
+					networkId={this.props.networkId}
+					blockchain={this.props.blockchain}
+					dispatcher={this.props.dispatcher}
+					isOpen={this.state.isPickerOpen}
+					currentTokenAddress={this.props.assetToken.address}
+					onTokenChosen={this._onTokenChosen.bind(this)}
+					tokenByAddress={this.props.tokenByAddress}
+				/>
+			</div>
+		);
+	}
+	private _onTokenChosen(tokenAddress: string) {
+		const assetToken: AssetToken = {
+			address: tokenAddress,
+			amount: this.props.assetToken.amount,
+		};
+		this.props.updateChosenAssetToken(this.props.side, assetToken);
+		this.setState({
+			isPickerOpen: false,
+		});
+	}
+	private _onToggleHover(isHoveringIcon: boolean) {
+		this.setState({
+			isHoveringIcon,
+		});
+	}
+	private _onAssetClicked() {
+		if (this.props.blockchainErr !== BlockchainErrs.NoError) {
+			this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
+			return;
+		}
 
-        this.setState({
-            isPickerOpen: true,
-        });
-    }
+		this.setState({
+			isPickerOpen: true,
+		});
+	}
 }
diff --git a/packages/website/ts/components/order_json.tsx b/packages/website/ts/components/order_json.tsx
index 1b6b32a04..1640a178e 100644
--- a/packages/website/ts/components/order_json.tsx
+++ b/packages/website/ts/components/order_json.tsx
@@ -11,172 +11,172 @@ import { errorReporter } from 'ts/utils/error_reporter';
 import { utils } from 'ts/utils/utils';
 
 interface OrderJSONProps {
-    exchangeContractIfExists: string;
-    orderExpiryTimestamp: BigNumber;
-    orderSignatureData: SignatureData;
-    orderTakerAddress: string;
-    orderMakerAddress: string;
-    orderSalt: BigNumber;
-    orderMakerFee: BigNumber;
-    orderTakerFee: BigNumber;
-    orderFeeRecipient: string;
-    networkId: number;
-    sideToAssetToken: SideToAssetToken;
-    tokenByAddress: TokenByAddress;
+	exchangeContractIfExists: string;
+	orderExpiryTimestamp: BigNumber;
+	orderSignatureData: SignatureData;
+	orderTakerAddress: string;
+	orderMakerAddress: string;
+	orderSalt: BigNumber;
+	orderMakerFee: BigNumber;
+	orderTakerFee: BigNumber;
+	orderFeeRecipient: string;
+	networkId: number;
+	sideToAssetToken: SideToAssetToken;
+	tokenByAddress: TokenByAddress;
 }
 
 interface OrderJSONState {
-    shareLink: string;
+	shareLink: string;
 }
 
 export class OrderJSON extends React.Component<OrderJSONProps, OrderJSONState> {
-    constructor(props: OrderJSONProps) {
-        super(props);
-        this.state = {
-            shareLink: '',
-        };
-        // tslint:disable-next-line:no-floating-promises
-        this._setShareLinkAsync();
-    }
-    public render() {
-        const order = utils.generateOrder(
-            this.props.networkId,
-            this.props.exchangeContractIfExists,
-            this.props.sideToAssetToken,
-            this.props.orderExpiryTimestamp,
-            this.props.orderTakerAddress,
-            this.props.orderMakerAddress,
-            this.props.orderMakerFee,
-            this.props.orderTakerFee,
-            this.props.orderFeeRecipient,
-            this.props.orderSignatureData,
-            this.props.tokenByAddress,
-            this.props.orderSalt,
-        );
-        const orderJSON = JSON.stringify(order);
-        return (
-            <div>
-                <div className="pb2">
-                    You have successfully generated and cryptographically signed an order! The following JSON contains
-                    the order parameters and cryptographic signature that your counterparty will need to execute a trade
-                    with you.
-                </div>
-                <div className="pb2 flex">
-                    <div className="inline-block pl1" style={{ top: 1 }}>
-                        <CopyIcon data={orderJSON} callToAction="Copy" />
-                    </div>
-                </div>
-                <Paper className="center overflow-hidden">
-                    <TextField
-                        id="orderJSON"
-                        style={{ width: 710 }}
-                        value={JSON.stringify(order, null, '\t')}
-                        multiLine={true}
-                        rows={2}
-                        rowsMax={8}
-                        underlineStyle={{ display: 'none' }}
-                    />
-                </Paper>
-                <div className="pt3 pb2 center">
-                    <div>Share your signed order!</div>
-                    <div>
-                        <div className="mx-auto overflow-hidden" style={{ width: 152 }}>
-                            <TextField id={`${this.state.shareLink}-bitly`} value={this.state.shareLink} />
-                        </div>
-                    </div>
-                    <div className="mx-auto pt1 flex" style={{ width: 91 }}>
-                        <div>
-                            <i
-                                style={{ cursor: 'pointer', fontSize: 29 }}
-                                onClick={this._shareViaFacebook.bind(this)}
-                                className="zmdi zmdi-facebook-box"
-                            />
-                        </div>
-                        <div className="pl1" style={{ position: 'relative', width: 28 }}>
-                            <i
-                                style={{
-                                    cursor: 'pointer',
-                                    fontSize: 32,
-                                    position: 'absolute',
-                                    top: -2,
-                                    left: 8,
-                                }}
-                                onClick={this._shareViaEmailAsync.bind(this)}
-                                className="zmdi zmdi-email"
-                            />
-                        </div>
-                        <div className="pl1">
-                            <i
-                                style={{ cursor: 'pointer', fontSize: 29 }}
-                                onClick={this._shareViaTwitterAsync.bind(this)}
-                                className="zmdi zmdi-twitter-box"
-                            />
-                        </div>
-                    </div>
-                </div>
-            </div>
-        );
-    }
-    private async _shareViaTwitterAsync() {
-        const tweetText = encodeURIComponent(`Fill my order using the 0x protocol: ${this.state.shareLink}`);
-        window.open(`https://twitter.com/intent/tweet?text=${tweetText}`, 'Share your order', 'width=500,height=400');
-    }
-    private async _shareViaFacebook() {
-        (window as any).FB.ui(
-            {
-                display: 'popup',
-                href: this.state.shareLink,
-                method: 'share',
-            },
-            _.noop,
-        );
-    }
-    private async _shareViaEmailAsync() {
-        const encodedSubject = encodeURIComponent("Let's trade using the 0x protocol");
-        const encodedBody = encodeURIComponent(`I generated an order with the 0x protocol.
+	constructor(props: OrderJSONProps) {
+		super(props);
+		this.state = {
+			shareLink: '',
+		};
+		// tslint:disable-next-line:no-floating-promises
+		this._setShareLinkAsync();
+	}
+	public render() {
+		const order = utils.generateOrder(
+			this.props.networkId,
+			this.props.exchangeContractIfExists,
+			this.props.sideToAssetToken,
+			this.props.orderExpiryTimestamp,
+			this.props.orderTakerAddress,
+			this.props.orderMakerAddress,
+			this.props.orderMakerFee,
+			this.props.orderTakerFee,
+			this.props.orderFeeRecipient,
+			this.props.orderSignatureData,
+			this.props.tokenByAddress,
+			this.props.orderSalt,
+		);
+		const orderJSON = JSON.stringify(order);
+		return (
+			<div>
+				<div className="pb2">
+					You have successfully generated and cryptographically signed an order! The following JSON contains
+					the order parameters and cryptographic signature that your counterparty will need to execute a trade
+					with you.
+				</div>
+				<div className="pb2 flex">
+					<div className="inline-block pl1" style={{ top: 1 }}>
+						<CopyIcon data={orderJSON} callToAction="Copy" />
+					</div>
+				</div>
+				<Paper className="center overflow-hidden">
+					<TextField
+						id="orderJSON"
+						style={{ width: 710 }}
+						value={JSON.stringify(order, null, '\t')}
+						multiLine={true}
+						rows={2}
+						rowsMax={8}
+						underlineStyle={{ display: 'none' }}
+					/>
+				</Paper>
+				<div className="pt3 pb2 center">
+					<div>Share your signed order!</div>
+					<div>
+						<div className="mx-auto overflow-hidden" style={{ width: 152 }}>
+							<TextField id={`${this.state.shareLink}-bitly`} value={this.state.shareLink} />
+						</div>
+					</div>
+					<div className="mx-auto pt1 flex" style={{ width: 91 }}>
+						<div>
+							<i
+								style={{ cursor: 'pointer', fontSize: 29 }}
+								onClick={this._shareViaFacebook.bind(this)}
+								className="zmdi zmdi-facebook-box"
+							/>
+						</div>
+						<div className="pl1" style={{ position: 'relative', width: 28 }}>
+							<i
+								style={{
+									cursor: 'pointer',
+									fontSize: 32,
+									position: 'absolute',
+									top: -2,
+									left: 8,
+								}}
+								onClick={this._shareViaEmailAsync.bind(this)}
+								className="zmdi zmdi-email"
+							/>
+						</div>
+						<div className="pl1">
+							<i
+								style={{ cursor: 'pointer', fontSize: 29 }}
+								onClick={this._shareViaTwitterAsync.bind(this)}
+								className="zmdi zmdi-twitter-box"
+							/>
+						</div>
+					</div>
+				</div>
+			</div>
+		);
+	}
+	private async _shareViaTwitterAsync() {
+		const tweetText = encodeURIComponent(`Fill my order using the 0x protocol: ${this.state.shareLink}`);
+		window.open(`https://twitter.com/intent/tweet?text=${tweetText}`, 'Share your order', 'width=500,height=400');
+	}
+	private async _shareViaFacebook() {
+		(window as any).FB.ui(
+			{
+				display: 'popup',
+				href: this.state.shareLink,
+				method: 'share',
+			},
+			_.noop,
+		);
+	}
+	private async _shareViaEmailAsync() {
+		const encodedSubject = encodeURIComponent("Let's trade using the 0x protocol");
+		const encodedBody = encodeURIComponent(`I generated an order with the 0x protocol.
 You can see and fill it here: ${this.state.shareLink}`);
-        const mailToLink = `mailto:mail@example.org?subject=${encodedSubject}&body=${encodedBody}`;
-        window.open(mailToLink, '_blank');
-    }
-    private async _setShareLinkAsync() {
-        const shareLink = await this._generateShareLinkAsync();
-        this.setState({
-            shareLink,
-        });
-    }
-    private async _generateShareLinkAsync(): Promise<string> {
-        const longUrl = encodeURIComponent(this._getOrderUrl());
-        const bitlyRequestUrl = `${constants.URL_BITLY_API}/v3/shorten?access_token=${
-            configs.BITLY_ACCESS_TOKEN
-        }&longUrl=${longUrl}`;
-        const response = await fetch(bitlyRequestUrl);
-        const responseBody = await response.text();
-        const bodyObj = JSON.parse(responseBody);
-        if (response.status !== 200 || bodyObj.status_code !== 200) {
-            // TODO: Show error message in UI
-            utils.consoleLog(`Unexpected status code: ${response.status} -> ${responseBody}`);
-            await errorReporter.reportAsync(new Error(`Bitly returned non-200: ${JSON.stringify(response)}`));
-            return '';
-        }
-        return bodyObj.data.url;
-    }
-    private _getOrderUrl() {
-        const order = utils.generateOrder(
-            this.props.networkId,
-            this.props.exchangeContractIfExists,
-            this.props.sideToAssetToken,
-            this.props.orderExpiryTimestamp,
-            this.props.orderTakerAddress,
-            this.props.orderMakerAddress,
-            this.props.orderMakerFee,
-            this.props.orderTakerFee,
-            this.props.orderFeeRecipient,
-            this.props.orderSignatureData,
-            this.props.tokenByAddress,
-            this.props.orderSalt,
-        );
-        const orderJSONString = JSON.stringify(order);
-        const orderUrl = `${configs.BASE_URL}${WebsitePaths.Portal}/fill?order=${orderJSONString}`;
-        return orderUrl;
-    }
+		const mailToLink = `mailto:mail@example.org?subject=${encodedSubject}&body=${encodedBody}`;
+		window.open(mailToLink, '_blank');
+	}
+	private async _setShareLinkAsync() {
+		const shareLink = await this._generateShareLinkAsync();
+		this.setState({
+			shareLink,
+		});
+	}
+	private async _generateShareLinkAsync(): Promise<string> {
+		const longUrl = encodeURIComponent(this._getOrderUrl());
+		const bitlyRequestUrl = `${constants.URL_BITLY_API}/v3/shorten?access_token=${
+			configs.BITLY_ACCESS_TOKEN
+		}&longUrl=${longUrl}`;
+		const response = await fetch(bitlyRequestUrl);
+		const responseBody = await response.text();
+		const bodyObj = JSON.parse(responseBody);
+		if (response.status !== 200 || bodyObj.status_code !== 200) {
+			// TODO: Show error message in UI
+			utils.consoleLog(`Unexpected status code: ${response.status} -> ${responseBody}`);
+			await errorReporter.reportAsync(new Error(`Bitly returned non-200: ${JSON.stringify(response)}`));
+			return '';
+		}
+		return bodyObj.data.url;
+	}
+	private _getOrderUrl() {
+		const order = utils.generateOrder(
+			this.props.networkId,
+			this.props.exchangeContractIfExists,
+			this.props.sideToAssetToken,
+			this.props.orderExpiryTimestamp,
+			this.props.orderTakerAddress,
+			this.props.orderMakerAddress,
+			this.props.orderMakerFee,
+			this.props.orderTakerFee,
+			this.props.orderFeeRecipient,
+			this.props.orderSignatureData,
+			this.props.tokenByAddress,
+			this.props.orderSalt,
+		);
+		const orderJSONString = JSON.stringify(order);
+		const orderUrl = `${configs.BASE_URL}${WebsitePaths.Portal}/fill?order=${orderJSONString}`;
+		return orderUrl;
+	}
 }
diff --git a/packages/website/ts/components/portal.tsx b/packages/website/ts/components/portal.tsx
index e2e28e8b6..e163a1fa2 100644
--- a/packages/website/ts/components/portal.tsx
+++ b/packages/website/ts/components/portal.tsx
@@ -23,14 +23,14 @@ import { Dispatcher } from 'ts/redux/dispatcher';
 import { orderSchema } from 'ts/schemas/order_schema';
 import { SchemaValidator } from 'ts/schemas/validator';
 import {
-    BlockchainErrs,
-    HashData,
-    Order,
-    ScreenWidths,
-    Token,
-    TokenByAddress,
-    TokenStateByAddress,
-    WebsitePaths,
+	BlockchainErrs,
+	HashData,
+	Order,
+	ScreenWidths,
+	Token,
+	TokenByAddress,
+	TokenStateByAddress,
+	WebsitePaths,
 } from 'ts/types';
 import { colors } from 'ts/utils/colors';
 import { configs } from 'ts/utils/configs';
@@ -42,320 +42,320 @@ const THROTTLE_TIMEOUT = 100;
 export interface PortalPassedProps {}
 
 export interface PortalAllProps {
-    blockchainErr: BlockchainErrs;
-    blockchainIsLoaded: boolean;
-    dispatcher: Dispatcher;
-    hashData: HashData;
-    networkId: number;
-    nodeVersion: string;
-    orderFillAmount: BigNumber;
-    screenWidth: ScreenWidths;
-    tokenByAddress: TokenByAddress;
-    tokenStateByAddress: TokenStateByAddress;
-    userEtherBalance: BigNumber;
-    userAddress: string;
-    shouldBlockchainErrDialogBeOpen: boolean;
-    userSuppliedOrderCache: Order;
-    location: Location;
-    flashMessage?: string | React.ReactNode;
+	blockchainErr: BlockchainErrs;
+	blockchainIsLoaded: boolean;
+	dispatcher: Dispatcher;
+	hashData: HashData;
+	networkId: number;
+	nodeVersion: string;
+	orderFillAmount: BigNumber;
+	screenWidth: ScreenWidths;
+	tokenByAddress: TokenByAddress;
+	tokenStateByAddress: TokenStateByAddress;
+	userEtherBalance: BigNumber;
+	userAddress: string;
+	shouldBlockchainErrDialogBeOpen: boolean;
+	userSuppliedOrderCache: Order;
+	location: Location;
+	flashMessage?: string | React.ReactNode;
 }
 
 interface PortalAllState {
-    prevNetworkId: number;
-    prevNodeVersion: string;
-    prevUserAddress: string;
-    prevPathname: string;
-    isDisclaimerDialogOpen: boolean;
-    isWethNoticeDialogOpen: boolean;
+	prevNetworkId: number;
+	prevNodeVersion: string;
+	prevUserAddress: string;
+	prevPathname: string;
+	isDisclaimerDialogOpen: boolean;
+	isWethNoticeDialogOpen: boolean;
 }
 
 export class Portal extends React.Component<PortalAllProps, PortalAllState> {
-    private _blockchain: Blockchain;
-    private _sharedOrderIfExists: Order;
-    private _throttledScreenWidthUpdate: () => void;
-    public static hasAlreadyDismissedWethNotice() {
-        const didDismissWethNotice = localStorage.getItemIfExists(constants.LOCAL_STORAGE_KEY_DISMISS_WETH_NOTICE);
-        const hasAlreadyDismissedWethNotice = !_.isUndefined(didDismissWethNotice) && !_.isEmpty(didDismissWethNotice);
-        return hasAlreadyDismissedWethNotice;
-    }
-    constructor(props: PortalAllProps) {
-        super(props);
-        this._sharedOrderIfExists = this._getSharedOrderIfExists();
-        this._throttledScreenWidthUpdate = _.throttle(this._updateScreenWidth.bind(this), THROTTLE_TIMEOUT);
+	private _blockchain: Blockchain;
+	private _sharedOrderIfExists: Order;
+	private _throttledScreenWidthUpdate: () => void;
+	public static hasAlreadyDismissedWethNotice() {
+		const didDismissWethNotice = localStorage.getItemIfExists(constants.LOCAL_STORAGE_KEY_DISMISS_WETH_NOTICE);
+		const hasAlreadyDismissedWethNotice = !_.isUndefined(didDismissWethNotice) && !_.isEmpty(didDismissWethNotice);
+		return hasAlreadyDismissedWethNotice;
+	}
+	constructor(props: PortalAllProps) {
+		super(props);
+		this._sharedOrderIfExists = this._getSharedOrderIfExists();
+		this._throttledScreenWidthUpdate = _.throttle(this._updateScreenWidth.bind(this), THROTTLE_TIMEOUT);
 
-        const isViewingBalances = _.includes(props.location.pathname, `${WebsitePaths.Portal}/balances`);
-        const hasAlreadyDismissedWethNotice = Portal.hasAlreadyDismissedWethNotice();
+		const isViewingBalances = _.includes(props.location.pathname, `${WebsitePaths.Portal}/balances`);
+		const hasAlreadyDismissedWethNotice = Portal.hasAlreadyDismissedWethNotice();
 
-        const didAcceptPortalDisclaimer = localStorage.getItemIfExists(constants.LOCAL_STORAGE_KEY_ACCEPT_DISCLAIMER);
-        const hasAcceptedDisclaimer =
-            !_.isUndefined(didAcceptPortalDisclaimer) && !_.isEmpty(didAcceptPortalDisclaimer);
-        this.state = {
-            prevNetworkId: this.props.networkId,
-            prevNodeVersion: this.props.nodeVersion,
-            prevUserAddress: this.props.userAddress,
-            prevPathname: this.props.location.pathname,
-            isDisclaimerDialogOpen: !hasAcceptedDisclaimer,
-            isWethNoticeDialogOpen: !hasAlreadyDismissedWethNotice && isViewingBalances,
-        };
-    }
-    public componentDidMount() {
-        window.addEventListener('resize', this._throttledScreenWidthUpdate);
-        window.scrollTo(0, 0);
-    }
-    public componentWillMount() {
-        this._blockchain = new Blockchain(this.props.dispatcher);
-    }
-    public componentWillUnmount() {
-        this._blockchain.destroy();
-        window.removeEventListener('resize', this._throttledScreenWidthUpdate);
-        // We re-set the entire redux state when the portal is unmounted so that when it is re-rendered
-        // the initialization process always occurs from the same base state. This helps avoid
-        // initialization inconsistencies (i.e While the portal was unrendered, the user might have
-        // become disconnected from their backing Ethereum node, changes user accounts, etc...)
-        this.props.dispatcher.resetState();
-    }
-    public componentWillReceiveProps(nextProps: PortalAllProps) {
-        if (nextProps.networkId !== this.state.prevNetworkId) {
-            // tslint:disable-next-line:no-floating-promises
-            this._blockchain.networkIdUpdatedFireAndForgetAsync(nextProps.networkId);
-            this.setState({
-                prevNetworkId: nextProps.networkId,
-            });
-        }
-        if (nextProps.userAddress !== this.state.prevUserAddress) {
-            // tslint:disable-next-line:no-floating-promises
-            this._blockchain.userAddressUpdatedFireAndForgetAsync(nextProps.userAddress);
-            if (!_.isEmpty(nextProps.userAddress) && nextProps.blockchainIsLoaded) {
-                const tokens = _.values(nextProps.tokenByAddress);
-                // tslint:disable-next-line:no-floating-promises
-                this._updateBalanceAndAllowanceWithLoadingScreenAsync(tokens);
-            }
-            this.setState({
-                prevUserAddress: nextProps.userAddress,
-            });
-        }
-        if (nextProps.nodeVersion !== this.state.prevNodeVersion) {
-            // tslint:disable-next-line:no-floating-promises
-            this._blockchain.nodeVersionUpdatedFireAndForgetAsync(nextProps.nodeVersion);
-        }
-        if (nextProps.location.pathname !== this.state.prevPathname) {
-            const isViewingBalances = _.includes(nextProps.location.pathname, `${WebsitePaths.Portal}/balances`);
-            const hasAlreadyDismissedWethNotice = Portal.hasAlreadyDismissedWethNotice();
-            this.setState({
-                prevPathname: nextProps.location.pathname,
-                isWethNoticeDialogOpen: !hasAlreadyDismissedWethNotice && isViewingBalances,
-            });
-        }
-    }
-    public render() {
-        const updateShouldBlockchainErrDialogBeOpen = this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen.bind(
-            this.props.dispatcher,
-        );
-        const portalStyle: React.CSSProperties = {
-            minHeight: '100vh',
-            display: 'flex',
-            flexDirection: 'column',
-            justifyContent: 'space-between',
-        };
-        const portalMenuContainerStyle: React.CSSProperties = {
-            overflow: 'hidden',
-            backgroundColor: colors.darkestGrey,
-            color: colors.white,
-        };
-        return (
-            <div style={portalStyle}>
-                <DocumentTitle title="0x Portal DApp" />
-                <TopBar
-                    userAddress={this.props.userAddress}
-                    blockchainIsLoaded={this.props.blockchainIsLoaded}
-                    location={this.props.location}
-                />
-                <div id="portal" className="mx-auto max-width-4" style={{ width: '100%' }}>
-                    <Paper className="mb3 mt2">
-                        {!configs.IS_MAINNET_ENABLED && this.props.networkId === constants.NETWORK_ID_MAINNET ? (
-                            <div className="p3 center">
-                                <div className="h2 py2">Mainnet unavailable</div>
-                                <div className="mx-auto pb2 pt2">
-                                    <img src="/images/zrx_token.png" style={{ width: 150 }} />
-                                </div>
-                                <div>
-                                    0x portal is currently unavailable on the Ethereum mainnet.
-                                    <div>To try it out, switch to the Kovan test network (networkId: 42).</div>
-                                    <div className="py2">Check back soon!</div>
-                                </div>
-                            </div>
-                        ) : (
-                            <div className="mx-auto flex">
-                                <div className="col col-2 pr2 pt1 sm-hide xs-hide" style={portalMenuContainerStyle}>
-                                    <PortalMenu menuItemStyle={{ color: colors.white }} />
-                                </div>
-                                <div className="col col-12 lg-col-10 md-col-10 sm-col sm-col-12">
-                                    <div className="py2" style={{ backgroundColor: colors.grey50 }}>
-                                        {this.props.blockchainIsLoaded ? (
-                                            <Switch>
-                                                <Route
-                                                    path={`${WebsitePaths.Portal}/weth`}
-                                                    render={this._renderEthWrapper.bind(this)}
-                                                />
-                                                <Route
-                                                    path={`${WebsitePaths.Portal}/fill`}
-                                                    render={this._renderFillOrder.bind(this)}
-                                                />
-                                                <Route
-                                                    path={`${WebsitePaths.Portal}/balances`}
-                                                    render={this._renderTokenBalances.bind(this)}
-                                                />
-                                                <Route
-                                                    path={`${WebsitePaths.Portal}/trades`}
-                                                    component={this._renderTradeHistory.bind(this)}
-                                                />
-                                                <Route
-                                                    path={`${WebsitePaths.Home}`}
-                                                    render={this._renderGenerateOrderForm.bind(this)}
-                                                />
-                                            </Switch>
-                                        ) : (
-                                            <Loading />
-                                        )}
-                                    </div>
-                                </div>
-                            </div>
-                        )}
-                    </Paper>
-                    <BlockchainErrDialog
-                        blockchain={this._blockchain}
-                        blockchainErr={this.props.blockchainErr}
-                        isOpen={this.props.shouldBlockchainErrDialogBeOpen}
-                        userAddress={this.props.userAddress}
-                        toggleDialogFn={updateShouldBlockchainErrDialogBeOpen}
-                        networkId={this.props.networkId}
-                    />
-                    <WrappedEthSectionNoticeDialog
-                        isOpen={this.state.isWethNoticeDialogOpen}
-                        onToggleDialog={this._onWethNoticeAccepted.bind(this)}
-                    />
-                    <PortalDisclaimerDialog
-                        isOpen={this.state.isDisclaimerDialogOpen}
-                        onToggleDialog={this._onPortalDisclaimerAccepted.bind(this)}
-                    />
-                    <FlashMessage dispatcher={this.props.dispatcher} flashMessage={this.props.flashMessage} />
-                </div>
-                <Footer />
-            </div>
-        );
-    }
-    private _renderEthWrapper() {
-        return (
-            <EthWrappers
-                networkId={this.props.networkId}
-                blockchain={this._blockchain}
-                dispatcher={this.props.dispatcher}
-                tokenByAddress={this.props.tokenByAddress}
-                tokenStateByAddress={this.props.tokenStateByAddress}
-                userAddress={this.props.userAddress}
-                userEtherBalance={this.props.userEtherBalance}
-            />
-        );
-    }
-    private _renderTradeHistory() {
-        return (
-            <TradeHistory
-                tokenByAddress={this.props.tokenByAddress}
-                userAddress={this.props.userAddress}
-                networkId={this.props.networkId}
-            />
-        );
-    }
-    private _renderTokenBalances() {
-        return (
-            <TokenBalances
-                blockchain={this._blockchain}
-                blockchainErr={this.props.blockchainErr}
-                blockchainIsLoaded={this.props.blockchainIsLoaded}
-                dispatcher={this.props.dispatcher}
-                screenWidth={this.props.screenWidth}
-                tokenByAddress={this.props.tokenByAddress}
-                tokenStateByAddress={this.props.tokenStateByAddress}
-                userAddress={this.props.userAddress}
-                userEtherBalance={this.props.userEtherBalance}
-                networkId={this.props.networkId}
-            />
-        );
-    }
-    private _renderFillOrder(match: any, location: Location, history: History) {
-        const initialFillOrder = !_.isUndefined(this.props.userSuppliedOrderCache)
-            ? this.props.userSuppliedOrderCache
-            : this._sharedOrderIfExists;
-        return (
-            <FillOrder
-                blockchain={this._blockchain}
-                blockchainErr={this.props.blockchainErr}
-                initialOrder={initialFillOrder}
-                isOrderInUrl={!_.isUndefined(this._sharedOrderIfExists)}
-                orderFillAmount={this.props.orderFillAmount}
-                networkId={this.props.networkId}
-                userAddress={this.props.userAddress}
-                tokenByAddress={this.props.tokenByAddress}
-                tokenStateByAddress={this.props.tokenStateByAddress}
-                dispatcher={this.props.dispatcher}
-            />
-        );
-    }
-    private _renderGenerateOrderForm(match: any, location: Location, history: History) {
-        return (
-            <GenerateOrderForm
-                blockchain={this._blockchain}
-                hashData={this.props.hashData}
-                dispatcher={this.props.dispatcher}
-            />
-        );
-    }
-    private _onPortalDisclaimerAccepted() {
-        localStorage.setItem(constants.LOCAL_STORAGE_KEY_ACCEPT_DISCLAIMER, 'set');
-        this.setState({
-            isDisclaimerDialogOpen: false,
-        });
-    }
-    private _onWethNoticeAccepted() {
-        localStorage.setItem(constants.LOCAL_STORAGE_KEY_DISMISS_WETH_NOTICE, 'set');
-        this.setState({
-            isWethNoticeDialogOpen: false,
-        });
-    }
-    private _getSharedOrderIfExists(): Order | undefined {
-        const queryString = window.location.search;
-        if (queryString.length === 0) {
-            return undefined;
-        }
-        const queryParams = queryString.substring(1).split('&');
-        const orderQueryParam = _.find(queryParams, queryParam => {
-            const queryPair = queryParam.split('=');
-            return queryPair[0] === 'order';
-        });
-        if (_.isUndefined(orderQueryParam)) {
-            return undefined;
-        }
-        const orderPair = orderQueryParam.split('=');
-        if (orderPair.length !== 2) {
-            return undefined;
-        }
+		const didAcceptPortalDisclaimer = localStorage.getItemIfExists(constants.LOCAL_STORAGE_KEY_ACCEPT_DISCLAIMER);
+		const hasAcceptedDisclaimer =
+			!_.isUndefined(didAcceptPortalDisclaimer) && !_.isEmpty(didAcceptPortalDisclaimer);
+		this.state = {
+			prevNetworkId: this.props.networkId,
+			prevNodeVersion: this.props.nodeVersion,
+			prevUserAddress: this.props.userAddress,
+			prevPathname: this.props.location.pathname,
+			isDisclaimerDialogOpen: !hasAcceptedDisclaimer,
+			isWethNoticeDialogOpen: !hasAlreadyDismissedWethNotice && isViewingBalances,
+		};
+	}
+	public componentDidMount() {
+		window.addEventListener('resize', this._throttledScreenWidthUpdate);
+		window.scrollTo(0, 0);
+	}
+	public componentWillMount() {
+		this._blockchain = new Blockchain(this.props.dispatcher);
+	}
+	public componentWillUnmount() {
+		this._blockchain.destroy();
+		window.removeEventListener('resize', this._throttledScreenWidthUpdate);
+		// We re-set the entire redux state when the portal is unmounted so that when it is re-rendered
+		// the initialization process always occurs from the same base state. This helps avoid
+		// initialization inconsistencies (i.e While the portal was unrendered, the user might have
+		// become disconnected from their backing Ethereum node, changes user accounts, etc...)
+		this.props.dispatcher.resetState();
+	}
+	public componentWillReceiveProps(nextProps: PortalAllProps) {
+		if (nextProps.networkId !== this.state.prevNetworkId) {
+			// tslint:disable-next-line:no-floating-promises
+			this._blockchain.networkIdUpdatedFireAndForgetAsync(nextProps.networkId);
+			this.setState({
+				prevNetworkId: nextProps.networkId,
+			});
+		}
+		if (nextProps.userAddress !== this.state.prevUserAddress) {
+			// tslint:disable-next-line:no-floating-promises
+			this._blockchain.userAddressUpdatedFireAndForgetAsync(nextProps.userAddress);
+			if (!_.isEmpty(nextProps.userAddress) && nextProps.blockchainIsLoaded) {
+				const tokens = _.values(nextProps.tokenByAddress);
+				// tslint:disable-next-line:no-floating-promises
+				this._updateBalanceAndAllowanceWithLoadingScreenAsync(tokens);
+			}
+			this.setState({
+				prevUserAddress: nextProps.userAddress,
+			});
+		}
+		if (nextProps.nodeVersion !== this.state.prevNodeVersion) {
+			// tslint:disable-next-line:no-floating-promises
+			this._blockchain.nodeVersionUpdatedFireAndForgetAsync(nextProps.nodeVersion);
+		}
+		if (nextProps.location.pathname !== this.state.prevPathname) {
+			const isViewingBalances = _.includes(nextProps.location.pathname, `${WebsitePaths.Portal}/balances`);
+			const hasAlreadyDismissedWethNotice = Portal.hasAlreadyDismissedWethNotice();
+			this.setState({
+				prevPathname: nextProps.location.pathname,
+				isWethNoticeDialogOpen: !hasAlreadyDismissedWethNotice && isViewingBalances,
+			});
+		}
+	}
+	public render() {
+		const updateShouldBlockchainErrDialogBeOpen = this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen.bind(
+			this.props.dispatcher,
+		);
+		const portalStyle: React.CSSProperties = {
+			minHeight: '100vh',
+			display: 'flex',
+			flexDirection: 'column',
+			justifyContent: 'space-between',
+		};
+		const portalMenuContainerStyle: React.CSSProperties = {
+			overflow: 'hidden',
+			backgroundColor: colors.darkestGrey,
+			color: colors.white,
+		};
+		return (
+			<div style={portalStyle}>
+				<DocumentTitle title="0x Portal DApp" />
+				<TopBar
+					userAddress={this.props.userAddress}
+					blockchainIsLoaded={this.props.blockchainIsLoaded}
+					location={this.props.location}
+				/>
+				<div id="portal" className="mx-auto max-width-4" style={{ width: '100%' }}>
+					<Paper className="mb3 mt2">
+						{!configs.IS_MAINNET_ENABLED && this.props.networkId === constants.NETWORK_ID_MAINNET ? (
+							<div className="p3 center">
+								<div className="h2 py2">Mainnet unavailable</div>
+								<div className="mx-auto pb2 pt2">
+									<img src="/images/zrx_token.png" style={{ width: 150 }} />
+								</div>
+								<div>
+									0x portal is currently unavailable on the Ethereum mainnet.
+									<div>To try it out, switch to the Kovan test network (networkId: 42).</div>
+									<div className="py2">Check back soon!</div>
+								</div>
+							</div>
+						) : (
+							<div className="mx-auto flex">
+								<div className="col col-2 pr2 pt1 sm-hide xs-hide" style={portalMenuContainerStyle}>
+									<PortalMenu menuItemStyle={{ color: colors.white }} />
+								</div>
+								<div className="col col-12 lg-col-10 md-col-10 sm-col sm-col-12">
+									<div className="py2" style={{ backgroundColor: colors.grey50 }}>
+										{this.props.blockchainIsLoaded ? (
+											<Switch>
+												<Route
+													path={`${WebsitePaths.Portal}/weth`}
+													render={this._renderEthWrapper.bind(this)}
+												/>
+												<Route
+													path={`${WebsitePaths.Portal}/fill`}
+													render={this._renderFillOrder.bind(this)}
+												/>
+												<Route
+													path={`${WebsitePaths.Portal}/balances`}
+													render={this._renderTokenBalances.bind(this)}
+												/>
+												<Route
+													path={`${WebsitePaths.Portal}/trades`}
+													component={this._renderTradeHistory.bind(this)}
+												/>
+												<Route
+													path={`${WebsitePaths.Home}`}
+													render={this._renderGenerateOrderForm.bind(this)}
+												/>
+											</Switch>
+										) : (
+											<Loading />
+										)}
+									</div>
+								</div>
+							</div>
+						)}
+					</Paper>
+					<BlockchainErrDialog
+						blockchain={this._blockchain}
+						blockchainErr={this.props.blockchainErr}
+						isOpen={this.props.shouldBlockchainErrDialogBeOpen}
+						userAddress={this.props.userAddress}
+						toggleDialogFn={updateShouldBlockchainErrDialogBeOpen}
+						networkId={this.props.networkId}
+					/>
+					<WrappedEthSectionNoticeDialog
+						isOpen={this.state.isWethNoticeDialogOpen}
+						onToggleDialog={this._onWethNoticeAccepted.bind(this)}
+					/>
+					<PortalDisclaimerDialog
+						isOpen={this.state.isDisclaimerDialogOpen}
+						onToggleDialog={this._onPortalDisclaimerAccepted.bind(this)}
+					/>
+					<FlashMessage dispatcher={this.props.dispatcher} flashMessage={this.props.flashMessage} />
+				</div>
+				<Footer />
+			</div>
+		);
+	}
+	private _renderEthWrapper() {
+		return (
+			<EthWrappers
+				networkId={this.props.networkId}
+				blockchain={this._blockchain}
+				dispatcher={this.props.dispatcher}
+				tokenByAddress={this.props.tokenByAddress}
+				tokenStateByAddress={this.props.tokenStateByAddress}
+				userAddress={this.props.userAddress}
+				userEtherBalance={this.props.userEtherBalance}
+			/>
+		);
+	}
+	private _renderTradeHistory() {
+		return (
+			<TradeHistory
+				tokenByAddress={this.props.tokenByAddress}
+				userAddress={this.props.userAddress}
+				networkId={this.props.networkId}
+			/>
+		);
+	}
+	private _renderTokenBalances() {
+		return (
+			<TokenBalances
+				blockchain={this._blockchain}
+				blockchainErr={this.props.blockchainErr}
+				blockchainIsLoaded={this.props.blockchainIsLoaded}
+				dispatcher={this.props.dispatcher}
+				screenWidth={this.props.screenWidth}
+				tokenByAddress={this.props.tokenByAddress}
+				tokenStateByAddress={this.props.tokenStateByAddress}
+				userAddress={this.props.userAddress}
+				userEtherBalance={this.props.userEtherBalance}
+				networkId={this.props.networkId}
+			/>
+		);
+	}
+	private _renderFillOrder(match: any, location: Location, history: History) {
+		const initialFillOrder = !_.isUndefined(this.props.userSuppliedOrderCache)
+			? this.props.userSuppliedOrderCache
+			: this._sharedOrderIfExists;
+		return (
+			<FillOrder
+				blockchain={this._blockchain}
+				blockchainErr={this.props.blockchainErr}
+				initialOrder={initialFillOrder}
+				isOrderInUrl={!_.isUndefined(this._sharedOrderIfExists)}
+				orderFillAmount={this.props.orderFillAmount}
+				networkId={this.props.networkId}
+				userAddress={this.props.userAddress}
+				tokenByAddress={this.props.tokenByAddress}
+				tokenStateByAddress={this.props.tokenStateByAddress}
+				dispatcher={this.props.dispatcher}
+			/>
+		);
+	}
+	private _renderGenerateOrderForm(match: any, location: Location, history: History) {
+		return (
+			<GenerateOrderForm
+				blockchain={this._blockchain}
+				hashData={this.props.hashData}
+				dispatcher={this.props.dispatcher}
+			/>
+		);
+	}
+	private _onPortalDisclaimerAccepted() {
+		localStorage.setItem(constants.LOCAL_STORAGE_KEY_ACCEPT_DISCLAIMER, 'set');
+		this.setState({
+			isDisclaimerDialogOpen: false,
+		});
+	}
+	private _onWethNoticeAccepted() {
+		localStorage.setItem(constants.LOCAL_STORAGE_KEY_DISMISS_WETH_NOTICE, 'set');
+		this.setState({
+			isWethNoticeDialogOpen: false,
+		});
+	}
+	private _getSharedOrderIfExists(): Order | undefined {
+		const queryString = window.location.search;
+		if (queryString.length === 0) {
+			return undefined;
+		}
+		const queryParams = queryString.substring(1).split('&');
+		const orderQueryParam = _.find(queryParams, queryParam => {
+			const queryPair = queryParam.split('=');
+			return queryPair[0] === 'order';
+		});
+		if (_.isUndefined(orderQueryParam)) {
+			return undefined;
+		}
+		const orderPair = orderQueryParam.split('=');
+		if (orderPair.length !== 2) {
+			return undefined;
+		}
 
-        const validator = new SchemaValidator();
-        const order = JSON.parse(decodeURIComponent(orderPair[1]));
-        const validationResult = validator.validate(order, orderSchema);
-        if (validationResult.errors.length > 0) {
-            utils.consoleLog(`Invalid shared order: ${validationResult.errors}`);
-            return undefined;
-        }
-        return order;
-    }
-    private _updateScreenWidth() {
-        const newScreenWidth = utils.getScreenWidth();
-        this.props.dispatcher.updateScreenWidth(newScreenWidth);
-    }
-    private async _updateBalanceAndAllowanceWithLoadingScreenAsync(tokens: Token[]) {
-        this.props.dispatcher.updateBlockchainIsLoaded(false);
-        await this._blockchain.updateTokenBalancesAndAllowancesAsync(tokens);
-        this.props.dispatcher.updateBlockchainIsLoaded(true);
-    }
+		const validator = new SchemaValidator();
+		const order = JSON.parse(decodeURIComponent(orderPair[1]));
+		const validationResult = validator.validate(order, orderSchema);
+		if (validationResult.errors.length > 0) {
+			utils.consoleLog(`Invalid shared order: ${validationResult.errors}`);
+			return undefined;
+		}
+		return order;
+	}
+	private _updateScreenWidth() {
+		const newScreenWidth = utils.getScreenWidth();
+		this.props.dispatcher.updateScreenWidth(newScreenWidth);
+	}
+	private async _updateBalanceAndAllowanceWithLoadingScreenAsync(tokens: Token[]) {
+		this.props.dispatcher.updateBlockchainIsLoaded(false);
+		await this._blockchain.updateTokenBalancesAndAllowancesAsync(tokens);
+		this.props.dispatcher.updateBlockchainIsLoaded(true);
+	}
 }
diff --git a/packages/website/ts/components/portal_menu.tsx b/packages/website/ts/components/portal_menu.tsx
index a2f9340c8..b025f527e 100644
--- a/packages/website/ts/components/portal_menu.tsx
+++ b/packages/website/ts/components/portal_menu.tsx
@@ -4,70 +4,70 @@ import { MenuItem } from 'ts/components/ui/menu_item';
 import { WebsitePaths } from 'ts/types';
 
 export interface PortalMenuProps {
-    menuItemStyle: React.CSSProperties;
-    onClick?: () => void;
+	menuItemStyle: React.CSSProperties;
+	onClick?: () => void;
 }
 
 interface PortalMenuState {}
 
 export class PortalMenu extends React.Component<PortalMenuProps, PortalMenuState> {
-    public static defaultProps: Partial<PortalMenuProps> = {
-        onClick: _.noop,
-    };
-    public render() {
-        return (
-            <div>
-                <MenuItem
-                    style={this.props.menuItemStyle}
-                    className="py2"
-                    to={`${WebsitePaths.Portal}`}
-                    onClick={this.props.onClick.bind(this)}
-                >
-                    {this._renderMenuItemWithIcon('Generate order', 'zmdi-arrow-right-top')}
-                </MenuItem>
-                <MenuItem
-                    style={this.props.menuItemStyle}
-                    className="py2"
-                    to={`${WebsitePaths.Portal}/fill`}
-                    onClick={this.props.onClick.bind(this)}
-                >
-                    {this._renderMenuItemWithIcon('Fill order', 'zmdi-arrow-left-bottom')}
-                </MenuItem>
-                <MenuItem
-                    style={this.props.menuItemStyle}
-                    className="py2"
-                    to={`${WebsitePaths.Portal}/balances`}
-                    onClick={this.props.onClick.bind(this)}
-                >
-                    {this._renderMenuItemWithIcon('Balances', 'zmdi-balance-wallet')}
-                </MenuItem>
-                <MenuItem
-                    style={this.props.menuItemStyle}
-                    className="py2"
-                    to={`${WebsitePaths.Portal}/trades`}
-                    onClick={this.props.onClick.bind(this)}
-                >
-                    {this._renderMenuItemWithIcon('Trade history', 'zmdi-format-list-bulleted')}
-                </MenuItem>
-                <MenuItem
-                    style={this.props.menuItemStyle}
-                    className="py2"
-                    to={`${WebsitePaths.Portal}/weth`}
-                    onClick={this.props.onClick.bind(this)}
-                >
-                    {this._renderMenuItemWithIcon('Wrap ETH', 'zmdi-circle-o')}
-                </MenuItem>
-            </div>
-        );
-    }
-    private _renderMenuItemWithIcon(title: string, iconName: string) {
-        return (
-            <div className="flex" style={{ fontWeight: 100 }}>
-                <div className="pr1 pl2">
-                    <i style={{ fontSize: 20 }} className={`zmdi ${iconName}`} />
-                </div>
-                <div className="pl1">{title}</div>
-            </div>
-        );
-    }
+	public static defaultProps: Partial<PortalMenuProps> = {
+		onClick: _.noop,
+	};
+	public render() {
+		return (
+			<div>
+				<MenuItem
+					style={this.props.menuItemStyle}
+					className="py2"
+					to={`${WebsitePaths.Portal}`}
+					onClick={this.props.onClick.bind(this)}
+				>
+					{this._renderMenuItemWithIcon('Generate order', 'zmdi-arrow-right-top')}
+				</MenuItem>
+				<MenuItem
+					style={this.props.menuItemStyle}
+					className="py2"
+					to={`${WebsitePaths.Portal}/fill`}
+					onClick={this.props.onClick.bind(this)}
+				>
+					{this._renderMenuItemWithIcon('Fill order', 'zmdi-arrow-left-bottom')}
+				</MenuItem>
+				<MenuItem
+					style={this.props.menuItemStyle}
+					className="py2"
+					to={`${WebsitePaths.Portal}/balances`}
+					onClick={this.props.onClick.bind(this)}
+				>
+					{this._renderMenuItemWithIcon('Balances', 'zmdi-balance-wallet')}
+				</MenuItem>
+				<MenuItem
+					style={this.props.menuItemStyle}
+					className="py2"
+					to={`${WebsitePaths.Portal}/trades`}
+					onClick={this.props.onClick.bind(this)}
+				>
+					{this._renderMenuItemWithIcon('Trade history', 'zmdi-format-list-bulleted')}
+				</MenuItem>
+				<MenuItem
+					style={this.props.menuItemStyle}
+					className="py2"
+					to={`${WebsitePaths.Portal}/weth`}
+					onClick={this.props.onClick.bind(this)}
+				>
+					{this._renderMenuItemWithIcon('Wrap ETH', 'zmdi-circle-o')}
+				</MenuItem>
+			</div>
+		);
+	}
+	private _renderMenuItemWithIcon(title: string, iconName: string) {
+		return (
+			<div className="flex" style={{ fontWeight: 100 }}>
+				<div className="pr1 pl2">
+					<i style={{ fontSize: 20 }} className={`zmdi ${iconName}`} />
+				</div>
+				<div className="pl1">{title}</div>
+			</div>
+		);
+	}
 }
diff --git a/packages/website/ts/components/send_button.tsx b/packages/website/ts/components/send_button.tsx
index f94ec346a..f97d9250b 100644
--- a/packages/website/ts/components/send_button.tsx
+++ b/packages/website/ts/components/send_button.tsx
@@ -10,78 +10,78 @@ import { errorReporter } from 'ts/utils/error_reporter';
 import { utils } from 'ts/utils/utils';
 
 interface SendButtonProps {
-    token: Token;
-    tokenState: TokenState;
-    dispatcher: Dispatcher;
-    blockchain: Blockchain;
-    onError: () => void;
+	token: Token;
+	tokenState: TokenState;
+	dispatcher: Dispatcher;
+	blockchain: Blockchain;
+	onError: () => void;
 }
 
 interface SendButtonState {
-    isSendDialogVisible: boolean;
-    isSending: boolean;
+	isSendDialogVisible: boolean;
+	isSending: boolean;
 }
 
 export class SendButton extends React.Component<SendButtonProps, SendButtonState> {
-    public constructor(props: SendButtonProps) {
-        super(props);
-        this.state = {
-            isSendDialogVisible: false,
-            isSending: false,
-        };
-    }
-    public render() {
-        const labelStyle = this.state.isSending ? { fontSize: 10 } : {};
-        return (
-            <div>
-                <RaisedButton
-                    style={{ width: '100%' }}
-                    labelStyle={labelStyle}
-                    disabled={this.state.isSending}
-                    label={this.state.isSending ? 'Sending...' : 'Send'}
-                    onClick={this._toggleSendDialog.bind(this)}
-                />
-                <SendDialog
-                    isOpen={this.state.isSendDialogVisible}
-                    onComplete={this._onSendAmountSelectedAsync.bind(this)}
-                    onCancelled={this._toggleSendDialog.bind(this)}
-                    token={this.props.token}
-                    tokenState={this.props.tokenState}
-                />
-            </div>
-        );
-    }
-    private _toggleSendDialog() {
-        this.setState({
-            isSendDialogVisible: !this.state.isSendDialogVisible,
-        });
-    }
-    private async _onSendAmountSelectedAsync(recipient: string, value: BigNumber) {
-        this.setState({
-            isSending: true,
-        });
-        this._toggleSendDialog();
-        const token = this.props.token;
-        const tokenState = this.props.tokenState;
-        let balance = tokenState.balance;
-        try {
-            await this.props.blockchain.transferAsync(token, recipient, value);
-            balance = balance.minus(value);
-            this.props.dispatcher.replaceTokenBalanceByAddress(token.address, balance);
-        } catch (err) {
-            const errMsg = `${err}`;
-            if (_.includes(errMsg, BlockchainCallErrs.UserHasNoAssociatedAddresses)) {
-                this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
-                return;
-            } else if (!_.includes(errMsg, 'User denied transaction')) {
-                utils.consoleLog(`Unexpected error encountered: ${err}`);
-                utils.consoleLog(err.stack);
-                this.props.onError();
-                await errorReporter.reportAsync(err);
-            }
-        }
-        this.setState({
-            isSending: false,
-        });
-    }
+	public constructor(props: SendButtonProps) {
+		super(props);
+		this.state = {
+			isSendDialogVisible: false,
+			isSending: false,
+		};
+	}
+	public render() {
+		const labelStyle = this.state.isSending ? { fontSize: 10 } : {};
+		return (
+			<div>
+				<RaisedButton
+					style={{ width: '100%' }}
+					labelStyle={labelStyle}
+					disabled={this.state.isSending}
+					label={this.state.isSending ? 'Sending...' : 'Send'}
+					onClick={this._toggleSendDialog.bind(this)}
+				/>
+				<SendDialog
+					isOpen={this.state.isSendDialogVisible}
+					onComplete={this._onSendAmountSelectedAsync.bind(this)}
+					onCancelled={this._toggleSendDialog.bind(this)}
+					token={this.props.token}
+					tokenState={this.props.tokenState}
+				/>
+			</div>
+		);
+	}
+	private _toggleSendDialog() {
+		this.setState({
+			isSendDialogVisible: !this.state.isSendDialogVisible,
+		});
+	}
+	private async _onSendAmountSelectedAsync(recipient: string, value: BigNumber) {
+		this.setState({
+			isSending: true,
+		});
+		this._toggleSendDialog();
+		const token = this.props.token;
+		const tokenState = this.props.tokenState;
+		let balance = tokenState.balance;
+		try {
+			await this.props.blockchain.transferAsync(token, recipient, value);
+			balance = balance.minus(value);
+			this.props.dispatcher.replaceTokenBalanceByAddress(token.address, balance);
+		} catch (err) {
+			const errMsg = `${err}`;
+			if (_.includes(errMsg, BlockchainCallErrs.UserHasNoAssociatedAddresses)) {
+				this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
+				return;
+			} else if (!_.includes(errMsg, 'User denied transaction')) {
+				utils.consoleLog(`Unexpected error encountered: ${err}`);
+				utils.consoleLog(err.stack);
+				this.props.onError();
+				await errorReporter.reportAsync(err);
+			}
+		}
+		this.setState({
+			isSending: false,
+		});
+	}
 }
diff --git a/packages/website/ts/components/token_balances.tsx b/packages/website/ts/components/token_balances.tsx
index 2cef413c7..480652c34 100644
--- a/packages/website/ts/components/token_balances.tsx
+++ b/packages/website/ts/components/token_balances.tsx
@@ -23,16 +23,16 @@ import { TokenIcon } from 'ts/components/ui/token_icon';
 import { trackedTokenStorage } from 'ts/local_storage/tracked_token_storage';
 import { Dispatcher } from 'ts/redux/dispatcher';
 import {
-    BalanceErrs,
-    BlockchainCallErrs,
-    BlockchainErrs,
-    EtherscanLinkSuffixes,
-    ScreenWidths,
-    Styles,
-    Token,
-    TokenByAddress,
-    TokenStateByAddress,
-    TokenVisibility,
+	BalanceErrs,
+	BlockchainCallErrs,
+	BlockchainErrs,
+	EtherscanLinkSuffixes,
+	ScreenWidths,
+	Styles,
+	Token,
+	TokenByAddress,
+	TokenStateByAddress,
+	TokenVisibility,
 } from 'ts/types';
 import { colors } from 'ts/utils/colors';
 import { configs } from 'ts/utils/configs';
@@ -53,554 +53,554 @@ const TOKEN_COL_SPAN_LG = 2;
 const TOKEN_COL_SPAN_SM = 1;
 
 const styles: Styles = {
-    bgColor: {
-        backgroundColor: colors.grey50,
-    },
+	bgColor: {
+		backgroundColor: colors.grey50,
+	},
 };
 
 interface TokenBalancesProps {
-    blockchain: Blockchain;
-    blockchainErr: BlockchainErrs;
-    blockchainIsLoaded: boolean;
-    dispatcher: Dispatcher;
-    screenWidth: ScreenWidths;
-    tokenByAddress: TokenByAddress;
-    tokenStateByAddress: TokenStateByAddress;
-    userAddress: string;
-    userEtherBalance: BigNumber;
-    networkId: number;
+	blockchain: Blockchain;
+	blockchainErr: BlockchainErrs;
+	blockchainIsLoaded: boolean;
+	dispatcher: Dispatcher;
+	screenWidth: ScreenWidths;
+	tokenByAddress: TokenByAddress;
+	tokenStateByAddress: TokenStateByAddress;
+	userAddress: string;
+	userEtherBalance: BigNumber;
+	networkId: number;
 }
 
 interface TokenBalancesState {
-    errorType: BalanceErrs;
-    isBalanceSpinnerVisible: boolean;
-    isDharmaDialogVisible: boolean;
-    isZRXSpinnerVisible: boolean;
-    currentZrxBalance?: BigNumber;
-    isTokenPickerOpen: boolean;
-    isAddingToken: boolean;
+	errorType: BalanceErrs;
+	isBalanceSpinnerVisible: boolean;
+	isDharmaDialogVisible: boolean;
+	isZRXSpinnerVisible: boolean;
+	currentZrxBalance?: BigNumber;
+	isTokenPickerOpen: boolean;
+	isAddingToken: boolean;
 }
 
 export class TokenBalances extends React.Component<TokenBalancesProps, TokenBalancesState> {
-    public constructor(props: TokenBalancesProps) {
-        super(props);
-        this.state = {
-            errorType: undefined,
-            isBalanceSpinnerVisible: false,
-            isZRXSpinnerVisible: false,
-            isDharmaDialogVisible: DharmaLoanFrame.isAuthTokenPresent(),
-            isTokenPickerOpen: false,
-            isAddingToken: false,
-        };
-    }
-    public componentWillReceiveProps(nextProps: TokenBalancesProps) {
-        if (nextProps.userEtherBalance !== this.props.userEtherBalance) {
-            if (this.state.isBalanceSpinnerVisible) {
-                const receivedAmount = nextProps.userEtherBalance.minus(this.props.userEtherBalance);
-                this.props.dispatcher.showFlashMessage(`Received ${receivedAmount.toString(10)} Kovan Ether`);
-            }
-            this.setState({
-                isBalanceSpinnerVisible: false,
-            });
-        }
-        const nextZrxToken = _.find(_.values(nextProps.tokenByAddress), t => t.symbol === ZRX_TOKEN_SYMBOL);
-        const nextZrxTokenBalance = nextProps.tokenStateByAddress[nextZrxToken.address].balance;
-        if (!_.isUndefined(this.state.currentZrxBalance) && !nextZrxTokenBalance.eq(this.state.currentZrxBalance)) {
-            if (this.state.isZRXSpinnerVisible) {
-                const receivedAmount = nextZrxTokenBalance.minus(this.state.currentZrxBalance);
-                const receiveAmountInUnits = ZeroEx.toUnitAmount(receivedAmount, constants.DECIMAL_PLACES_ZRX);
-                this.props.dispatcher.showFlashMessage(`Received ${receiveAmountInUnits.toString(10)} Kovan ZRX`);
-            }
-            this.setState({
-                isZRXSpinnerVisible: false,
-                currentZrxBalance: undefined,
-            });
-        }
-    }
-    public componentDidMount() {
-        window.scrollTo(0, 0);
-    }
-    public render() {
-        const errorDialogActions = [
-            <FlatButton
-                key="errorOkBtn"
-                label="Ok"
-                primary={true}
-                onTouchTap={this._onErrorDialogToggle.bind(this, false)}
-            />,
-        ];
-        const dharmaDialogActions = [
-            <FlatButton
-                key="dharmaCloseBtn"
-                label="Close"
-                primary={true}
-                onTouchTap={this._onDharmaDialogToggle.bind(this, false)}
-            />,
-        ];
-        const isTestNetwork = this.props.networkId === constants.NETWORK_ID_TESTNET;
-        const dharmaButtonColumnStyle = {
-            paddingLeft: 3,
-            display: isTestNetwork ? 'table-cell' : 'none',
-        };
-        const stubColumnStyle = {
-            display: isTestNetwork ? 'none' : 'table-cell',
-        };
-        const allTokenRowHeight = _.size(this.props.tokenByAddress) * TOKEN_TABLE_ROW_HEIGHT;
-        const tokenTableHeight =
-            allTokenRowHeight < MAX_TOKEN_TABLE_HEIGHT ? allTokenRowHeight : MAX_TOKEN_TABLE_HEIGHT;
-        const isSmallScreen = this.props.screenWidth === ScreenWidths.Sm;
-        const tokenColSpan = isSmallScreen ? TOKEN_COL_SPAN_SM : TOKEN_COL_SPAN_LG;
-        const dharmaLoanExplanation =
-            'If you need access to larger amounts of ether,<br> \
+	public constructor(props: TokenBalancesProps) {
+		super(props);
+		this.state = {
+			errorType: undefined,
+			isBalanceSpinnerVisible: false,
+			isZRXSpinnerVisible: false,
+			isDharmaDialogVisible: DharmaLoanFrame.isAuthTokenPresent(),
+			isTokenPickerOpen: false,
+			isAddingToken: false,
+		};
+	}
+	public componentWillReceiveProps(nextProps: TokenBalancesProps) {
+		if (nextProps.userEtherBalance !== this.props.userEtherBalance) {
+			if (this.state.isBalanceSpinnerVisible) {
+				const receivedAmount = nextProps.userEtherBalance.minus(this.props.userEtherBalance);
+				this.props.dispatcher.showFlashMessage(`Received ${receivedAmount.toString(10)} Kovan Ether`);
+			}
+			this.setState({
+				isBalanceSpinnerVisible: false,
+			});
+		}
+		const nextZrxToken = _.find(_.values(nextProps.tokenByAddress), t => t.symbol === ZRX_TOKEN_SYMBOL);
+		const nextZrxTokenBalance = nextProps.tokenStateByAddress[nextZrxToken.address].balance;
+		if (!_.isUndefined(this.state.currentZrxBalance) && !nextZrxTokenBalance.eq(this.state.currentZrxBalance)) {
+			if (this.state.isZRXSpinnerVisible) {
+				const receivedAmount = nextZrxTokenBalance.minus(this.state.currentZrxBalance);
+				const receiveAmountInUnits = ZeroEx.toUnitAmount(receivedAmount, constants.DECIMAL_PLACES_ZRX);
+				this.props.dispatcher.showFlashMessage(`Received ${receiveAmountInUnits.toString(10)} Kovan ZRX`);
+			}
+			this.setState({
+				isZRXSpinnerVisible: false,
+				currentZrxBalance: undefined,
+			});
+		}
+	}
+	public componentDidMount() {
+		window.scrollTo(0, 0);
+	}
+	public render() {
+		const errorDialogActions = [
+			<FlatButton
+				key="errorOkBtn"
+				label="Ok"
+				primary={true}
+				onTouchTap={this._onErrorDialogToggle.bind(this, false)}
+			/>,
+		];
+		const dharmaDialogActions = [
+			<FlatButton
+				key="dharmaCloseBtn"
+				label="Close"
+				primary={true}
+				onTouchTap={this._onDharmaDialogToggle.bind(this, false)}
+			/>,
+		];
+		const isTestNetwork = this.props.networkId === constants.NETWORK_ID_TESTNET;
+		const dharmaButtonColumnStyle = {
+			paddingLeft: 3,
+			display: isTestNetwork ? 'table-cell' : 'none',
+		};
+		const stubColumnStyle = {
+			display: isTestNetwork ? 'none' : 'table-cell',
+		};
+		const allTokenRowHeight = _.size(this.props.tokenByAddress) * TOKEN_TABLE_ROW_HEIGHT;
+		const tokenTableHeight =
+			allTokenRowHeight < MAX_TOKEN_TABLE_HEIGHT ? allTokenRowHeight : MAX_TOKEN_TABLE_HEIGHT;
+		const isSmallScreen = this.props.screenWidth === ScreenWidths.Sm;
+		const tokenColSpan = isSmallScreen ? TOKEN_COL_SPAN_SM : TOKEN_COL_SPAN_LG;
+		const dharmaLoanExplanation =
+			'If you need access to larger amounts of ether,<br> \
                                      you can request a loan from the Dharma Loan<br> \
                                      network.  Your loan should be funded in 5<br>  \
                                      minutes or less.';
-        const allowanceExplanation =
-            '0x smart contracts require access to your<br> \
+		const allowanceExplanation =
+			'0x smart contracts require access to your<br> \
                                   token balances in order to execute trades.<br> \
                                   Toggling sets an allowance for the<br> \
                                   smart contract so you can start trading that token.';
-        return (
-            <div className="lg-px4 md-px4 sm-px1 pb2">
-                <h3>{isTestNetwork ? 'Test ether' : 'Ether'}</h3>
-                <Divider />
-                <div className="pt2 pb2">
-                    {isTestNetwork
-                        ? 'In order to try out the 0x Portal Dapp, request some test ether to pay for \
+		return (
+			<div className="lg-px4 md-px4 sm-px1 pb2">
+				<h3>{isTestNetwork ? 'Test ether' : 'Ether'}</h3>
+				<Divider />
+				<div className="pt2 pb2">
+					{isTestNetwork
+						? 'In order to try out the 0x Portal Dapp, request some test ether to pay for \
                         gas costs. It might take a bit of time for the test ether to show up.'
-                        : 'Ether must be converted to Ether Tokens in order to be tradable via 0x. \
+						: 'Ether must be converted to Ether Tokens in order to be tradable via 0x. \
                          You can convert between Ether and Ether Tokens from the "Wrap ETH" tab.'}
-                </div>
-                <Table selectable={false} style={styles.bgColor}>
-                    <TableHeader displaySelectAll={false} adjustForCheckbox={false}>
-                        <TableRow>
-                            <TableHeaderColumn>Currency</TableHeaderColumn>
-                            <TableHeaderColumn>Balance</TableHeaderColumn>
-                            <TableRowColumn className="sm-hide xs-hide" style={stubColumnStyle} />
-                            {isTestNetwork && (
-                                <TableHeaderColumn style={{ paddingLeft: 3 }}>
-                                    {isSmallScreen ? 'Faucet' : 'Request from faucet'}
-                                </TableHeaderColumn>
-                            )}
-                            {isTestNetwork && (
-                                <TableHeaderColumn style={dharmaButtonColumnStyle}>
-                                    {isSmallScreen ? 'Loan' : 'Request Dharma loan'}
-                                    <HelpTooltip style={{ paddingLeft: 4 }} explanation={dharmaLoanExplanation} />
-                                </TableHeaderColumn>
-                            )}
-                        </TableRow>
-                    </TableHeader>
-                    <TableBody displayRowCheckbox={false}>
-                        <TableRow key="ETH">
-                            <TableRowColumn className="py1">
-                                <img style={{ width: ICON_DIMENSION, height: ICON_DIMENSION }} src={ETHER_ICON_PATH} />
-                            </TableRowColumn>
-                            <TableRowColumn>
-                                {this.props.userEtherBalance.toFixed(PRECISION)} ETH
-                                {this.state.isBalanceSpinnerVisible && (
-                                    <span className="pl1">
-                                        <i className="zmdi zmdi-spinner zmdi-hc-spin" />
-                                    </span>
-                                )}
-                            </TableRowColumn>
-                            <TableRowColumn className="sm-hide xs-hide" style={stubColumnStyle} />
-                            {isTestNetwork && (
-                                <TableRowColumn style={{ paddingLeft: 3 }}>
-                                    <LifeCycleRaisedButton
-                                        labelReady="Request"
-                                        labelLoading="Sending..."
-                                        labelComplete="Sent!"
-                                        onClickAsyncFn={this._faucetRequestAsync.bind(this, true)}
-                                    />
-                                </TableRowColumn>
-                            )}
-                            {isTestNetwork && (
-                                <TableRowColumn style={dharmaButtonColumnStyle}>
-                                    <RaisedButton
-                                        label="Request"
-                                        style={{ width: '100%' }}
-                                        onTouchTap={this._onDharmaDialogToggle.bind(this)}
-                                    />
-                                </TableRowColumn>
-                            )}
-                        </TableRow>
-                    </TableBody>
-                </Table>
-                <div className="clearfix" style={{ paddingBottom: 1 }}>
-                    <div className="col col-10">
-                        <h3 className="pt2">{isTestNetwork ? 'Test tokens' : 'Tokens'}</h3>
-                    </div>
-                    <div className="col col-1 pt3 align-right">
-                        <FloatingActionButton mini={true} zDepth={0} onClick={this._onAddTokenClicked.bind(this)}>
-                            <ContentAdd />
-                        </FloatingActionButton>
-                    </div>
-                    <div className="col col-1 pt3 align-right">
-                        <FloatingActionButton mini={true} zDepth={0} onClick={this._onRemoveTokenClicked.bind(this)}>
-                            <ContentRemove />
-                        </FloatingActionButton>
-                    </div>
-                </div>
-                <Divider />
-                <div className="pt2 pb2">
-                    {isTestNetwork
-                        ? "Mint some test tokens you'd like to use to generate or fill an order using 0x."
-                        : "Set trading permissions for a token you'd like to start trading."}
-                </div>
-                <Table selectable={false} bodyStyle={{ height: tokenTableHeight }} style={styles.bgColor}>
-                    <TableHeader displaySelectAll={false} adjustForCheckbox={false}>
-                        <TableRow>
-                            <TableHeaderColumn colSpan={tokenColSpan}>Token</TableHeaderColumn>
-                            <TableHeaderColumn style={{ paddingLeft: 3 }}>Balance</TableHeaderColumn>
-                            <TableHeaderColumn>
-                                <div className="inline-block">Allowance</div>
-                                <HelpTooltip style={{ paddingLeft: 4 }} explanation={allowanceExplanation} />
-                            </TableHeaderColumn>
-                            <TableHeaderColumn>Action</TableHeaderColumn>
-                            {this.props.screenWidth !== ScreenWidths.Sm && <TableHeaderColumn>Send</TableHeaderColumn>}
-                        </TableRow>
-                    </TableHeader>
-                    <TableBody displayRowCheckbox={false}>{this._renderTokenTableRows()}</TableBody>
-                </Table>
-                <Dialog
-                    title="Oh oh"
-                    titleStyle={{ fontWeight: 100 }}
-                    actions={errorDialogActions}
-                    open={!_.isUndefined(this.state.errorType)}
-                    onRequestClose={this._onErrorDialogToggle.bind(this, false)}
-                >
-                    {this._renderErrorDialogBody()}
-                </Dialog>
-                <Dialog
-                    title="Request Dharma Loan"
-                    titleStyle={{ fontWeight: 100, backgroundColor: colors.white }}
-                    bodyStyle={{ backgroundColor: colors.dharmaDarkGrey }}
-                    actionsContainerStyle={{ backgroundColor: colors.white }}
-                    autoScrollBodyContent={true}
-                    actions={dharmaDialogActions}
-                    open={this.state.isDharmaDialogVisible}
-                >
-                    {this._renderDharmaLoanFrame()}
-                </Dialog>
-                <AssetPicker
-                    userAddress={this.props.userAddress}
-                    networkId={this.props.networkId}
-                    blockchain={this.props.blockchain}
-                    dispatcher={this.props.dispatcher}
-                    isOpen={this.state.isTokenPickerOpen}
-                    currentTokenAddress={''}
-                    onTokenChosen={this._onAssetTokenPicked.bind(this)}
-                    tokenByAddress={this.props.tokenByAddress}
-                    tokenVisibility={this.state.isAddingToken ? TokenVisibility.UNTRACKED : TokenVisibility.TRACKED}
-                />
-            </div>
-        );
-    }
-    private _renderTokenTableRows() {
-        if (!this.props.blockchainIsLoaded || this.props.blockchainErr !== BlockchainErrs.NoError) {
-            return '';
-        }
-        const isSmallScreen = this.props.screenWidth === ScreenWidths.Sm;
-        const tokenColSpan = isSmallScreen ? TOKEN_COL_SPAN_SM : TOKEN_COL_SPAN_LG;
-        const actionPaddingX = isSmallScreen ? 2 : 24;
-        const allTokens = _.values(this.props.tokenByAddress);
-        const trackedTokens = _.filter(allTokens, t => t.isTracked);
-        const trackedTokensStartingWithEtherToken = trackedTokens.sort(
-            firstBy((t: Token) => t.symbol !== ETHER_TOKEN_SYMBOL)
-                .thenBy((t: Token) => t.symbol !== ZRX_TOKEN_SYMBOL)
-                .thenBy('address'),
-        );
-        const tableRows = _.map(
-            trackedTokensStartingWithEtherToken,
-            this._renderTokenRow.bind(this, tokenColSpan, actionPaddingX),
-        );
-        return tableRows;
-    }
-    private _renderTokenRow(tokenColSpan: number, actionPaddingX: number, token: Token) {
-        const tokenState = this.props.tokenStateByAddress[token.address];
-        const tokenLink = utils.getEtherScanLinkIfExists(
-            token.address,
-            this.props.networkId,
-            EtherscanLinkSuffixes.Address,
-        );
-        const isMintable =
-            _.includes(configs.SYMBOLS_OF_MINTABLE_TOKENS, token.symbol) &&
-            this.props.networkId !== constants.NETWORK_ID_MAINNET;
-        return (
-            <TableRow key={token.address} style={{ height: TOKEN_TABLE_ROW_HEIGHT }}>
-                <TableRowColumn colSpan={tokenColSpan}>
-                    {_.isUndefined(tokenLink) ? (
-                        this._renderTokenName(token)
-                    ) : (
-                        <a href={tokenLink} target="_blank" style={{ textDecoration: 'none' }}>
-                            {this._renderTokenName(token)}
-                        </a>
-                    )}
-                </TableRowColumn>
-                <TableRowColumn style={{ paddingRight: 3, paddingLeft: 3 }}>
-                    {this._renderAmount(tokenState.balance, token.decimals)} {token.symbol}
-                    {this.state.isZRXSpinnerVisible &&
-                        token.symbol === ZRX_TOKEN_SYMBOL && (
-                            <span className="pl1">
-                                <i className="zmdi zmdi-spinner zmdi-hc-spin" />
-                            </span>
-                        )}
-                </TableRowColumn>
-                <TableRowColumn>
-                    <AllowanceToggle
-                        blockchain={this.props.blockchain}
-                        dispatcher={this.props.dispatcher}
-                        token={token}
-                        tokenState={tokenState}
-                        onErrorOccurred={this._onErrorOccurred.bind(this)}
-                        userAddress={this.props.userAddress}
-                    />
-                </TableRowColumn>
-                <TableRowColumn style={{ paddingLeft: actionPaddingX, paddingRight: actionPaddingX }}>
-                    {isMintable && (
-                        <LifeCycleRaisedButton
-                            labelReady="Mint"
-                            labelLoading={<span style={{ fontSize: 12 }}>Minting...</span>}
-                            labelComplete="Minted!"
-                            onClickAsyncFn={this._onMintTestTokensAsync.bind(this, token)}
-                        />
-                    )}
-                    {token.symbol === ZRX_TOKEN_SYMBOL &&
-                        this.props.networkId === constants.NETWORK_ID_TESTNET && (
-                            <LifeCycleRaisedButton
-                                labelReady="Request"
-                                labelLoading="Sending..."
-                                labelComplete="Sent!"
-                                onClickAsyncFn={this._faucetRequestAsync.bind(this, false)}
-                            />
-                        )}
-                </TableRowColumn>
-                {this.props.screenWidth !== ScreenWidths.Sm && (
-                    <TableRowColumn
-                        style={{
-                            paddingLeft: actionPaddingX,
-                            paddingRight: actionPaddingX,
-                        }}
-                    >
-                        <SendButton
-                            blockchain={this.props.blockchain}
-                            dispatcher={this.props.dispatcher}
-                            token={token}
-                            tokenState={tokenState}
-                            onError={this._onSendFailed.bind(this)}
-                        />
-                    </TableRowColumn>
-                )}
-            </TableRow>
-        );
-    }
-    private _onAssetTokenPicked(tokenAddress: string) {
-        if (_.isEmpty(tokenAddress)) {
-            this.setState({
-                isTokenPickerOpen: false,
-            });
-            return;
-        }
-        const token = this.props.tokenByAddress[tokenAddress];
-        const isDefaultTrackedToken = _.includes(configs.DEFAULT_TRACKED_TOKEN_SYMBOLS, token.symbol);
-        if (!this.state.isAddingToken && !isDefaultTrackedToken) {
-            if (token.isRegistered) {
-                // Remove the token from tracked tokens
-                const newToken = {
-                    ...token,
-                    isTracked: false,
-                };
-                this.props.dispatcher.updateTokenByAddress([newToken]);
-            } else {
-                this.props.dispatcher.removeTokenToTokenByAddress(token);
-            }
-            this.props.dispatcher.removeFromTokenStateByAddress(tokenAddress);
-            trackedTokenStorage.removeTrackedToken(this.props.userAddress, this.props.networkId, tokenAddress);
-        } else if (isDefaultTrackedToken) {
-            this.props.dispatcher.showFlashMessage(`Cannot remove ${token.name} because it's a default token`);
-        }
-        this.setState({
-            isTokenPickerOpen: false,
-        });
-    }
-    private _onSendFailed() {
-        this.setState({
-            errorType: BalanceErrs.sendFailed,
-        });
-    }
-    private _renderAmount(amount: BigNumber, decimals: number) {
-        const unitAmount = ZeroEx.toUnitAmount(amount, decimals);
-        return unitAmount.toNumber().toFixed(PRECISION);
-    }
-    private _renderTokenName(token: Token) {
-        const tooltipId = `tooltip-${token.address}`;
-        return (
-            <div className="flex">
-                <TokenIcon token={token} diameter={ICON_DIMENSION} />
-                <div data-tip={true} data-for={tooltipId} className="mt2 ml2 sm-hide xs-hide">
-                    {token.name}
-                </div>
-                <ReactTooltip id={tooltipId}>{token.address}</ReactTooltip>
-            </div>
-        );
-    }
-    private _renderErrorDialogBody() {
-        switch (this.state.errorType) {
-            case BalanceErrs.incorrectNetworkForFaucet:
-                return (
-                    <div>
-                        Our faucet can only send test Ether to addresses on the {constants.TESTNET_NAME} testnet
-                        (networkId {constants.NETWORK_ID_TESTNET}). Please make sure you are connected to the{' '}
-                        {constants.TESTNET_NAME} testnet and try requesting ether again.
-                    </div>
-                );
+				</div>
+				<Table selectable={false} style={styles.bgColor}>
+					<TableHeader displaySelectAll={false} adjustForCheckbox={false}>
+						<TableRow>
+							<TableHeaderColumn>Currency</TableHeaderColumn>
+							<TableHeaderColumn>Balance</TableHeaderColumn>
+							<TableRowColumn className="sm-hide xs-hide" style={stubColumnStyle} />
+							{isTestNetwork && (
+								<TableHeaderColumn style={{ paddingLeft: 3 }}>
+									{isSmallScreen ? 'Faucet' : 'Request from faucet'}
+								</TableHeaderColumn>
+							)}
+							{isTestNetwork && (
+								<TableHeaderColumn style={dharmaButtonColumnStyle}>
+									{isSmallScreen ? 'Loan' : 'Request Dharma loan'}
+									<HelpTooltip style={{ paddingLeft: 4 }} explanation={dharmaLoanExplanation} />
+								</TableHeaderColumn>
+							)}
+						</TableRow>
+					</TableHeader>
+					<TableBody displayRowCheckbox={false}>
+						<TableRow key="ETH">
+							<TableRowColumn className="py1">
+								<img style={{ width: ICON_DIMENSION, height: ICON_DIMENSION }} src={ETHER_ICON_PATH} />
+							</TableRowColumn>
+							<TableRowColumn>
+								{this.props.userEtherBalance.toFixed(PRECISION)} ETH
+								{this.state.isBalanceSpinnerVisible && (
+									<span className="pl1">
+										<i className="zmdi zmdi-spinner zmdi-hc-spin" />
+									</span>
+								)}
+							</TableRowColumn>
+							<TableRowColumn className="sm-hide xs-hide" style={stubColumnStyle} />
+							{isTestNetwork && (
+								<TableRowColumn style={{ paddingLeft: 3 }}>
+									<LifeCycleRaisedButton
+										labelReady="Request"
+										labelLoading="Sending..."
+										labelComplete="Sent!"
+										onClickAsyncFn={this._faucetRequestAsync.bind(this, true)}
+									/>
+								</TableRowColumn>
+							)}
+							{isTestNetwork && (
+								<TableRowColumn style={dharmaButtonColumnStyle}>
+									<RaisedButton
+										label="Request"
+										style={{ width: '100%' }}
+										onTouchTap={this._onDharmaDialogToggle.bind(this)}
+									/>
+								</TableRowColumn>
+							)}
+						</TableRow>
+					</TableBody>
+				</Table>
+				<div className="clearfix" style={{ paddingBottom: 1 }}>
+					<div className="col col-10">
+						<h3 className="pt2">{isTestNetwork ? 'Test tokens' : 'Tokens'}</h3>
+					</div>
+					<div className="col col-1 pt3 align-right">
+						<FloatingActionButton mini={true} zDepth={0} onClick={this._onAddTokenClicked.bind(this)}>
+							<ContentAdd />
+						</FloatingActionButton>
+					</div>
+					<div className="col col-1 pt3 align-right">
+						<FloatingActionButton mini={true} zDepth={0} onClick={this._onRemoveTokenClicked.bind(this)}>
+							<ContentRemove />
+						</FloatingActionButton>
+					</div>
+				</div>
+				<Divider />
+				<div className="pt2 pb2">
+					{isTestNetwork
+						? "Mint some test tokens you'd like to use to generate or fill an order using 0x."
+						: "Set trading permissions for a token you'd like to start trading."}
+				</div>
+				<Table selectable={false} bodyStyle={{ height: tokenTableHeight }} style={styles.bgColor}>
+					<TableHeader displaySelectAll={false} adjustForCheckbox={false}>
+						<TableRow>
+							<TableHeaderColumn colSpan={tokenColSpan}>Token</TableHeaderColumn>
+							<TableHeaderColumn style={{ paddingLeft: 3 }}>Balance</TableHeaderColumn>
+							<TableHeaderColumn>
+								<div className="inline-block">Allowance</div>
+								<HelpTooltip style={{ paddingLeft: 4 }} explanation={allowanceExplanation} />
+							</TableHeaderColumn>
+							<TableHeaderColumn>Action</TableHeaderColumn>
+							{this.props.screenWidth !== ScreenWidths.Sm && <TableHeaderColumn>Send</TableHeaderColumn>}
+						</TableRow>
+					</TableHeader>
+					<TableBody displayRowCheckbox={false}>{this._renderTokenTableRows()}</TableBody>
+				</Table>
+				<Dialog
+					title="Oh oh"
+					titleStyle={{ fontWeight: 100 }}
+					actions={errorDialogActions}
+					open={!_.isUndefined(this.state.errorType)}
+					onRequestClose={this._onErrorDialogToggle.bind(this, false)}
+				>
+					{this._renderErrorDialogBody()}
+				</Dialog>
+				<Dialog
+					title="Request Dharma Loan"
+					titleStyle={{ fontWeight: 100, backgroundColor: colors.white }}
+					bodyStyle={{ backgroundColor: colors.dharmaDarkGrey }}
+					actionsContainerStyle={{ backgroundColor: colors.white }}
+					autoScrollBodyContent={true}
+					actions={dharmaDialogActions}
+					open={this.state.isDharmaDialogVisible}
+				>
+					{this._renderDharmaLoanFrame()}
+				</Dialog>
+				<AssetPicker
+					userAddress={this.props.userAddress}
+					networkId={this.props.networkId}
+					blockchain={this.props.blockchain}
+					dispatcher={this.props.dispatcher}
+					isOpen={this.state.isTokenPickerOpen}
+					currentTokenAddress={''}
+					onTokenChosen={this._onAssetTokenPicked.bind(this)}
+					tokenByAddress={this.props.tokenByAddress}
+					tokenVisibility={this.state.isAddingToken ? TokenVisibility.UNTRACKED : TokenVisibility.TRACKED}
+				/>
+			</div>
+		);
+	}
+	private _renderTokenTableRows() {
+		if (!this.props.blockchainIsLoaded || this.props.blockchainErr !== BlockchainErrs.NoError) {
+			return '';
+		}
+		const isSmallScreen = this.props.screenWidth === ScreenWidths.Sm;
+		const tokenColSpan = isSmallScreen ? TOKEN_COL_SPAN_SM : TOKEN_COL_SPAN_LG;
+		const actionPaddingX = isSmallScreen ? 2 : 24;
+		const allTokens = _.values(this.props.tokenByAddress);
+		const trackedTokens = _.filter(allTokens, t => t.isTracked);
+		const trackedTokensStartingWithEtherToken = trackedTokens.sort(
+			firstBy((t: Token) => t.symbol !== ETHER_TOKEN_SYMBOL)
+				.thenBy((t: Token) => t.symbol !== ZRX_TOKEN_SYMBOL)
+				.thenBy('address'),
+		);
+		const tableRows = _.map(
+			trackedTokensStartingWithEtherToken,
+			this._renderTokenRow.bind(this, tokenColSpan, actionPaddingX),
+		);
+		return tableRows;
+	}
+	private _renderTokenRow(tokenColSpan: number, actionPaddingX: number, token: Token) {
+		const tokenState = this.props.tokenStateByAddress[token.address];
+		const tokenLink = utils.getEtherScanLinkIfExists(
+			token.address,
+			this.props.networkId,
+			EtherscanLinkSuffixes.Address,
+		);
+		const isMintable =
+			_.includes(configs.SYMBOLS_OF_MINTABLE_TOKENS, token.symbol) &&
+			this.props.networkId !== constants.NETWORK_ID_MAINNET;
+		return (
+			<TableRow key={token.address} style={{ height: TOKEN_TABLE_ROW_HEIGHT }}>
+				<TableRowColumn colSpan={tokenColSpan}>
+					{_.isUndefined(tokenLink) ? (
+						this._renderTokenName(token)
+					) : (
+						<a href={tokenLink} target="_blank" style={{ textDecoration: 'none' }}>
+							{this._renderTokenName(token)}
+						</a>
+					)}
+				</TableRowColumn>
+				<TableRowColumn style={{ paddingRight: 3, paddingLeft: 3 }}>
+					{this._renderAmount(tokenState.balance, token.decimals)} {token.symbol}
+					{this.state.isZRXSpinnerVisible &&
+						token.symbol === ZRX_TOKEN_SYMBOL && (
+							<span className="pl1">
+								<i className="zmdi zmdi-spinner zmdi-hc-spin" />
+							</span>
+						)}
+				</TableRowColumn>
+				<TableRowColumn>
+					<AllowanceToggle
+						blockchain={this.props.blockchain}
+						dispatcher={this.props.dispatcher}
+						token={token}
+						tokenState={tokenState}
+						onErrorOccurred={this._onErrorOccurred.bind(this)}
+						userAddress={this.props.userAddress}
+					/>
+				</TableRowColumn>
+				<TableRowColumn style={{ paddingLeft: actionPaddingX, paddingRight: actionPaddingX }}>
+					{isMintable && (
+						<LifeCycleRaisedButton
+							labelReady="Mint"
+							labelLoading={<span style={{ fontSize: 12 }}>Minting...</span>}
+							labelComplete="Minted!"
+							onClickAsyncFn={this._onMintTestTokensAsync.bind(this, token)}
+						/>
+					)}
+					{token.symbol === ZRX_TOKEN_SYMBOL &&
+						this.props.networkId === constants.NETWORK_ID_TESTNET && (
+							<LifeCycleRaisedButton
+								labelReady="Request"
+								labelLoading="Sending..."
+								labelComplete="Sent!"
+								onClickAsyncFn={this._faucetRequestAsync.bind(this, false)}
+							/>
+						)}
+				</TableRowColumn>
+				{this.props.screenWidth !== ScreenWidths.Sm && (
+					<TableRowColumn
+						style={{
+							paddingLeft: actionPaddingX,
+							paddingRight: actionPaddingX,
+						}}
+					>
+						<SendButton
+							blockchain={this.props.blockchain}
+							dispatcher={this.props.dispatcher}
+							token={token}
+							tokenState={tokenState}
+							onError={this._onSendFailed.bind(this)}
+						/>
+					</TableRowColumn>
+				)}
+			</TableRow>
+		);
+	}
+	private _onAssetTokenPicked(tokenAddress: string) {
+		if (_.isEmpty(tokenAddress)) {
+			this.setState({
+				isTokenPickerOpen: false,
+			});
+			return;
+		}
+		const token = this.props.tokenByAddress[tokenAddress];
+		const isDefaultTrackedToken = _.includes(configs.DEFAULT_TRACKED_TOKEN_SYMBOLS, token.symbol);
+		if (!this.state.isAddingToken && !isDefaultTrackedToken) {
+			if (token.isRegistered) {
+				// Remove the token from tracked tokens
+				const newToken = {
+					...token,
+					isTracked: false,
+				};
+				this.props.dispatcher.updateTokenByAddress([newToken]);
+			} else {
+				this.props.dispatcher.removeTokenToTokenByAddress(token);
+			}
+			this.props.dispatcher.removeFromTokenStateByAddress(tokenAddress);
+			trackedTokenStorage.removeTrackedToken(this.props.userAddress, this.props.networkId, tokenAddress);
+		} else if (isDefaultTrackedToken) {
+			this.props.dispatcher.showFlashMessage(`Cannot remove ${token.name} because it's a default token`);
+		}
+		this.setState({
+			isTokenPickerOpen: false,
+		});
+	}
+	private _onSendFailed() {
+		this.setState({
+			errorType: BalanceErrs.sendFailed,
+		});
+	}
+	private _renderAmount(amount: BigNumber, decimals: number) {
+		const unitAmount = ZeroEx.toUnitAmount(amount, decimals);
+		return unitAmount.toNumber().toFixed(PRECISION);
+	}
+	private _renderTokenName(token: Token) {
+		const tooltipId = `tooltip-${token.address}`;
+		return (
+			<div className="flex">
+				<TokenIcon token={token} diameter={ICON_DIMENSION} />
+				<div data-tip={true} data-for={tooltipId} className="mt2 ml2 sm-hide xs-hide">
+					{token.name}
+				</div>
+				<ReactTooltip id={tooltipId}>{token.address}</ReactTooltip>
+			</div>
+		);
+	}
+	private _renderErrorDialogBody() {
+		switch (this.state.errorType) {
+			case BalanceErrs.incorrectNetworkForFaucet:
+				return (
+					<div>
+						Our faucet can only send test Ether to addresses on the {constants.TESTNET_NAME} testnet
+						(networkId {constants.NETWORK_ID_TESTNET}). Please make sure you are connected to the{' '}
+						{constants.TESTNET_NAME} testnet and try requesting ether again.
+					</div>
+				);
 
-            case BalanceErrs.faucetRequestFailed:
-                return (
-                    <div>
-                        An unexpected error occurred while trying to request test Ether from our faucet. Please refresh
-                        the page and try again.
-                    </div>
-                );
+			case BalanceErrs.faucetRequestFailed:
+				return (
+					<div>
+						An unexpected error occurred while trying to request test Ether from our faucet. Please refresh
+						the page and try again.
+					</div>
+				);
 
-            case BalanceErrs.faucetQueueIsFull:
-                return <div>Our test Ether faucet queue is full. Please try requesting test Ether again later.</div>;
+			case BalanceErrs.faucetQueueIsFull:
+				return <div>Our test Ether faucet queue is full. Please try requesting test Ether again later.</div>;
 
-            case BalanceErrs.mintingFailed:
-                return <div>Minting your test tokens failed unexpectedly. Please refresh the page and try again.</div>;
+			case BalanceErrs.mintingFailed:
+				return <div>Minting your test tokens failed unexpectedly. Please refresh the page and try again.</div>;
 
-            case BalanceErrs.allowanceSettingFailed:
-                return (
-                    <div>
-                        An unexpected error occurred while trying to set your test token allowance. Please refresh the
-                        page and try again.
-                    </div>
-                );
+			case BalanceErrs.allowanceSettingFailed:
+				return (
+					<div>
+						An unexpected error occurred while trying to set your test token allowance. Please refresh the
+						page and try again.
+					</div>
+				);
 
-            case undefined:
-                return null; // No error to show
+			case undefined:
+				return null; // No error to show
 
-            default:
-                throw utils.spawnSwitchErr('errorType', this.state.errorType);
-        }
-    }
-    private _renderDharmaLoanFrame() {
-        if (utils.isUserOnMobile()) {
-            return (
-                <h4 style={{ textAlign: 'center' }}>
-                    We apologize -- Dharma loan requests are not available on mobile yet. Please try again through your
-                    desktop browser.
-                </h4>
-            );
-        } else {
-            return (
-                <DharmaLoanFrame
-                    partner="0x"
-                    env={utils.getCurrentEnvironment()}
-                    screenWidth={this.props.screenWidth}
-                />
-            );
-        }
-    }
-    private _onErrorOccurred(errorType: BalanceErrs) {
-        this.setState({
-            errorType,
-        });
-    }
-    private async _onMintTestTokensAsync(token: Token): Promise<boolean> {
-        try {
-            await this.props.blockchain.mintTestTokensAsync(token);
-            const amount = ZeroEx.toUnitAmount(constants.MINT_AMOUNT, token.decimals);
-            this.props.dispatcher.showFlashMessage(`Successfully minted ${amount.toString(10)} ${token.symbol}`);
-            return true;
-        } catch (err) {
-            const errMsg = `${err}`;
-            if (_.includes(errMsg, BlockchainCallErrs.UserHasNoAssociatedAddresses)) {
-                this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
-                return false;
-            }
-            if (_.includes(errMsg, 'User denied transaction')) {
-                return false;
-            }
-            utils.consoleLog(`Unexpected error encountered: ${err}`);
-            utils.consoleLog(err.stack);
-            this.setState({
-                errorType: BalanceErrs.mintingFailed,
-            });
-            await errorReporter.reportAsync(err);
-            return false;
-        }
-    }
-    private async _faucetRequestAsync(isEtherRequest: boolean): Promise<boolean> {
-        if (this.props.userAddress === '') {
-            this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
-            return false;
-        }
+			default:
+				throw utils.spawnSwitchErr('errorType', this.state.errorType);
+		}
+	}
+	private _renderDharmaLoanFrame() {
+		if (utils.isUserOnMobile()) {
+			return (
+				<h4 style={{ textAlign: 'center' }}>
+					We apologize -- Dharma loan requests are not available on mobile yet. Please try again through your
+					desktop browser.
+				</h4>
+			);
+		} else {
+			return (
+				<DharmaLoanFrame
+					partner="0x"
+					env={utils.getCurrentEnvironment()}
+					screenWidth={this.props.screenWidth}
+				/>
+			);
+		}
+	}
+	private _onErrorOccurred(errorType: BalanceErrs) {
+		this.setState({
+			errorType,
+		});
+	}
+	private async _onMintTestTokensAsync(token: Token): Promise<boolean> {
+		try {
+			await this.props.blockchain.mintTestTokensAsync(token);
+			const amount = ZeroEx.toUnitAmount(constants.MINT_AMOUNT, token.decimals);
+			this.props.dispatcher.showFlashMessage(`Successfully minted ${amount.toString(10)} ${token.symbol}`);
+			return true;
+		} catch (err) {
+			const errMsg = `${err}`;
+			if (_.includes(errMsg, BlockchainCallErrs.UserHasNoAssociatedAddresses)) {
+				this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
+				return false;
+			}
+			if (_.includes(errMsg, 'User denied transaction')) {
+				return false;
+			}
+			utils.consoleLog(`Unexpected error encountered: ${err}`);
+			utils.consoleLog(err.stack);
+			this.setState({
+				errorType: BalanceErrs.mintingFailed,
+			});
+			await errorReporter.reportAsync(err);
+			return false;
+		}
+	}
+	private async _faucetRequestAsync(isEtherRequest: boolean): Promise<boolean> {
+		if (this.props.userAddress === '') {
+			this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
+			return false;
+		}
 
-        // If on another network other then the testnet our faucet serves test ether
-        // from, we must show user an error message
-        if (this.props.blockchain.networkId !== constants.NETWORK_ID_TESTNET) {
-            this.setState({
-                errorType: BalanceErrs.incorrectNetworkForFaucet,
-            });
-            return false;
-        }
+		// If on another network other then the testnet our faucet serves test ether
+		// from, we must show user an error message
+		if (this.props.blockchain.networkId !== constants.NETWORK_ID_TESTNET) {
+			this.setState({
+				errorType: BalanceErrs.incorrectNetworkForFaucet,
+			});
+			return false;
+		}
 
-        await utils.sleepAsync(ARTIFICIAL_FAUCET_REQUEST_DELAY);
+		await utils.sleepAsync(ARTIFICIAL_FAUCET_REQUEST_DELAY);
 
-        const segment = isEtherRequest ? 'ether' : 'zrx';
-        const response = await fetch(`${constants.URL_ETHER_FAUCET}/${segment}/${this.props.userAddress}`);
-        const responseBody = await response.text();
-        if (response.status !== constants.SUCCESS_STATUS) {
-            utils.consoleLog(`Unexpected status code: ${response.status} -> ${responseBody}`);
-            const errorType =
-                response.status === constants.UNAVAILABLE_STATUS
-                    ? BalanceErrs.faucetQueueIsFull
-                    : BalanceErrs.faucetRequestFailed;
-            this.setState({
-                errorType,
-            });
-            await errorReporter.reportAsync(new Error(`Faucet returned non-200: ${JSON.stringify(response)}`));
-            return false;
-        }
+		const segment = isEtherRequest ? 'ether' : 'zrx';
+		const response = await fetch(`${constants.URL_ETHER_FAUCET}/${segment}/${this.props.userAddress}`);
+		const responseBody = await response.text();
+		if (response.status !== constants.SUCCESS_STATUS) {
+			utils.consoleLog(`Unexpected status code: ${response.status} -> ${responseBody}`);
+			const errorType =
+				response.status === constants.UNAVAILABLE_STATUS
+					? BalanceErrs.faucetQueueIsFull
+					: BalanceErrs.faucetRequestFailed;
+			this.setState({
+				errorType,
+			});
+			await errorReporter.reportAsync(new Error(`Faucet returned non-200: ${JSON.stringify(response)}`));
+			return false;
+		}
 
-        if (isEtherRequest) {
-            this.setState({
-                isBalanceSpinnerVisible: true,
-            });
-        } else {
-            const tokens = _.values(this.props.tokenByAddress);
-            const zrxToken = _.find(tokens, t => t.symbol === ZRX_TOKEN_SYMBOL);
-            const zrxTokenState = this.props.tokenStateByAddress[zrxToken.address];
-            this.setState({
-                isZRXSpinnerVisible: true,
-                currentZrxBalance: zrxTokenState.balance,
-            });
-            // tslint:disable-next-line:no-floating-promises
-            this.props.blockchain.pollTokenBalanceAsync(zrxToken);
-        }
-        return true;
-    }
-    private _onErrorDialogToggle(isOpen: boolean) {
-        this.setState({
-            errorType: undefined,
-        });
-    }
-    private _onDharmaDialogToggle() {
-        this.setState({
-            isDharmaDialogVisible: !this.state.isDharmaDialogVisible,
-        });
-    }
-    private _onAddTokenClicked() {
-        this.setState({
-            isTokenPickerOpen: true,
-            isAddingToken: true,
-        });
-    }
-    private _onRemoveTokenClicked() {
-        this.setState({
-            isTokenPickerOpen: true,
-            isAddingToken: false,
-        });
-    }
+		if (isEtherRequest) {
+			this.setState({
+				isBalanceSpinnerVisible: true,
+			});
+		} else {
+			const tokens = _.values(this.props.tokenByAddress);
+			const zrxToken = _.find(tokens, t => t.symbol === ZRX_TOKEN_SYMBOL);
+			const zrxTokenState = this.props.tokenStateByAddress[zrxToken.address];
+			this.setState({
+				isZRXSpinnerVisible: true,
+				currentZrxBalance: zrxTokenState.balance,
+			});
+			// tslint:disable-next-line:no-floating-promises
+			this.props.blockchain.pollTokenBalanceAsync(zrxToken);
+		}
+		return true;
+	}
+	private _onErrorDialogToggle(isOpen: boolean) {
+		this.setState({
+			errorType: undefined,
+		});
+	}
+	private _onDharmaDialogToggle() {
+		this.setState({
+			isDharmaDialogVisible: !this.state.isDharmaDialogVisible,
+		});
+	}
+	private _onAddTokenClicked() {
+		this.setState({
+			isTokenPickerOpen: true,
+			isAddingToken: true,
+		});
+	}
+	private _onRemoveTokenClicked() {
+		this.setState({
+			isTokenPickerOpen: true,
+			isAddingToken: false,
+		});
+	}
 } // tslint:disable:max-file-line-count
diff --git a/packages/website/ts/components/top_bar.tsx b/packages/website/ts/components/top_bar.tsx
index 11d3e7cc2..1f111cb07 100644
--- a/packages/website/ts/components/top_bar.tsx
+++ b/packages/website/ts/components/top_bar.tsx
@@ -15,333 +15,333 @@ import { colors } from 'ts/utils/colors';
 import { constants } from 'ts/utils/constants';
 
 interface TopBarProps {
-    userAddress?: string;
-    blockchainIsLoaded: boolean;
-    location: Location;
-    docsVersion?: string;
-    availableDocVersions?: string[];
-    menu?: DocsMenu;
-    menuSubsectionsBySection?: MenuSubsectionsBySection;
-    shouldFullWidth?: boolean;
-    docsInfo?: DocsInfo;
-    style?: React.CSSProperties;
-    isNightVersion?: boolean;
+	userAddress?: string;
+	blockchainIsLoaded: boolean;
+	location: Location;
+	docsVersion?: string;
+	availableDocVersions?: string[];
+	menu?: DocsMenu;
+	menuSubsectionsBySection?: MenuSubsectionsBySection;
+	shouldFullWidth?: boolean;
+	docsInfo?: DocsInfo;
+	style?: React.CSSProperties;
+	isNightVersion?: boolean;
 }
 
 interface TopBarState {
-    isDrawerOpen: boolean;
+	isDrawerOpen: boolean;
 }
 
 const styles: Styles = {
-    address: {
-        marginRight: 12,
-        overflow: 'hidden',
-        paddingTop: 4,
-        textOverflow: 'ellipsis',
-        whiteSpace: 'nowrap',
-        width: 70,
-    },
-    topBar: {
-        backgroundcolor: colors.white,
-        height: 59,
-        width: '100%',
-        position: 'relative',
-        top: 0,
-        zIndex: 1100,
-        paddingBottom: 1,
-    },
-    bottomBar: {
-        boxShadow: 'rgba(0, 0, 0, 0.187647) 0px 1px 3px',
-    },
-    menuItem: {
-        fontSize: 14,
-        color: colors.darkestGrey,
-        paddingTop: 6,
-        paddingBottom: 6,
-        marginTop: 17,
-        cursor: 'pointer',
-        fontWeight: 400,
-    },
+	address: {
+		marginRight: 12,
+		overflow: 'hidden',
+		paddingTop: 4,
+		textOverflow: 'ellipsis',
+		whiteSpace: 'nowrap',
+		width: 70,
+	},
+	topBar: {
+		backgroundcolor: colors.white,
+		height: 59,
+		width: '100%',
+		position: 'relative',
+		top: 0,
+		zIndex: 1100,
+		paddingBottom: 1,
+	},
+	bottomBar: {
+		boxShadow: 'rgba(0, 0, 0, 0.187647) 0px 1px 3px',
+	},
+	menuItem: {
+		fontSize: 14,
+		color: colors.darkestGrey,
+		paddingTop: 6,
+		paddingBottom: 6,
+		marginTop: 17,
+		cursor: 'pointer',
+		fontWeight: 400,
+	},
 };
 
 export class TopBar extends React.Component<TopBarProps, TopBarState> {
-    public static defaultProps: Partial<TopBarProps> = {
-        shouldFullWidth: false,
-        style: {},
-        isNightVersion: false,
-    };
-    constructor(props: TopBarProps) {
-        super(props);
-        this.state = {
-            isDrawerOpen: false,
-        };
-    }
-    public render() {
-        const isNightVersion = this.props.isNightVersion;
-        const isFullWidthPage = this.props.shouldFullWidth;
-        const parentClassNames = `flex mx-auto ${isFullWidthPage ? 'pl2' : 'max-width-4'}`;
-        const developerSectionMenuItems = [
-            <Link key="subMenuItem-zeroEx" to={WebsitePaths.ZeroExJs} className="text-decoration-none">
-                <MenuItem style={{ fontSize: styles.menuItem.fontSize }} primaryText="0x.js" />
-            </Link>,
-            <Link key="subMenuItem-smartContracts" to={WebsitePaths.SmartContracts} className="text-decoration-none">
-                <MenuItem style={{ fontSize: styles.menuItem.fontSize }} primaryText="Smart Contracts" />
-            </Link>,
-            <Link key="subMenuItem-0xconnect" to={WebsitePaths.Connect} className="text-decoration-none">
-                <MenuItem style={{ fontSize: styles.menuItem.fontSize }} primaryText="0x Connect" />
-            </Link>,
-            <a
-                key="subMenuItem-standard-relayer-api"
-                target="_blank"
-                className="text-decoration-none"
-                href={constants.URL_STANDARD_RELAYER_API_GITHUB}
-            >
-                <MenuItem style={{ fontSize: styles.menuItem.fontSize }} primaryText="Standard Relayer API" />
-            </a>,
-            <a
-                key="subMenuItem-github"
-                target="_blank"
-                className="text-decoration-none"
-                href={constants.URL_GITHUB_ORG}
-            >
-                <MenuItem style={{ fontSize: styles.menuItem.fontSize }} primaryText="GitHub" />
-            </a>,
-            <a
-                key="subMenuItem-whitePaper"
-                target="_blank"
-                className="text-decoration-none"
-                href={`${WebsitePaths.Whitepaper}`}
-            >
-                <MenuItem style={{ fontSize: styles.menuItem.fontSize }} primaryText="Whitepaper" />
-            </a>,
-        ];
-        const bottomBorderStyle = this._shouldDisplayBottomBar() ? styles.bottomBar : {};
-        const fullWidthClasses = isFullWidthPage ? 'pr4' : '';
-        const logoUrl = isNightVersion ? '/images/protocol_logo_white.png' : '/images/protocol_logo_black.png';
-        const menuClasses = `col col-${isFullWidthPage ? '4' : '5'} ${fullWidthClasses} lg-pr0 md-pr2 sm-hide xs-hide`;
-        const menuIconStyle = {
-            fontSize: 25,
-            color: isNightVersion ? 'white' : 'black',
-            cursor: 'pointer',
-            paddingTop: 16,
-        };
-        return (
-            <div style={{ ...styles.topBar, ...bottomBorderStyle, ...this.props.style }} className="pb1">
-                <div className={parentClassNames}>
-                    <div className="col col-2 sm-pl2 md-pl2 lg-pl0" style={{ paddingTop: 15 }}>
-                        <Link to={`${WebsitePaths.Home}`} className="text-decoration-none">
-                            <img src={logoUrl} height="30" />
-                        </Link>
-                    </div>
-                    <div className={`col col-${isFullWidthPage ? '8' : '9'} lg-hide md-hide`} />
-                    <div className={`col col-${isFullWidthPage ? '6' : '5'} sm-hide xs-hide`} />
-                    {!this._isViewingPortal() && (
-                        <div className={menuClasses}>
-                            <div className="flex justify-between">
-                                <DropDownMenuItem
-                                    title="Developers"
-                                    subMenuItems={developerSectionMenuItems}
-                                    style={styles.menuItem}
-                                    isNightVersion={isNightVersion}
-                                />
-                                <TopBarMenuItem
-                                    title="Wiki"
-                                    path={`${WebsitePaths.Wiki}`}
-                                    style={styles.menuItem}
-                                    isNightVersion={isNightVersion}
-                                />
-                                <TopBarMenuItem
-                                    title="About"
-                                    path={`${WebsitePaths.About}`}
-                                    style={styles.menuItem}
-                                    isNightVersion={isNightVersion}
-                                />
-                                <TopBarMenuItem
-                                    title="Portal DApp"
-                                    path={`${WebsitePaths.Portal}`}
-                                    isPrimary={true}
-                                    style={styles.menuItem}
-                                    className={`${isFullWidthPage && 'md-hide'}`}
-                                    isNightVersion={isNightVersion}
-                                />
-                            </div>
-                        </div>
-                    )}
-                    {this.props.blockchainIsLoaded &&
-                        !_.isEmpty(this.props.userAddress) && (
-                            <div className="col col-5 sm-hide xs-hide">{this._renderUser()}</div>
-                        )}
-                    <div className={`col ${isFullWidthPage ? 'col-2 pl2' : 'col-1'} md-hide lg-hide`}>
-                        <div style={menuIconStyle}>
-                            <i className="zmdi zmdi-menu" onClick={this._onMenuButtonClick.bind(this)} />
-                        </div>
-                    </div>
-                </div>
-                {this._renderDrawer()}
-            </div>
-        );
-    }
-    private _renderDrawer() {
-        return (
-            <Drawer
-                open={this.state.isDrawerOpen}
-                docked={false}
-                openSecondary={true}
-                onRequestChange={this._onMenuButtonClick.bind(this)}
-            >
-                {this._renderPortalMenu()}
-                {this._renderDocsMenu()}
-                {this._renderWiki()}
-                <div className="pl1 py1 mt3" style={{ backgroundColor: colors.lightGrey }}>
-                    Website
-                </div>
-                <Link to={WebsitePaths.Home} className="text-decoration-none">
-                    <MenuItem className="py2">Home</MenuItem>
-                </Link>
-                <Link to={`${WebsitePaths.Wiki}`} className="text-decoration-none">
-                    <MenuItem className="py2">Wiki</MenuItem>
-                </Link>
-                {!this._isViewing0xjsDocs() && (
-                    <Link to={WebsitePaths.ZeroExJs} className="text-decoration-none">
-                        <MenuItem className="py2">0x.js Docs</MenuItem>
-                    </Link>
-                )}
-                {!this._isViewingConnectDocs() && (
-                    <Link to={WebsitePaths.Connect} className="text-decoration-none">
-                        <MenuItem className="py2">0x Connect Docs</MenuItem>
-                    </Link>
-                )}
-                {!this._isViewingSmartContractsDocs() && (
-                    <Link to={WebsitePaths.SmartContracts} className="text-decoration-none">
-                        <MenuItem className="py2">Smart Contract Docs</MenuItem>
-                    </Link>
-                )}
-                {!this._isViewingPortal() && (
-                    <Link to={`${WebsitePaths.Portal}`} className="text-decoration-none">
-                        <MenuItem className="py2">Portal DApp</MenuItem>
-                    </Link>
-                )}
-                <a className="text-decoration-none" target="_blank" href={`${WebsitePaths.Whitepaper}`}>
-                    <MenuItem className="py2">Whitepaper</MenuItem>
-                </a>
-                <Link to={`${WebsitePaths.About}`} className="text-decoration-none">
-                    <MenuItem className="py2">About</MenuItem>
-                </Link>
-                <a className="text-decoration-none" target="_blank" href={constants.URL_BLOG}>
-                    <MenuItem className="py2">Blog</MenuItem>
-                </a>
-                <Link to={`${WebsitePaths.FAQ}`} className="text-decoration-none">
-                    <MenuItem className="py2" onTouchTap={this._onMenuButtonClick.bind(this)}>
-                        FAQ
-                    </MenuItem>
-                </Link>
-            </Drawer>
-        );
-    }
-    private _renderDocsMenu(): React.ReactNode {
-        if (
-            (!this._isViewing0xjsDocs() && !this._isViewingSmartContractsDocs() && !this._isViewingConnectDocs()) ||
-            _.isUndefined(this.props.menu)
-        ) {
-            return undefined;
-        }
+	public static defaultProps: Partial<TopBarProps> = {
+		shouldFullWidth: false,
+		style: {},
+		isNightVersion: false,
+	};
+	constructor(props: TopBarProps) {
+		super(props);
+		this.state = {
+			isDrawerOpen: false,
+		};
+	}
+	public render() {
+		const isNightVersion = this.props.isNightVersion;
+		const isFullWidthPage = this.props.shouldFullWidth;
+		const parentClassNames = `flex mx-auto ${isFullWidthPage ? 'pl2' : 'max-width-4'}`;
+		const developerSectionMenuItems = [
+			<Link key="subMenuItem-zeroEx" to={WebsitePaths.ZeroExJs} className="text-decoration-none">
+				<MenuItem style={{ fontSize: styles.menuItem.fontSize }} primaryText="0x.js" />
+			</Link>,
+			<Link key="subMenuItem-smartContracts" to={WebsitePaths.SmartContracts} className="text-decoration-none">
+				<MenuItem style={{ fontSize: styles.menuItem.fontSize }} primaryText="Smart Contracts" />
+			</Link>,
+			<Link key="subMenuItem-0xconnect" to={WebsitePaths.Connect} className="text-decoration-none">
+				<MenuItem style={{ fontSize: styles.menuItem.fontSize }} primaryText="0x Connect" />
+			</Link>,
+			<a
+				key="subMenuItem-standard-relayer-api"
+				target="_blank"
+				className="text-decoration-none"
+				href={constants.URL_STANDARD_RELAYER_API_GITHUB}
+			>
+				<MenuItem style={{ fontSize: styles.menuItem.fontSize }} primaryText="Standard Relayer API" />
+			</a>,
+			<a
+				key="subMenuItem-github"
+				target="_blank"
+				className="text-decoration-none"
+				href={constants.URL_GITHUB_ORG}
+			>
+				<MenuItem style={{ fontSize: styles.menuItem.fontSize }} primaryText="GitHub" />
+			</a>,
+			<a
+				key="subMenuItem-whitePaper"
+				target="_blank"
+				className="text-decoration-none"
+				href={`${WebsitePaths.Whitepaper}`}
+			>
+				<MenuItem style={{ fontSize: styles.menuItem.fontSize }} primaryText="Whitepaper" />
+			</a>,
+		];
+		const bottomBorderStyle = this._shouldDisplayBottomBar() ? styles.bottomBar : {};
+		const fullWidthClasses = isFullWidthPage ? 'pr4' : '';
+		const logoUrl = isNightVersion ? '/images/protocol_logo_white.png' : '/images/protocol_logo_black.png';
+		const menuClasses = `col col-${isFullWidthPage ? '4' : '5'} ${fullWidthClasses} lg-pr0 md-pr2 sm-hide xs-hide`;
+		const menuIconStyle = {
+			fontSize: 25,
+			color: isNightVersion ? 'white' : 'black',
+			cursor: 'pointer',
+			paddingTop: 16,
+		};
+		return (
+			<div style={{ ...styles.topBar, ...bottomBorderStyle, ...this.props.style }} className="pb1">
+				<div className={parentClassNames}>
+					<div className="col col-2 sm-pl2 md-pl2 lg-pl0" style={{ paddingTop: 15 }}>
+						<Link to={`${WebsitePaths.Home}`} className="text-decoration-none">
+							<img src={logoUrl} height="30" />
+						</Link>
+					</div>
+					<div className={`col col-${isFullWidthPage ? '8' : '9'} lg-hide md-hide`} />
+					<div className={`col col-${isFullWidthPage ? '6' : '5'} sm-hide xs-hide`} />
+					{!this._isViewingPortal() && (
+						<div className={menuClasses}>
+							<div className="flex justify-between">
+								<DropDownMenuItem
+									title="Developers"
+									subMenuItems={developerSectionMenuItems}
+									style={styles.menuItem}
+									isNightVersion={isNightVersion}
+								/>
+								<TopBarMenuItem
+									title="Wiki"
+									path={`${WebsitePaths.Wiki}`}
+									style={styles.menuItem}
+									isNightVersion={isNightVersion}
+								/>
+								<TopBarMenuItem
+									title="About"
+									path={`${WebsitePaths.About}`}
+									style={styles.menuItem}
+									isNightVersion={isNightVersion}
+								/>
+								<TopBarMenuItem
+									title="Portal DApp"
+									path={`${WebsitePaths.Portal}`}
+									isPrimary={true}
+									style={styles.menuItem}
+									className={`${isFullWidthPage && 'md-hide'}`}
+									isNightVersion={isNightVersion}
+								/>
+							</div>
+						</div>
+					)}
+					{this.props.blockchainIsLoaded &&
+						!_.isEmpty(this.props.userAddress) && (
+							<div className="col col-5 sm-hide xs-hide">{this._renderUser()}</div>
+						)}
+					<div className={`col ${isFullWidthPage ? 'col-2 pl2' : 'col-1'} md-hide lg-hide`}>
+						<div style={menuIconStyle}>
+							<i className="zmdi zmdi-menu" onClick={this._onMenuButtonClick.bind(this)} />
+						</div>
+					</div>
+				</div>
+				{this._renderDrawer()}
+			</div>
+		);
+	}
+	private _renderDrawer() {
+		return (
+			<Drawer
+				open={this.state.isDrawerOpen}
+				docked={false}
+				openSecondary={true}
+				onRequestChange={this._onMenuButtonClick.bind(this)}
+			>
+				{this._renderPortalMenu()}
+				{this._renderDocsMenu()}
+				{this._renderWiki()}
+				<div className="pl1 py1 mt3" style={{ backgroundColor: colors.lightGrey }}>
+					Website
+				</div>
+				<Link to={WebsitePaths.Home} className="text-decoration-none">
+					<MenuItem className="py2">Home</MenuItem>
+				</Link>
+				<Link to={`${WebsitePaths.Wiki}`} className="text-decoration-none">
+					<MenuItem className="py2">Wiki</MenuItem>
+				</Link>
+				{!this._isViewing0xjsDocs() && (
+					<Link to={WebsitePaths.ZeroExJs} className="text-decoration-none">
+						<MenuItem className="py2">0x.js Docs</MenuItem>
+					</Link>
+				)}
+				{!this._isViewingConnectDocs() && (
+					<Link to={WebsitePaths.Connect} className="text-decoration-none">
+						<MenuItem className="py2">0x Connect Docs</MenuItem>
+					</Link>
+				)}
+				{!this._isViewingSmartContractsDocs() && (
+					<Link to={WebsitePaths.SmartContracts} className="text-decoration-none">
+						<MenuItem className="py2">Smart Contract Docs</MenuItem>
+					</Link>
+				)}
+				{!this._isViewingPortal() && (
+					<Link to={`${WebsitePaths.Portal}`} className="text-decoration-none">
+						<MenuItem className="py2">Portal DApp</MenuItem>
+					</Link>
+				)}
+				<a className="text-decoration-none" target="_blank" href={`${WebsitePaths.Whitepaper}`}>
+					<MenuItem className="py2">Whitepaper</MenuItem>
+				</a>
+				<Link to={`${WebsitePaths.About}`} className="text-decoration-none">
+					<MenuItem className="py2">About</MenuItem>
+				</Link>
+				<a className="text-decoration-none" target="_blank" href={constants.URL_BLOG}>
+					<MenuItem className="py2">Blog</MenuItem>
+				</a>
+				<Link to={`${WebsitePaths.FAQ}`} className="text-decoration-none">
+					<MenuItem className="py2" onTouchTap={this._onMenuButtonClick.bind(this)}>
+						FAQ
+					</MenuItem>
+				</Link>
+			</Drawer>
+		);
+	}
+	private _renderDocsMenu(): React.ReactNode {
+		if (
+			(!this._isViewing0xjsDocs() && !this._isViewingSmartContractsDocs() && !this._isViewingConnectDocs()) ||
+			_.isUndefined(this.props.menu)
+		) {
+			return undefined;
+		}
 
-        const sectionTitle = `${this.props.docsInfo.displayName} Docs`;
-        return (
-            <div className="lg-hide md-hide">
-                <div className="pl1 py1" style={{ backgroundColor: colors.lightGrey }}>
-                    {sectionTitle}
-                </div>
-                <NestedSidebarMenu
-                    topLevelMenu={this.props.menu}
-                    menuSubsectionsBySection={this.props.menuSubsectionsBySection}
-                    shouldDisplaySectionHeaders={false}
-                    onMenuItemClick={this._onMenuButtonClick.bind(this)}
-                    selectedVersion={this.props.docsVersion}
-                    docPath={this.props.docsInfo.websitePath}
-                    versions={this.props.availableDocVersions}
-                />
-            </div>
-        );
-    }
-    private _renderWiki(): React.ReactNode {
-        if (!this._isViewingWiki()) {
-            return undefined;
-        }
+		const sectionTitle = `${this.props.docsInfo.displayName} Docs`;
+		return (
+			<div className="lg-hide md-hide">
+				<div className="pl1 py1" style={{ backgroundColor: colors.lightGrey }}>
+					{sectionTitle}
+				</div>
+				<NestedSidebarMenu
+					topLevelMenu={this.props.menu}
+					menuSubsectionsBySection={this.props.menuSubsectionsBySection}
+					shouldDisplaySectionHeaders={false}
+					onMenuItemClick={this._onMenuButtonClick.bind(this)}
+					selectedVersion={this.props.docsVersion}
+					docPath={this.props.docsInfo.websitePath}
+					versions={this.props.availableDocVersions}
+				/>
+			</div>
+		);
+	}
+	private _renderWiki(): React.ReactNode {
+		if (!this._isViewingWiki()) {
+			return undefined;
+		}
 
-        return (
-            <div className="lg-hide md-hide">
-                <div className="pl1 py1" style={{ backgroundColor: colors.lightGrey }}>
-                    0x Protocol Wiki
-                </div>
-                <NestedSidebarMenu
-                    topLevelMenu={this.props.menuSubsectionsBySection}
-                    menuSubsectionsBySection={this.props.menuSubsectionsBySection}
-                    shouldDisplaySectionHeaders={false}
-                    onMenuItemClick={this._onMenuButtonClick.bind(this)}
-                />
-            </div>
-        );
-    }
-    private _renderPortalMenu(): React.ReactNode {
-        if (!this._isViewingPortal()) {
-            return undefined;
-        }
+		return (
+			<div className="lg-hide md-hide">
+				<div className="pl1 py1" style={{ backgroundColor: colors.lightGrey }}>
+					0x Protocol Wiki
+				</div>
+				<NestedSidebarMenu
+					topLevelMenu={this.props.menuSubsectionsBySection}
+					menuSubsectionsBySection={this.props.menuSubsectionsBySection}
+					shouldDisplaySectionHeaders={false}
+					onMenuItemClick={this._onMenuButtonClick.bind(this)}
+				/>
+			</div>
+		);
+	}
+	private _renderPortalMenu(): React.ReactNode {
+		if (!this._isViewingPortal()) {
+			return undefined;
+		}
 
-        return (
-            <div className="lg-hide md-hide">
-                <div className="pl1 py1" style={{ backgroundColor: colors.lightGrey }}>
-                    Portal DApp
-                </div>
-                <PortalMenu menuItemStyle={{ color: 'black' }} onClick={this._onMenuButtonClick.bind(this)} />
-            </div>
-        );
-    }
-    private _renderUser() {
-        const userAddress = this.props.userAddress;
-        const identiconDiameter = 26;
-        return (
-            <div className="flex right lg-pr0 md-pr2 sm-pr2" style={{ paddingTop: 16 }}>
-                <div style={styles.address} data-tip={true} data-for="userAddressTooltip">
-                    {!_.isEmpty(userAddress) ? userAddress : ''}
-                </div>
-                <ReactTooltip id="userAddressTooltip">{userAddress}</ReactTooltip>
-                <div>
-                    <Identicon address={userAddress} diameter={identiconDiameter} />
-                </div>
-            </div>
-        );
-    }
-    private _onMenuButtonClick() {
-        this.setState({
-            isDrawerOpen: !this.state.isDrawerOpen,
-        });
-    }
-    private _isViewingPortal() {
-        return _.includes(this.props.location.pathname, WebsitePaths.Portal);
-    }
-    private _isViewingFAQ() {
-        return _.includes(this.props.location.pathname, WebsitePaths.FAQ);
-    }
-    private _isViewing0xjsDocs() {
-        return _.includes(this.props.location.pathname, WebsitePaths.ZeroExJs);
-    }
-    private _isViewingConnectDocs() {
-        return _.includes(this.props.location.pathname, WebsitePaths.Connect);
-    }
-    private _isViewingSmartContractsDocs() {
-        return _.includes(this.props.location.pathname, WebsitePaths.SmartContracts);
-    }
-    private _isViewingWiki() {
-        return _.includes(this.props.location.pathname, WebsitePaths.Wiki);
-    }
-    private _shouldDisplayBottomBar() {
-        return (
-            this._isViewingWiki() ||
-            this._isViewing0xjsDocs() ||
-            this._isViewingFAQ() ||
-            this._isViewingSmartContractsDocs() ||
-            this._isViewingConnectDocs()
-        );
-    }
+		return (
+			<div className="lg-hide md-hide">
+				<div className="pl1 py1" style={{ backgroundColor: colors.lightGrey }}>
+					Portal DApp
+				</div>
+				<PortalMenu menuItemStyle={{ color: 'black' }} onClick={this._onMenuButtonClick.bind(this)} />
+			</div>
+		);
+	}
+	private _renderUser() {
+		const userAddress = this.props.userAddress;
+		const identiconDiameter = 26;
+		return (
+			<div className="flex right lg-pr0 md-pr2 sm-pr2" style={{ paddingTop: 16 }}>
+				<div style={styles.address} data-tip={true} data-for="userAddressTooltip">
+					{!_.isEmpty(userAddress) ? userAddress : ''}
+				</div>
+				<ReactTooltip id="userAddressTooltip">{userAddress}</ReactTooltip>
+				<div>
+					<Identicon address={userAddress} diameter={identiconDiameter} />
+				</div>
+			</div>
+		);
+	}
+	private _onMenuButtonClick() {
+		this.setState({
+			isDrawerOpen: !this.state.isDrawerOpen,
+		});
+	}
+	private _isViewingPortal() {
+		return _.includes(this.props.location.pathname, WebsitePaths.Portal);
+	}
+	private _isViewingFAQ() {
+		return _.includes(this.props.location.pathname, WebsitePaths.FAQ);
+	}
+	private _isViewing0xjsDocs() {
+		return _.includes(this.props.location.pathname, WebsitePaths.ZeroExJs);
+	}
+	private _isViewingConnectDocs() {
+		return _.includes(this.props.location.pathname, WebsitePaths.Connect);
+	}
+	private _isViewingSmartContractsDocs() {
+		return _.includes(this.props.location.pathname, WebsitePaths.SmartContracts);
+	}
+	private _isViewingWiki() {
+		return _.includes(this.props.location.pathname, WebsitePaths.Wiki);
+	}
+	private _shouldDisplayBottomBar() {
+		return (
+			this._isViewingWiki() ||
+			this._isViewing0xjsDocs() ||
+			this._isViewingFAQ() ||
+			this._isViewingSmartContractsDocs() ||
+			this._isViewingConnectDocs()
+		);
+	}
 }
diff --git a/packages/website/ts/components/top_bar_menu_item.tsx b/packages/website/ts/components/top_bar_menu_item.tsx
index 96ee86142..0138740ba 100644
--- a/packages/website/ts/components/top_bar_menu_item.tsx
+++ b/packages/website/ts/components/top_bar_menu_item.tsx
@@ -4,49 +4,49 @@ import { Link } from 'react-router-dom';
 import { colors } from 'ts/utils/colors';
 
 const DEFAULT_STYLE = {
-    color: colors.darkestGrey,
+	color: colors.darkestGrey,
 };
 
 interface TopBarMenuItemProps {
-    title: string;
-    path?: string;
-    isPrimary?: boolean;
-    style?: React.CSSProperties;
-    className?: string;
-    isNightVersion?: boolean;
+	title: string;
+	path?: string;
+	isPrimary?: boolean;
+	style?: React.CSSProperties;
+	className?: string;
+	isNightVersion?: boolean;
 }
 
 interface TopBarMenuItemState {}
 
 export class TopBarMenuItem extends React.Component<TopBarMenuItemProps, TopBarMenuItemState> {
-    public static defaultProps: Partial<TopBarMenuItemProps> = {
-        isPrimary: false,
-        style: DEFAULT_STYLE,
-        className: '',
-        isNightVersion: false,
-    };
-    public render() {
-        const primaryStyles = this.props.isPrimary
-            ? {
-                  borderRadius: 4,
-                  border: `1px solid ${this.props.isNightVersion ? colors.grey : colors.greyishPink}`,
-                  marginTop: 15,
-                  paddingLeft: 9,
-                  paddingRight: 9,
-                  width: 77,
-              }
-            : {};
-        const menuItemColor = this.props.isNightVersion ? 'white' : this.props.style.color;
-        const linkColor = _.isUndefined(menuItemColor) ? colors.darkestGrey : menuItemColor;
-        return (
-            <div
-                className={`center ${this.props.className}`}
-                style={{ ...this.props.style, ...primaryStyles, color: menuItemColor }}
-            >
-                <Link to={this.props.path} className="text-decoration-none" style={{ color: linkColor }}>
-                    {this.props.title}
-                </Link>
-            </div>
-        );
-    }
+	public static defaultProps: Partial<TopBarMenuItemProps> = {
+		isPrimary: false,
+		style: DEFAULT_STYLE,
+		className: '',
+		isNightVersion: false,
+	};
+	public render() {
+		const primaryStyles = this.props.isPrimary
+			? {
+					borderRadius: 4,
+					border: `1px solid ${this.props.isNightVersion ? colors.grey : colors.greyishPink}`,
+					marginTop: 15,
+					paddingLeft: 9,
+					paddingRight: 9,
+					width: 77,
+				}
+			: {};
+		const menuItemColor = this.props.isNightVersion ? 'white' : this.props.style.color;
+		const linkColor = _.isUndefined(menuItemColor) ? colors.darkestGrey : menuItemColor;
+		return (
+			<div
+				className={`center ${this.props.className}`}
+				style={{ ...this.props.style, ...primaryStyles, color: menuItemColor }}
+			>
+				<Link to={this.props.path} className="text-decoration-none" style={{ color: linkColor }}>
+					{this.props.title}
+				</Link>
+			</div>
+		);
+	}
 }
diff --git a/packages/website/ts/components/track_token_confirmation.tsx b/packages/website/ts/components/track_token_confirmation.tsx
index 76971aefa..1887bd11c 100644
--- a/packages/website/ts/components/track_token_confirmation.tsx
+++ b/packages/website/ts/components/track_token_confirmation.tsx
@@ -6,56 +6,56 @@ import { colors } from 'ts/utils/colors';
 import { utils } from 'ts/utils/utils';
 
 interface TrackTokenConfirmationProps {
-    tokens: Token[];
-    tokenByAddress: TokenByAddress;
-    networkId: number;
-    isAddingTokenToTracked: boolean;
+	tokens: Token[];
+	tokenByAddress: TokenByAddress;
+	networkId: number;
+	isAddingTokenToTracked: boolean;
 }
 
 interface TrackTokenConfirmationState {}
 
 export class TrackTokenConfirmation extends React.Component<TrackTokenConfirmationProps, TrackTokenConfirmationState> {
-    public render() {
-        const isMultipleTokens = this.props.tokens.length > 1;
-        const allTokens = _.values(this.props.tokenByAddress);
-        return (
-            <div style={{ color: colors.grey700 }}>
-                {this.props.isAddingTokenToTracked ? (
-                    <div className="py4 my4 center">
-                        <span className="pr1">
-                            <i className="zmdi zmdi-spinner zmdi-hc-spin" />
-                        </span>
-                        <span>Adding token{isMultipleTokens && 's'}...</span>
-                    </div>
-                ) : (
-                    <div>
-                        <div>You do not currently track the following token{isMultipleTokens && 's'}:</div>
-                        <div className="py2 clearfix mx-auto center" style={{ width: 355 }}>
-                            {_.map(this.props.tokens, (token: Token) => (
-                                <div
-                                    key={`token-profile-${token.name}`}
-                                    className={`col col-${isMultipleTokens ? '6' : '12'} px2`}
-                                >
-                                    <Party
-                                        label={token.name}
-                                        address={token.address}
-                                        networkId={this.props.networkId}
-                                        alternativeImage={token.iconUrl}
-                                        isInTokenRegistry={token.isRegistered}
-                                        hasUniqueNameAndSymbol={utils.hasUniqueNameAndSymbol(allTokens, token)}
-                                    />
-                                </div>
-                            ))}
-                        </div>
-                        <div>
-                            Tracking a token adds it to the balances section of 0x Portal and allows you to
-                            generate/fill orders involving the token
-                            {isMultipleTokens && 's'}. Would you like to start tracking{' '}
-                            {isMultipleTokens ? 'these' : 'this'} token?
-                        </div>
-                    </div>
-                )}
-            </div>
-        );
-    }
+	public render() {
+		const isMultipleTokens = this.props.tokens.length > 1;
+		const allTokens = _.values(this.props.tokenByAddress);
+		return (
+			<div style={{ color: colors.grey700 }}>
+				{this.props.isAddingTokenToTracked ? (
+					<div className="py4 my4 center">
+						<span className="pr1">
+							<i className="zmdi zmdi-spinner zmdi-hc-spin" />
+						</span>
+						<span>Adding token{isMultipleTokens && 's'}...</span>
+					</div>
+				) : (
+					<div>
+						<div>You do not currently track the following token{isMultipleTokens && 's'}:</div>
+						<div className="py2 clearfix mx-auto center" style={{ width: 355 }}>
+							{_.map(this.props.tokens, (token: Token) => (
+								<div
+									key={`token-profile-${token.name}`}
+									className={`col col-${isMultipleTokens ? '6' : '12'} px2`}
+								>
+									<Party
+										label={token.name}
+										address={token.address}
+										networkId={this.props.networkId}
+										alternativeImage={token.iconUrl}
+										isInTokenRegistry={token.isRegistered}
+										hasUniqueNameAndSymbol={utils.hasUniqueNameAndSymbol(allTokens, token)}
+									/>
+								</div>
+							))}
+						</div>
+						<div>
+							Tracking a token adds it to the balances section of 0x Portal and allows you to
+							generate/fill orders involving the token
+							{isMultipleTokens && 's'}. Would you like to start tracking{' '}
+							{isMultipleTokens ? 'these' : 'this'} token?
+						</div>
+					</div>
+				)}
+			</div>
+		);
+	}
 }
diff --git a/packages/website/ts/components/trade_history/trade_history.tsx b/packages/website/ts/components/trade_history/trade_history.tsx
index 635358627..3963135f7 100644
--- a/packages/website/ts/components/trade_history/trade_history.tsx
+++ b/packages/website/ts/components/trade_history/trade_history.tsx
@@ -10,106 +10,106 @@ import { utils } from 'ts/utils/utils';
 const FILL_POLLING_INTERVAL = 1000;
 
 interface TradeHistoryProps {
-    tokenByAddress: TokenByAddress;
-    userAddress: string;
-    networkId: number;
+	tokenByAddress: TokenByAddress;
+	userAddress: string;
+	networkId: number;
 }
 
 interface TradeHistoryState {
-    sortedFills: Fill[];
+	sortedFills: Fill[];
 }
 
 export class TradeHistory extends React.Component<TradeHistoryProps, TradeHistoryState> {
-    private _fillPollingIntervalId: number;
-    public constructor(props: TradeHistoryProps) {
-        super(props);
-        const sortedFills = this._getSortedFills();
-        this.state = {
-            sortedFills,
-        };
-    }
-    public componentWillMount() {
-        this._startPollingForFills();
-    }
-    public componentWillUnmount() {
-        this._stopPollingForFills();
-    }
-    public componentDidMount() {
-        window.scrollTo(0, 0);
-    }
-    public render() {
-        return (
-            <div className="lg-px4 md-px4 sm-px2">
-                <h3>Trade history</h3>
-                <Divider />
-                <div className="pt2" style={{ height: 608, overflow: 'scroll' }}>
-                    {this._renderTrades()}
-                </div>
-            </div>
-        );
-    }
-    private _renderTrades() {
-        const numNonCustomFills = this._numFillsWithoutCustomERC20Tokens();
-        if (numNonCustomFills === 0) {
-            return this._renderEmptyNotice();
-        }
+	private _fillPollingIntervalId: number;
+	public constructor(props: TradeHistoryProps) {
+		super(props);
+		const sortedFills = this._getSortedFills();
+		this.state = {
+			sortedFills,
+		};
+	}
+	public componentWillMount() {
+		this._startPollingForFills();
+	}
+	public componentWillUnmount() {
+		this._stopPollingForFills();
+	}
+	public componentDidMount() {
+		window.scrollTo(0, 0);
+	}
+	public render() {
+		return (
+			<div className="lg-px4 md-px4 sm-px2">
+				<h3>Trade history</h3>
+				<Divider />
+				<div className="pt2" style={{ height: 608, overflow: 'scroll' }}>
+					{this._renderTrades()}
+				</div>
+			</div>
+		);
+	}
+	private _renderTrades() {
+		const numNonCustomFills = this._numFillsWithoutCustomERC20Tokens();
+		if (numNonCustomFills === 0) {
+			return this._renderEmptyNotice();
+		}
 
-        return _.map(this.state.sortedFills, (fill, index) => {
-            return (
-                <TradeHistoryItem
-                    key={`${fill.orderHash}-${fill.filledTakerTokenAmount}-${index}`}
-                    fill={fill}
-                    tokenByAddress={this.props.tokenByAddress}
-                    userAddress={this.props.userAddress}
-                    networkId={this.props.networkId}
-                />
-            );
-        });
-    }
-    private _renderEmptyNotice() {
-        return (
-            <Paper className="mt1 p2 mx-auto center" style={{ width: '80%' }}>
-                No filled orders yet.
-            </Paper>
-        );
-    }
-    private _numFillsWithoutCustomERC20Tokens() {
-        let numNonCustomFills = 0;
-        const tokens = _.values(this.props.tokenByAddress);
-        _.each(this.state.sortedFills, fill => {
-            const takerToken = _.find(tokens, token => {
-                return token.address === fill.takerToken;
-            });
-            const makerToken = _.find(tokens, token => {
-                return token.address === fill.makerToken;
-            });
-            // For now we don't show history items for orders using custom ERC20
-            // tokens the client does not know how to display.
-            // TODO: Try to retrieve the name/symbol of an unknown token in order to display it
-            // Be sure to remove similar logic in trade_history_item.tsx
-            if (!_.isUndefined(takerToken) && !_.isUndefined(makerToken)) {
-                numNonCustomFills += 1;
-            }
-        });
-        return numNonCustomFills;
-    }
-    private _startPollingForFills() {
-        this._fillPollingIntervalId = window.setInterval(() => {
-            const sortedFills = this._getSortedFills();
-            if (!utils.deepEqual(sortedFills, this.state.sortedFills)) {
-                this.setState({
-                    sortedFills,
-                });
-            }
-        }, FILL_POLLING_INTERVAL);
-    }
-    private _stopPollingForFills() {
-        clearInterval(this._fillPollingIntervalId);
-    }
-    private _getSortedFills() {
-        const fillsByHash = tradeHistoryStorage.getUserFillsByHash(this.props.userAddress, this.props.networkId);
-        const fills = _.values(fillsByHash);
-        const sortedFills = _.sortBy(fills, [(fill: Fill) => fill.blockTimestamp * -1]);
-        return sortedFills;
-    }
+		return _.map(this.state.sortedFills, (fill, index) => {
+			return (
+				<TradeHistoryItem
+					key={`${fill.orderHash}-${fill.filledTakerTokenAmount}-${index}`}
+					fill={fill}
+					tokenByAddress={this.props.tokenByAddress}
+					userAddress={this.props.userAddress}
+					networkId={this.props.networkId}
+				/>
+			);
+		});
+	}
+	private _renderEmptyNotice() {
+		return (
+			<Paper className="mt1 p2 mx-auto center" style={{ width: '80%' }}>
+				No filled orders yet.
+			</Paper>
+		);
+	}
+	private _numFillsWithoutCustomERC20Tokens() {
+		let numNonCustomFills = 0;
+		const tokens = _.values(this.props.tokenByAddress);
+		_.each(this.state.sortedFills, fill => {
+			const takerToken = _.find(tokens, token => {
+				return token.address === fill.takerToken;
+			});
+			const makerToken = _.find(tokens, token => {
+				return token.address === fill.makerToken;
+			});
+			// For now we don't show history items for orders using custom ERC20
+			// tokens the client does not know how to display.
+			// TODO: Try to retrieve the name/symbol of an unknown token in order to display it
+			// Be sure to remove similar logic in trade_history_item.tsx
+			if (!_.isUndefined(takerToken) && !_.isUndefined(makerToken)) {
+				numNonCustomFills += 1;
+			}
+		});
+		return numNonCustomFills;
+	}
+	private _startPollingForFills() {
+		this._fillPollingIntervalId = window.setInterval(() => {
+			const sortedFills = this._getSortedFills();
+			if (!utils.deepEqual(sortedFills, this.state.sortedFills)) {
+				this.setState({
+					sortedFills,
+				});
+			}
+		}, FILL_POLLING_INTERVAL);
+	}
+	private _stopPollingForFills() {
+		clearInterval(this._fillPollingIntervalId);
+	}
+	private _getSortedFills() {
+		const fillsByHash = tradeHistoryStorage.getUserFillsByHash(this.props.userAddress, this.props.networkId);
+		const fills = _.values(fillsByHash);
+		const sortedFills = _.sortBy(fills, [(fill: Fill) => fill.blockTimestamp * -1]);
+		return sortedFills;
+	}
 }
diff --git a/packages/website/ts/components/trade_history/trade_history_item.tsx b/packages/website/ts/components/trade_history/trade_history_item.tsx
index 7e42e64e6..118bde3b9 100644
--- a/packages/website/ts/components/trade_history/trade_history_item.tsx
+++ b/packages/website/ts/components/trade_history/trade_history_item.tsx
@@ -14,157 +14,157 @@ const PRECISION = 5;
 const IDENTICON_DIAMETER = 40;
 
 interface TradeHistoryItemProps {
-    fill: Fill;
-    tokenByAddress: TokenByAddress;
-    userAddress: string;
-    networkId: number;
+	fill: Fill;
+	tokenByAddress: TokenByAddress;
+	userAddress: string;
+	networkId: number;
 }
 
 interface TradeHistoryItemState {}
 
 export class TradeHistoryItem extends React.Component<TradeHistoryItemProps, TradeHistoryItemState> {
-    public render() {
-        const fill = this.props.fill;
-        const tokens = _.values(this.props.tokenByAddress);
-        const takerToken = _.find(tokens, token => {
-            return token.address === fill.takerToken;
-        });
-        const makerToken = _.find(tokens, token => {
-            return token.address === fill.makerToken;
-        });
-        // For now we don't show history items for orders using custom ERC20
-        // tokens the client does not know how to display.
-        // TODO: Try to retrieve the name/symbol of an unknown token in order to display it
-        // Be sure to remove similar logic in trade_history.tsx
-        if (_.isUndefined(takerToken) || _.isUndefined(makerToken)) {
-            return null;
-        }
+	public render() {
+		const fill = this.props.fill;
+		const tokens = _.values(this.props.tokenByAddress);
+		const takerToken = _.find(tokens, token => {
+			return token.address === fill.takerToken;
+		});
+		const makerToken = _.find(tokens, token => {
+			return token.address === fill.makerToken;
+		});
+		// For now we don't show history items for orders using custom ERC20
+		// tokens the client does not know how to display.
+		// TODO: Try to retrieve the name/symbol of an unknown token in order to display it
+		// Be sure to remove similar logic in trade_history.tsx
+		if (_.isUndefined(takerToken) || _.isUndefined(makerToken)) {
+			return null;
+		}
 
-        const amountColStyle: React.CSSProperties = {
-            fontWeight: 100,
-            display: 'inline-block',
-        };
-        const amountColClassNames =
-            'col col-12 lg-col-4 md-col-4 lg-py2 md-py2 sm-py1 lg-pr2 md-pr2 \
+		const amountColStyle: React.CSSProperties = {
+			fontWeight: 100,
+			display: 'inline-block',
+		};
+		const amountColClassNames =
+			'col col-12 lg-col-4 md-col-4 lg-py2 md-py2 sm-py1 lg-pr2 md-pr2 \
                                      lg-right-align md-right-align sm-center';
 
-        return (
-            <Paper className="py1" style={{ margin: '3px 3px 15px 3px' }}>
-                <div className="clearfix">
-                    <div className="col col-12 lg-col-1 md-col-1 pt2 lg-pl3 md-pl3">{this._renderDate()}</div>
-                    <div
-                        className="col col-12 lg-col-6 md-col-6 lg-pl3 md-pl3"
-                        style={{ fontSize: 12, fontWeight: 100 }}
-                    >
-                        <div className="flex sm-mx-auto xs-mx-auto" style={{ paddingTop: 4, width: 224 }}>
-                            <Party
-                                label="Maker"
-                                address={fill.maker}
-                                identiconDiameter={IDENTICON_DIAMETER}
-                                networkId={this.props.networkId}
-                            />
-                            <i style={{ fontSize: 30 }} className="zmdi zmdi-swap py3" />
-                            <Party
-                                label="Taker"
-                                address={fill.taker}
-                                identiconDiameter={IDENTICON_DIAMETER}
-                                networkId={this.props.networkId}
-                            />
-                        </div>
-                    </div>
-                    <div className={amountColClassNames} style={amountColStyle}>
-                        {this._renderAmounts(makerToken, takerToken)}
-                    </div>
-                    <div className="col col-12 lg-col-1 md-col-1 lg-pr3 md-pr3 lg-py3 md-py3 sm-pb1 sm-center">
-                        <div className="pt1 lg-right md-right sm-mx-auto" style={{ width: 13 }}>
-                            <EtherScanIcon
-                                addressOrTxHash={fill.transactionHash}
-                                networkId={this.props.networkId}
-                                etherscanLinkSuffixes={EtherscanLinkSuffixes.Tx}
-                            />
-                        </div>
-                    </div>
-                </div>
-            </Paper>
-        );
-    }
-    private _renderAmounts(makerToken: Token, takerToken: Token) {
-        const fill = this.props.fill;
-        const filledTakerTokenAmountInUnits = ZeroEx.toUnitAmount(fill.filledTakerTokenAmount, takerToken.decimals);
-        const filledMakerTokenAmountInUnits = ZeroEx.toUnitAmount(fill.filledMakerTokenAmount, takerToken.decimals);
-        let exchangeRate = filledTakerTokenAmountInUnits.div(filledMakerTokenAmountInUnits);
-        const fillMakerTokenAmount = ZeroEx.toBaseUnitAmount(filledMakerTokenAmountInUnits, makerToken.decimals);
+		return (
+			<Paper className="py1" style={{ margin: '3px 3px 15px 3px' }}>
+				<div className="clearfix">
+					<div className="col col-12 lg-col-1 md-col-1 pt2 lg-pl3 md-pl3">{this._renderDate()}</div>
+					<div
+						className="col col-12 lg-col-6 md-col-6 lg-pl3 md-pl3"
+						style={{ fontSize: 12, fontWeight: 100 }}
+					>
+						<div className="flex sm-mx-auto xs-mx-auto" style={{ paddingTop: 4, width: 224 }}>
+							<Party
+								label="Maker"
+								address={fill.maker}
+								identiconDiameter={IDENTICON_DIAMETER}
+								networkId={this.props.networkId}
+							/>
+							<i style={{ fontSize: 30 }} className="zmdi zmdi-swap py3" />
+							<Party
+								label="Taker"
+								address={fill.taker}
+								identiconDiameter={IDENTICON_DIAMETER}
+								networkId={this.props.networkId}
+							/>
+						</div>
+					</div>
+					<div className={amountColClassNames} style={amountColStyle}>
+						{this._renderAmounts(makerToken, takerToken)}
+					</div>
+					<div className="col col-12 lg-col-1 md-col-1 lg-pr3 md-pr3 lg-py3 md-py3 sm-pb1 sm-center">
+						<div className="pt1 lg-right md-right sm-mx-auto" style={{ width: 13 }}>
+							<EtherScanIcon
+								addressOrTxHash={fill.transactionHash}
+								networkId={this.props.networkId}
+								etherscanLinkSuffixes={EtherscanLinkSuffixes.Tx}
+							/>
+						</div>
+					</div>
+				</div>
+			</Paper>
+		);
+	}
+	private _renderAmounts(makerToken: Token, takerToken: Token) {
+		const fill = this.props.fill;
+		const filledTakerTokenAmountInUnits = ZeroEx.toUnitAmount(fill.filledTakerTokenAmount, takerToken.decimals);
+		const filledMakerTokenAmountInUnits = ZeroEx.toUnitAmount(fill.filledMakerTokenAmount, takerToken.decimals);
+		let exchangeRate = filledTakerTokenAmountInUnits.div(filledMakerTokenAmountInUnits);
+		const fillMakerTokenAmount = ZeroEx.toBaseUnitAmount(filledMakerTokenAmountInUnits, makerToken.decimals);
 
-        let receiveAmount;
-        let receiveToken;
-        let givenAmount;
-        let givenToken;
-        if (this.props.userAddress === fill.maker && this.props.userAddress === fill.taker) {
-            receiveAmount = new BigNumber(0);
-            givenAmount = new BigNumber(0);
-            receiveToken = makerToken;
-            givenToken = takerToken;
-        } else if (this.props.userAddress === fill.maker) {
-            receiveAmount = fill.filledTakerTokenAmount;
-            givenAmount = fillMakerTokenAmount;
-            receiveToken = takerToken;
-            givenToken = makerToken;
-            exchangeRate = new BigNumber(1).div(exchangeRate);
-        } else if (this.props.userAddress === fill.taker) {
-            receiveAmount = fillMakerTokenAmount;
-            givenAmount = fill.filledTakerTokenAmount;
-            receiveToken = makerToken;
-            givenToken = takerToken;
-        } else {
-            // This condition should never be hit
-            throw new Error("Found Fill that wasn't performed by this user");
-        }
+		let receiveAmount;
+		let receiveToken;
+		let givenAmount;
+		let givenToken;
+		if (this.props.userAddress === fill.maker && this.props.userAddress === fill.taker) {
+			receiveAmount = new BigNumber(0);
+			givenAmount = new BigNumber(0);
+			receiveToken = makerToken;
+			givenToken = takerToken;
+		} else if (this.props.userAddress === fill.maker) {
+			receiveAmount = fill.filledTakerTokenAmount;
+			givenAmount = fillMakerTokenAmount;
+			receiveToken = takerToken;
+			givenToken = makerToken;
+			exchangeRate = new BigNumber(1).div(exchangeRate);
+		} else if (this.props.userAddress === fill.taker) {
+			receiveAmount = fillMakerTokenAmount;
+			givenAmount = fill.filledTakerTokenAmount;
+			receiveToken = makerToken;
+			givenToken = takerToken;
+		} else {
+			// This condition should never be hit
+			throw new Error("Found Fill that wasn't performed by this user");
+		}
 
-        return (
-            <div>
-                <div style={{ color: colors.green400, fontSize: 16 }}>
-                    <span>+ </span>
-                    {this._renderAmount(receiveAmount, receiveToken.symbol, receiveToken.decimals)}
-                </div>
-                <div className="pb1 inline-block" style={{ color: colors.red200, fontSize: 16 }}>
-                    <span>- </span>
-                    {this._renderAmount(givenAmount, givenToken.symbol, givenToken.decimals)}
-                </div>
-                <div style={{ color: colors.grey400, fontSize: 14 }}>
-                    {exchangeRate.toFixed(PRECISION)} {givenToken.symbol}/{receiveToken.symbol}
-                </div>
-            </div>
-        );
-    }
-    private _renderDate() {
-        const blockMoment = moment.unix(this.props.fill.blockTimestamp);
-        if (!blockMoment.isValid()) {
-            return null;
-        }
+		return (
+			<div>
+				<div style={{ color: colors.green400, fontSize: 16 }}>
+					<span>+ </span>
+					{this._renderAmount(receiveAmount, receiveToken.symbol, receiveToken.decimals)}
+				</div>
+				<div className="pb1 inline-block" style={{ color: colors.red200, fontSize: 16 }}>
+					<span>- </span>
+					{this._renderAmount(givenAmount, givenToken.symbol, givenToken.decimals)}
+				</div>
+				<div style={{ color: colors.grey400, fontSize: 14 }}>
+					{exchangeRate.toFixed(PRECISION)} {givenToken.symbol}/{receiveToken.symbol}
+				</div>
+			</div>
+		);
+	}
+	private _renderDate() {
+		const blockMoment = moment.unix(this.props.fill.blockTimestamp);
+		if (!blockMoment.isValid()) {
+			return null;
+		}
 
-        const dayOfMonth = blockMoment.format('D');
-        const monthAbreviation = blockMoment.format('MMM');
-        const formattedBlockDate = blockMoment.format('H:mmA - MMMM D, YYYY');
-        const dateTooltipId = `${this.props.fill.transactionHash}-date`;
+		const dayOfMonth = blockMoment.format('D');
+		const monthAbreviation = blockMoment.format('MMM');
+		const formattedBlockDate = blockMoment.format('H:mmA - MMMM D, YYYY');
+		const dateTooltipId = `${this.props.fill.transactionHash}-date`;
 
-        return (
-            <div data-tip={true} data-for={dateTooltipId}>
-                <div className="center pt1" style={{ fontSize: 13 }}>
-                    {monthAbreviation}
-                </div>
-                <div className="center" style={{ fontSize: 24, fontWeight: 100 }}>
-                    {dayOfMonth}
-                </div>
-                <ReactTooltip id={dateTooltipId}>{formattedBlockDate}</ReactTooltip>
-            </div>
-        );
-    }
-    private _renderAmount(amount: BigNumber, symbol: string, decimals: number) {
-        const unitAmount = ZeroEx.toUnitAmount(amount, decimals);
-        return (
-            <span>
-                {unitAmount.toFixed(PRECISION)} {symbol}
-            </span>
-        );
-    }
+		return (
+			<div data-tip={true} data-for={dateTooltipId}>
+				<div className="center pt1" style={{ fontSize: 13 }}>
+					{monthAbreviation}
+				</div>
+				<div className="center" style={{ fontSize: 24, fontWeight: 100 }}>
+					{dayOfMonth}
+				</div>
+				<ReactTooltip id={dateTooltipId}>{formattedBlockDate}</ReactTooltip>
+			</div>
+		);
+	}
+	private _renderAmount(amount: BigNumber, symbol: string, decimals: number) {
+		const unitAmount = ZeroEx.toUnitAmount(amount, decimals);
+		return (
+			<span>
+				{unitAmount.toFixed(PRECISION)} {symbol}
+			</span>
+		);
+	}
 }
diff --git a/packages/website/ts/components/ui/alert.tsx b/packages/website/ts/components/ui/alert.tsx
index 54881b499..91ef8f76e 100644
--- a/packages/website/ts/components/ui/alert.tsx
+++ b/packages/website/ts/components/ui/alert.tsx
@@ -3,23 +3,23 @@ import { AlertTypes } from 'ts/types';
 import { colors } from 'ts/utils/colors';
 
 interface AlertProps {
-    type: AlertTypes;
-    message: string | React.ReactNode;
+	type: AlertTypes;
+	message: string | React.ReactNode;
 }
 
 export function Alert(props: AlertProps) {
-    const isAlert = props.type === AlertTypes.ERROR;
-    const errMsgStyles = {
-        background: isAlert ? colors.red200 : colors.lightestGreen,
-        color: colors.white,
-        marginTop: 10,
-        padding: 4,
-        paddingLeft: 8,
-    };
+	const isAlert = props.type === AlertTypes.ERROR;
+	const errMsgStyles = {
+		background: isAlert ? colors.red200 : colors.lightestGreen,
+		color: colors.white,
+		marginTop: 10,
+		padding: 4,
+		paddingLeft: 8,
+	};
 
-    return (
-        <div className="rounded center" style={errMsgStyles}>
-            {props.message}
-        </div>
-    );
+	return (
+		<div className="rounded center" style={errMsgStyles}>
+			{props.message}
+		</div>
+	);
 }
diff --git a/packages/website/ts/components/ui/badge.tsx b/packages/website/ts/components/ui/badge.tsx
index 7f7ea006e..1d2d81af6 100644
--- a/packages/website/ts/components/ui/badge.tsx
+++ b/packages/website/ts/components/ui/badge.tsx
@@ -3,55 +3,55 @@ import * as React from 'react';
 import { Styles } from 'ts/types';
 
 const styles: Styles = {
-    badge: {
-        width: 50,
-        fontSize: 11,
-        height: 10,
-        borderRadius: 5,
-        marginTop: 25,
-        lineHeight: 0.9,
-        fontFamily: 'Roboto Mono',
-        marginLeft: 3,
-        marginRight: 3,
-    },
+	badge: {
+		width: 50,
+		fontSize: 11,
+		height: 10,
+		borderRadius: 5,
+		marginTop: 25,
+		lineHeight: 0.9,
+		fontFamily: 'Roboto Mono',
+		marginLeft: 3,
+		marginRight: 3,
+	},
 };
 
 interface BadgeProps {
-    title: string;
-    backgroundColor: string;
+	title: string;
+	backgroundColor: string;
 }
 
 interface BadgeState {
-    isHovering: boolean;
+	isHovering: boolean;
 }
 
 export class Badge extends React.Component<BadgeProps, BadgeState> {
-    constructor(props: BadgeProps) {
-        super(props);
-        this.state = {
-            isHovering: false,
-        };
-    }
-    public render() {
-        const badgeStyle = {
-            ...styles.badge,
-            backgroundColor: this.props.backgroundColor,
-            opacity: this.state.isHovering ? 0.7 : 1,
-        };
-        return (
-            <div
-                className="p1 center"
-                style={badgeStyle}
-                onMouseOver={this._setHoverState.bind(this, true)}
-                onMouseOut={this._setHoverState.bind(this, false)}
-            >
-                {this.props.title}
-            </div>
-        );
-    }
-    private _setHoverState(isHovering: boolean) {
-        this.setState({
-            isHovering,
-        });
-    }
+	constructor(props: BadgeProps) {
+		super(props);
+		this.state = {
+			isHovering: false,
+		};
+	}
+	public render() {
+		const badgeStyle = {
+			...styles.badge,
+			backgroundColor: this.props.backgroundColor,
+			opacity: this.state.isHovering ? 0.7 : 1,
+		};
+		return (
+			<div
+				className="p1 center"
+				style={badgeStyle}
+				onMouseOver={this._setHoverState.bind(this, true)}
+				onMouseOut={this._setHoverState.bind(this, false)}
+			>
+				{this.props.title}
+			</div>
+		);
+	}
+	private _setHoverState(isHovering: boolean) {
+		this.setState({
+			isHovering,
+		});
+	}
 }
diff --git a/packages/website/ts/components/ui/copy_icon.tsx b/packages/website/ts/components/ui/copy_icon.tsx
index df55e0922..72ab77e1f 100644
--- a/packages/website/ts/components/ui/copy_icon.tsx
+++ b/packages/website/ts/components/ui/copy_icon.tsx
@@ -6,74 +6,74 @@ import ReactTooltip = require('react-tooltip');
 import { colors } from 'ts/utils/colors';
 
 interface CopyIconProps {
-    data: string;
-    callToAction?: string;
+	data: string;
+	callToAction?: string;
 }
 
 interface CopyIconState {
-    isHovering: boolean;
+	isHovering: boolean;
 }
 
 export class CopyIcon extends React.Component<CopyIconProps, CopyIconState> {
-    private _copyTooltipTimeoutId: number;
-    private _copyable: HTMLInputElement;
-    constructor(props: CopyIconProps) {
-        super(props);
-        this.state = {
-            isHovering: false,
-        };
-    }
-    public componentDidUpdate() {
-        // Remove tooltip if hover away
-        if (!this.state.isHovering && this._copyTooltipTimeoutId) {
-            clearInterval(this._copyTooltipTimeoutId);
-            this._hideTooltip();
-        }
-    }
-    public render() {
-        return (
-            <div className="inline-block">
-                <CopyToClipboard text={this.props.data} onCopy={this._onCopy.bind(this)}>
-                    <div
-                        className="inline flex"
-                        style={{ cursor: 'pointer', color: colors.amber600 }}
-                        ref={this._setRefToProperty.bind(this)}
-                        data-tip={true}
-                        data-for="copy"
-                        data-event="click"
-                        data-iscapture={true} // This let's the click event continue to propogate
-                        onMouseOver={this._setHoverState.bind(this, true)}
-                        onMouseOut={this._setHoverState.bind(this, false)}
-                    >
-                        <div>
-                            <i style={{ fontSize: 15 }} className="zmdi zmdi-copy" />
-                        </div>
-                        {this.props.callToAction && <div className="pl1">{this.props.callToAction}</div>}
-                    </div>
-                </CopyToClipboard>
-                <ReactTooltip id="copy">Copied!</ReactTooltip>
-            </div>
-        );
-    }
-    private _setRefToProperty(el: HTMLInputElement) {
-        this._copyable = el;
-    }
-    private _setHoverState(isHovering: boolean) {
-        this.setState({
-            isHovering,
-        });
-    }
-    private _onCopy() {
-        if (this._copyTooltipTimeoutId) {
-            clearInterval(this._copyTooltipTimeoutId);
-        }
+	private _copyTooltipTimeoutId: number;
+	private _copyable: HTMLInputElement;
+	constructor(props: CopyIconProps) {
+		super(props);
+		this.state = {
+			isHovering: false,
+		};
+	}
+	public componentDidUpdate() {
+		// Remove tooltip if hover away
+		if (!this.state.isHovering && this._copyTooltipTimeoutId) {
+			clearInterval(this._copyTooltipTimeoutId);
+			this._hideTooltip();
+		}
+	}
+	public render() {
+		return (
+			<div className="inline-block">
+				<CopyToClipboard text={this.props.data} onCopy={this._onCopy.bind(this)}>
+					<div
+						className="inline flex"
+						style={{ cursor: 'pointer', color: colors.amber600 }}
+						ref={this._setRefToProperty.bind(this)}
+						data-tip={true}
+						data-for="copy"
+						data-event="click"
+						data-iscapture={true} // This let's the click event continue to propogate
+						onMouseOver={this._setHoverState.bind(this, true)}
+						onMouseOut={this._setHoverState.bind(this, false)}
+					>
+						<div>
+							<i style={{ fontSize: 15 }} className="zmdi zmdi-copy" />
+						</div>
+						{this.props.callToAction && <div className="pl1">{this.props.callToAction}</div>}
+					</div>
+				</CopyToClipboard>
+				<ReactTooltip id="copy">Copied!</ReactTooltip>
+			</div>
+		);
+	}
+	private _setRefToProperty(el: HTMLInputElement) {
+		this._copyable = el;
+	}
+	private _setHoverState(isHovering: boolean) {
+		this.setState({
+			isHovering,
+		});
+	}
+	private _onCopy() {
+		if (this._copyTooltipTimeoutId) {
+			clearInterval(this._copyTooltipTimeoutId);
+		}
 
-        const tooltipLifespanMs = 1000;
-        this._copyTooltipTimeoutId = window.setTimeout(() => {
-            this._hideTooltip();
-        }, tooltipLifespanMs);
-    }
-    private _hideTooltip() {
-        ReactTooltip.hide(ReactDOM.findDOMNode(this._copyable));
-    }
+		const tooltipLifespanMs = 1000;
+		this._copyTooltipTimeoutId = window.setTimeout(() => {
+			this._hideTooltip();
+		}, tooltipLifespanMs);
+	}
+	private _hideTooltip() {
+		ReactTooltip.hide(ReactDOM.findDOMNode(this._copyable));
+	}
 }
diff --git a/packages/website/ts/components/ui/drop_down_menu_item.tsx b/packages/website/ts/components/ui/drop_down_menu_item.tsx
index a578fb4f9..64f88f318 100644
--- a/packages/website/ts/components/ui/drop_down_menu_item.tsx
+++ b/packages/website/ts/components/ui/drop_down_menu_item.tsx
@@ -6,99 +6,99 @@ import { colors } from 'ts/utils/colors';
 
 const CHECK_CLOSE_POPOVER_INTERVAL_MS = 300;
 const DEFAULT_STYLE = {
-    fontSize: 14,
+	fontSize: 14,
 };
 
 interface DropDownMenuItemProps {
-    title: string;
-    subMenuItems: React.ReactNode[];
-    style?: React.CSSProperties;
-    menuItemStyle?: React.CSSProperties;
-    isNightVersion?: boolean;
+	title: string;
+	subMenuItems: React.ReactNode[];
+	style?: React.CSSProperties;
+	menuItemStyle?: React.CSSProperties;
+	isNightVersion?: boolean;
 }
 
 interface DropDownMenuItemState {
-    isDropDownOpen: boolean;
-    anchorEl?: HTMLInputElement;
+	isDropDownOpen: boolean;
+	anchorEl?: HTMLInputElement;
 }
 
 export class DropDownMenuItem extends React.Component<DropDownMenuItemProps, DropDownMenuItemState> {
-    public static defaultProps: Partial<DropDownMenuItemProps> = {
-        style: DEFAULT_STYLE,
-        menuItemStyle: DEFAULT_STYLE,
-        isNightVersion: false,
-    };
-    private _isHovering: boolean;
-    private _popoverCloseCheckIntervalId: number;
-    constructor(props: DropDownMenuItemProps) {
-        super(props);
-        this.state = {
-            isDropDownOpen: false,
-        };
-    }
-    public componentDidMount() {
-        this._popoverCloseCheckIntervalId = window.setInterval(() => {
-            this._checkIfShouldClosePopover();
-        }, CHECK_CLOSE_POPOVER_INTERVAL_MS);
-    }
-    public componentWillUnmount() {
-        window.clearInterval(this._popoverCloseCheckIntervalId);
-    }
-    public render() {
-        const colorStyle = this.props.isNightVersion ? 'white' : this.props.style.color;
-        return (
-            <div
-                style={{ ...this.props.style, color: colorStyle }}
-                onMouseEnter={this._onHover.bind(this)}
-                onMouseLeave={this._onHoverOff.bind(this)}
-            >
-                <div className="flex relative">
-                    <div style={{ paddingRight: 10 }}>{this.props.title}</div>
-                    <div className="absolute" style={{ paddingLeft: 3, right: 3, top: -2 }}>
-                        <i className="zmdi zmdi-caret-right" style={{ fontSize: 22 }} />
-                    </div>
-                </div>
-                <Popover
-                    open={this.state.isDropDownOpen}
-                    anchorEl={this.state.anchorEl}
-                    anchorOrigin={{ horizontal: 'middle', vertical: 'bottom' }}
-                    targetOrigin={{ horizontal: 'middle', vertical: 'top' }}
-                    onRequestClose={this._closePopover.bind(this)}
-                    useLayerForClickAway={false}
-                >
-                    <div onMouseEnter={this._onHover.bind(this)} onMouseLeave={this._onHoverOff.bind(this)}>
-                        <Menu style={{ color: colors.grey }}>{this.props.subMenuItems}</Menu>
-                    </div>
-                </Popover>
-            </div>
-        );
-    }
-    private _onHover(event: React.FormEvent<HTMLInputElement>) {
-        this._isHovering = true;
-        this._checkIfShouldOpenPopover(event);
-    }
-    private _checkIfShouldOpenPopover(event: React.FormEvent<HTMLInputElement>) {
-        if (this.state.isDropDownOpen) {
-            return; // noop
-        }
+	public static defaultProps: Partial<DropDownMenuItemProps> = {
+		style: DEFAULT_STYLE,
+		menuItemStyle: DEFAULT_STYLE,
+		isNightVersion: false,
+	};
+	private _isHovering: boolean;
+	private _popoverCloseCheckIntervalId: number;
+	constructor(props: DropDownMenuItemProps) {
+		super(props);
+		this.state = {
+			isDropDownOpen: false,
+		};
+	}
+	public componentDidMount() {
+		this._popoverCloseCheckIntervalId = window.setInterval(() => {
+			this._checkIfShouldClosePopover();
+		}, CHECK_CLOSE_POPOVER_INTERVAL_MS);
+	}
+	public componentWillUnmount() {
+		window.clearInterval(this._popoverCloseCheckIntervalId);
+	}
+	public render() {
+		const colorStyle = this.props.isNightVersion ? 'white' : this.props.style.color;
+		return (
+			<div
+				style={{ ...this.props.style, color: colorStyle }}
+				onMouseEnter={this._onHover.bind(this)}
+				onMouseLeave={this._onHoverOff.bind(this)}
+			>
+				<div className="flex relative">
+					<div style={{ paddingRight: 10 }}>{this.props.title}</div>
+					<div className="absolute" style={{ paddingLeft: 3, right: 3, top: -2 }}>
+						<i className="zmdi zmdi-caret-right" style={{ fontSize: 22 }} />
+					</div>
+				</div>
+				<Popover
+					open={this.state.isDropDownOpen}
+					anchorEl={this.state.anchorEl}
+					anchorOrigin={{ horizontal: 'middle', vertical: 'bottom' }}
+					targetOrigin={{ horizontal: 'middle', vertical: 'top' }}
+					onRequestClose={this._closePopover.bind(this)}
+					useLayerForClickAway={false}
+				>
+					<div onMouseEnter={this._onHover.bind(this)} onMouseLeave={this._onHoverOff.bind(this)}>
+						<Menu style={{ color: colors.grey }}>{this.props.subMenuItems}</Menu>
+					</div>
+				</Popover>
+			</div>
+		);
+	}
+	private _onHover(event: React.FormEvent<HTMLInputElement>) {
+		this._isHovering = true;
+		this._checkIfShouldOpenPopover(event);
+	}
+	private _checkIfShouldOpenPopover(event: React.FormEvent<HTMLInputElement>) {
+		if (this.state.isDropDownOpen) {
+			return; // noop
+		}
 
-        this.setState({
-            isDropDownOpen: true,
-            anchorEl: event.currentTarget,
-        });
-    }
-    private _onHoverOff(event: React.FormEvent<HTMLInputElement>) {
-        this._isHovering = false;
-    }
-    private _checkIfShouldClosePopover() {
-        if (!this.state.isDropDownOpen || this._isHovering) {
-            return; // noop
-        }
-        this._closePopover();
-    }
-    private _closePopover() {
-        this.setState({
-            isDropDownOpen: false,
-        });
-    }
+		this.setState({
+			isDropDownOpen: true,
+			anchorEl: event.currentTarget,
+		});
+	}
+	private _onHoverOff(event: React.FormEvent<HTMLInputElement>) {
+		this._isHovering = false;
+	}
+	private _checkIfShouldClosePopover() {
+		if (!this.state.isDropDownOpen || this._isHovering) {
+			return; // noop
+		}
+		this._closePopover();
+	}
+	private _closePopover() {
+		this.setState({
+			isDropDownOpen: false,
+		});
+	}
 }
diff --git a/packages/website/ts/components/ui/ethereum_address.tsx b/packages/website/ts/components/ui/ethereum_address.tsx
index b75d97e39..ba51135be 100644
--- a/packages/website/ts/components/ui/ethereum_address.tsx
+++ b/packages/website/ts/components/ui/ethereum_address.tsx
@@ -5,26 +5,26 @@ import { EtherscanLinkSuffixes } from 'ts/types';
 import { utils } from 'ts/utils/utils';
 
 interface EthereumAddressProps {
-    address: string;
-    networkId: number;
+	address: string;
+	networkId: number;
 }
 
 export const EthereumAddress = (props: EthereumAddressProps) => {
-    const tooltipId = `${props.address}-ethereum-address`;
-    const truncatedAddress = utils.getAddressBeginAndEnd(props.address);
-    return (
-        <div>
-            <div className="inline" style={{ fontSize: 13 }} data-tip={true} data-for={tooltipId}>
-                {truncatedAddress}
-            </div>
-            <div className="pl1 inline">
-                <EtherScanIcon
-                    addressOrTxHash={props.address}
-                    networkId={props.networkId}
-                    etherscanLinkSuffixes={EtherscanLinkSuffixes.Address}
-                />
-            </div>
-            <ReactTooltip id={tooltipId}>{props.address}</ReactTooltip>
-        </div>
-    );
+	const tooltipId = `${props.address}-ethereum-address`;
+	const truncatedAddress = utils.getAddressBeginAndEnd(props.address);
+	return (
+		<div>
+			<div className="inline" style={{ fontSize: 13 }} data-tip={true} data-for={tooltipId}>
+				{truncatedAddress}
+			</div>
+			<div className="pl1 inline">
+				<EtherScanIcon
+					addressOrTxHash={props.address}
+					networkId={props.networkId}
+					etherscanLinkSuffixes={EtherscanLinkSuffixes.Address}
+				/>
+			</div>
+			<ReactTooltip id={tooltipId}>{props.address}</ReactTooltip>
+		</div>
+	);
 };
diff --git a/packages/website/ts/components/ui/etherscan_icon.tsx b/packages/website/ts/components/ui/etherscan_icon.tsx
index 3b17bd0fa..5b224c3e1 100644
--- a/packages/website/ts/components/ui/etherscan_icon.tsx
+++ b/packages/website/ts/components/ui/etherscan_icon.tsx
@@ -6,36 +6,36 @@ import { colors } from 'ts/utils/colors';
 import { utils } from 'ts/utils/utils';
 
 interface EtherScanIconProps {
-    addressOrTxHash: string;
-    etherscanLinkSuffixes: EtherscanLinkSuffixes;
-    networkId: number;
+	addressOrTxHash: string;
+	etherscanLinkSuffixes: EtherscanLinkSuffixes;
+	networkId: number;
 }
 
 export const EtherScanIcon = (props: EtherScanIconProps) => {
-    const etherscanLinkIfExists = utils.getEtherScanLinkIfExists(
-        props.addressOrTxHash,
-        props.networkId,
-        EtherscanLinkSuffixes.Address,
-    );
-    const transactionTooltipId = `${props.addressOrTxHash}-etherscan-icon-tooltip`;
-    return (
-        <div className="inline">
-            {!_.isUndefined(etherscanLinkIfExists) ? (
-                <a href={etherscanLinkIfExists} target="_blank">
-                    {renderIcon()}
-                </a>
-            ) : (
-                <div className="inline" data-tip={true} data-for={transactionTooltipId}>
-                    {renderIcon()}
-                    <ReactTooltip id={transactionTooltipId}>
-                        Your network (id: {props.networkId}) is not supported by Etherscan
-                    </ReactTooltip>
-                </div>
-            )}
-        </div>
-    );
+	const etherscanLinkIfExists = utils.getEtherScanLinkIfExists(
+		props.addressOrTxHash,
+		props.networkId,
+		EtherscanLinkSuffixes.Address,
+	);
+	const transactionTooltipId = `${props.addressOrTxHash}-etherscan-icon-tooltip`;
+	return (
+		<div className="inline">
+			{!_.isUndefined(etherscanLinkIfExists) ? (
+				<a href={etherscanLinkIfExists} target="_blank">
+					{renderIcon()}
+				</a>
+			) : (
+				<div className="inline" data-tip={true} data-for={transactionTooltipId}>
+					{renderIcon()}
+					<ReactTooltip id={transactionTooltipId}>
+						Your network (id: {props.networkId}) is not supported by Etherscan
+					</ReactTooltip>
+				</div>
+			)}
+		</div>
+	);
 };
 
 function renderIcon() {
-    return <i style={{ color: colors.amber600 }} className="zmdi zmdi-open-in-new" />;
+	return <i style={{ color: colors.amber600 }} className="zmdi zmdi-open-in-new" />;
 }
diff --git a/packages/website/ts/components/ui/fake_text_field.tsx b/packages/website/ts/components/ui/fake_text_field.tsx
index f3d9410f6..6d321bb46 100644
--- a/packages/website/ts/components/ui/fake_text_field.tsx
+++ b/packages/website/ts/components/ui/fake_text_field.tsx
@@ -3,32 +3,32 @@ import { InputLabel } from 'ts/components/ui/input_label';
 import { Styles } from 'ts/types';
 
 const styles: Styles = {
-    hr: {
-        borderBottom: '1px solid rgb(224, 224, 224)',
-        borderLeft: 'none rgb(224, 224, 224)',
-        borderRight: 'none rgb(224, 224, 224)',
-        borderTop: 'none rgb(224, 224, 224)',
-        bottom: 6,
-        boxSizing: 'content-box',
-        margin: 0,
-        position: 'absolute',
-        width: '100%',
-    },
+	hr: {
+		borderBottom: '1px solid rgb(224, 224, 224)',
+		borderLeft: 'none rgb(224, 224, 224)',
+		borderRight: 'none rgb(224, 224, 224)',
+		borderTop: 'none rgb(224, 224, 224)',
+		bottom: 6,
+		boxSizing: 'content-box',
+		margin: 0,
+		position: 'absolute',
+		width: '100%',
+	},
 };
 
 interface FakeTextFieldProps {
-    label?: React.ReactNode | string;
-    children?: any;
+	label?: React.ReactNode | string;
+	children?: any;
 }
 
 export function FakeTextField(props: FakeTextFieldProps) {
-    return (
-        <div className="relative">
-            {props.label !== '' && <InputLabel text={props.label} />}
-            <div className="pb2" style={{ height: 23 }}>
-                {props.children}
-            </div>
-            <hr style={styles.hr} />
-        </div>
-    );
+	return (
+		<div className="relative">
+			{props.label !== '' && <InputLabel text={props.label} />}
+			<div className="pb2" style={{ height: 23 }}>
+				{props.children}
+			</div>
+			<hr style={styles.hr} />
+		</div>
+	);
 }
diff --git a/packages/website/ts/components/ui/flash_message.tsx b/packages/website/ts/components/ui/flash_message.tsx
index 2cb1fc764..57a66d21f 100644
--- a/packages/website/ts/components/ui/flash_message.tsx
+++ b/packages/website/ts/components/ui/flash_message.tsx
@@ -6,35 +6,35 @@ import { Dispatcher } from 'ts/redux/dispatcher';
 const SHOW_DURATION_MS = 4000;
 
 interface FlashMessageProps {
-    dispatcher: Dispatcher;
-    flashMessage?: string | React.ReactNode;
-    showDurationMs?: number;
-    bodyStyle?: React.CSSProperties;
+	dispatcher: Dispatcher;
+	flashMessage?: string | React.ReactNode;
+	showDurationMs?: number;
+	bodyStyle?: React.CSSProperties;
 }
 
 interface FlashMessageState {}
 
 export class FlashMessage extends React.Component<FlashMessageProps, FlashMessageState> {
-    public static defaultProps: Partial<FlashMessageProps> = {
-        showDurationMs: SHOW_DURATION_MS,
-        bodyStyle: {},
-    };
-    public render() {
-        if (!_.isUndefined(this.props.flashMessage)) {
-            return (
-                <Snackbar
-                    open={true}
-                    message={this.props.flashMessage}
-                    autoHideDuration={this.props.showDurationMs}
-                    onRequestClose={this._onClose.bind(this)}
-                    bodyStyle={this.props.bodyStyle}
-                />
-            );
-        } else {
-            return null;
-        }
-    }
-    private _onClose() {
-        this.props.dispatcher.hideFlashMessage();
-    }
+	public static defaultProps: Partial<FlashMessageProps> = {
+		showDurationMs: SHOW_DURATION_MS,
+		bodyStyle: {},
+	};
+	public render() {
+		if (!_.isUndefined(this.props.flashMessage)) {
+			return (
+				<Snackbar
+					open={true}
+					message={this.props.flashMessage}
+					autoHideDuration={this.props.showDurationMs}
+					onRequestClose={this._onClose.bind(this)}
+					bodyStyle={this.props.bodyStyle}
+				/>
+			);
+		} else {
+			return null;
+		}
+	}
+	private _onClose() {
+		this.props.dispatcher.hideFlashMessage();
+	}
 }
diff --git a/packages/website/ts/components/ui/help_tooltip.tsx b/packages/website/ts/components/ui/help_tooltip.tsx
index d827eebb9..c946a70cb 100644
--- a/packages/website/ts/components/ui/help_tooltip.tsx
+++ b/packages/website/ts/components/ui/help_tooltip.tsx
@@ -2,21 +2,21 @@ import * as React from 'react';
 import ReactTooltip = require('react-tooltip');
 
 interface HelpTooltipProps {
-    style?: React.CSSProperties;
-    explanation: React.ReactNode;
+	style?: React.CSSProperties;
+	explanation: React.ReactNode;
 }
 
 export const HelpTooltip = (props: HelpTooltipProps) => {
-    return (
-        <div
-            style={{ ...props.style }}
-            className="inline-block"
-            data-tip={props.explanation}
-            data-for="helpTooltip"
-            data-multiline={true}
-        >
-            <i style={{ fontSize: 16 }} className="zmdi zmdi-help" />
-            <ReactTooltip id="helpTooltip" />
-        </div>
-    );
+	return (
+		<div
+			style={{ ...props.style }}
+			className="inline-block"
+			data-tip={props.explanation}
+			data-for="helpTooltip"
+			data-multiline={true}
+		>
+			<i style={{ fontSize: 16 }} className="zmdi zmdi-help" />
+			<ReactTooltip id="helpTooltip" />
+		</div>
+	);
 };
diff --git a/packages/website/ts/components/ui/identicon.tsx b/packages/website/ts/components/ui/identicon.tsx
index bad6c2a78..bad7a657d 100644
--- a/packages/website/ts/components/ui/identicon.tsx
+++ b/packages/website/ts/components/ui/identicon.tsx
@@ -4,45 +4,45 @@ import * as React from 'react';
 import { constants } from 'ts/utils/constants';
 
 interface IdenticonProps {
-    address: string;
-    diameter: number;
-    style?: React.CSSProperties;
+	address: string;
+	diameter: number;
+	style?: React.CSSProperties;
 }
 
 interface IdenticonState {}
 
 export class Identicon extends React.Component<IdenticonProps, IdenticonState> {
-    public static defaultProps: Partial<IdenticonProps> = {
-        style: {},
-    };
-    public render() {
-        let address = this.props.address;
-        if (_.isEmpty(address)) {
-            address = constants.NULL_ADDRESS;
-        }
-        const diameter = this.props.diameter;
-        const icon = blockies({
-            seed: address.toLowerCase(),
-        });
-        return (
-            <div
-                className="circle mx-auto relative transitionFix"
-                style={{
-                    width: diameter,
-                    height: diameter,
-                    overflow: 'hidden',
-                    ...this.props.style,
-                }}
-            >
-                <img
-                    src={icon.toDataURL()}
-                    style={{
-                        width: diameter,
-                        height: diameter,
-                        imageRendering: 'pixelated',
-                    }}
-                />
-            </div>
-        );
-    }
+	public static defaultProps: Partial<IdenticonProps> = {
+		style: {},
+	};
+	public render() {
+		let address = this.props.address;
+		if (_.isEmpty(address)) {
+			address = constants.NULL_ADDRESS;
+		}
+		const diameter = this.props.diameter;
+		const icon = blockies({
+			seed: address.toLowerCase(),
+		});
+		return (
+			<div
+				className="circle mx-auto relative transitionFix"
+				style={{
+					width: diameter,
+					height: diameter,
+					overflow: 'hidden',
+					...this.props.style,
+				}}
+			>
+				<img
+					src={icon.toDataURL()}
+					style={{
+						width: diameter,
+						height: diameter,
+						imageRendering: 'pixelated',
+					}}
+				/>
+			</div>
+		);
+	}
 }
diff --git a/packages/website/ts/components/ui/input_label.tsx b/packages/website/ts/components/ui/input_label.tsx
index e2009ad20..1cbda6692 100644
--- a/packages/website/ts/components/ui/input_label.tsx
+++ b/packages/website/ts/components/ui/input_label.tsx
@@ -2,24 +2,24 @@ import * as React from 'react';
 import { colors } from 'ts/utils/colors';
 
 export interface InputLabelProps {
-    text: string | Element | React.ReactNode;
+	text: string | Element | React.ReactNode;
 }
 
 const styles = {
-    label: {
-        color: colors.grey,
-        fontSize: 12,
-        pointerEvents: 'none',
-        textAlign: 'left',
-        transform: 'scale(0.75) translate(0px, -28px)',
-        transformOrigin: 'left top 0px',
-        transition: 'all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms',
-        userSelect: 'none',
-        width: 240,
-        zIndex: 1,
-    },
+	label: {
+		color: colors.grey,
+		fontSize: 12,
+		pointerEvents: 'none',
+		textAlign: 'left',
+		transform: 'scale(0.75) translate(0px, -28px)',
+		transformOrigin: 'left top 0px',
+		transition: 'all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms',
+		userSelect: 'none',
+		width: 240,
+		zIndex: 1,
+	},
 };
 
 export const InputLabel = (props: InputLabelProps) => {
-    return <label style={styles.label}>{props.text}</label>;
+	return <label style={styles.label}>{props.text}</label>;
 };
diff --git a/packages/website/ts/components/ui/lifecycle_raised_button.tsx b/packages/website/ts/components/ui/lifecycle_raised_button.tsx
index 8ff856a75..fd23912f1 100644
--- a/packages/website/ts/components/ui/lifecycle_raised_button.tsx
+++ b/packages/website/ts/components/ui/lifecycle_raised_button.tsx
@@ -7,97 +7,97 @@ import { utils } from 'ts/utils/utils';
 const COMPLETE_STATE_SHOW_LENGTH_MS = 2000;
 
 enum ButtonState {
-    READY,
-    LOADING,
-    COMPLETE,
+	READY,
+	LOADING,
+	COMPLETE,
 }
 
 interface LifeCycleRaisedButtonProps {
-    isHidden?: boolean;
-    isDisabled?: boolean;
-    isPrimary?: boolean;
-    labelReady: React.ReactNode | string;
-    labelLoading: React.ReactNode | string;
-    labelComplete: React.ReactNode | string;
-    onClickAsyncFn: () => Promise<boolean>;
-    backgroundColor?: string;
-    labelColor?: string;
+	isHidden?: boolean;
+	isDisabled?: boolean;
+	isPrimary?: boolean;
+	labelReady: React.ReactNode | string;
+	labelLoading: React.ReactNode | string;
+	labelComplete: React.ReactNode | string;
+	onClickAsyncFn: () => Promise<boolean>;
+	backgroundColor?: string;
+	labelColor?: string;
 }
 
 interface LifeCycleRaisedButtonState {
-    buttonState: ButtonState;
+	buttonState: ButtonState;
 }
 
 export class LifeCycleRaisedButton extends React.Component<LifeCycleRaisedButtonProps, LifeCycleRaisedButtonState> {
-    public static defaultProps: Partial<LifeCycleRaisedButtonProps> = {
-        isDisabled: false,
-        backgroundColor: colors.white,
-        labelColor: colors.darkGrey,
-    };
-    private _buttonTimeoutId: number;
-    private _didUnmount: boolean;
-    constructor(props: LifeCycleRaisedButtonProps) {
-        super(props);
-        this.state = {
-            buttonState: ButtonState.READY,
-        };
-    }
-    public componentWillUnmount() {
-        clearTimeout(this._buttonTimeoutId);
-        this._didUnmount = true;
-    }
-    public render() {
-        if (this.props.isHidden) {
-            return <span />;
-        }
+	public static defaultProps: Partial<LifeCycleRaisedButtonProps> = {
+		isDisabled: false,
+		backgroundColor: colors.white,
+		labelColor: colors.darkGrey,
+	};
+	private _buttonTimeoutId: number;
+	private _didUnmount: boolean;
+	constructor(props: LifeCycleRaisedButtonProps) {
+		super(props);
+		this.state = {
+			buttonState: ButtonState.READY,
+		};
+	}
+	public componentWillUnmount() {
+		clearTimeout(this._buttonTimeoutId);
+		this._didUnmount = true;
+	}
+	public render() {
+		if (this.props.isHidden) {
+			return <span />;
+		}
 
-        let label;
-        switch (this.state.buttonState) {
-            case ButtonState.READY:
-                label = this.props.labelReady;
-                break;
-            case ButtonState.LOADING:
-                label = this.props.labelLoading;
-                break;
-            case ButtonState.COMPLETE:
-                label = this.props.labelComplete;
-                break;
-            default:
-                throw utils.spawnSwitchErr('ButtonState', this.state.buttonState);
-        }
-        return (
-            <RaisedButton
-                primary={this.props.isPrimary}
-                label={label}
-                style={{ width: '100%' }}
-                backgroundColor={this.props.backgroundColor}
-                labelColor={this.props.labelColor}
-                onTouchTap={this.onClickAsync.bind(this)}
-                disabled={this.props.isDisabled || this.state.buttonState !== ButtonState.READY}
-            />
-        );
-    }
-    public async onClickAsync() {
-        this.setState({
-            buttonState: ButtonState.LOADING,
-        });
-        const didSucceed = await this.props.onClickAsyncFn();
-        if (this._didUnmount) {
-            return; // noop since unmount called before async callback returned.
-        }
-        if (didSucceed) {
-            this.setState({
-                buttonState: ButtonState.COMPLETE,
-            });
-            this._buttonTimeoutId = window.setTimeout(() => {
-                this.setState({
-                    buttonState: ButtonState.READY,
-                });
-            }, COMPLETE_STATE_SHOW_LENGTH_MS);
-        } else {
-            this.setState({
-                buttonState: ButtonState.READY,
-            });
-        }
-    }
+		let label;
+		switch (this.state.buttonState) {
+			case ButtonState.READY:
+				label = this.props.labelReady;
+				break;
+			case ButtonState.LOADING:
+				label = this.props.labelLoading;
+				break;
+			case ButtonState.COMPLETE:
+				label = this.props.labelComplete;
+				break;
+			default:
+				throw utils.spawnSwitchErr('ButtonState', this.state.buttonState);
+		}
+		return (
+			<RaisedButton
+				primary={this.props.isPrimary}
+				label={label}
+				style={{ width: '100%' }}
+				backgroundColor={this.props.backgroundColor}
+				labelColor={this.props.labelColor}
+				onTouchTap={this.onClickAsync.bind(this)}
+				disabled={this.props.isDisabled || this.state.buttonState !== ButtonState.READY}
+			/>
+		);
+	}
+	public async onClickAsync() {
+		this.setState({
+			buttonState: ButtonState.LOADING,
+		});
+		const didSucceed = await this.props.onClickAsyncFn();
+		if (this._didUnmount) {
+			return; // noop since unmount called before async callback returned.
+		}
+		if (didSucceed) {
+			this.setState({
+				buttonState: ButtonState.COMPLETE,
+			});
+			this._buttonTimeoutId = window.setTimeout(() => {
+				this.setState({
+					buttonState: ButtonState.READY,
+				});
+			}, COMPLETE_STATE_SHOW_LENGTH_MS);
+		} else {
+			this.setState({
+				buttonState: ButtonState.READY,
+			});
+		}
+	}
 }
diff --git a/packages/website/ts/components/ui/loading.tsx b/packages/website/ts/components/ui/loading.tsx
index aa319e9e9..e9bfe3316 100644
--- a/packages/website/ts/components/ui/loading.tsx
+++ b/packages/website/ts/components/ui/loading.tsx
@@ -10,30 +10,30 @@ interface LoadingProps {}
 interface LoadingState {}
 
 export class Loading extends React.Component<LoadingProps, LoadingState> {
-    public render() {
-        return (
-            <div className="pt4 sm-px2 sm-pt2 sm-m1" style={{ height: 500 }}>
-                <Paper className="mx-auto" style={{ maxWidth: 400 }}>
-                    {utils.isUserOnMobile() ? (
-                        <img className="p1" src="/gifs/0xAnimation.gif" width="96%" />
-                    ) : (
-                        <div style={{ pointerEvents: 'none' }}>
-                            <Video
-                                autoPlay={true}
-                                loop={true}
-                                muted={true}
-                                controls={[]}
-                                poster="/images/loading_poster.png"
-                            >
-                                <source src="/videos/0xAnimation.mp4" type="video/mp4" />
-                            </Video>
-                        </div>
-                    )}
-                    <div className="center pt2" style={{ paddingBottom: 11 }}>
-                        Connecting to the blockchain...
-                    </div>
-                </Paper>
-            </div>
-        );
-    }
+	public render() {
+		return (
+			<div className="pt4 sm-px2 sm-pt2 sm-m1" style={{ height: 500 }}>
+				<Paper className="mx-auto" style={{ maxWidth: 400 }}>
+					{utils.isUserOnMobile() ? (
+						<img className="p1" src="/gifs/0xAnimation.gif" width="96%" />
+					) : (
+						<div style={{ pointerEvents: 'none' }}>
+							<Video
+								autoPlay={true}
+								loop={true}
+								muted={true}
+								controls={[]}
+								poster="/images/loading_poster.png"
+							>
+								<source src="/videos/0xAnimation.mp4" type="video/mp4" />
+							</Video>
+						</div>
+					)}
+					<div className="center pt2" style={{ paddingBottom: 11 }}>
+						Connecting to the blockchain...
+					</div>
+				</Paper>
+			</div>
+		);
+	}
 }
diff --git a/packages/website/ts/components/ui/menu_item.tsx b/packages/website/ts/components/ui/menu_item.tsx
index 3482f436c..956b5eae8 100644
--- a/packages/website/ts/components/ui/menu_item.tsx
+++ b/packages/website/ts/components/ui/menu_item.tsx
@@ -3,49 +3,49 @@ import * as React from 'react';
 import { Link } from 'react-router-dom';
 
 interface MenuItemProps {
-    to: string;
-    style?: React.CSSProperties;
-    onClick?: () => void;
-    className?: string;
+	to: string;
+	style?: React.CSSProperties;
+	onClick?: () => void;
+	className?: string;
 }
 
 interface MenuItemState {
-    isHovering: boolean;
+	isHovering: boolean;
 }
 
 export class MenuItem extends React.Component<MenuItemProps, MenuItemState> {
-    public static defaultProps: Partial<MenuItemProps> = {
-        onClick: _.noop,
-        className: '',
-    };
-    public constructor(props: MenuItemProps) {
-        super(props);
-        this.state = {
-            isHovering: false,
-        };
-    }
-    public render() {
-        const menuItemStyles = {
-            cursor: 'pointer',
-            opacity: this.state.isHovering ? 0.5 : 1,
-        };
-        return (
-            <Link to={this.props.to} style={{ textDecoration: 'none', ...this.props.style }}>
-                <div
-                    onClick={this.props.onClick.bind(this)}
-                    className={`mx-auto ${this.props.className}`}
-                    style={menuItemStyles}
-                    onMouseEnter={this._onToggleHover.bind(this, true)}
-                    onMouseLeave={this._onToggleHover.bind(this, false)}
-                >
-                    {this.props.children}
-                </div>
-            </Link>
-        );
-    }
-    private _onToggleHover(isHovering: boolean) {
-        this.setState({
-            isHovering,
-        });
-    }
+	public static defaultProps: Partial<MenuItemProps> = {
+		onClick: _.noop,
+		className: '',
+	};
+	public constructor(props: MenuItemProps) {
+		super(props);
+		this.state = {
+			isHovering: false,
+		};
+	}
+	public render() {
+		const menuItemStyles = {
+			cursor: 'pointer',
+			opacity: this.state.isHovering ? 0.5 : 1,
+		};
+		return (
+			<Link to={this.props.to} style={{ textDecoration: 'none', ...this.props.style }}>
+				<div
+					onClick={this.props.onClick.bind(this)}
+					className={`mx-auto ${this.props.className}`}
+					style={menuItemStyles}
+					onMouseEnter={this._onToggleHover.bind(this, true)}
+					onMouseLeave={this._onToggleHover.bind(this, false)}
+				>
+					{this.props.children}
+				</div>
+			</Link>
+		);
+	}
+	private _onToggleHover(isHovering: boolean) {
+		this.setState({
+			isHovering,
+		});
+	}
 }
diff --git a/packages/website/ts/components/ui/party.tsx b/packages/website/ts/components/ui/party.tsx
index ca2577b61..ef3c7b425 100644
--- a/packages/website/ts/components/ui/party.tsx
+++ b/packages/website/ts/components/ui/party.tsx
@@ -11,129 +11,129 @@ const IMAGE_DIMENSION = 100;
 const IDENTICON_DIAMETER = 95;
 
 interface PartyProps {
-    label: string;
-    address: string;
-    networkId: number;
-    alternativeImage?: string;
-    identiconDiameter?: number;
-    identiconStyle?: React.CSSProperties;
-    isInTokenRegistry?: boolean;
-    hasUniqueNameAndSymbol?: boolean;
+	label: string;
+	address: string;
+	networkId: number;
+	alternativeImage?: string;
+	identiconDiameter?: number;
+	identiconStyle?: React.CSSProperties;
+	isInTokenRegistry?: boolean;
+	hasUniqueNameAndSymbol?: boolean;
 }
 
 interface PartyState {}
 
 export class Party extends React.Component<PartyProps, PartyState> {
-    public static defaultProps: Partial<PartyProps> = {
-        identiconStyle: {},
-        identiconDiameter: IDENTICON_DIAMETER,
-    };
-    public render() {
-        const label = this.props.label;
-        const address = this.props.address;
-        const identiconDiameter = this.props.identiconDiameter;
-        const emptyIdenticonStyles = {
-            width: identiconDiameter,
-            height: identiconDiameter,
-            backgroundColor: 'lightgray',
-            marginTop: 13,
-            marginBottom: 10,
-        };
-        const tokenImageStyle = {
-            width: IMAGE_DIMENSION,
-            height: IMAGE_DIMENSION,
-        };
-        const etherscanLinkIfExists = utils.getEtherScanLinkIfExists(
-            this.props.address,
-            this.props.networkId,
-            EtherscanLinkSuffixes.Address,
-        );
-        const isRegistered = this.props.isInTokenRegistry;
-        const registeredTooltipId = `${this.props.address}-${isRegistered}-registeredTooltip`;
-        const uniqueNameAndSymbolTooltipId = `${this.props.address}-${isRegistered}-uniqueTooltip`;
-        return (
-            <div style={{ overflow: 'hidden' }}>
-                <div className="pb1 center">{label}</div>
-                {_.isEmpty(address) ? (
-                    <div className="circle mx-auto" style={emptyIdenticonStyles} />
-                ) : (
-                    <a href={etherscanLinkIfExists} target="_blank">
-                        {isRegistered && !_.isUndefined(this.props.alternativeImage) ? (
-                            <img style={tokenImageStyle} src={this.props.alternativeImage} />
-                        ) : (
-                            <div className="mx-auto" style={{ height: identiconDiameter, width: identiconDiameter }}>
-                                <Identicon
-                                    address={this.props.address}
-                                    diameter={identiconDiameter}
-                                    style={this.props.identiconStyle}
-                                />
-                            </div>
-                        )}
-                    </a>
-                )}
-                <div className="mx-auto center pt1">
-                    <div style={{ height: 25 }}>
-                        <EthereumAddress address={address} networkId={this.props.networkId} />
-                    </div>
-                    {!_.isUndefined(this.props.isInTokenRegistry) && (
-                        <div>
-                            <div
-                                data-tip={true}
-                                data-for={registeredTooltipId}
-                                className="mx-auto"
-                                style={{ fontSize: 13, width: 127 }}
-                            >
-                                <span
-                                    style={{
-                                        color: isRegistered ? colors.brightGreen : colors.red500,
-                                    }}
-                                >
-                                    <i
-                                        className={`zmdi ${isRegistered ? 'zmdi-check-circle' : 'zmdi-alert-triangle'}`}
-                                    />
-                                </span>{' '}
-                                <span>{isRegistered ? 'Registered' : 'Unregistered'} token</span>
-                                <ReactTooltip id={registeredTooltipId}>
-                                    {isRegistered ? (
-                                        <div>
-                                            This token address was found in the token registry<br />
-                                            smart contract and is therefore believed to be a<br />
-                                            legitimate token.
-                                        </div>
-                                    ) : (
-                                        <div>
-                                            This token is not included in the token registry<br />
-                                            smart contract. We cannot guarantee the legitimacy<br />
-                                            of this token. Make sure to verify its address on Etherscan.
-                                        </div>
-                                    )}
-                                </ReactTooltip>
-                            </div>
-                        </div>
-                    )}
-                    {!_.isUndefined(this.props.hasUniqueNameAndSymbol) &&
-                        !this.props.hasUniqueNameAndSymbol && (
-                            <div>
-                                <div
-                                    data-tip={true}
-                                    data-for={uniqueNameAndSymbolTooltipId}
-                                    className="mx-auto"
-                                    style={{ fontSize: 13, width: 127 }}
-                                >
-                                    <span style={{ color: colors.red500 }}>
-                                        <i className="zmdi zmdi-alert-octagon" />
-                                    </span>{' '}
-                                    <span>Suspicious token</span>
-                                    <ReactTooltip id={uniqueNameAndSymbolTooltipId}>
-                                        This token shares it's name, symbol or both with<br />
-                                        a token in the 0x Token Registry but it has a different<br />
-                                        smart contract address. This is most likely a scam token!
-                                    </ReactTooltip>
-                                </div>
-                            </div>
-                        )}
-                </div>
-            </div>
-        );
-    }
+	public static defaultProps: Partial<PartyProps> = {
+		identiconStyle: {},
+		identiconDiameter: IDENTICON_DIAMETER,
+	};
+	public render() {
+		const label = this.props.label;
+		const address = this.props.address;
+		const identiconDiameter = this.props.identiconDiameter;
+		const emptyIdenticonStyles = {
+			width: identiconDiameter,
+			height: identiconDiameter,
+			backgroundColor: 'lightgray',
+			marginTop: 13,
+			marginBottom: 10,
+		};
+		const tokenImageStyle = {
+			width: IMAGE_DIMENSION,
+			height: IMAGE_DIMENSION,
+		};
+		const etherscanLinkIfExists = utils.getEtherScanLinkIfExists(
+			this.props.address,
+			this.props.networkId,
+			EtherscanLinkSuffixes.Address,
+		);
+		const isRegistered = this.props.isInTokenRegistry;
+		const registeredTooltipId = `${this.props.address}-${isRegistered}-registeredTooltip`;
+		const uniqueNameAndSymbolTooltipId = `${this.props.address}-${isRegistered}-uniqueTooltip`;
+		return (
+			<div style={{ overflow: 'hidden' }}>
+				<div className="pb1 center">{label}</div>
+				{_.isEmpty(address) ? (
+					<div className="circle mx-auto" style={emptyIdenticonStyles} />
+				) : (
+					<a href={etherscanLinkIfExists} target="_blank">
+						{isRegistered && !_.isUndefined(this.props.alternativeImage) ? (
+							<img style={tokenImageStyle} src={this.props.alternativeImage} />
+						) : (
+							<div className="mx-auto" style={{ height: identiconDiameter, width: identiconDiameter }}>
+								<Identicon
+									address={this.props.address}
+									diameter={identiconDiameter}
+									style={this.props.identiconStyle}
+								/>
+							</div>
+						)}
+					</a>
+				)}
+				<div className="mx-auto center pt1">
+					<div style={{ height: 25 }}>
+						<EthereumAddress address={address} networkId={this.props.networkId} />
+					</div>
+					{!_.isUndefined(this.props.isInTokenRegistry) && (
+						<div>
+							<div
+								data-tip={true}
+								data-for={registeredTooltipId}
+								className="mx-auto"
+								style={{ fontSize: 13, width: 127 }}
+							>
+								<span
+									style={{
+										color: isRegistered ? colors.brightGreen : colors.red500,
+									}}
+								>
+									<i
+										className={`zmdi ${isRegistered ? 'zmdi-check-circle' : 'zmdi-alert-triangle'}`}
+									/>
+								</span>{' '}
+								<span>{isRegistered ? 'Registered' : 'Unregistered'} token</span>
+								<ReactTooltip id={registeredTooltipId}>
+									{isRegistered ? (
+										<div>
+											This token address was found in the token registry<br />
+											smart contract and is therefore believed to be a<br />
+											legitimate token.
+										</div>
+									) : (
+										<div>
+											This token is not included in the token registry<br />
+											smart contract. We cannot guarantee the legitimacy<br />
+											of this token. Make sure to verify its address on Etherscan.
+										</div>
+									)}
+								</ReactTooltip>
+							</div>
+						</div>
+					)}
+					{!_.isUndefined(this.props.hasUniqueNameAndSymbol) &&
+						!this.props.hasUniqueNameAndSymbol && (
+							<div>
+								<div
+									data-tip={true}
+									data-for={uniqueNameAndSymbolTooltipId}
+									className="mx-auto"
+									style={{ fontSize: 13, width: 127 }}
+								>
+									<span style={{ color: colors.red500 }}>
+										<i className="zmdi zmdi-alert-octagon" />
+									</span>{' '}
+									<span>Suspicious token</span>
+									<ReactTooltip id={uniqueNameAndSymbolTooltipId}>
+										This token shares it's name, symbol or both with<br />
+										a token in the 0x Token Registry but it has a different<br />
+										smart contract address. This is most likely a scam token!
+									</ReactTooltip>
+								</div>
+							</div>
+						)}
+				</div>
+			</div>
+		);
+	}
 }
diff --git a/packages/website/ts/components/ui/required_label.tsx b/packages/website/ts/components/ui/required_label.tsx
index a5e7a22ce..638683427 100644
--- a/packages/website/ts/components/ui/required_label.tsx
+++ b/packages/website/ts/components/ui/required_label.tsx
@@ -2,14 +2,14 @@ import * as React from 'react';
 import { colors } from 'ts/utils/colors';
 
 export interface RequiredLabelProps {
-    label: string | React.ReactNode;
+	label: string | React.ReactNode;
 }
 
 export const RequiredLabel = (props: RequiredLabelProps) => {
-    return (
-        <span>
-            {props.label}
-            <span style={{ color: colors.red600 }}>*</span>
-        </span>
-    );
+	return (
+		<span>
+			{props.label}
+			<span style={{ color: colors.red600 }}>*</span>
+		</span>
+	);
 };
diff --git a/packages/website/ts/components/ui/simple_loading.tsx b/packages/website/ts/components/ui/simple_loading.tsx
index 81744196d..9f1fd5a13 100644
--- a/packages/website/ts/components/ui/simple_loading.tsx
+++ b/packages/website/ts/components/ui/simple_loading.tsx
@@ -2,16 +2,16 @@ import CircularProgress from 'material-ui/CircularProgress';
 import * as React from 'react';
 
 export interface SimpleLoadingProps {
-    message: string;
+	message: string;
 }
 
 export const SimpleLoading = (props: SimpleLoadingProps) => {
-    return (
-        <div className="mx-auto pt3" style={{ maxWidth: 400, height: 409 }}>
-            <div className="relative" style={{ top: '50%', transform: 'translateY(-50%)', height: 95 }}>
-                <CircularProgress />
-                <div className="pt3 pb3">{props.message}</div>
-            </div>
-        </div>
-    );
+	return (
+		<div className="mx-auto pt3" style={{ maxWidth: 400, height: 409 }}>
+			<div className="relative" style={{ top: '50%', transform: 'translateY(-50%)', height: 95 }}>
+				<CircularProgress />
+				<div className="pt3 pb3">{props.message}</div>
+			</div>
+		</div>
+	);
 };
diff --git a/packages/website/ts/components/ui/swap_icon.tsx b/packages/website/ts/components/ui/swap_icon.tsx
index c41592287..99e3450de 100644
--- a/packages/website/ts/components/ui/swap_icon.tsx
+++ b/packages/website/ts/components/ui/swap_icon.tsx
@@ -3,40 +3,40 @@ import * as React from 'react';
 import { colors } from 'ts/utils/colors';
 
 interface SwapIconProps {
-    swapTokensFn: () => void;
+	swapTokensFn: () => void;
 }
 
 interface SwapIconState {
-    isHovering: boolean;
+	isHovering: boolean;
 }
 
 export class SwapIcon extends React.Component<SwapIconProps, SwapIconState> {
-    public constructor(props: SwapIconProps) {
-        super(props);
-        this.state = {
-            isHovering: false,
-        };
-    }
-    public render() {
-        const swapStyles = {
-            color: this.state.isHovering ? colors.amber600 : colors.amber800,
-            fontSize: 50,
-        };
-        return (
-            <div
-                className="mx-auto pt4"
-                style={{ cursor: 'pointer', height: 50, width: 37.5 }}
-                onClick={this.props.swapTokensFn}
-                onMouseEnter={this._onToggleHover.bind(this, true)}
-                onMouseLeave={this._onToggleHover.bind(this, false)}
-            >
-                <i style={swapStyles} className="zmdi zmdi-swap" />
-            </div>
-        );
-    }
-    private _onToggleHover(isHovering: boolean) {
-        this.setState({
-            isHovering,
-        });
-    }
+	public constructor(props: SwapIconProps) {
+		super(props);
+		this.state = {
+			isHovering: false,
+		};
+	}
+	public render() {
+		const swapStyles = {
+			color: this.state.isHovering ? colors.amber600 : colors.amber800,
+			fontSize: 50,
+		};
+		return (
+			<div
+				className="mx-auto pt4"
+				style={{ cursor: 'pointer', height: 50, width: 37.5 }}
+				onClick={this.props.swapTokensFn}
+				onMouseEnter={this._onToggleHover.bind(this, true)}
+				onMouseLeave={this._onToggleHover.bind(this, false)}
+			>
+				<i style={swapStyles} className="zmdi zmdi-swap" />
+			</div>
+		);
+	}
+	private _onToggleHover(isHovering: boolean) {
+		this.setState({
+			isHovering,
+		});
+	}
 }
diff --git a/packages/website/ts/components/ui/token_icon.tsx b/packages/website/ts/components/ui/token_icon.tsx
index ff57a96de..a729821ce 100644
--- a/packages/website/ts/components/ui/token_icon.tsx
+++ b/packages/website/ts/components/ui/token_icon.tsx
@@ -4,24 +4,24 @@ import { Identicon } from 'ts/components/ui/identicon';
 import { Token } from 'ts/types';
 
 interface TokenIconProps {
-    token: Token;
-    diameter: number;
+	token: Token;
+	diameter: number;
 }
 
 interface TokenIconState {}
 
 export class TokenIcon extends React.Component<TokenIconProps, TokenIconState> {
-    public render() {
-        const token = this.props.token;
-        const diameter = this.props.diameter;
-        return (
-            <div>
-                {token.isRegistered && !_.isUndefined(token.iconUrl) ? (
-                    <img style={{ width: diameter, height: diameter }} src={token.iconUrl} />
-                ) : (
-                    <Identicon address={token.address} diameter={diameter} />
-                )}
-            </div>
-        );
-    }
+	public render() {
+		const token = this.props.token;
+		const diameter = this.props.diameter;
+		return (
+			<div>
+				{token.isRegistered && !_.isUndefined(token.iconUrl) ? (
+					<img style={{ width: diameter, height: diameter }} src={token.iconUrl} />
+				) : (
+					<Identicon address={token.address} diameter={diameter} />
+				)}
+			</div>
+		);
+	}
 }
diff --git a/packages/website/ts/components/visual_order.tsx b/packages/website/ts/components/visual_order.tsx
index 092954086..a9779ac62 100644
--- a/packages/website/ts/components/visual_order.tsx
+++ b/packages/website/ts/components/visual_order.tsx
@@ -8,69 +8,69 @@ import { utils } from 'ts/utils/utils';
 const PRECISION = 5;
 
 interface VisualOrderProps {
-    orderTakerAddress: string;
-    orderMakerAddress: string;
-    makerAssetToken: AssetToken;
-    takerAssetToken: AssetToken;
-    makerToken: Token;
-    takerToken: Token;
-    networkId: number;
-    tokenByAddress: TokenByAddress;
-    isMakerTokenAddressInRegistry: boolean;
-    isTakerTokenAddressInRegistry: boolean;
+	orderTakerAddress: string;
+	orderMakerAddress: string;
+	makerAssetToken: AssetToken;
+	takerAssetToken: AssetToken;
+	makerToken: Token;
+	takerToken: Token;
+	networkId: number;
+	tokenByAddress: TokenByAddress;
+	isMakerTokenAddressInRegistry: boolean;
+	isTakerTokenAddressInRegistry: boolean;
 }
 
 interface VisualOrderState {}
 
 export class VisualOrder extends React.Component<VisualOrderProps, VisualOrderState> {
-    public render() {
-        const allTokens = _.values(this.props.tokenByAddress);
-        const makerImage = this.props.makerToken.iconUrl;
-        const takerImage = this.props.takerToken.iconUrl;
-        return (
-            <div>
-                <div className="clearfix">
-                    <div className="col col-5 center">
-                        <Party
-                            label="Send"
-                            address={this.props.takerToken.address}
-                            alternativeImage={takerImage}
-                            networkId={this.props.networkId}
-                            isInTokenRegistry={this.props.isTakerTokenAddressInRegistry}
-                            hasUniqueNameAndSymbol={utils.hasUniqueNameAndSymbol(allTokens, this.props.takerToken)}
-                        />
-                    </div>
-                    <div className="col col-2 center pt1">
-                        <div className="pb1">
-                            {this._renderAmount(this.props.takerAssetToken, this.props.takerToken)}
-                        </div>
-                        <div className="lg-p2 md-p2 sm-p1">
-                            <img src="/images/trade_arrows.png" style={{ width: 47 }} />
-                        </div>
-                        <div className="pt1">
-                            {this._renderAmount(this.props.makerAssetToken, this.props.makerToken)}
-                        </div>
-                    </div>
-                    <div className="col col-5 center">
-                        <Party
-                            label="Receive"
-                            address={this.props.makerToken.address}
-                            alternativeImage={makerImage}
-                            networkId={this.props.networkId}
-                            isInTokenRegistry={this.props.isMakerTokenAddressInRegistry}
-                            hasUniqueNameAndSymbol={utils.hasUniqueNameAndSymbol(allTokens, this.props.makerToken)}
-                        />
-                    </div>
-                </div>
-            </div>
-        );
-    }
-    private _renderAmount(assetToken: AssetToken, token: Token) {
-        const unitAmount = ZeroEx.toUnitAmount(assetToken.amount, token.decimals);
-        return (
-            <div style={{ fontSize: 13 }}>
-                {unitAmount.toNumber().toFixed(PRECISION)} {token.symbol}
-            </div>
-        );
-    }
+	public render() {
+		const allTokens = _.values(this.props.tokenByAddress);
+		const makerImage = this.props.makerToken.iconUrl;
+		const takerImage = this.props.takerToken.iconUrl;
+		return (
+			<div>
+				<div className="clearfix">
+					<div className="col col-5 center">
+						<Party
+							label="Send"
+							address={this.props.takerToken.address}
+							alternativeImage={takerImage}
+							networkId={this.props.networkId}
+							isInTokenRegistry={this.props.isTakerTokenAddressInRegistry}
+							hasUniqueNameAndSymbol={utils.hasUniqueNameAndSymbol(allTokens, this.props.takerToken)}
+						/>
+					</div>
+					<div className="col col-2 center pt1">
+						<div className="pb1">
+							{this._renderAmount(this.props.takerAssetToken, this.props.takerToken)}
+						</div>
+						<div className="lg-p2 md-p2 sm-p1">
+							<img src="/images/trade_arrows.png" style={{ width: 47 }} />
+						</div>
+						<div className="pt1">
+							{this._renderAmount(this.props.makerAssetToken, this.props.makerToken)}
+						</div>
+					</div>
+					<div className="col col-5 center">
+						<Party
+							label="Receive"
+							address={this.props.makerToken.address}
+							alternativeImage={makerImage}
+							networkId={this.props.networkId}
+							isInTokenRegistry={this.props.isMakerTokenAddressInRegistry}
+							hasUniqueNameAndSymbol={utils.hasUniqueNameAndSymbol(allTokens, this.props.makerToken)}
+						/>
+					</div>
+				</div>
+			</div>
+		);
+	}
+	private _renderAmount(assetToken: AssetToken, token: Token) {
+		const unitAmount = ZeroEx.toUnitAmount(assetToken.amount, token.decimals);
+		return (
+			<div style={{ fontSize: 13 }}>
+				{unitAmount.toNumber().toFixed(PRECISION)} {token.symbol}
+			</div>
+		);
+	}
 }
diff --git a/packages/website/ts/containers/connect_documentation.tsx b/packages/website/ts/containers/connect_documentation.tsx
index 3e02a7d05..2f5326d57 100644
--- a/packages/website/ts/containers/connect_documentation.tsx
+++ b/packages/website/ts/containers/connect_documentation.tsx
@@ -16,81 +16,81 @@ const InstallationMarkdown = require('md/docs/connect/installation');
 /* tslint:enable:no-var-requires */
 
 const connectDocSections = {
-    introduction: 'introduction',
-    installation: 'installation',
-    httpClient: 'httpClient',
-    webSocketOrderbookChannel: 'webSocketOrderbookChannel',
-    types: constants.TYPES_SECTION_NAME,
+	introduction: 'introduction',
+	installation: 'installation',
+	httpClient: 'httpClient',
+	webSocketOrderbookChannel: 'webSocketOrderbookChannel',
+	types: constants.TYPES_SECTION_NAME,
 };
 
 const docsInfoConfig: DocsInfoConfig = {
-    displayName: '0x Connect',
-    subPackageName: 'connect',
-    packageUrl: 'https://github.com/0xProject/0x.js',
-    websitePath: WebsitePaths.Connect,
-    docsJsonRoot: 'https://s3.amazonaws.com/connect-docs-jsons',
-    menu: {
-        introduction: [connectDocSections.introduction],
-        install: [connectDocSections.installation],
-        httpClient: [connectDocSections.httpClient],
-        webSocketOrderbookChannel: [connectDocSections.webSocketOrderbookChannel],
-        types: [connectDocSections.types],
-    },
-    sectionNameToMarkdown: {
-        [connectDocSections.introduction]: IntroMarkdown,
-        [connectDocSections.installation]: InstallationMarkdown,
-    },
-    // Note: This needs to be kept in sync with the types exported in index.ts. Unfortunately there is
-    // currently no way to extract the re-exported types from index.ts via TypeDoc :(
-    publicTypes: [
-        'Client',
-        'FeesRequest',
-        'FeesResponse',
-        'OrderbookChannel',
-        'OrderbookChannelHandler',
-        'OrderbookChannelSubscriptionOpts',
-        'OrderbookRequest',
-        'OrderbookResponse',
-        'OrdersRequest',
-        'TokenPairsItem',
-        'TokenPairsRequest',
-        'TokenTradeInfo',
-        'Order',
-        'SignedOrder',
-        'ECSignature',
-    ],
-    sectionNameToModulePath: {
-        [connectDocSections.httpClient]: ['"src/http_client"'],
-        [connectDocSections.webSocketOrderbookChannel]: ['"src/ws_orderbook_channel"'],
-        [connectDocSections.types]: ['"src/types"'],
-    },
-    menuSubsectionToVersionWhenIntroduced: {},
-    sections: connectDocSections,
-    visibleConstructors: [connectDocSections.httpClient, connectDocSections.webSocketOrderbookChannel],
-    convertToDocAgnosticFormatFn: typeDocUtils.convertToDocAgnosticFormat.bind(typeDocUtils),
+	displayName: '0x Connect',
+	subPackageName: 'connect',
+	packageUrl: 'https://github.com/0xProject/0x.js',
+	websitePath: WebsitePaths.Connect,
+	docsJsonRoot: 'https://s3.amazonaws.com/connect-docs-jsons',
+	menu: {
+		introduction: [connectDocSections.introduction],
+		install: [connectDocSections.installation],
+		httpClient: [connectDocSections.httpClient],
+		webSocketOrderbookChannel: [connectDocSections.webSocketOrderbookChannel],
+		types: [connectDocSections.types],
+	},
+	sectionNameToMarkdown: {
+		[connectDocSections.introduction]: IntroMarkdown,
+		[connectDocSections.installation]: InstallationMarkdown,
+	},
+	// Note: This needs to be kept in sync with the types exported in index.ts. Unfortunately there is
+	// currently no way to extract the re-exported types from index.ts via TypeDoc :(
+	publicTypes: [
+		'Client',
+		'FeesRequest',
+		'FeesResponse',
+		'OrderbookChannel',
+		'OrderbookChannelHandler',
+		'OrderbookChannelSubscriptionOpts',
+		'OrderbookRequest',
+		'OrderbookResponse',
+		'OrdersRequest',
+		'TokenPairsItem',
+		'TokenPairsRequest',
+		'TokenTradeInfo',
+		'Order',
+		'SignedOrder',
+		'ECSignature',
+	],
+	sectionNameToModulePath: {
+		[connectDocSections.httpClient]: ['"src/http_client"'],
+		[connectDocSections.webSocketOrderbookChannel]: ['"src/ws_orderbook_channel"'],
+		[connectDocSections.types]: ['"src/types"'],
+	},
+	menuSubsectionToVersionWhenIntroduced: {},
+	sections: connectDocSections,
+	visibleConstructors: [connectDocSections.httpClient, connectDocSections.webSocketOrderbookChannel],
+	convertToDocAgnosticFormatFn: typeDocUtils.convertToDocAgnosticFormat.bind(typeDocUtils),
 };
 const docsInfo = new DocsInfo(docsInfoConfig);
 
 interface ConnectedState {
-    docsVersion: string;
-    availableDocVersions: string[];
-    docsInfo: DocsInfo;
+	docsVersion: string;
+	availableDocVersions: string[];
+	docsInfo: DocsInfo;
 }
 
 interface ConnectedDispatch {
-    dispatcher: Dispatcher;
+	dispatcher: Dispatcher;
 }
 
 const mapStateToProps = (state: State, ownProps: DocumentationAllProps): ConnectedState => ({
-    docsVersion: state.docsVersion,
-    availableDocVersions: state.availableDocVersions,
-    docsInfo,
+	docsVersion: state.docsVersion,
+	availableDocVersions: state.availableDocVersions,
+	docsInfo,
 });
 
 const mapDispatchToProps = (dispatch: Dispatch<State>): ConnectedDispatch => ({
-    dispatcher: new Dispatcher(dispatch),
+	dispatcher: new Dispatcher(dispatch),
 });
 
 export const Documentation: React.ComponentClass<DocumentationAllProps> = connect(mapStateToProps, mapDispatchToProps)(
-    DocumentationComponent,
+	DocumentationComponent,
 );
diff --git a/packages/website/ts/containers/generate_order_form.tsx b/packages/website/ts/containers/generate_order_form.tsx
index 3fd31087f..c2b781557 100644
--- a/packages/website/ts/containers/generate_order_form.tsx
+++ b/packages/website/ts/containers/generate_order_form.tsx
@@ -7,48 +7,48 @@ import { GenerateOrderForm as GenerateOrderFormComponent } from 'ts/components/g
 import { Dispatcher } from 'ts/redux/dispatcher';
 import { State } from 'ts/redux/reducer';
 import {
-    BlockchainErrs,
-    HashData,
-    SideToAssetToken,
-    SignatureData,
-    TokenByAddress,
-    TokenStateByAddress,
+	BlockchainErrs,
+	HashData,
+	SideToAssetToken,
+	SignatureData,
+	TokenByAddress,
+	TokenStateByAddress,
 } from 'ts/types';
 
 interface GenerateOrderFormProps {
-    blockchain: Blockchain;
-    hashData: HashData;
-    dispatcher: Dispatcher;
+	blockchain: Blockchain;
+	hashData: HashData;
+	dispatcher: Dispatcher;
 }
 
 interface ConnectedState {
-    blockchainErr: BlockchainErrs;
-    blockchainIsLoaded: boolean;
-    orderExpiryTimestamp: BigNumber;
-    orderSignatureData: SignatureData;
-    userAddress: string;
-    orderTakerAddress: string;
-    orderSalt: BigNumber;
-    networkId: number;
-    sideToAssetToken: SideToAssetToken;
-    tokenByAddress: TokenByAddress;
-    tokenStateByAddress: TokenStateByAddress;
+	blockchainErr: BlockchainErrs;
+	blockchainIsLoaded: boolean;
+	orderExpiryTimestamp: BigNumber;
+	orderSignatureData: SignatureData;
+	userAddress: string;
+	orderTakerAddress: string;
+	orderSalt: BigNumber;
+	networkId: number;
+	sideToAssetToken: SideToAssetToken;
+	tokenByAddress: TokenByAddress;
+	tokenStateByAddress: TokenStateByAddress;
 }
 
 const mapStateToProps = (state: State, ownProps: GenerateOrderFormProps): ConnectedState => ({
-    blockchainErr: state.blockchainErr,
-    blockchainIsLoaded: state.blockchainIsLoaded,
-    orderExpiryTimestamp: state.orderExpiryTimestamp,
-    orderSignatureData: state.orderSignatureData,
-    orderTakerAddress: state.orderTakerAddress,
-    orderSalt: state.orderSalt,
-    networkId: state.networkId,
-    sideToAssetToken: state.sideToAssetToken,
-    tokenByAddress: state.tokenByAddress,
-    tokenStateByAddress: state.tokenStateByAddress,
-    userAddress: state.userAddress,
+	blockchainErr: state.blockchainErr,
+	blockchainIsLoaded: state.blockchainIsLoaded,
+	orderExpiryTimestamp: state.orderExpiryTimestamp,
+	orderSignatureData: state.orderSignatureData,
+	orderTakerAddress: state.orderTakerAddress,
+	orderSalt: state.orderSalt,
+	networkId: state.networkId,
+	sideToAssetToken: state.sideToAssetToken,
+	tokenByAddress: state.tokenByAddress,
+	tokenStateByAddress: state.tokenStateByAddress,
+	userAddress: state.userAddress,
 });
 
 export const GenerateOrderForm: React.ComponentClass<GenerateOrderFormProps> = connect(mapStateToProps)(
-    GenerateOrderFormComponent,
+	GenerateOrderFormComponent,
 );
diff --git a/packages/website/ts/containers/portal.tsx b/packages/website/ts/containers/portal.tsx
index f0247935b..bc7aa213c 100644
--- a/packages/website/ts/containers/portal.tsx
+++ b/packages/website/ts/containers/portal.tsx
@@ -10,72 +10,72 @@ import { BlockchainErrs, HashData, Order, ScreenWidths, Side, TokenByAddress, To
 import { constants } from 'ts/utils/constants';
 
 interface ConnectedState {
-    blockchainErr: BlockchainErrs;
-    blockchainIsLoaded: boolean;
-    hashData: HashData;
-    networkId: number;
-    nodeVersion: string;
-    orderFillAmount: BigNumber;
-    tokenByAddress: TokenByAddress;
-    tokenStateByAddress: TokenStateByAddress;
-    userEtherBalance: BigNumber;
-    screenWidth: ScreenWidths;
-    shouldBlockchainErrDialogBeOpen: boolean;
-    userAddress: string;
-    userSuppliedOrderCache: Order;
-    flashMessage?: string | React.ReactNode;
+	blockchainErr: BlockchainErrs;
+	blockchainIsLoaded: boolean;
+	hashData: HashData;
+	networkId: number;
+	nodeVersion: string;
+	orderFillAmount: BigNumber;
+	tokenByAddress: TokenByAddress;
+	tokenStateByAddress: TokenStateByAddress;
+	userEtherBalance: BigNumber;
+	screenWidth: ScreenWidths;
+	shouldBlockchainErrDialogBeOpen: boolean;
+	userAddress: string;
+	userSuppliedOrderCache: Order;
+	flashMessage?: string | React.ReactNode;
 }
 
 interface ConnectedDispatch {
-    dispatcher: Dispatcher;
+	dispatcher: Dispatcher;
 }
 
 const mapStateToProps = (state: State, ownProps: PortalComponentAllProps): ConnectedState => {
-    const receiveAssetToken = state.sideToAssetToken[Side.Receive];
-    const depositAssetToken = state.sideToAssetToken[Side.Deposit];
-    const receiveAddress = !_.isUndefined(receiveAssetToken.address)
-        ? receiveAssetToken.address
-        : constants.NULL_ADDRESS;
-    const depositAddress = !_.isUndefined(depositAssetToken.address)
-        ? depositAssetToken.address
-        : constants.NULL_ADDRESS;
-    const receiveAmount = !_.isUndefined(receiveAssetToken.amount) ? receiveAssetToken.amount : new BigNumber(0);
-    const depositAmount = !_.isUndefined(depositAssetToken.amount) ? depositAssetToken.amount : new BigNumber(0);
-    const hashData = {
-        depositAmount,
-        depositTokenContractAddr: depositAddress,
-        feeRecipientAddress: constants.NULL_ADDRESS,
-        makerFee: constants.MAKER_FEE,
-        orderExpiryTimestamp: state.orderExpiryTimestamp,
-        orderMakerAddress: state.userAddress,
-        orderTakerAddress: state.orderTakerAddress !== '' ? state.orderTakerAddress : constants.NULL_ADDRESS,
-        receiveAmount,
-        receiveTokenContractAddr: receiveAddress,
-        takerFee: constants.TAKER_FEE,
-        orderSalt: state.orderSalt,
-    };
-    return {
-        blockchainErr: state.blockchainErr,
-        blockchainIsLoaded: state.blockchainIsLoaded,
-        networkId: state.networkId,
-        nodeVersion: state.nodeVersion,
-        orderFillAmount: state.orderFillAmount,
-        hashData,
-        screenWidth: state.screenWidth,
-        shouldBlockchainErrDialogBeOpen: state.shouldBlockchainErrDialogBeOpen,
-        tokenByAddress: state.tokenByAddress,
-        tokenStateByAddress: state.tokenStateByAddress,
-        userAddress: state.userAddress,
-        userEtherBalance: state.userEtherBalance,
-        userSuppliedOrderCache: state.userSuppliedOrderCache,
-        flashMessage: state.flashMessage,
-    };
+	const receiveAssetToken = state.sideToAssetToken[Side.Receive];
+	const depositAssetToken = state.sideToAssetToken[Side.Deposit];
+	const receiveAddress = !_.isUndefined(receiveAssetToken.address)
+		? receiveAssetToken.address
+		: constants.NULL_ADDRESS;
+	const depositAddress = !_.isUndefined(depositAssetToken.address)
+		? depositAssetToken.address
+		: constants.NULL_ADDRESS;
+	const receiveAmount = !_.isUndefined(receiveAssetToken.amount) ? receiveAssetToken.amount : new BigNumber(0);
+	const depositAmount = !_.isUndefined(depositAssetToken.amount) ? depositAssetToken.amount : new BigNumber(0);
+	const hashData = {
+		depositAmount,
+		depositTokenContractAddr: depositAddress,
+		feeRecipientAddress: constants.NULL_ADDRESS,
+		makerFee: constants.MAKER_FEE,
+		orderExpiryTimestamp: state.orderExpiryTimestamp,
+		orderMakerAddress: state.userAddress,
+		orderTakerAddress: state.orderTakerAddress !== '' ? state.orderTakerAddress : constants.NULL_ADDRESS,
+		receiveAmount,
+		receiveTokenContractAddr: receiveAddress,
+		takerFee: constants.TAKER_FEE,
+		orderSalt: state.orderSalt,
+	};
+	return {
+		blockchainErr: state.blockchainErr,
+		blockchainIsLoaded: state.blockchainIsLoaded,
+		networkId: state.networkId,
+		nodeVersion: state.nodeVersion,
+		orderFillAmount: state.orderFillAmount,
+		hashData,
+		screenWidth: state.screenWidth,
+		shouldBlockchainErrDialogBeOpen: state.shouldBlockchainErrDialogBeOpen,
+		tokenByAddress: state.tokenByAddress,
+		tokenStateByAddress: state.tokenStateByAddress,
+		userAddress: state.userAddress,
+		userEtherBalance: state.userEtherBalance,
+		userSuppliedOrderCache: state.userSuppliedOrderCache,
+		flashMessage: state.flashMessage,
+	};
 };
 
 const mapDispatchToProps = (dispatch: Dispatch<State>): ConnectedDispatch => ({
-    dispatcher: new Dispatcher(dispatch),
+	dispatcher: new Dispatcher(dispatch),
 });
 
 export const Portal: React.ComponentClass<PortalComponentAllProps> = connect(mapStateToProps, mapDispatchToProps)(
-    PortalComponent,
+	PortalComponent,
 );
diff --git a/packages/website/ts/containers/smart_contracts_documentation.tsx b/packages/website/ts/containers/smart_contracts_documentation.tsx
index 8be33b546..addfd1af9 100644
--- a/packages/website/ts/containers/smart_contracts_documentation.tsx
+++ b/packages/website/ts/containers/smart_contracts_documentation.tsx
@@ -14,49 +14,49 @@ const IntroMarkdown = require('md/docs/smart_contracts/introduction');
 /* tslint:enable:no-var-requires */
 
 const docsInfoConfig: DocsInfoConfig = {
-    displayName: '0x Smart Contracts',
-    packageUrl: 'https://github.com/0xProject/contracts',
-    websitePath: WebsitePaths.SmartContracts,
-    docsJsonRoot: 'https://s3.amazonaws.com/smart-contracts-docs-json',
-    menu: {
-        introduction: [Sections.Introduction],
-        contracts: [Sections.Exchange, Sections.TokenRegistry, Sections.ZRXToken, Sections.TokenTransferProxy],
-    },
-    sectionNameToMarkdown: {
-        [Sections.Introduction]: IntroMarkdown,
-    },
-    sections: {
-        Introduction: Sections.Introduction,
-        Exchange: Sections.Exchange,
-        TokenTransferProxy: Sections.TokenTransferProxy,
-        TokenRegistry: Sections.TokenRegistry,
-        ZRXToken: Sections.ZRXToken,
-    },
-    visibleConstructors: [Sections.Exchange, Sections.TokenRegistry, Sections.ZRXToken, Sections.TokenTransferProxy],
-    convertToDocAgnosticFormatFn: doxityUtils.convertToDocAgnosticFormat.bind(doxityUtils),
+	displayName: '0x Smart Contracts',
+	packageUrl: 'https://github.com/0xProject/contracts',
+	websitePath: WebsitePaths.SmartContracts,
+	docsJsonRoot: 'https://s3.amazonaws.com/smart-contracts-docs-json',
+	menu: {
+		introduction: [Sections.Introduction],
+		contracts: [Sections.Exchange, Sections.TokenRegistry, Sections.ZRXToken, Sections.TokenTransferProxy],
+	},
+	sectionNameToMarkdown: {
+		[Sections.Introduction]: IntroMarkdown,
+	},
+	sections: {
+		Introduction: Sections.Introduction,
+		Exchange: Sections.Exchange,
+		TokenTransferProxy: Sections.TokenTransferProxy,
+		TokenRegistry: Sections.TokenRegistry,
+		ZRXToken: Sections.ZRXToken,
+	},
+	visibleConstructors: [Sections.Exchange, Sections.TokenRegistry, Sections.ZRXToken, Sections.TokenTransferProxy],
+	convertToDocAgnosticFormatFn: doxityUtils.convertToDocAgnosticFormat.bind(doxityUtils),
 };
 const docsInfo = new DocsInfo(docsInfoConfig);
 
 interface ConnectedState {
-    docsVersion: string;
-    availableDocVersions: string[];
+	docsVersion: string;
+	availableDocVersions: string[];
 }
 
 interface ConnectedDispatch {
-    dispatcher: Dispatcher;
-    docsInfo: DocsInfo;
+	dispatcher: Dispatcher;
+	docsInfo: DocsInfo;
 }
 
 const mapStateToProps = (state: State, ownProps: DocumentationAllProps): ConnectedState => ({
-    docsVersion: state.docsVersion,
-    availableDocVersions: state.availableDocVersions,
+	docsVersion: state.docsVersion,
+	availableDocVersions: state.availableDocVersions,
 });
 
 const mapDispatchToProps = (dispatch: Dispatch<State>): ConnectedDispatch => ({
-    dispatcher: new Dispatcher(dispatch),
-    docsInfo,
+	dispatcher: new Dispatcher(dispatch),
+	docsInfo,
 });
 
 export const Documentation: React.ComponentClass<DocumentationAllProps> = connect(mapStateToProps, mapDispatchToProps)(
-    DocumentationComponent,
+	DocumentationComponent,
 );
diff --git a/packages/website/ts/containers/zero_ex_js_documentation.tsx b/packages/website/ts/containers/zero_ex_js_documentation.tsx
index 8ae6a7b73..d416cbc12 100644
--- a/packages/website/ts/containers/zero_ex_js_documentation.tsx
+++ b/packages/website/ts/containers/zero_ex_js_documentation.tsx
@@ -19,152 +19,152 @@ const versioningMarkdown = require('md/docs/0xjs/versioning');
 /* tslint:enable:no-var-requires */
 
 const zeroExJsDocSections = {
-    introduction: 'introduction',
-    installation: 'installation',
-    testrpc: 'testrpc',
-    async: 'async',
-    errors: 'errors',
-    versioning: 'versioning',
-    zeroEx: 'zeroEx',
-    exchange: 'exchange',
-    token: 'token',
-    tokenRegistry: 'tokenRegistry',
-    etherToken: 'etherToken',
-    proxy: 'proxy',
-    orderWatcher: 'orderWatcher',
-    types: constants.TYPES_SECTION_NAME,
+	introduction: 'introduction',
+	installation: 'installation',
+	testrpc: 'testrpc',
+	async: 'async',
+	errors: 'errors',
+	versioning: 'versioning',
+	zeroEx: 'zeroEx',
+	exchange: 'exchange',
+	token: 'token',
+	tokenRegistry: 'tokenRegistry',
+	etherToken: 'etherToken',
+	proxy: 'proxy',
+	orderWatcher: 'orderWatcher',
+	types: constants.TYPES_SECTION_NAME,
 };
 
 const docsInfoConfig: DocsInfoConfig = {
-    displayName: '0x.js',
-    packageUrl: 'https://github.com/0xProject/0x.js',
-    subPackageName: '0x.js',
-    websitePath: WebsitePaths.ZeroExJs,
-    docsJsonRoot: 'https://s3.amazonaws.com/0xjs-docs-jsons',
-    menu: {
-        introduction: [zeroExJsDocSections.introduction],
-        install: [zeroExJsDocSections.installation],
-        topics: [zeroExJsDocSections.async, zeroExJsDocSections.errors, zeroExJsDocSections.versioning],
-        zeroEx: [zeroExJsDocSections.zeroEx],
-        contracts: [
-            zeroExJsDocSections.exchange,
-            zeroExJsDocSections.token,
-            zeroExJsDocSections.tokenRegistry,
-            zeroExJsDocSections.etherToken,
-            zeroExJsDocSections.proxy,
-        ],
-        orderWatcher: [zeroExJsDocSections.orderWatcher],
-        types: [zeroExJsDocSections.types],
-    },
-    sectionNameToMarkdown: {
-        [zeroExJsDocSections.introduction]: IntroMarkdown,
-        [zeroExJsDocSections.installation]: InstallationMarkdown,
-        [zeroExJsDocSections.async]: AsyncMarkdown,
-        [zeroExJsDocSections.errors]: ErrorsMarkdown,
-        [zeroExJsDocSections.versioning]: versioningMarkdown,
-    },
-    // Note: This needs to be kept in sync with the types exported in index.ts. Unfortunately there is
-    // currently no way to extract the re-exported types from index.ts via TypeDoc :(
-    publicTypes: [
-        'Order',
-        'SignedOrder',
-        'ECSignature',
-        'ZeroExError',
-        'EventCallback',
-        'EventCallbackAsync',
-        'EventCallbackSync',
-        'ExchangeContractErrs',
-        'ContractEvent',
-        'Token',
-        'ExchangeEvents',
-        'IndexedFilterValues',
-        'SubscriptionOpts',
-        'BlockRange',
-        'BlockParam',
-        'OrderFillOrKillRequest',
-        'OrderCancellationRequest',
-        'OrderFillRequest',
-        'ContractEventEmitter',
-        'Web3Provider',
-        'ContractEventArgs',
-        'LogCancelArgs',
-        'LogFillArgs',
-        'LogErrorContractEventArgs',
-        'LogFillContractEventArgs',
-        'LogCancelContractEventArgs',
-        'EtherTokenContractEventArgs',
-        'WithdrawalContractEventArgs',
-        'DepositContractEventArgs',
-        'TokenEvents',
-        'ExchangeContractEventArgs',
-        'TransferContractEventArgs',
-        'ApprovalContractEventArgs',
-        'TokenContractEventArgs',
-        'ZeroExConfig',
-        'TransactionReceiptWithDecodedLogs',
-        'LogWithDecodedArgs',
-        'EtherTokenEvents',
-        'BlockParamLiteral',
-        'DecodedLogArgs',
-        'MethodOpts',
-        'ValidateOrderFillableOpts',
-        'OrderTransactionOpts',
-        'TransactionOpts',
-        'ContractEventArg',
-        'LogEvent',
-        'LogEntry',
-        'DecodedLogEvent',
-        'EventWatcherCallback',
-        'OnOrderStateChangeCallback',
-        'OrderStateValid',
-        'OrderStateInvalid',
-        'OrderState',
-        'FilterObject',
-    ],
-    sectionNameToModulePath: {
-        [zeroExJsDocSections.zeroEx]: ['"src/0x"'],
-        [zeroExJsDocSections.exchange]: ['"src/contract_wrappers/exchange_wrapper"'],
-        [zeroExJsDocSections.tokenRegistry]: ['"src/contract_wrappers/token_registry_wrapper"'],
-        [zeroExJsDocSections.token]: ['"src/contract_wrappers/token_wrapper"'],
-        [zeroExJsDocSections.etherToken]: ['"src/contract_wrappers/ether_token_wrapper"'],
-        [zeroExJsDocSections.proxy]: [
-            '"src/contract_wrappers/proxy_wrapper"',
-            '"src/contract_wrappers/token_transfer_proxy_wrapper"',
-        ],
-        [zeroExJsDocSections.orderWatcher]: ['"src/order_watcher/order_state_watcher"'],
-        [zeroExJsDocSections.types]: ['"src/types"'],
-    },
-    menuSubsectionToVersionWhenIntroduced: {
-        [zeroExJsDocSections.etherToken]: '0.7.1',
-        [zeroExJsDocSections.proxy]: '0.8.0',
-        [zeroExJsDocSections.orderWatcher]: '0.27.1',
-    },
-    sections: zeroExJsDocSections,
-    visibleConstructors: [zeroExJsDocSections.zeroEx],
-    convertToDocAgnosticFormatFn: typeDocUtils.convertToDocAgnosticFormat.bind(typeDocUtils),
+	displayName: '0x.js',
+	packageUrl: 'https://github.com/0xProject/0x.js',
+	subPackageName: '0x.js',
+	websitePath: WebsitePaths.ZeroExJs,
+	docsJsonRoot: 'https://s3.amazonaws.com/0xjs-docs-jsons',
+	menu: {
+		introduction: [zeroExJsDocSections.introduction],
+		install: [zeroExJsDocSections.installation],
+		topics: [zeroExJsDocSections.async, zeroExJsDocSections.errors, zeroExJsDocSections.versioning],
+		zeroEx: [zeroExJsDocSections.zeroEx],
+		contracts: [
+			zeroExJsDocSections.exchange,
+			zeroExJsDocSections.token,
+			zeroExJsDocSections.tokenRegistry,
+			zeroExJsDocSections.etherToken,
+			zeroExJsDocSections.proxy,
+		],
+		orderWatcher: [zeroExJsDocSections.orderWatcher],
+		types: [zeroExJsDocSections.types],
+	},
+	sectionNameToMarkdown: {
+		[zeroExJsDocSections.introduction]: IntroMarkdown,
+		[zeroExJsDocSections.installation]: InstallationMarkdown,
+		[zeroExJsDocSections.async]: AsyncMarkdown,
+		[zeroExJsDocSections.errors]: ErrorsMarkdown,
+		[zeroExJsDocSections.versioning]: versioningMarkdown,
+	},
+	// Note: This needs to be kept in sync with the types exported in index.ts. Unfortunately there is
+	// currently no way to extract the re-exported types from index.ts via TypeDoc :(
+	publicTypes: [
+		'Order',
+		'SignedOrder',
+		'ECSignature',
+		'ZeroExError',
+		'EventCallback',
+		'EventCallbackAsync',
+		'EventCallbackSync',
+		'ExchangeContractErrs',
+		'ContractEvent',
+		'Token',
+		'ExchangeEvents',
+		'IndexedFilterValues',
+		'SubscriptionOpts',
+		'BlockRange',
+		'BlockParam',
+		'OrderFillOrKillRequest',
+		'OrderCancellationRequest',
+		'OrderFillRequest',
+		'ContractEventEmitter',
+		'Web3Provider',
+		'ContractEventArgs',
+		'LogCancelArgs',
+		'LogFillArgs',
+		'LogErrorContractEventArgs',
+		'LogFillContractEventArgs',
+		'LogCancelContractEventArgs',
+		'EtherTokenContractEventArgs',
+		'WithdrawalContractEventArgs',
+		'DepositContractEventArgs',
+		'TokenEvents',
+		'ExchangeContractEventArgs',
+		'TransferContractEventArgs',
+		'ApprovalContractEventArgs',
+		'TokenContractEventArgs',
+		'ZeroExConfig',
+		'TransactionReceiptWithDecodedLogs',
+		'LogWithDecodedArgs',
+		'EtherTokenEvents',
+		'BlockParamLiteral',
+		'DecodedLogArgs',
+		'MethodOpts',
+		'ValidateOrderFillableOpts',
+		'OrderTransactionOpts',
+		'TransactionOpts',
+		'ContractEventArg',
+		'LogEvent',
+		'LogEntry',
+		'DecodedLogEvent',
+		'EventWatcherCallback',
+		'OnOrderStateChangeCallback',
+		'OrderStateValid',
+		'OrderStateInvalid',
+		'OrderState',
+		'FilterObject',
+	],
+	sectionNameToModulePath: {
+		[zeroExJsDocSections.zeroEx]: ['"src/0x"'],
+		[zeroExJsDocSections.exchange]: ['"src/contract_wrappers/exchange_wrapper"'],
+		[zeroExJsDocSections.tokenRegistry]: ['"src/contract_wrappers/token_registry_wrapper"'],
+		[zeroExJsDocSections.token]: ['"src/contract_wrappers/token_wrapper"'],
+		[zeroExJsDocSections.etherToken]: ['"src/contract_wrappers/ether_token_wrapper"'],
+		[zeroExJsDocSections.proxy]: [
+			'"src/contract_wrappers/proxy_wrapper"',
+			'"src/contract_wrappers/token_transfer_proxy_wrapper"',
+		],
+		[zeroExJsDocSections.orderWatcher]: ['"src/order_watcher/order_state_watcher"'],
+		[zeroExJsDocSections.types]: ['"src/types"'],
+	},
+	menuSubsectionToVersionWhenIntroduced: {
+		[zeroExJsDocSections.etherToken]: '0.7.1',
+		[zeroExJsDocSections.proxy]: '0.8.0',
+		[zeroExJsDocSections.orderWatcher]: '0.27.1',
+	},
+	sections: zeroExJsDocSections,
+	visibleConstructors: [zeroExJsDocSections.zeroEx],
+	convertToDocAgnosticFormatFn: typeDocUtils.convertToDocAgnosticFormat.bind(typeDocUtils),
 };
 const docsInfo = new DocsInfo(docsInfoConfig);
 
 interface ConnectedState {
-    docsVersion: string;
-    availableDocVersions: string[];
-    docsInfo: DocsInfo;
+	docsVersion: string;
+	availableDocVersions: string[];
+	docsInfo: DocsInfo;
 }
 
 interface ConnectedDispatch {
-    dispatcher: Dispatcher;
+	dispatcher: Dispatcher;
 }
 
 const mapStateToProps = (state: State, ownProps: DocumentationAllProps): ConnectedState => ({
-    docsVersion: state.docsVersion,
-    availableDocVersions: state.availableDocVersions,
-    docsInfo,
+	docsVersion: state.docsVersion,
+	availableDocVersions: state.availableDocVersions,
+	docsInfo,
 });
 
 const mapDispatchToProps = (dispatch: Dispatch<State>): ConnectedDispatch => ({
-    dispatcher: new Dispatcher(dispatch),
+	dispatcher: new Dispatcher(dispatch),
 });
 
 export const Documentation: React.ComponentClass<DocumentationAllProps> = connect(mapStateToProps, mapDispatchToProps)(
-    DocumentationComponent,
+	DocumentationComponent,
 );
diff --git a/packages/website/ts/globals.d.ts b/packages/website/ts/globals.d.ts
index 383e5cbe0..736b23d9d 100644
--- a/packages/website/ts/globals.d.ts
+++ b/packages/website/ts/globals.d.ts
@@ -14,10 +14,10 @@ declare module 'ledgerco';
 declare module 'ethereumjs-tx';
 
 declare module '*.json' {
-    const json: any;
-    /* tslint:disable */
-    export default json;
-    /* tslint:enable */
+	const json: any;
+	/* tslint:disable */
+	export default json;
+	/* tslint:enable */
 }
 
 // tslint:disable:max-classes-per-file
@@ -25,137 +25,137 @@ declare module '*.json' {
 // find-version declarations
 declare function findVersions(version: string): string[];
 declare module 'find-versions' {
-    export = findVersions;
+	export = findVersions;
 }
 
 // compare-version declarations
 declare function compareVersions(firstVersion: string, secondVersion: string): number;
 declare module 'compare-versions' {
-    export = compareVersions;
+	export = compareVersions;
 }
 
 // semver-sort declarations
 declare module 'semver-sort' {
-    const desc: (versions: string[]) => string[];
+	const desc: (versions: string[]) => string[];
 }
 
 // xml-js declarations
 declare interface XML2JSONOpts {
-    compact?: boolean;
-    spaces?: number;
+	compact?: boolean;
+	spaces?: number;
 }
 declare module 'xml-js' {
-    const xml2json: (xml: string, opts: XML2JSONOpts) => string;
+	const xml2json: (xml: string, opts: XML2JSONOpts) => string;
 }
 
 // This will be defined by default in TS 2.4
 // Source: https://github.com/Microsoft/TypeScript/issues/12364
 interface System {
-    import<T>(module: string): Promise<T>;
+	import<T>(module: string): Promise<T>;
 }
 declare var System: System;
 
 // jsonschema declarations
 // Source: https://github.com/tdegrunt/jsonschema/blob/master/lib/index.d.ts
 declare interface Schema {
-    id?: string;
-    $schema?: string;
-    title?: string;
-    description?: string;
-    multipleOf?: number;
-    maximum?: number;
-    exclusiveMaximum?: boolean;
-    minimum?: number;
-    exclusiveMinimum?: boolean;
-    maxLength?: number;
-    minLength?: number;
-    pattern?: string;
-    additionalItems?: boolean | Schema;
-    items?: Schema | Schema[];
-    maxItems?: number;
-    minItems?: number;
-    uniqueItems?: boolean;
-    maxProperties?: number;
-    minProperties?: number;
-    required?: string[];
-    additionalProperties?: boolean | Schema;
-    definitions?: {
-        [name: string]: Schema;
-    };
-    properties?: {
-        [name: string]: Schema;
-    };
-    patternProperties?: {
-        [name: string]: Schema;
-    };
-    dependencies?: {
-        [name: string]: Schema | string[];
-    };
-    enum?: any[];
-    type?: string | string[];
-    allOf?: Schema[];
-    anyOf?: Schema[];
-    oneOf?: Schema[];
-    not?: Schema;
-    // This is the only property that's not defined in https://github.com/tdegrunt/jsonschema/blob/master/lib/index.d.ts
-    // There is an open issue for that: https://github.com/tdegrunt/jsonschema/issues/194
-    // There is also an opened PR: https://github.com/tdegrunt/jsonschema/pull/218/files
-    // As soon as it gets merged we should be good to use types from 'jsonschema' package
-    $ref?: string;
+	id?: string;
+	$schema?: string;
+	title?: string;
+	description?: string;
+	multipleOf?: number;
+	maximum?: number;
+	exclusiveMaximum?: boolean;
+	minimum?: number;
+	exclusiveMinimum?: boolean;
+	maxLength?: number;
+	minLength?: number;
+	pattern?: string;
+	additionalItems?: boolean | Schema;
+	items?: Schema | Schema[];
+	maxItems?: number;
+	minItems?: number;
+	uniqueItems?: boolean;
+	maxProperties?: number;
+	minProperties?: number;
+	required?: string[];
+	additionalProperties?: boolean | Schema;
+	definitions?: {
+		[name: string]: Schema;
+	};
+	properties?: {
+		[name: string]: Schema;
+	};
+	patternProperties?: {
+		[name: string]: Schema;
+	};
+	dependencies?: {
+		[name: string]: Schema | string[];
+	};
+	enum?: any[];
+	type?: string | string[];
+	allOf?: Schema[];
+	anyOf?: Schema[];
+	oneOf?: Schema[];
+	not?: Schema;
+	// This is the only property that's not defined in https://github.com/tdegrunt/jsonschema/blob/master/lib/index.d.ts
+	// There is an open issue for that: https://github.com/tdegrunt/jsonschema/issues/194
+	// There is also an opened PR: https://github.com/tdegrunt/jsonschema/pull/218/files
+	// As soon as it gets merged we should be good to use types from 'jsonschema' package
+	$ref?: string;
 }
 
 // blockies declarations
 declare interface BlockiesIcon {
-    toDataURL(): string;
+	toDataURL(): string;
 }
 declare interface BlockiesConfig {
-    seed: string;
+	seed: string;
 }
 declare function blockies(config: BlockiesConfig): BlockiesIcon;
 declare module 'blockies' {
-    export = blockies;
+	export = blockies;
 }
 
 // is-mobile declarations
 declare function isMobile(): boolean;
 declare module 'is-mobile' {
-    export = isMobile;
+	export = isMobile;
 }
 
 // web3-provider-engine declarations
 declare class Subprovider {}
 declare module 'web3-provider-engine/subproviders/subprovider' {
-    export = Subprovider;
+	export = Subprovider;
 }
 declare module 'web3-provider-engine/subproviders/rpc' {
-    import * as Web3 from 'web3';
-    class RpcSubprovider {
-        constructor(options: { rpcUrl: string });
-        public handleRequest(
-            payload: Web3.JSONRPCRequestPayload,
-            next: () => void,
-            end: (err: Error | null, data?: any) => void,
-        ): void;
-    }
-    export = RpcSubprovider;
+	import * as Web3 from 'web3';
+	class RpcSubprovider {
+		constructor(options: { rpcUrl: string });
+		public handleRequest(
+			payload: Web3.JSONRPCRequestPayload,
+			next: () => void,
+			end: (err: Error | null, data?: any) => void,
+		): void;
+	}
+	export = RpcSubprovider;
 }
 declare module 'web3-provider-engine' {
-    class Web3ProviderEngine {
-        public on(event: string, handler: () => void): void;
-        public send(payload: any): void;
-        public sendAsync(payload: any, callback: (error: any, response: any) => void): void;
-        public addProvider(provider: any): void;
-        public start(): void;
-        public stop(): void;
-    }
-    export = Web3ProviderEngine;
+	class Web3ProviderEngine {
+		public on(event: string, handler: () => void): void;
+		public send(payload: any): void;
+		public sendAsync(payload: any, callback: (error: any, response: any) => void): void;
+		public addProvider(provider: any): void;
+		public start(): void;
+		public stop(): void;
+	}
+	export = Web3ProviderEngine;
 }
 
 declare interface Artifact {
-    abi: any;
-    networks: {
-        [networkId: number]: {
-            address: string;
-        };
-    };
+	abi: any;
+	networks: {
+		[networkId: number]: {
+			address: string;
+		};
+	};
 }
diff --git a/packages/website/ts/index.tsx b/packages/website/ts/index.tsx
index ffb551561..df45c80bd 100644
--- a/packages/website/ts/index.tsx
+++ b/packages/website/ts/index.tsx
@@ -32,44 +32,44 @@ import 'less/all.less';
 // At the same time webpack statically parses for System.import() to determine bundle chunk split points
 // so each lazy import needs it's own `System.import()` declaration.
 const LazyPortal = createLazyComponent('Portal', async () =>
-    System.import<any>(/* webpackChunkName: "portal" */ 'ts/containers/portal'),
+	System.import<any>(/* webpackChunkName: "portal" */ 'ts/containers/portal'),
 );
 const LazyZeroExJSDocumentation = createLazyComponent('Documentation', async () =>
-    System.import<any>(/* webpackChunkName: "zeroExDocs" */ 'ts/containers/zero_ex_js_documentation'),
+	System.import<any>(/* webpackChunkName: "zeroExDocs" */ 'ts/containers/zero_ex_js_documentation'),
 );
 const LazySmartContractsDocumentation = createLazyComponent('Documentation', async () =>
-    System.import<any>(/* webpackChunkName: "smartContractDocs" */ 'ts/containers/smart_contracts_documentation'),
+	System.import<any>(/* webpackChunkName: "smartContractDocs" */ 'ts/containers/smart_contracts_documentation'),
 );
 const LazyConnectDocumentation = createLazyComponent('Documentation', async () =>
-    System.import<any>(/* webpackChunkName: "connectDocs" */ 'ts/containers/connect_documentation'),
+	System.import<any>(/* webpackChunkName: "connectDocs" */ 'ts/containers/connect_documentation'),
 );
 
 const store: ReduxStore<State> = createStore(reducer);
 render(
-    <Router>
-        <div>
-            <MuiThemeProvider muiTheme={muiTheme}>
-                <Provider store={store}>
-                    <div>
-                        <Switch>
-                            <Route exact={true} path="/" component={Landing as any} />
-                            <Redirect from="/otc" to={`${WebsitePaths.Portal}`} />
-                            <Route path={`${WebsitePaths.Portal}`} component={LazyPortal} />
-                            <Route path={`${WebsitePaths.FAQ}`} component={FAQ as any} />
-                            <Route path={`${WebsitePaths.About}`} component={About as any} />
-                            <Route path={`${WebsitePaths.Wiki}`} component={Wiki as any} />
-                            <Route path={`${WebsitePaths.ZeroExJs}/:version?`} component={LazyZeroExJSDocumentation} />
-                            <Route path={`${WebsitePaths.Connect}/:version?`} component={LazyConnectDocumentation} />
-                            <Route
-                                path={`${WebsitePaths.SmartContracts}/:version?`}
-                                component={LazySmartContractsDocumentation}
-                            />
-                            <Route component={NotFound as any} />
-                        </Switch>
-                    </div>
-                </Provider>
-            </MuiThemeProvider>
-        </div>
-    </Router>,
-    document.getElementById('app'),
+	<Router>
+		<div>
+			<MuiThemeProvider muiTheme={muiTheme}>
+				<Provider store={store}>
+					<div>
+						<Switch>
+							<Route exact={true} path="/" component={Landing as any} />
+							<Redirect from="/otc" to={`${WebsitePaths.Portal}`} />
+							<Route path={`${WebsitePaths.Portal}`} component={LazyPortal} />
+							<Route path={`${WebsitePaths.FAQ}`} component={FAQ as any} />
+							<Route path={`${WebsitePaths.About}`} component={About as any} />
+							<Route path={`${WebsitePaths.Wiki}`} component={Wiki as any} />
+							<Route path={`${WebsitePaths.ZeroExJs}/:version?`} component={LazyZeroExJSDocumentation} />
+							<Route path={`${WebsitePaths.Connect}/:version?`} component={LazyConnectDocumentation} />
+							<Route
+								path={`${WebsitePaths.SmartContracts}/:version?`}
+								component={LazySmartContractsDocumentation}
+							/>
+							<Route component={NotFound as any} />
+						</Switch>
+					</div>
+				</Provider>
+			</MuiThemeProvider>
+		</div>
+	</Router>,
+	document.getElementById('app'),
 );
diff --git a/packages/website/ts/lazy_component.tsx b/packages/website/ts/lazy_component.tsx
index 48800c2dd..5efebb667 100644
--- a/packages/website/ts/lazy_component.tsx
+++ b/packages/website/ts/lazy_component.tsx
@@ -2,12 +2,12 @@ import * as _ from 'lodash';
 import * as React from 'react';
 
 interface LazyComponentProps {
-    reactComponentPromise: Promise<React.ComponentClass<any>>;
-    reactComponentProps: any;
+	reactComponentPromise: Promise<React.ComponentClass<any>>;
+	reactComponentProps: any;
 }
 
 interface LazyComponentState {
-    component?: React.ComponentClass<any>;
+	component?: React.ComponentClass<any>;
 }
 
 /**
@@ -15,33 +15,33 @@ interface LazyComponentState {
  * Source: https://reacttraining.com/react-router/web/guides/code-splitting
  */
 export class LazyComponent extends React.Component<LazyComponentProps, LazyComponentState> {
-    constructor(props: LazyComponentProps) {
-        super(props);
-        this.state = {
-            component: undefined,
-        };
-    }
-    public componentWillMount() {
-        // tslint:disable-next-line:no-floating-promises
-        this._loadComponentFireAndForgetAsync(this.props);
-    }
-    public componentWillReceiveProps(nextProps: LazyComponentProps) {
-        if (nextProps.reactComponentPromise !== this.props.reactComponentPromise) {
-            // tslint:disable-next-line:no-floating-promises
-            this._loadComponentFireAndForgetAsync(nextProps);
-        }
-    }
-    public render() {
-        return _.isUndefined(this.state.component)
-            ? null
-            : React.createElement(this.state.component, this.props.reactComponentProps);
-    }
-    private async _loadComponentFireAndForgetAsync(props: LazyComponentProps) {
-        const component = await props.reactComponentPromise;
-        this.setState({
-            component,
-        });
-    }
+	constructor(props: LazyComponentProps) {
+		super(props);
+		this.state = {
+			component: undefined,
+		};
+	}
+	public componentWillMount() {
+		// tslint:disable-next-line:no-floating-promises
+		this._loadComponentFireAndForgetAsync(this.props);
+	}
+	public componentWillReceiveProps(nextProps: LazyComponentProps) {
+		if (nextProps.reactComponentPromise !== this.props.reactComponentPromise) {
+			// tslint:disable-next-line:no-floating-promises
+			this._loadComponentFireAndForgetAsync(nextProps);
+		}
+	}
+	public render() {
+		return _.isUndefined(this.state.component)
+			? null
+			: React.createElement(this.state.component, this.props.reactComponentProps);
+	}
+	private async _loadComponentFireAndForgetAsync(props: LazyComponentProps) {
+		const component = await props.reactComponentPromise;
+		this.setState({
+			component,
+		});
+	}
 }
 
 /**
@@ -52,15 +52,15 @@ export class LazyComponent extends React.Component<LazyComponentProps, LazyCompo
  * @example `const LazyPortal = createLazyComponent('Portal', () => System.import<any>('ts/containers/portal'));``
  */
 export const createLazyComponent = (componentName: string, lazyImport: () => Promise<any>) => {
-    return (props: any) => {
-        const reactComponentPromise = (async (): Promise<React.ComponentClass<any>> => {
-            const mod = await lazyImport();
-            const component = mod[componentName];
-            if (_.isUndefined(component)) {
-                throw new Error(`Did not find exported component: ${componentName}`);
-            }
-            return component;
-        })();
-        return <LazyComponent reactComponentPromise={reactComponentPromise} reactComponentProps={props} />;
-    };
+	return (props: any) => {
+		const reactComponentPromise = (async (): Promise<React.ComponentClass<any>> => {
+			const mod = await lazyImport();
+			const component = mod[componentName];
+			if (_.isUndefined(component)) {
+				throw new Error(`Did not find exported component: ${componentName}`);
+			}
+			return component;
+		})();
+		return <LazyComponent reactComponentPromise={reactComponentPromise} reactComponentProps={props} />;
+	};
 };
diff --git a/packages/website/ts/local_storage/local_storage.ts b/packages/website/ts/local_storage/local_storage.ts
index d94e6877b..4e5b77a0a 100644
--- a/packages/website/ts/local_storage/local_storage.ts
+++ b/packages/website/ts/local_storage/local_storage.ts
@@ -1,35 +1,35 @@
 import * as _ from 'lodash';
 
 export const localStorage = {
-    doesExist() {
-        return !!window.localStorage;
-    },
-    getItemIfExists(key: string): string {
-        if (!this.doesExist) {
-            return undefined;
-        }
-        const item = window.localStorage.getItem(key);
-        if (_.isNull(item) || item === 'undefined') {
-            return '';
-        }
-        return item;
-    },
-    setItem(key: string, value: string) {
-        if (!this.doesExist || _.isUndefined(value)) {
-            return;
-        }
-        window.localStorage.setItem(key, value);
-    },
-    removeItem(key: string) {
-        if (!this.doesExist) {
-            return;
-        }
-        window.localStorage.removeItem(key);
-    },
-    getAllKeys(): string[] {
-        if (!this.doesExist) {
-            return [];
-        }
-        return _.keys(window.localStorage);
-    },
+	doesExist() {
+		return !!window.localStorage;
+	},
+	getItemIfExists(key: string): string {
+		if (!this.doesExist) {
+			return undefined;
+		}
+		const item = window.localStorage.getItem(key);
+		if (_.isNull(item) || item === 'undefined') {
+			return '';
+		}
+		return item;
+	},
+	setItem(key: string, value: string) {
+		if (!this.doesExist || _.isUndefined(value)) {
+			return;
+		}
+		window.localStorage.setItem(key, value);
+	},
+	removeItem(key: string) {
+		if (!this.doesExist) {
+			return;
+		}
+		window.localStorage.removeItem(key);
+	},
+	getAllKeys(): string[] {
+		if (!this.doesExist) {
+			return [];
+		}
+		return _.keys(window.localStorage);
+	},
 };
diff --git a/packages/website/ts/local_storage/tracked_token_storage.ts b/packages/website/ts/local_storage/tracked_token_storage.ts
index 7733e8436..2c62084e0 100644
--- a/packages/website/ts/local_storage/tracked_token_storage.ts
+++ b/packages/website/ts/local_storage/tracked_token_storage.ts
@@ -7,61 +7,61 @@ const TRACKED_TOKENS_KEY = 'trackedTokens';
 const TRACKED_TOKENS_CLEAR_KEY = 'lastClearTrackedTokensDate';
 
 export const trackedTokenStorage = {
-    // Clear trackedTokens localStorage if we've updated the config variable in an update
-    // that introduced a backward incompatible change requiring the tracked tokens to be re-set
-    clearIfRequired(): void {
-        const lastClearFillDate = localStorage.getItemIfExists(TRACKED_TOKENS_CLEAR_KEY);
-        if (lastClearFillDate !== configs.LAST_LOCAL_STORAGE_TRACKED_TOKEN_CLEARANCE_DATE) {
-            localStorage.removeItem(TRACKED_TOKENS_KEY);
-        }
-        localStorage.setItem(TRACKED_TOKENS_CLEAR_KEY, configs.LAST_LOCAL_STORAGE_TRACKED_TOKEN_CLEARANCE_DATE);
-    },
-    addTrackedTokenToUser(userAddress: string, networkId: number, token: Token): void {
-        const trackedTokensByUserAddress = this.getTrackedTokensByUserAddress();
-        let trackedTokensByNetworkId = trackedTokensByUserAddress[userAddress];
-        if (_.isUndefined(trackedTokensByNetworkId)) {
-            trackedTokensByNetworkId = {};
-        }
-        const trackedTokens = !_.isUndefined(trackedTokensByNetworkId[networkId])
-            ? trackedTokensByNetworkId[networkId]
-            : [];
-        trackedTokens.push(token);
-        trackedTokensByNetworkId[networkId] = trackedTokens;
-        trackedTokensByUserAddress[userAddress] = trackedTokensByNetworkId;
-        const trackedTokensByUserAddressJSONString = JSON.stringify(trackedTokensByUserAddress);
-        localStorage.setItem(TRACKED_TOKENS_KEY, trackedTokensByUserAddressJSONString);
-    },
-    getTrackedTokensByUserAddress(): TrackedTokensByUserAddress {
-        const trackedTokensJSONString = localStorage.getItemIfExists(TRACKED_TOKENS_KEY);
-        if (_.isEmpty(trackedTokensJSONString)) {
-            return {};
-        }
-        const trackedTokensByUserAddress = JSON.parse(trackedTokensJSONString);
-        return trackedTokensByUserAddress;
-    },
-    getTrackedTokensIfExists(userAddress: string, networkId: number): Token[] {
-        const trackedTokensJSONString = localStorage.getItemIfExists(TRACKED_TOKENS_KEY);
-        if (_.isEmpty(trackedTokensJSONString)) {
-            return undefined;
-        }
-        const trackedTokensByUserAddress = JSON.parse(trackedTokensJSONString);
-        const trackedTokensByNetworkId = trackedTokensByUserAddress[userAddress];
-        if (_.isUndefined(trackedTokensByNetworkId)) {
-            return undefined;
-        }
-        const trackedTokens = trackedTokensByNetworkId[networkId];
-        return trackedTokens;
-    },
-    removeTrackedToken(userAddress: string, networkId: number, tokenAddress: string): void {
-        const trackedTokensByUserAddress = this.getTrackedTokensByUserAddress();
-        const trackedTokensByNetworkId = trackedTokensByUserAddress[userAddress];
-        const trackedTokens = trackedTokensByNetworkId[networkId];
-        const remainingTrackedTokens = _.filter(trackedTokens, (token: Token) => {
-            return token.address !== tokenAddress;
-        });
-        trackedTokensByNetworkId[networkId] = remainingTrackedTokens;
-        trackedTokensByUserAddress[userAddress] = trackedTokensByNetworkId;
-        const trackedTokensByUserAddressJSONString = JSON.stringify(trackedTokensByUserAddress);
-        localStorage.setItem(TRACKED_TOKENS_KEY, trackedTokensByUserAddressJSONString);
-    },
+	// Clear trackedTokens localStorage if we've updated the config variable in an update
+	// that introduced a backward incompatible change requiring the tracked tokens to be re-set
+	clearIfRequired(): void {
+		const lastClearFillDate = localStorage.getItemIfExists(TRACKED_TOKENS_CLEAR_KEY);
+		if (lastClearFillDate !== configs.LAST_LOCAL_STORAGE_TRACKED_TOKEN_CLEARANCE_DATE) {
+			localStorage.removeItem(TRACKED_TOKENS_KEY);
+		}
+		localStorage.setItem(TRACKED_TOKENS_CLEAR_KEY, configs.LAST_LOCAL_STORAGE_TRACKED_TOKEN_CLEARANCE_DATE);
+	},
+	addTrackedTokenToUser(userAddress: string, networkId: number, token: Token): void {
+		const trackedTokensByUserAddress = this.getTrackedTokensByUserAddress();
+		let trackedTokensByNetworkId = trackedTokensByUserAddress[userAddress];
+		if (_.isUndefined(trackedTokensByNetworkId)) {
+			trackedTokensByNetworkId = {};
+		}
+		const trackedTokens = !_.isUndefined(trackedTokensByNetworkId[networkId])
+			? trackedTokensByNetworkId[networkId]
+			: [];
+		trackedTokens.push(token);
+		trackedTokensByNetworkId[networkId] = trackedTokens;
+		trackedTokensByUserAddress[userAddress] = trackedTokensByNetworkId;
+		const trackedTokensByUserAddressJSONString = JSON.stringify(trackedTokensByUserAddress);
+		localStorage.setItem(TRACKED_TOKENS_KEY, trackedTokensByUserAddressJSONString);
+	},
+	getTrackedTokensByUserAddress(): TrackedTokensByUserAddress {
+		const trackedTokensJSONString = localStorage.getItemIfExists(TRACKED_TOKENS_KEY);
+		if (_.isEmpty(trackedTokensJSONString)) {
+			return {};
+		}
+		const trackedTokensByUserAddress = JSON.parse(trackedTokensJSONString);
+		return trackedTokensByUserAddress;
+	},
+	getTrackedTokensIfExists(userAddress: string, networkId: number): Token[] {
+		const trackedTokensJSONString = localStorage.getItemIfExists(TRACKED_TOKENS_KEY);
+		if (_.isEmpty(trackedTokensJSONString)) {
+			return undefined;
+		}
+		const trackedTokensByUserAddress = JSON.parse(trackedTokensJSONString);
+		const trackedTokensByNetworkId = trackedTokensByUserAddress[userAddress];
+		if (_.isUndefined(trackedTokensByNetworkId)) {
+			return undefined;
+		}
+		const trackedTokens = trackedTokensByNetworkId[networkId];
+		return trackedTokens;
+	},
+	removeTrackedToken(userAddress: string, networkId: number, tokenAddress: string): void {
+		const trackedTokensByUserAddress = this.getTrackedTokensByUserAddress();
+		const trackedTokensByNetworkId = trackedTokensByUserAddress[userAddress];
+		const trackedTokens = trackedTokensByNetworkId[networkId];
+		const remainingTrackedTokens = _.filter(trackedTokens, (token: Token) => {
+			return token.address !== tokenAddress;
+		});
+		trackedTokensByNetworkId[networkId] = remainingTrackedTokens;
+		trackedTokensByUserAddress[userAddress] = trackedTokensByNetworkId;
+		const trackedTokensByUserAddressJSONString = JSON.stringify(trackedTokensByUserAddress);
+		localStorage.setItem(TRACKED_TOKENS_KEY, trackedTokensByUserAddressJSONString);
+	},
 };
diff --git a/packages/website/ts/local_storage/trade_history_storage.tsx b/packages/website/ts/local_storage/trade_history_storage.tsx
index df731236e..b20244b29 100644
--- a/packages/website/ts/local_storage/trade_history_storage.tsx
+++ b/packages/website/ts/local_storage/trade_history_storage.tsx
@@ -11,84 +11,84 @@ const FILLS_LATEST_BLOCK = 'fillsLatestBlock';
 const FILL_CLEAR_KEY = 'lastClearFillDate';
 
 export const tradeHistoryStorage = {
-    // Clear all fill related localStorage if we've updated the config variable in an update
-    // that introduced a backward incompatible change requiring the user to re-fetch the fills from
-    // the blockchain
-    clearIfRequired() {
-        const lastClearFillDate = localStorage.getItemIfExists(FILL_CLEAR_KEY);
-        if (lastClearFillDate !== configs.LAST_LOCAL_STORAGE_FILL_CLEARANCE_DATE) {
-            const localStorageKeys = localStorage.getAllKeys();
-            _.each(localStorageKeys, key => {
-                if (_.startsWith(key, `${FILLS_KEY}-`) || _.startsWith(key, `${FILLS_LATEST_BLOCK}-`)) {
-                    localStorage.removeItem(key);
-                }
-            });
-        }
-        localStorage.setItem(FILL_CLEAR_KEY, configs.LAST_LOCAL_STORAGE_FILL_CLEARANCE_DATE);
-    },
-    addFillToUser(userAddress: string, networkId: number, fill: Fill) {
-        const fillsByHash = this.getUserFillsByHash(userAddress, networkId);
-        const fillHash = this._getFillHash(fill);
-        const doesFillExist = !_.isUndefined(fillsByHash[fillHash]);
-        if (doesFillExist) {
-            return; // noop
-        }
-        fillsByHash[fillHash] = fill;
-        const userFillsJSONString = JSON.stringify(fillsByHash);
-        const userFillsKey = this._getUserFillsKey(userAddress, networkId);
-        localStorage.setItem(userFillsKey, userFillsJSONString);
-    },
-    removeFillFromUser(userAddress: string, networkId: number, fill: Fill) {
-        const fillsByHash = this.getUserFillsByHash(userAddress, networkId);
-        const fillHash = this._getFillHash(fill);
-        const doesFillExist = !_.isUndefined(fillsByHash[fillHash]);
-        if (!doesFillExist) {
-            return; // noop
-        }
-        delete fillsByHash[fillHash];
-        const userFillsJSONString = JSON.stringify(fillsByHash);
-        const userFillsKey = this._getUserFillsKey(userAddress, networkId);
-        localStorage.setItem(userFillsKey, userFillsJSONString);
-    },
-    getUserFillsByHash(userAddress: string, networkId: number): { [fillHash: string]: Fill } {
-        const userFillsKey = this._getUserFillsKey(userAddress, networkId);
-        const userFillsJSONString = localStorage.getItemIfExists(userFillsKey);
-        if (_.isEmpty(userFillsJSONString)) {
-            return {};
-        }
-        const userFillsByHash = JSON.parse(userFillsJSONString);
-        _.each(userFillsByHash, (fill, hash) => {
-            fill.paidMakerFee = new BigNumber(fill.paidMakerFee);
-            fill.paidTakerFee = new BigNumber(fill.paidTakerFee);
-            fill.filledTakerTokenAmount = new BigNumber(fill.filledTakerTokenAmount);
-            fill.filledMakerTokenAmount = new BigNumber(fill.filledMakerTokenAmount);
-        });
-        return userFillsByHash;
-    },
-    getFillsLatestBlock(userAddress: string, networkId: number): number {
-        const userFillsLatestBlockKey = this._getFillsLatestBlockKey(userAddress, networkId);
-        const blockNumberStr = localStorage.getItemIfExists(userFillsLatestBlockKey);
-        if (_.isEmpty(blockNumberStr)) {
-            return constants.GENESIS_ORDER_BLOCK_BY_NETWORK_ID[networkId];
-        }
-        const blockNumber = _.parseInt(blockNumberStr);
-        return blockNumber;
-    },
-    setFillsLatestBlock(userAddress: string, networkId: number, blockNumber: number) {
-        const userFillsLatestBlockKey = this._getFillsLatestBlockKey(userAddress, networkId);
-        localStorage.setItem(userFillsLatestBlockKey, `${blockNumber}`);
-    },
-    _getUserFillsKey(userAddress: string, networkId: number) {
-        const userFillsKey = `${FILLS_KEY}-${userAddress}-${networkId}`;
-        return userFillsKey;
-    },
-    _getFillsLatestBlockKey(userAddress: string, networkId: number) {
-        const userFillsLatestBlockKey = `${FILLS_LATEST_BLOCK}-${userAddress}-${networkId}`;
-        return userFillsLatestBlockKey;
-    },
-    _getFillHash(fill: Fill): string {
-        const fillJSON = JSON.stringify(fill);
-        const fillHash = ethUtil.sha256(fillJSON);
-        return fillHash.toString('hex');
-    },
+	// Clear all fill related localStorage if we've updated the config variable in an update
+	// that introduced a backward incompatible change requiring the user to re-fetch the fills from
+	// the blockchain
+	clearIfRequired() {
+		const lastClearFillDate = localStorage.getItemIfExists(FILL_CLEAR_KEY);
+		if (lastClearFillDate !== configs.LAST_LOCAL_STORAGE_FILL_CLEARANCE_DATE) {
+			const localStorageKeys = localStorage.getAllKeys();
+			_.each(localStorageKeys, key => {
+				if (_.startsWith(key, `${FILLS_KEY}-`) || _.startsWith(key, `${FILLS_LATEST_BLOCK}-`)) {
+					localStorage.removeItem(key);
+				}
+			});
+		}
+		localStorage.setItem(FILL_CLEAR_KEY, configs.LAST_LOCAL_STORAGE_FILL_CLEARANCE_DATE);
+	},
+	addFillToUser(userAddress: string, networkId: number, fill: Fill) {
+		const fillsByHash = this.getUserFillsByHash(userAddress, networkId);
+		const fillHash = this._getFillHash(fill);
+		const doesFillExist = !_.isUndefined(fillsByHash[fillHash]);
+		if (doesFillExist) {
+			return; // noop
+		}
+		fillsByHash[fillHash] = fill;
+		const userFillsJSONString = JSON.stringify(fillsByHash);
+		const userFillsKey = this._getUserFillsKey(userAddress, networkId);
+		localStorage.setItem(userFillsKey, userFillsJSONString);
+	},
+	removeFillFromUser(userAddress: string, networkId: number, fill: Fill) {
+		const fillsByHash = this.getUserFillsByHash(userAddress, networkId);
+		const fillHash = this._getFillHash(fill);
+		const doesFillExist = !_.isUndefined(fillsByHash[fillHash]);
+		if (!doesFillExist) {
+			return; // noop
+		}
+		delete fillsByHash[fillHash];
+		const userFillsJSONString = JSON.stringify(fillsByHash);
+		const userFillsKey = this._getUserFillsKey(userAddress, networkId);
+		localStorage.setItem(userFillsKey, userFillsJSONString);
+	},
+	getUserFillsByHash(userAddress: string, networkId: number): { [fillHash: string]: Fill } {
+		const userFillsKey = this._getUserFillsKey(userAddress, networkId);
+		const userFillsJSONString = localStorage.getItemIfExists(userFillsKey);
+		if (_.isEmpty(userFillsJSONString)) {
+			return {};
+		}
+		const userFillsByHash = JSON.parse(userFillsJSONString);
+		_.each(userFillsByHash, (fill, hash) => {
+			fill.paidMakerFee = new BigNumber(fill.paidMakerFee);
+			fill.paidTakerFee = new BigNumber(fill.paidTakerFee);
+			fill.filledTakerTokenAmount = new BigNumber(fill.filledTakerTokenAmount);
+			fill.filledMakerTokenAmount = new BigNumber(fill.filledMakerTokenAmount);
+		});
+		return userFillsByHash;
+	},
+	getFillsLatestBlock(userAddress: string, networkId: number): number {
+		const userFillsLatestBlockKey = this._getFillsLatestBlockKey(userAddress, networkId);
+		const blockNumberStr = localStorage.getItemIfExists(userFillsLatestBlockKey);
+		if (_.isEmpty(blockNumberStr)) {
+			return constants.GENESIS_ORDER_BLOCK_BY_NETWORK_ID[networkId];
+		}
+		const blockNumber = _.parseInt(blockNumberStr);
+		return blockNumber;
+	},
+	setFillsLatestBlock(userAddress: string, networkId: number, blockNumber: number) {
+		const userFillsLatestBlockKey = this._getFillsLatestBlockKey(userAddress, networkId);
+		localStorage.setItem(userFillsLatestBlockKey, `${blockNumber}`);
+	},
+	_getUserFillsKey(userAddress: string, networkId: number) {
+		const userFillsKey = `${FILLS_KEY}-${userAddress}-${networkId}`;
+		return userFillsKey;
+	},
+	_getFillsLatestBlockKey(userAddress: string, networkId: number) {
+		const userFillsLatestBlockKey = `${FILLS_LATEST_BLOCK}-${userAddress}-${networkId}`;
+		return userFillsLatestBlockKey;
+	},
+	_getFillHash(fill: Fill): string {
+		const fillJSON = JSON.stringify(fill);
+		const fillHash = ethUtil.sha256(fillJSON);
+		return fillHash.toString('hex');
+	},
 };
diff --git a/packages/website/ts/pages/about/about.tsx b/packages/website/ts/pages/about/about.tsx
index c929673f5..411456427 100644
--- a/packages/website/ts/pages/about/about.tsx
+++ b/packages/website/ts/pages/about/about.tsx
@@ -10,239 +10,239 @@ import { constants } from 'ts/utils/constants';
 import { utils } from 'ts/utils/utils';
 
 const teamRow1: ProfileInfo[] = [
-    {
-        name: 'Will Warren',
-        title: 'Co-founder & CEO',
-        description: `Smart contract R&D. Previously applied physics at Los Alamos \
+	{
+		name: 'Will Warren',
+		title: 'Co-founder & CEO',
+		description: `Smart contract R&D. Previously applied physics at Los Alamos \
                       Nat Lab. Mechanical engineering at UC San Diego. PhD dropout.`,
-        image: '/images/team/will.jpg',
-        linkedIn: 'https://www.linkedin.com/in/will-warren-92aab62b/',
-        github: 'https://github.com/willwarren89',
-        medium: 'https://medium.com/@willwarren89',
-    },
-    {
-        name: 'Amir Bandeali',
-        title: 'Co-founder & CTO',
-        description: `Smart contract R&D. Previously fixed income trader at DRW. \
+		image: '/images/team/will.jpg',
+		linkedIn: 'https://www.linkedin.com/in/will-warren-92aab62b/',
+		github: 'https://github.com/willwarren89',
+		medium: 'https://medium.com/@willwarren89',
+	},
+	{
+		name: 'Amir Bandeali',
+		title: 'Co-founder & CTO',
+		description: `Smart contract R&D. Previously fixed income trader at DRW. \
                       Finance at University of Illinois, Urbana-Champaign.`,
-        image: '/images/team/amir.jpeg',
-        linkedIn: 'https://www.linkedin.com/in/abandeali1/',
-        github: 'https://github.com/abandeali1',
-        medium: 'https://medium.com/@abandeali1',
-    },
-    {
-        name: 'Fabio Berger',
-        title: 'Senior Engineer',
-        description: `Full-stack blockchain engineer. Previously software engineer \
+		image: '/images/team/amir.jpeg',
+		linkedIn: 'https://www.linkedin.com/in/abandeali1/',
+		github: 'https://github.com/abandeali1',
+		medium: 'https://medium.com/@abandeali1',
+	},
+	{
+		name: 'Fabio Berger',
+		title: 'Senior Engineer',
+		description: `Full-stack blockchain engineer. Previously software engineer \
                       at Airtable and founder of WealthLift. Computer science at Duke.`,
-        image: '/images/team/fabio.jpg',
-        linkedIn: 'https://www.linkedin.com/in/fabio-berger-03ab261a/',
-        github: 'https://github.com/fabioberger',
-        medium: 'https://medium.com/@fabioberger',
-    },
+		image: '/images/team/fabio.jpg',
+		linkedIn: 'https://www.linkedin.com/in/fabio-berger-03ab261a/',
+		github: 'https://github.com/fabioberger',
+		medium: 'https://medium.com/@fabioberger',
+	},
 ];
 
 const teamRow2: ProfileInfo[] = [
-    {
-        name: 'Alex Xu',
-        title: 'Director of Operations',
-        description: `Strategy and operations. Previously digital marketing at Google \
+	{
+		name: 'Alex Xu',
+		title: 'Director of Operations',
+		description: `Strategy and operations. Previously digital marketing at Google \
                       and vendor management at Amazon. Economics at UC San Diego.`,
-        image: '/images/team/alex.jpg',
-        linkedIn: 'https://www.linkedin.com/in/alex-xu/',
-        github: '',
-        medium: 'https://medium.com/@aqxu',
-    },
-    {
-        name: 'Leonid Logvinov',
-        title: 'Engineer',
-        description: `Full-stack blockchain engineer. Previously blockchain engineer \
+		image: '/images/team/alex.jpg',
+		linkedIn: 'https://www.linkedin.com/in/alex-xu/',
+		github: '',
+		medium: 'https://medium.com/@aqxu',
+	},
+	{
+		name: 'Leonid Logvinov',
+		title: 'Engineer',
+		description: `Full-stack blockchain engineer. Previously blockchain engineer \
                       at Neufund. Computer science at University of Warsaw.`,
-        image: '/images/team/leonid.png',
-        linkedIn: 'https://www.linkedin.com/in/leonidlogvinov/',
-        github: 'https://github.com/LogvinovLeon',
-        medium: 'https://medium.com/@Logvinov',
-    },
-    {
-        name: 'Ben Burns',
-        title: 'Designer',
-        description: `Product, motion, and graphic designer. Previously designer \
+		image: '/images/team/leonid.png',
+		linkedIn: 'https://www.linkedin.com/in/leonidlogvinov/',
+		github: 'https://github.com/LogvinovLeon',
+		medium: 'https://medium.com/@Logvinov',
+	},
+	{
+		name: 'Ben Burns',
+		title: 'Designer',
+		description: `Product, motion, and graphic designer. Previously designer \
                       at Airtable and Apple. Digital Design at University of Cincinnati.`,
-        image: '/images/team/ben.jpg',
-        linkedIn: 'https://www.linkedin.com/in/ben-burns-30170478/',
-        github: '',
-        medium: '',
-    },
+		image: '/images/team/ben.jpg',
+		linkedIn: 'https://www.linkedin.com/in/ben-burns-30170478/',
+		github: '',
+		medium: '',
+	},
 ];
 
 const teamRow3: ProfileInfo[] = [
-    {
-        name: 'Brandon Millman',
-        title: 'Senior Engineer',
-        description: `Full-stack engineer. Previously senior software engineer at \
+	{
+		name: 'Brandon Millman',
+		title: 'Senior Engineer',
+		description: `Full-stack engineer. Previously senior software engineer at \
                       Twitter. Electrical and Computer Engineering at Duke.`,
-        image: '/images/team/brandon.png',
-        linkedIn: 'https://www.linkedin.com/in/brandon-millman-b093a022/',
-        github: 'https://github.com/BMillman19',
-        medium: 'https://medium.com/@bchillman',
-    },
-    {
-        name: 'Tom Schmidt',
-        title: 'Product Manager',
-        description: `Previously engineering at Apple, product management at Facebook and Instagram. Computer Science at Stanford.`,
-        image: '/images/team/tom.jpg',
-        linkedIn: 'https://www.linkedin.com/in/tomhschmidt/',
-        github: 'https://github.com/tomhschmidt',
-        medium: '',
-    },
-    {
-        name: 'Jacob Evans',
-        title: 'Blockchain Engineer',
-        description: `Previously software engineer at Qantas and RSA Security.`,
-        image: '/images/team/jacob.jpg',
-        linkedIn: 'https://www.linkedin.com/in/dekzter/',
-        github: 'https://github.com/dekz',
-        medium: '',
-    },
+		image: '/images/team/brandon.png',
+		linkedIn: 'https://www.linkedin.com/in/brandon-millman-b093a022/',
+		github: 'https://github.com/BMillman19',
+		medium: 'https://medium.com/@bchillman',
+	},
+	{
+		name: 'Tom Schmidt',
+		title: 'Product Manager',
+		description: `Previously engineering at Apple, product management at Facebook and Instagram. Computer Science at Stanford.`,
+		image: '/images/team/tom.jpg',
+		linkedIn: 'https://www.linkedin.com/in/tomhschmidt/',
+		github: 'https://github.com/tomhschmidt',
+		medium: '',
+	},
+	{
+		name: 'Jacob Evans',
+		title: 'Blockchain Engineer',
+		description: `Previously software engineer at Qantas and RSA Security.`,
+		image: '/images/team/jacob.jpg',
+		linkedIn: 'https://www.linkedin.com/in/dekzter/',
+		github: 'https://github.com/dekz',
+		medium: '',
+	},
 ];
 
 const advisors: ProfileInfo[] = [
-    {
-        name: 'Fred Ehrsam',
-        description: 'Co-founder of Coinbase. Previously FX trader at Goldman Sachs.',
-        image: '/images/advisors/fred.jpg',
-        linkedIn: 'https://www.linkedin.com/in/fredehrsam/',
-        medium: 'https://medium.com/@FEhrsam',
-        twitter: 'https://twitter.com/FEhrsam',
-    },
-    {
-        name: 'Olaf Carlson-Wee',
-        image: '/images/advisors/olaf.png',
-        description: 'Founder of Polychain Capital. First hire at Coinbase. Angel investor.',
-        linkedIn: 'https://www.linkedin.com/in/olafcw/',
-        angellist: 'https://angel.co/olafcw',
-    },
-    {
-        name: 'Joey Krug',
-        description: `Co-CIO at Pantera Capital. Founder of Augur. Thiel 20 Under 20 Fellow.`,
-        image: '/images/advisors/joey.jpg',
-        linkedIn: 'https://www.linkedin.com/in/joeykrug/',
-        github: 'https://github.com/joeykrug',
-        angellist: 'https://angel.co/joeykrug',
-    },
-    {
-        name: 'Linda Xie',
-        description: 'Co-founder of Scalar Capital. Previously PM at Coinbase.',
-        image: '/images/advisors/linda.jpg',
-        linkedIn: 'https://www.linkedin.com/in/lindaxie/',
-        medium: 'https://medium.com/@linda.xie',
-        twitter: 'https://twitter.com/ljxie',
-    },
+	{
+		name: 'Fred Ehrsam',
+		description: 'Co-founder of Coinbase. Previously FX trader at Goldman Sachs.',
+		image: '/images/advisors/fred.jpg',
+		linkedIn: 'https://www.linkedin.com/in/fredehrsam/',
+		medium: 'https://medium.com/@FEhrsam',
+		twitter: 'https://twitter.com/FEhrsam',
+	},
+	{
+		name: 'Olaf Carlson-Wee',
+		image: '/images/advisors/olaf.png',
+		description: 'Founder of Polychain Capital. First hire at Coinbase. Angel investor.',
+		linkedIn: 'https://www.linkedin.com/in/olafcw/',
+		angellist: 'https://angel.co/olafcw',
+	},
+	{
+		name: 'Joey Krug',
+		description: `Co-CIO at Pantera Capital. Founder of Augur. Thiel 20 Under 20 Fellow.`,
+		image: '/images/advisors/joey.jpg',
+		linkedIn: 'https://www.linkedin.com/in/joeykrug/',
+		github: 'https://github.com/joeykrug',
+		angellist: 'https://angel.co/joeykrug',
+	},
+	{
+		name: 'Linda Xie',
+		description: 'Co-founder of Scalar Capital. Previously PM at Coinbase.',
+		image: '/images/advisors/linda.jpg',
+		linkedIn: 'https://www.linkedin.com/in/lindaxie/',
+		medium: 'https://medium.com/@linda.xie',
+		twitter: 'https://twitter.com/ljxie',
+	},
 ];
 
 export interface AboutProps {
-    source: string;
-    location: Location;
+	source: string;
+	location: Location;
 }
 
 interface AboutState {}
 
 const styles: Styles = {
-    header: {
-        fontFamily: 'Roboto Mono',
-        fontSize: 36,
-        color: 'black',
-        paddingTop: 110,
-    },
-    weAreHiring: {
-        fontSize: 30,
-        color: colors.darkestGrey,
-        fontFamily: 'Roboto Mono',
-        letterSpacing: 7.5,
-    },
+	header: {
+		fontFamily: 'Roboto Mono',
+		fontSize: 36,
+		color: 'black',
+		paddingTop: 110,
+	},
+	weAreHiring: {
+		fontSize: 30,
+		color: colors.darkestGrey,
+		fontFamily: 'Roboto Mono',
+		letterSpacing: 7.5,
+	},
 };
 
 export class About extends React.Component<AboutProps, AboutState> {
-    public componentDidMount() {
-        window.scrollTo(0, 0);
-    }
-    public render() {
-        return (
-            <div style={{ backgroundColor: colors.lightestGrey }}>
-                <DocumentTitle title="0x About Us" />
-                <TopBar
-                    blockchainIsLoaded={false}
-                    location={this.props.location}
-                    style={{ backgroundColor: colors.lightestGrey }}
-                />
-                <div id="about" className="mx-auto max-width-4 py4" style={{ color: colors.grey800 }}>
-                    <div className="mx-auto pb4 sm-px3" style={{ maxWidth: 435 }}>
-                        <div style={styles.header}>About us:</div>
-                        <div
-                            className="pt3"
-                            style={{
-                                fontSize: 17,
-                                color: colors.darkestGrey,
-                                lineHeight: 1.5,
-                            }}
-                        >
-                            Our team is a diverse and globally distributed group with backgrounds in engineering,
-                            research, business and design. We are passionate about decentralized technology and its
-                            potential to act as an equalizing force in the world.
-                        </div>
-                    </div>
-                    <div className="pt3 md-px4 lg-px0">
-                        <div className="clearfix pb3">{this._renderProfiles(teamRow1)}</div>
-                        <div className="clearfix">{this._renderProfiles(teamRow2)}</div>
-                        <div className="clearfix">{this._renderProfiles(teamRow3)}</div>
-                    </div>
-                    <div className="pt3 pb2">
-                        <div
-                            className="pt2 pb3 sm-center md-pl4 lg-pl0 md-ml3"
-                            style={{
-                                color: colors.grey,
-                                fontSize: 24,
-                                fontFamily: 'Roboto Mono',
-                            }}
-                        >
-                            Advisors:
-                        </div>
-                        <div className="clearfix">{this._renderProfiles(advisors)}</div>
-                    </div>
-                    <div className="mx-auto py4 sm-px3" style={{ maxWidth: 308 }}>
-                        <div className="pb2" style={styles.weAreHiring}>
-                            WE'RE HIRING
-                        </div>
-                        <div
-                            className="pb4 mb4"
-                            style={{
-                                fontSize: 16,
-                                color: colors.darkestGrey,
-                                lineHeight: 1.5,
-                                letterSpacing: '0.5px',
-                            }}
-                        >
-                            We are seeking outstanding candidates to{' '}
-                            <a href={constants.URL_ANGELLIST} target="_blank" style={{ color: 'black' }}>
-                                join our team
-                            </a>
-                            . We value passion, diversity and unique perspectives.
-                        </div>
-                    </div>
-                </div>
-                <Footer />
-            </div>
-        );
-    }
-    private _renderProfiles(profiles: ProfileInfo[]) {
-        const numIndiv = profiles.length;
-        const colSize = utils.getColSize(numIndiv);
-        return _.map(profiles, profile => {
-            return (
-                <div key={`profile-${profile.name}`}>
-                    <Profile colSize={colSize} profileInfo={profile} />
-                </div>
-            );
-        });
-    }
+	public componentDidMount() {
+		window.scrollTo(0, 0);
+	}
+	public render() {
+		return (
+			<div style={{ backgroundColor: colors.lightestGrey }}>
+				<DocumentTitle title="0x About Us" />
+				<TopBar
+					blockchainIsLoaded={false}
+					location={this.props.location}
+					style={{ backgroundColor: colors.lightestGrey }}
+				/>
+				<div id="about" className="mx-auto max-width-4 py4" style={{ color: colors.grey800 }}>
+					<div className="mx-auto pb4 sm-px3" style={{ maxWidth: 435 }}>
+						<div style={styles.header}>About us:</div>
+						<div
+							className="pt3"
+							style={{
+								fontSize: 17,
+								color: colors.darkestGrey,
+								lineHeight: 1.5,
+							}}
+						>
+							Our team is a diverse and globally distributed group with backgrounds in engineering,
+							research, business and design. We are passionate about decentralized technology and its
+							potential to act as an equalizing force in the world.
+						</div>
+					</div>
+					<div className="pt3 md-px4 lg-px0">
+						<div className="clearfix pb3">{this._renderProfiles(teamRow1)}</div>
+						<div className="clearfix">{this._renderProfiles(teamRow2)}</div>
+						<div className="clearfix">{this._renderProfiles(teamRow3)}</div>
+					</div>
+					<div className="pt3 pb2">
+						<div
+							className="pt2 pb3 sm-center md-pl4 lg-pl0 md-ml3"
+							style={{
+								color: colors.grey,
+								fontSize: 24,
+								fontFamily: 'Roboto Mono',
+							}}
+						>
+							Advisors:
+						</div>
+						<div className="clearfix">{this._renderProfiles(advisors)}</div>
+					</div>
+					<div className="mx-auto py4 sm-px3" style={{ maxWidth: 308 }}>
+						<div className="pb2" style={styles.weAreHiring}>
+							WE'RE HIRING
+						</div>
+						<div
+							className="pb4 mb4"
+							style={{
+								fontSize: 16,
+								color: colors.darkestGrey,
+								lineHeight: 1.5,
+								letterSpacing: '0.5px',
+							}}
+						>
+							We are seeking outstanding candidates to{' '}
+							<a href={constants.URL_ANGELLIST} target="_blank" style={{ color: 'black' }}>
+								join our team
+							</a>
+							. We value passion, diversity and unique perspectives.
+						</div>
+					</div>
+				</div>
+				<Footer />
+			</div>
+		);
+	}
+	private _renderProfiles(profiles: ProfileInfo[]) {
+		const numIndiv = profiles.length;
+		const colSize = utils.getColSize(numIndiv);
+		return _.map(profiles, profile => {
+			return (
+				<div key={`profile-${profile.name}`}>
+					<Profile colSize={colSize} profileInfo={profile} />
+				</div>
+			);
+		});
+	}
 }
diff --git a/packages/website/ts/pages/about/profile.tsx b/packages/website/ts/pages/about/profile.tsx
index 18b4e0d5a..f1830851f 100644
--- a/packages/website/ts/pages/about/profile.tsx
+++ b/packages/website/ts/pages/about/profile.tsx
@@ -5,75 +5,75 @@ import { colors } from 'ts/utils/colors';
 
 const IMAGE_DIMENSION = 149;
 const styles: Styles = {
-    subheader: {
-        textTransform: 'uppercase',
-        fontSize: 32,
-        margin: 0,
-    },
-    imageContainer: {
-        width: IMAGE_DIMENSION,
-        height: IMAGE_DIMENSION,
-        boxShadow: 'rgba(0, 0, 0, 0.19) 2px 5px 10px',
-    },
+	subheader: {
+		textTransform: 'uppercase',
+		fontSize: 32,
+		margin: 0,
+	},
+	imageContainer: {
+		width: IMAGE_DIMENSION,
+		height: IMAGE_DIMENSION,
+		boxShadow: 'rgba(0, 0, 0, 0.19) 2px 5px 10px',
+	},
 };
 
 interface ProfileProps {
-    colSize: number;
-    profileInfo: ProfileInfo;
+	colSize: number;
+	profileInfo: ProfileInfo;
 }
 
 export function Profile(props: ProfileProps) {
-    return (
-        <div className={`lg-col md-col lg-col-${props.colSize} md-col-6`}>
-            <div style={{ maxWidth: 300 }} className="mx-auto lg-px3 md-px3 sm-px4 sm-pb3">
-                <div className="circle overflow-hidden mx-auto" style={styles.imageContainer}>
-                    <img width={IMAGE_DIMENSION} src={props.profileInfo.image} />
-                </div>
-                <div className="center" style={{ fontSize: 18, fontWeight: 'bold', paddingTop: 20 }}>
-                    {props.profileInfo.name}
-                </div>
-                {!_.isUndefined(props.profileInfo.title) && (
-                    <div
-                        className="pt1 center"
-                        style={{
-                            fontSize: 14,
-                            fontFamily: 'Roboto Mono',
-                            color: colors.darkGrey,
-                        }}
-                    >
-                        {props.profileInfo.title.toUpperCase()}
-                    </div>
-                )}
-                <div style={{ minHeight: 60, lineHeight: 1.4 }} className="pt1 pb2 mx-auto lg-h6 md-h6 sm-h5 sm-center">
-                    {props.profileInfo.description}
-                </div>
-                <div className="flex pb3 mx-auto sm-hide xs-hide" style={{ width: 280, opacity: 0.5 }}>
-                    {renderSocialMediaIcons(props.profileInfo)}
-                </div>
-            </div>
-        </div>
-    );
+	return (
+		<div className={`lg-col md-col lg-col-${props.colSize} md-col-6`}>
+			<div style={{ maxWidth: 300 }} className="mx-auto lg-px3 md-px3 sm-px4 sm-pb3">
+				<div className="circle overflow-hidden mx-auto" style={styles.imageContainer}>
+					<img width={IMAGE_DIMENSION} src={props.profileInfo.image} />
+				</div>
+				<div className="center" style={{ fontSize: 18, fontWeight: 'bold', paddingTop: 20 }}>
+					{props.profileInfo.name}
+				</div>
+				{!_.isUndefined(props.profileInfo.title) && (
+					<div
+						className="pt1 center"
+						style={{
+							fontSize: 14,
+							fontFamily: 'Roboto Mono',
+							color: colors.darkGrey,
+						}}
+					>
+						{props.profileInfo.title.toUpperCase()}
+					</div>
+				)}
+				<div style={{ minHeight: 60, lineHeight: 1.4 }} className="pt1 pb2 mx-auto lg-h6 md-h6 sm-h5 sm-center">
+					{props.profileInfo.description}
+				</div>
+				<div className="flex pb3 mx-auto sm-hide xs-hide" style={{ width: 280, opacity: 0.5 }}>
+					{renderSocialMediaIcons(props.profileInfo)}
+				</div>
+			</div>
+		</div>
+	);
 }
 
 function renderSocialMediaIcons(profileInfo: ProfileInfo) {
-    const icons = [
-        renderSocialMediaIcon('zmdi-github-box', profileInfo.github),
-        renderSocialMediaIcon('zmdi-linkedin-box', profileInfo.linkedIn),
-        renderSocialMediaIcon('zmdi-twitter-box', profileInfo.twitter),
-    ];
-    return icons;
+	const icons = [
+		renderSocialMediaIcon('zmdi-github-box', profileInfo.github),
+		renderSocialMediaIcon('zmdi-linkedin-box', profileInfo.linkedIn),
+		renderSocialMediaIcon('zmdi-twitter-box', profileInfo.twitter),
+	];
+	return icons;
 }
 
 function renderSocialMediaIcon(iconName: string, url: string) {
-    if (_.isEmpty(url)) {
-        return null;
-    }
+	if (_.isEmpty(url)) {
+		return null;
+	}
 
-    return (
-        <div key={url} className="pr1">
-            <a href={url} style={{ color: 'inherit' }} target="_blank" className="text-decoration-none">
-                <i className={`zmdi ${iconName}`} style={{ ...styles.socalIcon }} />
-            </a>
-        </div>
-    );
+	return (
+		<div key={url} className="pr1">
+			<a href={url} style={{ color: 'inherit' }} target="_blank" className="text-decoration-none">
+				<i className={`zmdi ${iconName}`} style={{ ...styles.socalIcon }} />
+			</a>
+		</div>
+	);
 }
diff --git a/packages/website/ts/pages/documentation/comment.tsx b/packages/website/ts/pages/documentation/comment.tsx
index 23cfd96bd..6be39f586 100644
--- a/packages/website/ts/pages/documentation/comment.tsx
+++ b/packages/website/ts/pages/documentation/comment.tsx
@@ -4,20 +4,20 @@ import * as ReactMarkdown from 'react-markdown';
 import { MarkdownCodeBlock } from 'ts/pages/shared/markdown_code_block';
 
 interface CommentProps {
-    comment: string;
-    className?: string;
+	comment: string;
+	className?: string;
 }
 
 const defaultProps = {
-    className: '',
+	className: '',
 };
 
 export const Comment: React.SFC<CommentProps> = (props: CommentProps) => {
-    return (
-        <div className={`${props.className} comment`}>
-            <ReactMarkdown source={props.comment} renderers={{ CodeBlock: MarkdownCodeBlock }} />
-        </div>
-    );
+	return (
+		<div className={`${props.className} comment`}>
+			<ReactMarkdown source={props.comment} renderers={{ CodeBlock: MarkdownCodeBlock }} />
+		</div>
+	);
 };
 
 Comment.defaultProps = defaultProps;
diff --git a/packages/website/ts/pages/documentation/custom_enum.tsx b/packages/website/ts/pages/documentation/custom_enum.tsx
index 8d50a2f52..0006b8d7e 100644
--- a/packages/website/ts/pages/documentation/custom_enum.tsx
+++ b/packages/website/ts/pages/documentation/custom_enum.tsx
@@ -6,27 +6,27 @@ import { utils } from 'ts/utils/utils';
 const STRING_ENUM_CODE_PREFIX = ' strEnum(';
 
 interface CustomEnumProps {
-    type: CustomType;
+	type: CustomType;
 }
 
 // This component renders custom string enums that was a work-around for versions of
 // TypeScript <2.4.0 that did not support them natively. We keep it around to support
 // older versions of 0x.js <0.9.0
 export function CustomEnum(props: CustomEnumProps) {
-    const type = props.type;
-    if (!_.startsWith(type.defaultValue, STRING_ENUM_CODE_PREFIX)) {
-        utils.consoleLog('We do not yet support `Variable` types that are not strEnums');
-        return null;
-    }
-    // Remove the prefix and postfix, leaving only the strEnum values without quotes.
-    const enumValues = type.defaultValue.slice(10, -3).replace(/'/g, '');
-    return (
-        <span>
-            {`{`}
-            {'\t'}
-            {enumValues}
-            <br />
-            {`}`}
-        </span>
-    );
+	const type = props.type;
+	if (!_.startsWith(type.defaultValue, STRING_ENUM_CODE_PREFIX)) {
+		utils.consoleLog('We do not yet support `Variable` types that are not strEnums');
+		return null;
+	}
+	// Remove the prefix and postfix, leaving only the strEnum values without quotes.
+	const enumValues = type.defaultValue.slice(10, -3).replace(/'/g, '');
+	return (
+		<span>
+			{`{`}
+			{'\t'}
+			{enumValues}
+			<br />
+			{`}`}
+		</span>
+	);
 }
diff --git a/packages/website/ts/pages/documentation/docs_info.ts b/packages/website/ts/pages/documentation/docs_info.ts
index 4b1ec122a..e1080f3a0 100644
--- a/packages/website/ts/pages/documentation/docs_info.ts
+++ b/packages/website/ts/pages/documentation/docs_info.ts
@@ -1,111 +1,111 @@
 import compareVersions = require('compare-versions');
 import * as _ from 'lodash';
 import {
-    DocAgnosticFormat,
-    DocsInfoConfig,
-    DocsMenu,
-    DoxityDocObj,
-    MenuSubsectionsBySection,
-    SectionsMap,
-    TypeDocNode,
+	DocAgnosticFormat,
+	DocsInfoConfig,
+	DocsMenu,
+	DoxityDocObj,
+	MenuSubsectionsBySection,
+	SectionsMap,
+	TypeDocNode,
 } from 'ts/types';
 
 export class DocsInfo {
-    public displayName: string;
-    public packageUrl: string;
-    public subPackageName?: string;
-    public websitePath: string;
-    public docsJsonRoot: string;
-    public menu: DocsMenu;
-    public sections: SectionsMap;
-    public sectionNameToMarkdown: { [sectionName: string]: string };
-    private _docsInfo: DocsInfoConfig;
-    constructor(config: DocsInfoConfig) {
-        this.displayName = config.displayName;
-        this.packageUrl = config.packageUrl;
-        this.subPackageName = config.subPackageName;
-        this.websitePath = config.websitePath;
-        this.docsJsonRoot = config.docsJsonRoot;
-        this.sections = config.sections;
-        this.sectionNameToMarkdown = config.sectionNameToMarkdown;
-        this._docsInfo = config;
-    }
-    public isPublicType(typeName: string): boolean {
-        if (_.isUndefined(this._docsInfo.publicTypes)) {
-            return false;
-        }
-        const isPublic = _.includes(this._docsInfo.publicTypes, typeName);
-        return isPublic;
-    }
-    public getModulePathsIfExists(sectionName: string): string[] {
-        const modulePathsIfExists = this._docsInfo.sectionNameToModulePath[sectionName];
-        return modulePathsIfExists;
-    }
-    public getMenu(selectedVersion?: string): { [section: string]: string[] } {
-        if (_.isUndefined(selectedVersion) || _.isUndefined(this._docsInfo.menuSubsectionToVersionWhenIntroduced)) {
-            return this._docsInfo.menu;
-        }
+	public displayName: string;
+	public packageUrl: string;
+	public subPackageName?: string;
+	public websitePath: string;
+	public docsJsonRoot: string;
+	public menu: DocsMenu;
+	public sections: SectionsMap;
+	public sectionNameToMarkdown: { [sectionName: string]: string };
+	private _docsInfo: DocsInfoConfig;
+	constructor(config: DocsInfoConfig) {
+		this.displayName = config.displayName;
+		this.packageUrl = config.packageUrl;
+		this.subPackageName = config.subPackageName;
+		this.websitePath = config.websitePath;
+		this.docsJsonRoot = config.docsJsonRoot;
+		this.sections = config.sections;
+		this.sectionNameToMarkdown = config.sectionNameToMarkdown;
+		this._docsInfo = config;
+	}
+	public isPublicType(typeName: string): boolean {
+		if (_.isUndefined(this._docsInfo.publicTypes)) {
+			return false;
+		}
+		const isPublic = _.includes(this._docsInfo.publicTypes, typeName);
+		return isPublic;
+	}
+	public getModulePathsIfExists(sectionName: string): string[] {
+		const modulePathsIfExists = this._docsInfo.sectionNameToModulePath[sectionName];
+		return modulePathsIfExists;
+	}
+	public getMenu(selectedVersion?: string): { [section: string]: string[] } {
+		if (_.isUndefined(selectedVersion) || _.isUndefined(this._docsInfo.menuSubsectionToVersionWhenIntroduced)) {
+			return this._docsInfo.menu;
+		}
 
-        const finalMenu = _.cloneDeep(this._docsInfo.menu);
-        if (_.isUndefined(finalMenu.contracts)) {
-            return finalMenu;
-        }
+		const finalMenu = _.cloneDeep(this._docsInfo.menu);
+		if (_.isUndefined(finalMenu.contracts)) {
+			return finalMenu;
+		}
 
-        // TODO: refactor to include more sections then simply the `contracts` section
-        finalMenu.contracts = _.filter(finalMenu.contracts, (contractName: string) => {
-            const versionIntroducedIfExists = this._docsInfo.menuSubsectionToVersionWhenIntroduced[contractName];
-            if (!_.isUndefined(versionIntroducedIfExists)) {
-                const existsInSelectedVersion = compareVersions(selectedVersion, versionIntroducedIfExists) >= 0;
-                return existsInSelectedVersion;
-            } else {
-                return true;
-            }
-        });
-        return finalMenu;
-    }
-    public getMenuSubsectionsBySection(docAgnosticFormat?: DocAgnosticFormat): MenuSubsectionsBySection {
-        const menuSubsectionsBySection = {} as MenuSubsectionsBySection;
-        if (_.isUndefined(docAgnosticFormat)) {
-            return menuSubsectionsBySection;
-        }
+		// TODO: refactor to include more sections then simply the `contracts` section
+		finalMenu.contracts = _.filter(finalMenu.contracts, (contractName: string) => {
+			const versionIntroducedIfExists = this._docsInfo.menuSubsectionToVersionWhenIntroduced[contractName];
+			if (!_.isUndefined(versionIntroducedIfExists)) {
+				const existsInSelectedVersion = compareVersions(selectedVersion, versionIntroducedIfExists) >= 0;
+				return existsInSelectedVersion;
+			} else {
+				return true;
+			}
+		});
+		return finalMenu;
+	}
+	public getMenuSubsectionsBySection(docAgnosticFormat?: DocAgnosticFormat): MenuSubsectionsBySection {
+		const menuSubsectionsBySection = {} as MenuSubsectionsBySection;
+		if (_.isUndefined(docAgnosticFormat)) {
+			return menuSubsectionsBySection;
+		}
 
-        const docSections = _.keys(this.sections);
-        _.each(docSections, sectionName => {
-            const docSection = docAgnosticFormat[sectionName];
-            if (_.isUndefined(docSection)) {
-                return; // no-op
-            }
+		const docSections = _.keys(this.sections);
+		_.each(docSections, sectionName => {
+			const docSection = docAgnosticFormat[sectionName];
+			if (_.isUndefined(docSection)) {
+				return; // no-op
+			}
 
-            if (!_.isUndefined(this.sections.types) && sectionName === this.sections.types) {
-                const sortedTypesNames = _.sortBy(docSection.types, 'name');
-                const typeNames = _.map(sortedTypesNames, t => t.name);
-                menuSubsectionsBySection[sectionName] = typeNames;
-            } else {
-                let eventNames: string[] = [];
-                if (!_.isUndefined(docSection.events)) {
-                    const sortedEventNames = _.sortBy(docSection.events, 'name');
-                    eventNames = _.map(sortedEventNames, m => m.name);
-                }
-                const sortedMethodNames = _.sortBy(docSection.methods, 'name');
-                const methodNames = _.map(sortedMethodNames, m => m.name);
-                menuSubsectionsBySection[sectionName] = [...methodNames, ...eventNames];
-            }
-        });
-        return menuSubsectionsBySection;
-    }
-    public getTypeDefinitionsByName(docAgnosticFormat: DocAgnosticFormat) {
-        if (_.isUndefined(this.sections.types)) {
-            return {};
-        }
+			if (!_.isUndefined(this.sections.types) && sectionName === this.sections.types) {
+				const sortedTypesNames = _.sortBy(docSection.types, 'name');
+				const typeNames = _.map(sortedTypesNames, t => t.name);
+				menuSubsectionsBySection[sectionName] = typeNames;
+			} else {
+				let eventNames: string[] = [];
+				if (!_.isUndefined(docSection.events)) {
+					const sortedEventNames = _.sortBy(docSection.events, 'name');
+					eventNames = _.map(sortedEventNames, m => m.name);
+				}
+				const sortedMethodNames = _.sortBy(docSection.methods, 'name');
+				const methodNames = _.map(sortedMethodNames, m => m.name);
+				menuSubsectionsBySection[sectionName] = [...methodNames, ...eventNames];
+			}
+		});
+		return menuSubsectionsBySection;
+	}
+	public getTypeDefinitionsByName(docAgnosticFormat: DocAgnosticFormat) {
+		if (_.isUndefined(this.sections.types)) {
+			return {};
+		}
 
-        const typeDocSection = docAgnosticFormat[this.sections.types];
-        const typeDefinitionByName = _.keyBy(typeDocSection.types, 'name');
-        return typeDefinitionByName;
-    }
-    public isVisibleConstructor(sectionName: string): boolean {
-        return _.includes(this._docsInfo.visibleConstructors, sectionName);
-    }
-    public convertToDocAgnosticFormat(docObj: DoxityDocObj | TypeDocNode): DocAgnosticFormat {
-        return this._docsInfo.convertToDocAgnosticFormatFn(docObj, this);
-    }
+		const typeDocSection = docAgnosticFormat[this.sections.types];
+		const typeDefinitionByName = _.keyBy(typeDocSection.types, 'name');
+		return typeDefinitionByName;
+	}
+	public isVisibleConstructor(sectionName: string): boolean {
+		return _.includes(this._docsInfo.visibleConstructors, sectionName);
+	}
+	public convertToDocAgnosticFormat(docObj: DoxityDocObj | TypeDocNode): DocAgnosticFormat {
+		return this._docsInfo.convertToDocAgnosticFormatFn(docObj, this);
+	}
 }
diff --git a/packages/website/ts/pages/documentation/documentation.tsx b/packages/website/ts/pages/documentation/documentation.tsx
index 2315847ad..0fc41d775 100644
--- a/packages/website/ts/pages/documentation/documentation.tsx
+++ b/packages/website/ts/pages/documentation/documentation.tsx
@@ -19,17 +19,17 @@ import { NestedSidebarMenu } from 'ts/pages/shared/nested_sidebar_menu';
 import { SectionHeader } from 'ts/pages/shared/section_header';
 import { Dispatcher } from 'ts/redux/dispatcher';
 import {
-    AddressByContractName,
-    DocAgnosticFormat,
-    DoxityDocObj,
-    EtherscanLinkSuffixes,
-    Event,
-    Networks,
-    Property,
-    SolidityMethod,
-    Styles,
-    TypeDefinitionByName,
-    TypescriptMethod,
+	AddressByContractName,
+	DocAgnosticFormat,
+	DoxityDocObj,
+	EtherscanLinkSuffixes,
+	Event,
+	Networks,
+	Property,
+	SolidityMethod,
+	Styles,
+	TypeDefinitionByName,
+	TypescriptMethod,
 } from 'ts/types';
 import { colors } from 'ts/utils/colors';
 import { configs } from 'ts/utils/configs';
@@ -40,340 +40,340 @@ import { utils } from 'ts/utils/utils';
 const SCROLL_TOP_ID = 'docsScrollTop';
 
 const networkNameToColor: { [network: string]: string } = {
-    [Networks.kovan]: colors.purple,
-    [Networks.ropsten]: colors.red,
-    [Networks.mainnet]: colors.turquois,
+	[Networks.kovan]: colors.purple,
+	[Networks.ropsten]: colors.red,
+	[Networks.mainnet]: colors.turquois,
 };
 
 export interface DocumentationAllProps {
-    source: string;
-    location: Location;
-    dispatcher: Dispatcher;
-    docsVersion: string;
-    availableDocVersions: string[];
-    docsInfo: DocsInfo;
+	source: string;
+	location: Location;
+	dispatcher: Dispatcher;
+	docsVersion: string;
+	availableDocVersions: string[];
+	docsInfo: DocsInfo;
 }
 
 interface DocumentationState {
-    docAgnosticFormat?: DocAgnosticFormat;
+	docAgnosticFormat?: DocAgnosticFormat;
 }
 
 const styles: Styles = {
-    mainContainers: {
-        position: 'absolute',
-        top: 1,
-        left: 0,
-        bottom: 0,
-        right: 0,
-        overflowZ: 'hidden',
-        overflowY: 'scroll',
-        minHeight: 'calc(100vh - 1px)',
-        WebkitOverflowScrolling: 'touch',
-    },
-    menuContainer: {
-        borderColor: colors.grey300,
-        maxWidth: 330,
-        marginLeft: 20,
-    },
+	mainContainers: {
+		position: 'absolute',
+		top: 1,
+		left: 0,
+		bottom: 0,
+		right: 0,
+		overflowZ: 'hidden',
+		overflowY: 'scroll',
+		minHeight: 'calc(100vh - 1px)',
+		WebkitOverflowScrolling: 'touch',
+	},
+	menuContainer: {
+		borderColor: colors.grey300,
+		maxWidth: 330,
+		marginLeft: 20,
+	},
 };
 
 export class Documentation extends React.Component<DocumentationAllProps, DocumentationState> {
-    constructor(props: DocumentationAllProps) {
-        super(props);
-        this.state = {
-            docAgnosticFormat: undefined,
-        };
-    }
-    public componentWillMount() {
-        const pathName = this.props.location.pathname;
-        const lastSegment = pathName.substr(pathName.lastIndexOf('/') + 1);
-        const versions = findVersions(lastSegment);
-        const preferredVersionIfExists = versions.length > 0 ? versions[0] : undefined;
-        // tslint:disable-next-line:no-floating-promises
-        this._fetchJSONDocsFireAndForgetAsync(preferredVersionIfExists);
-    }
-    public render() {
-        const menuSubsectionsBySection = _.isUndefined(this.state.docAgnosticFormat)
-            ? {}
-            : this.props.docsInfo.getMenuSubsectionsBySection(this.state.docAgnosticFormat);
-        return (
-            <div>
-                <DocumentTitle title={`${this.props.docsInfo.displayName} Documentation`} />
-                <TopBar
-                    blockchainIsLoaded={false}
-                    location={this.props.location}
-                    docsVersion={this.props.docsVersion}
-                    availableDocVersions={this.props.availableDocVersions}
-                    menu={this.props.docsInfo.getMenu(this.props.docsVersion)}
-                    menuSubsectionsBySection={menuSubsectionsBySection}
-                    shouldFullWidth={true}
-                    docsInfo={this.props.docsInfo}
-                />
-                {_.isUndefined(this.state.docAgnosticFormat) ? (
-                    <div className="col col-12" style={styles.mainContainers}>
-                        <div
-                            className="relative sm-px2 sm-pt2 sm-m1"
-                            style={{ height: 122, top: '50%', transform: 'translateY(-50%)' }}
-                        >
-                            <div className="center pb2">
-                                <CircularProgress size={40} thickness={5} />
-                            </div>
-                            <div className="center pt2" style={{ paddingBottom: 11 }}>
-                                Loading documentation...
-                            </div>
-                        </div>
-                    </div>
-                ) : (
-                    <div className="mx-auto flex" style={{ color: colors.grey800, height: 43 }}>
-                        <div className="relative col md-col-3 lg-col-3 lg-pl0 md-pl1 sm-hide xs-hide">
-                            <div
-                                className="border-right absolute"
-                                style={{ ...styles.menuContainer, ...styles.mainContainers }}
-                            >
-                                <NestedSidebarMenu
-                                    selectedVersion={this.props.docsVersion}
-                                    versions={this.props.availableDocVersions}
-                                    topLevelMenu={this.props.docsInfo.getMenu(this.props.docsVersion)}
-                                    menuSubsectionsBySection={menuSubsectionsBySection}
-                                    docPath={this.props.docsInfo.websitePath}
-                                />
-                            </div>
-                        </div>
-                        <div className="relative col lg-col-9 md-col-9 sm-col-12 col-12">
-                            <div id="documentation" style={styles.mainContainers} className="absolute">
-                                <div id={SCROLL_TOP_ID} />
-                                <h1 className="md-pl2 sm-pl3">
-                                    <a href={this.props.docsInfo.packageUrl} target="_blank">
-                                        {this.props.docsInfo.displayName}
-                                    </a>
-                                </h1>
-                                {this._renderDocumentation()}
-                            </div>
-                        </div>
-                    </div>
-                )}
-            </div>
-        );
-    }
-    private _renderDocumentation(): React.ReactNode {
-        const subMenus = _.values(this.props.docsInfo.getMenu());
-        const orderedSectionNames = _.flatten(subMenus);
+	constructor(props: DocumentationAllProps) {
+		super(props);
+		this.state = {
+			docAgnosticFormat: undefined,
+		};
+	}
+	public componentWillMount() {
+		const pathName = this.props.location.pathname;
+		const lastSegment = pathName.substr(pathName.lastIndexOf('/') + 1);
+		const versions = findVersions(lastSegment);
+		const preferredVersionIfExists = versions.length > 0 ? versions[0] : undefined;
+		// tslint:disable-next-line:no-floating-promises
+		this._fetchJSONDocsFireAndForgetAsync(preferredVersionIfExists);
+	}
+	public render() {
+		const menuSubsectionsBySection = _.isUndefined(this.state.docAgnosticFormat)
+			? {}
+			: this.props.docsInfo.getMenuSubsectionsBySection(this.state.docAgnosticFormat);
+		return (
+			<div>
+				<DocumentTitle title={`${this.props.docsInfo.displayName} Documentation`} />
+				<TopBar
+					blockchainIsLoaded={false}
+					location={this.props.location}
+					docsVersion={this.props.docsVersion}
+					availableDocVersions={this.props.availableDocVersions}
+					menu={this.props.docsInfo.getMenu(this.props.docsVersion)}
+					menuSubsectionsBySection={menuSubsectionsBySection}
+					shouldFullWidth={true}
+					docsInfo={this.props.docsInfo}
+				/>
+				{_.isUndefined(this.state.docAgnosticFormat) ? (
+					<div className="col col-12" style={styles.mainContainers}>
+						<div
+							className="relative sm-px2 sm-pt2 sm-m1"
+							style={{ height: 122, top: '50%', transform: 'translateY(-50%)' }}
+						>
+							<div className="center pb2">
+								<CircularProgress size={40} thickness={5} />
+							</div>
+							<div className="center pt2" style={{ paddingBottom: 11 }}>
+								Loading documentation...
+							</div>
+						</div>
+					</div>
+				) : (
+					<div className="mx-auto flex" style={{ color: colors.grey800, height: 43 }}>
+						<div className="relative col md-col-3 lg-col-3 lg-pl0 md-pl1 sm-hide xs-hide">
+							<div
+								className="border-right absolute"
+								style={{ ...styles.menuContainer, ...styles.mainContainers }}
+							>
+								<NestedSidebarMenu
+									selectedVersion={this.props.docsVersion}
+									versions={this.props.availableDocVersions}
+									topLevelMenu={this.props.docsInfo.getMenu(this.props.docsVersion)}
+									menuSubsectionsBySection={menuSubsectionsBySection}
+									docPath={this.props.docsInfo.websitePath}
+								/>
+							</div>
+						</div>
+						<div className="relative col lg-col-9 md-col-9 sm-col-12 col-12">
+							<div id="documentation" style={styles.mainContainers} className="absolute">
+								<div id={SCROLL_TOP_ID} />
+								<h1 className="md-pl2 sm-pl3">
+									<a href={this.props.docsInfo.packageUrl} target="_blank">
+										{this.props.docsInfo.displayName}
+									</a>
+								</h1>
+								{this._renderDocumentation()}
+							</div>
+						</div>
+					</div>
+				)}
+			</div>
+		);
+	}
+	private _renderDocumentation(): React.ReactNode {
+		const subMenus = _.values(this.props.docsInfo.getMenu());
+		const orderedSectionNames = _.flatten(subMenus);
 
-        const typeDefinitionByName = this.props.docsInfo.getTypeDefinitionsByName(this.state.docAgnosticFormat);
-        const renderedSections = _.map(orderedSectionNames, this._renderSection.bind(this, typeDefinitionByName));
+		const typeDefinitionByName = this.props.docsInfo.getTypeDefinitionsByName(this.state.docAgnosticFormat);
+		const renderedSections = _.map(orderedSectionNames, this._renderSection.bind(this, typeDefinitionByName));
 
-        return renderedSections;
-    }
-    private _renderSection(typeDefinitionByName: TypeDefinitionByName, sectionName: string): React.ReactNode {
-        const markdownFileIfExists = this.props.docsInfo.sectionNameToMarkdown[sectionName];
-        if (!_.isUndefined(markdownFileIfExists)) {
-            return (
-                <MarkdownSection
-                    key={`markdown-section-${sectionName}`}
-                    sectionName={sectionName}
-                    markdownContent={markdownFileIfExists}
-                />
-            );
-        }
+		return renderedSections;
+	}
+	private _renderSection(typeDefinitionByName: TypeDefinitionByName, sectionName: string): React.ReactNode {
+		const markdownFileIfExists = this.props.docsInfo.sectionNameToMarkdown[sectionName];
+		if (!_.isUndefined(markdownFileIfExists)) {
+			return (
+				<MarkdownSection
+					key={`markdown-section-${sectionName}`}
+					sectionName={sectionName}
+					markdownContent={markdownFileIfExists}
+				/>
+			);
+		}
 
-        const docSection = this.state.docAgnosticFormat[sectionName];
-        if (_.isUndefined(docSection)) {
-            return null;
-        }
+		const docSection = this.state.docAgnosticFormat[sectionName];
+		if (_.isUndefined(docSection)) {
+			return null;
+		}
 
-        const sortedTypes = _.sortBy(docSection.types, 'name');
-        const typeDefs = _.map(sortedTypes, customType => {
-            return (
-                <TypeDefinition
-                    sectionName={sectionName}
-                    key={`type-${customType.name}`}
-                    customType={customType}
-                    docsInfo={this.props.docsInfo}
-                />
-            );
-        });
+		const sortedTypes = _.sortBy(docSection.types, 'name');
+		const typeDefs = _.map(sortedTypes, customType => {
+			return (
+				<TypeDefinition
+					sectionName={sectionName}
+					key={`type-${customType.name}`}
+					customType={customType}
+					docsInfo={this.props.docsInfo}
+				/>
+			);
+		});
 
-        const sortedProperties = _.sortBy(docSection.properties, 'name');
-        const propertyDefs = _.map(sortedProperties, this._renderProperty.bind(this, sectionName));
+		const sortedProperties = _.sortBy(docSection.properties, 'name');
+		const propertyDefs = _.map(sortedProperties, this._renderProperty.bind(this, sectionName));
 
-        const sortedMethods = _.sortBy(docSection.methods, 'name');
-        const methodDefs = _.map(sortedMethods, method => {
-            const isConstructor = false;
-            return this._renderMethodBlocks(method, sectionName, isConstructor, typeDefinitionByName);
-        });
+		const sortedMethods = _.sortBy(docSection.methods, 'name');
+		const methodDefs = _.map(sortedMethods, method => {
+			const isConstructor = false;
+			return this._renderMethodBlocks(method, sectionName, isConstructor, typeDefinitionByName);
+		});
 
-        const sortedEvents = _.sortBy(docSection.events, 'name');
-        const eventDefs = _.map(sortedEvents, (event: Event, i: number) => {
-            return (
-                <EventDefinition
-                    key={`event-${event.name}-${i}`}
-                    event={event}
-                    sectionName={sectionName}
-                    docsInfo={this.props.docsInfo}
-                />
-            );
-        });
-        return (
-            <div key={`section-${sectionName}`} className="py2 pr3 md-pl2 sm-pl3">
-                <div className="flex">
-                    <div style={{ marginRight: 7 }}>
-                        <SectionHeader sectionName={sectionName} />
-                    </div>
-                    {this._renderNetworkBadgesIfExists(sectionName)}
-                </div>
-                {docSection.comment && <Comment comment={docSection.comment} />}
-                {docSection.constructors.length > 0 &&
-                    this.props.docsInfo.isVisibleConstructor(sectionName) && (
-                        <div>
-                            <h2 className="thin">Constructor</h2>
-                            {this._renderConstructors(docSection.constructors, sectionName, typeDefinitionByName)}
-                        </div>
-                    )}
-                {docSection.properties.length > 0 && (
-                    <div>
-                        <h2 className="thin">Properties</h2>
-                        <div>{propertyDefs}</div>
-                    </div>
-                )}
-                {docSection.methods.length > 0 && (
-                    <div>
-                        <h2 className="thin">Methods</h2>
-                        <div>{methodDefs}</div>
-                    </div>
-                )}
-                {!_.isUndefined(docSection.events) &&
-                    docSection.events.length > 0 && (
-                        <div>
-                            <h2 className="thin">Events</h2>
-                            <div>{eventDefs}</div>
-                        </div>
-                    )}
-                {!_.isUndefined(typeDefs) &&
-                    typeDefs.length > 0 && (
-                        <div>
-                            <div>{typeDefs}</div>
-                        </div>
-                    )}
-            </div>
-        );
-    }
-    private _renderNetworkBadgesIfExists(sectionName: string) {
-        const networkToAddressByContractName = configs.CONTRACT_ADDRESS[this.props.docsVersion];
-        const badges = _.map(
-            networkToAddressByContractName,
-            (addressByContractName: AddressByContractName, networkName: string) => {
-                const contractAddress = addressByContractName[sectionName];
-                if (_.isUndefined(contractAddress)) {
-                    return null;
-                }
-                const linkIfExists = utils.getEtherScanLinkIfExists(
-                    contractAddress,
-                    constants.NETWORK_ID_BY_NAME[networkName],
-                    EtherscanLinkSuffixes.Address,
-                );
-                return (
-                    <a
-                        key={`badge-${networkName}-${sectionName}`}
-                        href={linkIfExists}
-                        target="_blank"
-                        style={{ color: colors.white, textDecoration: 'none' }}
-                    >
-                        <Badge title={networkName} backgroundColor={networkNameToColor[networkName]} />
-                    </a>
-                );
-            },
-        );
-        return badges;
-    }
-    private _renderConstructors(
-        constructors: SolidityMethod[] | TypescriptMethod[],
-        sectionName: string,
-        typeDefinitionByName: TypeDefinitionByName,
-    ): React.ReactNode {
-        const constructorDefs = _.map(constructors, constructor => {
-            return this._renderMethodBlocks(constructor, sectionName, constructor.isConstructor, typeDefinitionByName);
-        });
-        return <div>{constructorDefs}</div>;
-    }
-    private _renderProperty(sectionName: string, property: Property): React.ReactNode {
-        return (
-            <div key={`property-${property.name}-${property.type.name}`} className="pb3">
-                <code className="hljs">
-                    {property.name}:
-                    <Type type={property.type} sectionName={sectionName} docsInfo={this.props.docsInfo} />
-                </code>
-                {property.source && (
-                    <SourceLink
-                        version={this.props.docsVersion}
-                        source={property.source}
-                        baseUrl={this.props.docsInfo.packageUrl}
-                        subPackageName={this.props.docsInfo.subPackageName}
-                    />
-                )}
-                {property.comment && <Comment comment={property.comment} className="py2" />}
-            </div>
-        );
-    }
-    private _renderMethodBlocks(
-        method: SolidityMethod | TypescriptMethod,
-        sectionName: string,
-        isConstructor: boolean,
-        typeDefinitionByName: TypeDefinitionByName,
-    ): React.ReactNode {
-        return (
-            <MethodBlock
-                key={`method-${method.name}-${sectionName}`}
-                sectionName={sectionName}
-                method={method}
-                typeDefinitionByName={typeDefinitionByName}
-                libraryVersion={this.props.docsVersion}
-                docsInfo={this.props.docsInfo}
-            />
-        );
-    }
-    private _scrollToHash(): void {
-        const hashWithPrefix = this.props.location.hash;
-        let hash = hashWithPrefix.slice(1);
-        if (_.isEmpty(hash)) {
-            hash = SCROLL_TOP_ID; // scroll to the top
-        }
+		const sortedEvents = _.sortBy(docSection.events, 'name');
+		const eventDefs = _.map(sortedEvents, (event: Event, i: number) => {
+			return (
+				<EventDefinition
+					key={`event-${event.name}-${i}`}
+					event={event}
+					sectionName={sectionName}
+					docsInfo={this.props.docsInfo}
+				/>
+			);
+		});
+		return (
+			<div key={`section-${sectionName}`} className="py2 pr3 md-pl2 sm-pl3">
+				<div className="flex">
+					<div style={{ marginRight: 7 }}>
+						<SectionHeader sectionName={sectionName} />
+					</div>
+					{this._renderNetworkBadgesIfExists(sectionName)}
+				</div>
+				{docSection.comment && <Comment comment={docSection.comment} />}
+				{docSection.constructors.length > 0 &&
+					this.props.docsInfo.isVisibleConstructor(sectionName) && (
+						<div>
+							<h2 className="thin">Constructor</h2>
+							{this._renderConstructors(docSection.constructors, sectionName, typeDefinitionByName)}
+						</div>
+					)}
+				{docSection.properties.length > 0 && (
+					<div>
+						<h2 className="thin">Properties</h2>
+						<div>{propertyDefs}</div>
+					</div>
+				)}
+				{docSection.methods.length > 0 && (
+					<div>
+						<h2 className="thin">Methods</h2>
+						<div>{methodDefs}</div>
+					</div>
+				)}
+				{!_.isUndefined(docSection.events) &&
+					docSection.events.length > 0 && (
+						<div>
+							<h2 className="thin">Events</h2>
+							<div>{eventDefs}</div>
+						</div>
+					)}
+				{!_.isUndefined(typeDefs) &&
+					typeDefs.length > 0 && (
+						<div>
+							<div>{typeDefs}</div>
+						</div>
+					)}
+			</div>
+		);
+	}
+	private _renderNetworkBadgesIfExists(sectionName: string) {
+		const networkToAddressByContractName = configs.CONTRACT_ADDRESS[this.props.docsVersion];
+		const badges = _.map(
+			networkToAddressByContractName,
+			(addressByContractName: AddressByContractName, networkName: string) => {
+				const contractAddress = addressByContractName[sectionName];
+				if (_.isUndefined(contractAddress)) {
+					return null;
+				}
+				const linkIfExists = utils.getEtherScanLinkIfExists(
+					contractAddress,
+					constants.NETWORK_ID_BY_NAME[networkName],
+					EtherscanLinkSuffixes.Address,
+				);
+				return (
+					<a
+						key={`badge-${networkName}-${sectionName}`}
+						href={linkIfExists}
+						target="_blank"
+						style={{ color: colors.white, textDecoration: 'none' }}
+					>
+						<Badge title={networkName} backgroundColor={networkNameToColor[networkName]} />
+					</a>
+				);
+			},
+		);
+		return badges;
+	}
+	private _renderConstructors(
+		constructors: SolidityMethod[] | TypescriptMethod[],
+		sectionName: string,
+		typeDefinitionByName: TypeDefinitionByName,
+	): React.ReactNode {
+		const constructorDefs = _.map(constructors, constructor => {
+			return this._renderMethodBlocks(constructor, sectionName, constructor.isConstructor, typeDefinitionByName);
+		});
+		return <div>{constructorDefs}</div>;
+	}
+	private _renderProperty(sectionName: string, property: Property): React.ReactNode {
+		return (
+			<div key={`property-${property.name}-${property.type.name}`} className="pb3">
+				<code className="hljs">
+					{property.name}:
+					<Type type={property.type} sectionName={sectionName} docsInfo={this.props.docsInfo} />
+				</code>
+				{property.source && (
+					<SourceLink
+						version={this.props.docsVersion}
+						source={property.source}
+						baseUrl={this.props.docsInfo.packageUrl}
+						subPackageName={this.props.docsInfo.subPackageName}
+					/>
+				)}
+				{property.comment && <Comment comment={property.comment} className="py2" />}
+			</div>
+		);
+	}
+	private _renderMethodBlocks(
+		method: SolidityMethod | TypescriptMethod,
+		sectionName: string,
+		isConstructor: boolean,
+		typeDefinitionByName: TypeDefinitionByName,
+	): React.ReactNode {
+		return (
+			<MethodBlock
+				key={`method-${method.name}-${sectionName}`}
+				sectionName={sectionName}
+				method={method}
+				typeDefinitionByName={typeDefinitionByName}
+				libraryVersion={this.props.docsVersion}
+				docsInfo={this.props.docsInfo}
+			/>
+		);
+	}
+	private _scrollToHash(): void {
+		const hashWithPrefix = this.props.location.hash;
+		let hash = hashWithPrefix.slice(1);
+		if (_.isEmpty(hash)) {
+			hash = SCROLL_TOP_ID; // scroll to the top
+		}
 
-        scroller.scrollTo(hash, {
-            duration: 0,
-            offset: 0,
-            containerId: 'documentation',
-        });
-    }
-    private async _fetchJSONDocsFireAndForgetAsync(preferredVersionIfExists?: string): Promise<void> {
-        const versionToFileName = await docUtils.getVersionToFileNameAsync(this.props.docsInfo.docsJsonRoot);
-        const versions = _.keys(versionToFileName);
-        this.props.dispatcher.updateAvailableDocVersions(versions);
-        const sortedVersions = semverSort.desc(versions);
-        const latestVersion = sortedVersions[0];
+		scroller.scrollTo(hash, {
+			duration: 0,
+			offset: 0,
+			containerId: 'documentation',
+		});
+	}
+	private async _fetchJSONDocsFireAndForgetAsync(preferredVersionIfExists?: string): Promise<void> {
+		const versionToFileName = await docUtils.getVersionToFileNameAsync(this.props.docsInfo.docsJsonRoot);
+		const versions = _.keys(versionToFileName);
+		this.props.dispatcher.updateAvailableDocVersions(versions);
+		const sortedVersions = semverSort.desc(versions);
+		const latestVersion = sortedVersions[0];
 
-        let versionToFetch = latestVersion;
-        if (!_.isUndefined(preferredVersionIfExists)) {
-            const preferredVersionFileNameIfExists = versionToFileName[preferredVersionIfExists];
-            if (!_.isUndefined(preferredVersionFileNameIfExists)) {
-                versionToFetch = preferredVersionIfExists;
-            }
-        }
-        this.props.dispatcher.updateCurrentDocsVersion(versionToFetch);
+		let versionToFetch = latestVersion;
+		if (!_.isUndefined(preferredVersionIfExists)) {
+			const preferredVersionFileNameIfExists = versionToFileName[preferredVersionIfExists];
+			if (!_.isUndefined(preferredVersionFileNameIfExists)) {
+				versionToFetch = preferredVersionIfExists;
+			}
+		}
+		this.props.dispatcher.updateCurrentDocsVersion(versionToFetch);
 
-        const versionFileNameToFetch = versionToFileName[versionToFetch];
-        const versionDocObj = await docUtils.getJSONDocFileAsync(
-            versionFileNameToFetch,
-            this.props.docsInfo.docsJsonRoot,
-        );
-        const docAgnosticFormat = this.props.docsInfo.convertToDocAgnosticFormat(versionDocObj as DoxityDocObj);
+		const versionFileNameToFetch = versionToFileName[versionToFetch];
+		const versionDocObj = await docUtils.getJSONDocFileAsync(
+			versionFileNameToFetch,
+			this.props.docsInfo.docsJsonRoot,
+		);
+		const docAgnosticFormat = this.props.docsInfo.convertToDocAgnosticFormat(versionDocObj as DoxityDocObj);
 
-        this.setState(
-            {
-                docAgnosticFormat,
-            },
-            () => {
-                this._scrollToHash();
-            },
-        );
-    }
+		this.setState(
+			{
+				docAgnosticFormat,
+			},
+			() => {
+				this._scrollToHash();
+			},
+		);
+	}
 }
diff --git a/packages/website/ts/pages/documentation/enum.tsx b/packages/website/ts/pages/documentation/enum.tsx
index 7dfdee771..cfcc7f8d7 100644
--- a/packages/website/ts/pages/documentation/enum.tsx
+++ b/packages/website/ts/pages/documentation/enum.tsx
@@ -3,20 +3,20 @@ import * as React from 'react';
 import { EnumValue } from 'ts/types';
 
 interface EnumProps {
-    values: EnumValue[];
+	values: EnumValue[];
 }
 
 export function Enum(props: EnumProps) {
-    const values = _.map(props.values, (value, i) => {
-        const defaultValueIfAny = !_.isUndefined(value.defaultValue) ? ` = ${value.defaultValue}` : '';
-        return `\n\t${value.name}${defaultValueIfAny},`;
-    });
-    return (
-        <span>
-            {`{`}
-            {values}
-            <br />
-            {`}`}
-        </span>
-    );
+	const values = _.map(props.values, (value, i) => {
+		const defaultValueIfAny = !_.isUndefined(value.defaultValue) ? ` = ${value.defaultValue}` : '';
+		return `\n\t${value.name}${defaultValueIfAny},`;
+	});
+	return (
+		<span>
+			{`{`}
+			{values}
+			<br />
+			{`}`}
+		</span>
+	);
 }
diff --git a/packages/website/ts/pages/documentation/event_definition.tsx b/packages/website/ts/pages/documentation/event_definition.tsx
index 0e53e38e7..9274ae512 100644
--- a/packages/website/ts/pages/documentation/event_definition.tsx
+++ b/packages/website/ts/pages/documentation/event_definition.tsx
@@ -7,76 +7,76 @@ import { Event, EventArg, HeaderSizes } from 'ts/types';
 import { colors } from 'ts/utils/colors';
 
 interface EventDefinitionProps {
-    event: Event;
-    sectionName: string;
-    docsInfo: DocsInfo;
+	event: Event;
+	sectionName: string;
+	docsInfo: DocsInfo;
 }
 
 interface EventDefinitionState {
-    shouldShowAnchor: boolean;
+	shouldShowAnchor: boolean;
 }
 
 export class EventDefinition extends React.Component<EventDefinitionProps, EventDefinitionState> {
-    constructor(props: EventDefinitionProps) {
-        super(props);
-        this.state = {
-            shouldShowAnchor: false,
-        };
-    }
-    public render() {
-        const event = this.props.event;
-        return (
-            <div
-                id={`${this.props.sectionName}-${event.name}`}
-                className="pb2"
-                style={{ overflow: 'hidden', width: '100%' }}
-                onMouseOver={this._setAnchorVisibility.bind(this, true)}
-                onMouseOut={this._setAnchorVisibility.bind(this, false)}
-            >
-                <AnchorTitle
-                    headerSize={HeaderSizes.H3}
-                    title={`Event ${event.name}`}
-                    id={event.name}
-                    shouldShowAnchor={this.state.shouldShowAnchor}
-                />
-                <div style={{ fontSize: 16 }}>
-                    <pre>
-                        <code className="hljs">{this._renderEventCode()}</code>
-                    </pre>
-                </div>
-            </div>
-        );
-    }
-    private _renderEventCode() {
-        const indexed = <span style={{ color: colors.green }}> indexed</span>;
-        const eventArgs = _.map(this.props.event.eventArgs, (eventArg: EventArg) => {
-            const type = (
-                <Type type={eventArg.type} sectionName={this.props.sectionName} docsInfo={this.props.docsInfo} />
-            );
-            return (
-                <span key={`eventArg-${eventArg.name}`}>
-                    {eventArg.name}
-                    {eventArg.isIndexed ? indexed : ''}: {type},
-                </span>
-            );
-        });
-        const argList = _.reduce(eventArgs, (prev: React.ReactNode, curr: React.ReactNode) => {
-            return [prev, '\n\t', curr];
-        });
-        return (
-            <span>
-                {`{`}
-                <br />
-                {'\t'}
-                {argList}
-                <br />
-                {`}`}
-            </span>
-        );
-    }
-    private _setAnchorVisibility(shouldShowAnchor: boolean) {
-        this.setState({
-            shouldShowAnchor,
-        });
-    }
+	constructor(props: EventDefinitionProps) {
+		super(props);
+		this.state = {
+			shouldShowAnchor: false,
+		};
+	}
+	public render() {
+		const event = this.props.event;
+		return (
+			<div
+				id={`${this.props.sectionName}-${event.name}`}
+				className="pb2"
+				style={{ overflow: 'hidden', width: '100%' }}
+				onMouseOver={this._setAnchorVisibility.bind(this, true)}
+				onMouseOut={this._setAnchorVisibility.bind(this, false)}
+			>
+				<AnchorTitle
+					headerSize={HeaderSizes.H3}
+					title={`Event ${event.name}`}
+					id={event.name}
+					shouldShowAnchor={this.state.shouldShowAnchor}
+				/>
+				<div style={{ fontSize: 16 }}>
+					<pre>
+						<code className="hljs">{this._renderEventCode()}</code>
+					</pre>
+				</div>
+			</div>
+		);
+	}
+	private _renderEventCode() {
+		const indexed = <span style={{ color: colors.green }}> indexed</span>;
+		const eventArgs = _.map(this.props.event.eventArgs, (eventArg: EventArg) => {
+			const type = (
+				<Type type={eventArg.type} sectionName={this.props.sectionName} docsInfo={this.props.docsInfo} />
+			);
+			return (
+				<span key={`eventArg-${eventArg.name}`}>
+					{eventArg.name}
+					{eventArg.isIndexed ? indexed : ''}: {type},
+				</span>
+			);
+		});
+		const argList = _.reduce(eventArgs, (prev: React.ReactNode, curr: React.ReactNode) => {
+			return [prev, '\n\t', curr];
+		});
+		return (
+			<span>
+				{`{`}
+				<br />
+				{'\t'}
+				{argList}
+				<br />
+				{`}`}
+			</span>
+		);
+	}
+	private _setAnchorVisibility(shouldShowAnchor: boolean) {
+		this.setState({
+			shouldShowAnchor,
+		});
+	}
 }
diff --git a/packages/website/ts/pages/documentation/interface.tsx b/packages/website/ts/pages/documentation/interface.tsx
index 16a772125..ee07a2c50 100644
--- a/packages/website/ts/pages/documentation/interface.tsx
+++ b/packages/website/ts/pages/documentation/interface.tsx
@@ -6,56 +6,56 @@ import { Type } from 'ts/pages/documentation/type';
 import { CustomType, TypeDocTypes } from 'ts/types';
 
 interface InterfaceProps {
-    type: CustomType;
-    sectionName: string;
-    docsInfo: DocsInfo;
+	type: CustomType;
+	sectionName: string;
+	docsInfo: DocsInfo;
 }
 
 export function Interface(props: InterfaceProps) {
-    const type = props.type;
-    const properties = _.map(type.children, property => {
-        return (
-            <span key={`property-${property.name}-${property.type}-${type.name}`}>
-                {property.name}:{' '}
-                {property.type.typeDocType !== TypeDocTypes.Reflection ? (
-                    <Type type={property.type} sectionName={props.sectionName} docsInfo={props.docsInfo} />
-                ) : (
-                    <MethodSignature
-                        method={property.type.method}
-                        sectionName={props.sectionName}
-                        shouldHideMethodName={true}
-                        shouldUseArrowSyntax={true}
-                        docsInfo={props.docsInfo}
-                    />
-                )},
-            </span>
-        );
-    });
-    const hasIndexSignature = !_.isUndefined(type.indexSignature);
-    if (hasIndexSignature) {
-        const is = type.indexSignature;
-        const param = (
-            <span key={`indexSigParams-${is.keyName}-${is.keyType}-${type.name}`}>
-                {is.keyName}: <Type type={is.keyType} sectionName={props.sectionName} docsInfo={props.docsInfo} />
-            </span>
-        );
-        properties.push(
-            <span key={`indexSignature-${type.name}-${is.keyType.name}`}>
-                [{param}]: {is.valueName},
-            </span>,
-        );
-    }
-    const propertyList = _.reduce(properties, (prev: React.ReactNode, curr: React.ReactNode) => {
-        return [prev, '\n\t', curr];
-    });
-    return (
-        <span>
-            {`{`}
-            <br />
-            {'\t'}
-            {propertyList}
-            <br />
-            {`}`}
-        </span>
-    );
+	const type = props.type;
+	const properties = _.map(type.children, property => {
+		return (
+			<span key={`property-${property.name}-${property.type}-${type.name}`}>
+				{property.name}:{' '}
+				{property.type.typeDocType !== TypeDocTypes.Reflection ? (
+					<Type type={property.type} sectionName={props.sectionName} docsInfo={props.docsInfo} />
+				) : (
+					<MethodSignature
+						method={property.type.method}
+						sectionName={props.sectionName}
+						shouldHideMethodName={true}
+						shouldUseArrowSyntax={true}
+						docsInfo={props.docsInfo}
+					/>
+				)},
+			</span>
+		);
+	});
+	const hasIndexSignature = !_.isUndefined(type.indexSignature);
+	if (hasIndexSignature) {
+		const is = type.indexSignature;
+		const param = (
+			<span key={`indexSigParams-${is.keyName}-${is.keyType}-${type.name}`}>
+				{is.keyName}: <Type type={is.keyType} sectionName={props.sectionName} docsInfo={props.docsInfo} />
+			</span>
+		);
+		properties.push(
+			<span key={`indexSignature-${type.name}-${is.keyType.name}`}>
+				[{param}]: {is.valueName},
+			</span>,
+		);
+	}
+	const propertyList = _.reduce(properties, (prev: React.ReactNode, curr: React.ReactNode) => {
+		return [prev, '\n\t', curr];
+	});
+	return (
+		<span>
+			{`{`}
+			<br />
+			{'\t'}
+			{propertyList}
+			<br />
+			{`}`}
+		</span>
+	);
 }
diff --git a/packages/website/ts/pages/documentation/method_block.tsx b/packages/website/ts/pages/documentation/method_block.tsx
index dfde5931b..fb03cf5be 100644
--- a/packages/website/ts/pages/documentation/method_block.tsx
+++ b/packages/website/ts/pages/documentation/method_block.tsx
@@ -10,133 +10,133 @@ import { colors } from 'ts/utils/colors';
 import { typeDocUtils } from 'ts/utils/typedoc_utils';
 
 interface MethodBlockProps {
-    method: SolidityMethod | TypescriptMethod;
-    sectionName: string;
-    libraryVersion: string;
-    typeDefinitionByName: TypeDefinitionByName;
-    docsInfo: DocsInfo;
+	method: SolidityMethod | TypescriptMethod;
+	sectionName: string;
+	libraryVersion: string;
+	typeDefinitionByName: TypeDefinitionByName;
+	docsInfo: DocsInfo;
 }
 
 interface MethodBlockState {
-    shouldShowAnchor: boolean;
+	shouldShowAnchor: boolean;
 }
 
 const styles: Styles = {
-    chip: {
-        fontSize: 13,
-        backgroundColor: colors.lightBlueA700,
-        color: colors.white,
-        height: 11,
-        borderRadius: 14,
-        marginTop: 19,
-        lineHeight: 0.8,
-    },
+	chip: {
+		fontSize: 13,
+		backgroundColor: colors.lightBlueA700,
+		color: colors.white,
+		height: 11,
+		borderRadius: 14,
+		marginTop: 19,
+		lineHeight: 0.8,
+	},
 };
 
 export class MethodBlock extends React.Component<MethodBlockProps, MethodBlockState> {
-    constructor(props: MethodBlockProps) {
-        super(props);
-        this.state = {
-            shouldShowAnchor: false,
-        };
-    }
-    public render() {
-        const method = this.props.method;
-        if (typeDocUtils.isPrivateOrProtectedProperty(method.name)) {
-            return null;
-        }
+	constructor(props: MethodBlockProps) {
+		super(props);
+		this.state = {
+			shouldShowAnchor: false,
+		};
+	}
+	public render() {
+		const method = this.props.method;
+		if (typeDocUtils.isPrivateOrProtectedProperty(method.name)) {
+			return null;
+		}
 
-        return (
-            <div
-                id={`${this.props.sectionName}-${method.name}`}
-                style={{ overflow: 'hidden', width: '100%' }}
-                className="pb4"
-                onMouseOver={this._setAnchorVisibility.bind(this, true)}
-                onMouseOut={this._setAnchorVisibility.bind(this, false)}
-            >
-                {!method.isConstructor && (
-                    <div className="flex">
-                        {(method as TypescriptMethod).isStatic && this._renderChip('Static')}
-                        {(method as SolidityMethod).isConstant && this._renderChip('Constant')}
-                        {(method as SolidityMethod).isPayable && this._renderChip('Payable')}
-                        <AnchorTitle
-                            headerSize={HeaderSizes.H3}
-                            title={method.name}
-                            id={`${this.props.sectionName}-${method.name}`}
-                            shouldShowAnchor={this.state.shouldShowAnchor}
-                        />
-                    </div>
-                )}
-                <code className="hljs">
-                    <MethodSignature
-                        method={method}
-                        sectionName={this.props.sectionName}
-                        typeDefinitionByName={this.props.typeDefinitionByName}
-                        docsInfo={this.props.docsInfo}
-                    />
-                </code>
-                {(method as TypescriptMethod).source && (
-                    <SourceLink
-                        version={this.props.libraryVersion}
-                        source={(method as TypescriptMethod).source}
-                        baseUrl={this.props.docsInfo.packageUrl}
-                        subPackageName={this.props.docsInfo.subPackageName}
-                    />
-                )}
-                {method.comment && <Comment comment={method.comment} className="py2" />}
-                {method.parameters &&
-                    !_.isEmpty(method.parameters) && (
-                        <div>
-                            <h4 className="pb1 thin" style={{ borderBottom: '1px solid #e1e8ed' }}>
-                                ARGUMENTS
-                            </h4>
-                            {this._renderParameterDescriptions(method.parameters)}
-                        </div>
-                    )}
-                {method.returnComment && (
-                    <div className="pt1 comment">
-                        <h4 className="pb1 thin" style={{ borderBottom: '1px solid #e1e8ed' }}>
-                            RETURNS
-                        </h4>
-                        <Comment comment={method.returnComment} />
-                    </div>
-                )}
-            </div>
-        );
-    }
-    private _renderChip(text: string) {
-        return (
-            <div className="p1 mr1" style={styles.chip}>
-                {text}
-            </div>
-        );
-    }
-    private _renderParameterDescriptions(parameters: Parameter[]) {
-        const descriptions = _.map(parameters, parameter => {
-            const isOptional = parameter.isOptional;
-            return (
-                <div
-                    key={`param-description-${parameter.name}`}
-                    className="flex pb1 mb2"
-                    style={{ borderBottom: '1px solid #f0f4f7' }}
-                >
-                    <div className="pl2 col lg-col-4 md-col-4 sm-col-12 col-12">
-                        <div className="bold">{parameter.name}</div>
-                        <div className="pt1" style={{ color: colors.grey, fontSize: 14 }}>
-                            {isOptional && 'optional'}
-                        </div>
-                    </div>
-                    <div className="col lg-col-8 md-col-8 sm-col-12 col-12">
-                        {parameter.comment && <Comment comment={parameter.comment} />}
-                    </div>
-                </div>
-            );
-        });
-        return descriptions;
-    }
-    private _setAnchorVisibility(shouldShowAnchor: boolean) {
-        this.setState({
-            shouldShowAnchor,
-        });
-    }
+		return (
+			<div
+				id={`${this.props.sectionName}-${method.name}`}
+				style={{ overflow: 'hidden', width: '100%' }}
+				className="pb4"
+				onMouseOver={this._setAnchorVisibility.bind(this, true)}
+				onMouseOut={this._setAnchorVisibility.bind(this, false)}
+			>
+				{!method.isConstructor && (
+					<div className="flex">
+						{(method as TypescriptMethod).isStatic && this._renderChip('Static')}
+						{(method as SolidityMethod).isConstant && this._renderChip('Constant')}
+						{(method as SolidityMethod).isPayable && this._renderChip('Payable')}
+						<AnchorTitle
+							headerSize={HeaderSizes.H3}
+							title={method.name}
+							id={`${this.props.sectionName}-${method.name}`}
+							shouldShowAnchor={this.state.shouldShowAnchor}
+						/>
+					</div>
+				)}
+				<code className="hljs">
+					<MethodSignature
+						method={method}
+						sectionName={this.props.sectionName}
+						typeDefinitionByName={this.props.typeDefinitionByName}
+						docsInfo={this.props.docsInfo}
+					/>
+				</code>
+				{(method as TypescriptMethod).source && (
+					<SourceLink
+						version={this.props.libraryVersion}
+						source={(method as TypescriptMethod).source}
+						baseUrl={this.props.docsInfo.packageUrl}
+						subPackageName={this.props.docsInfo.subPackageName}
+					/>
+				)}
+				{method.comment && <Comment comment={method.comment} className="py2" />}
+				{method.parameters &&
+					!_.isEmpty(method.parameters) && (
+						<div>
+							<h4 className="pb1 thin" style={{ borderBottom: '1px solid #e1e8ed' }}>
+								ARGUMENTS
+							</h4>
+							{this._renderParameterDescriptions(method.parameters)}
+						</div>
+					)}
+				{method.returnComment && (
+					<div className="pt1 comment">
+						<h4 className="pb1 thin" style={{ borderBottom: '1px solid #e1e8ed' }}>
+							RETURNS
+						</h4>
+						<Comment comment={method.returnComment} />
+					</div>
+				)}
+			</div>
+		);
+	}
+	private _renderChip(text: string) {
+		return (
+			<div className="p1 mr1" style={styles.chip}>
+				{text}
+			</div>
+		);
+	}
+	private _renderParameterDescriptions(parameters: Parameter[]) {
+		const descriptions = _.map(parameters, parameter => {
+			const isOptional = parameter.isOptional;
+			return (
+				<div
+					key={`param-description-${parameter.name}`}
+					className="flex pb1 mb2"
+					style={{ borderBottom: '1px solid #f0f4f7' }}
+				>
+					<div className="pl2 col lg-col-4 md-col-4 sm-col-12 col-12">
+						<div className="bold">{parameter.name}</div>
+						<div className="pt1" style={{ color: colors.grey, fontSize: 14 }}>
+							{isOptional && 'optional'}
+						</div>
+					</div>
+					<div className="col lg-col-8 md-col-8 sm-col-12 col-12">
+						{parameter.comment && <Comment comment={parameter.comment} />}
+					</div>
+				</div>
+			);
+		});
+		return descriptions;
+	}
+	private _setAnchorVisibility(shouldShowAnchor: boolean) {
+		this.setState({
+			shouldShowAnchor,
+		});
+	}
 }
diff --git a/packages/website/ts/pages/documentation/method_signature.tsx b/packages/website/ts/pages/documentation/method_signature.tsx
index 041dcd093..7c6bf96d2 100644
--- a/packages/website/ts/pages/documentation/method_signature.tsx
+++ b/packages/website/ts/pages/documentation/method_signature.tsx
@@ -6,94 +6,94 @@ import { Parameter, SolidityMethod, TypeDefinitionByName, TypescriptMethod } fro
 import { constants } from 'ts/utils/constants';
 
 interface MethodSignatureProps {
-    method: TypescriptMethod | SolidityMethod;
-    sectionName: string;
-    shouldHideMethodName?: boolean;
-    shouldUseArrowSyntax?: boolean;
-    typeDefinitionByName?: TypeDefinitionByName;
-    docsInfo: DocsInfo;
+	method: TypescriptMethod | SolidityMethod;
+	sectionName: string;
+	shouldHideMethodName?: boolean;
+	shouldUseArrowSyntax?: boolean;
+	typeDefinitionByName?: TypeDefinitionByName;
+	docsInfo: DocsInfo;
 }
 
 const defaultProps = {
-    shouldHideMethodName: false,
-    shouldUseArrowSyntax: false,
+	shouldHideMethodName: false,
+	shouldUseArrowSyntax: false,
 };
 
 export const MethodSignature: React.SFC<MethodSignatureProps> = (props: MethodSignatureProps) => {
-    const sectionName = constants.TYPES_SECTION_NAME;
-    const parameters = renderParameters(props.method, props.docsInfo, sectionName, props.typeDefinitionByName);
-    const paramString = _.reduce(parameters, (prev: React.ReactNode, curr: React.ReactNode) => {
-        return [prev, ', ', curr];
-    });
-    const methodName = props.shouldHideMethodName ? '' : props.method.name;
-    const typeParameterIfExists = _.isUndefined((props.method as TypescriptMethod).typeParameter)
-        ? undefined
-        : renderTypeParameter(props.method, props.docsInfo, sectionName, props.typeDefinitionByName);
-    return (
-        <span>
-            {props.method.callPath}
-            {methodName}
-            {typeParameterIfExists}({paramString})
-            {props.shouldUseArrowSyntax ? ' => ' : ': '}{' '}
-            {props.method.returnType && (
-                <Type
-                    type={props.method.returnType}
-                    sectionName={sectionName}
-                    typeDefinitionByName={props.typeDefinitionByName}
-                    docsInfo={props.docsInfo}
-                />
-            )}
-        </span>
-    );
+	const sectionName = constants.TYPES_SECTION_NAME;
+	const parameters = renderParameters(props.method, props.docsInfo, sectionName, props.typeDefinitionByName);
+	const paramString = _.reduce(parameters, (prev: React.ReactNode, curr: React.ReactNode) => {
+		return [prev, ', ', curr];
+	});
+	const methodName = props.shouldHideMethodName ? '' : props.method.name;
+	const typeParameterIfExists = _.isUndefined((props.method as TypescriptMethod).typeParameter)
+		? undefined
+		: renderTypeParameter(props.method, props.docsInfo, sectionName, props.typeDefinitionByName);
+	return (
+		<span>
+			{props.method.callPath}
+			{methodName}
+			{typeParameterIfExists}({paramString})
+			{props.shouldUseArrowSyntax ? ' => ' : ': '}{' '}
+			{props.method.returnType && (
+				<Type
+					type={props.method.returnType}
+					sectionName={sectionName}
+					typeDefinitionByName={props.typeDefinitionByName}
+					docsInfo={props.docsInfo}
+				/>
+			)}
+		</span>
+	);
 };
 
 MethodSignature.defaultProps = defaultProps;
 
 function renderParameters(
-    method: TypescriptMethod | SolidityMethod,
-    docsInfo: DocsInfo,
-    sectionName: string,
-    typeDefinitionByName?: TypeDefinitionByName,
+	method: TypescriptMethod | SolidityMethod,
+	docsInfo: DocsInfo,
+	sectionName: string,
+	typeDefinitionByName?: TypeDefinitionByName,
 ) {
-    const parameters = method.parameters;
-    const params = _.map(parameters, (p: Parameter) => {
-        const isOptional = p.isOptional;
-        const type = (
-            <Type
-                type={p.type}
-                sectionName={sectionName}
-                typeDefinitionByName={typeDefinitionByName}
-                docsInfo={docsInfo}
-            />
-        );
-        return (
-            <span key={`param-${p.type}-${p.name}`}>
-                {p.name}
-                {isOptional && '?'}: {type}
-            </span>
-        );
-    });
-    return params;
+	const parameters = method.parameters;
+	const params = _.map(parameters, (p: Parameter) => {
+		const isOptional = p.isOptional;
+		const type = (
+			<Type
+				type={p.type}
+				sectionName={sectionName}
+				typeDefinitionByName={typeDefinitionByName}
+				docsInfo={docsInfo}
+			/>
+		);
+		return (
+			<span key={`param-${p.type}-${p.name}`}>
+				{p.name}
+				{isOptional && '?'}: {type}
+			</span>
+		);
+	});
+	return params;
 }
 
 function renderTypeParameter(
-    method: TypescriptMethod,
-    docsInfo: DocsInfo,
-    sectionName: string,
-    typeDefinitionByName?: TypeDefinitionByName,
+	method: TypescriptMethod,
+	docsInfo: DocsInfo,
+	sectionName: string,
+	typeDefinitionByName?: TypeDefinitionByName,
 ) {
-    const typeParameter = method.typeParameter;
-    const typeParam = (
-        <span>
-            {`<${typeParameter.name} extends `}
-            <Type
-                type={typeParameter.type}
-                sectionName={sectionName}
-                typeDefinitionByName={typeDefinitionByName}
-                docsInfo={docsInfo}
-            />
-            {`>`}
-        </span>
-    );
-    return typeParam;
+	const typeParameter = method.typeParameter;
+	const typeParam = (
+		<span>
+			{`<${typeParameter.name} extends `}
+			<Type
+				type={typeParameter.type}
+				sectionName={sectionName}
+				typeDefinitionByName={typeDefinitionByName}
+				docsInfo={docsInfo}
+			/>
+			{`>`}
+		</span>
+	);
+	return typeParam;
 }
diff --git a/packages/website/ts/pages/documentation/source_link.tsx b/packages/website/ts/pages/documentation/source_link.tsx
index 6588ee39e..32126b7da 100644
--- a/packages/website/ts/pages/documentation/source_link.tsx
+++ b/packages/website/ts/pages/documentation/source_link.tsx
@@ -4,28 +4,28 @@ import { Source } from 'ts/types';
 import { colors } from 'ts/utils/colors';
 
 interface SourceLinkProps {
-    source: Source;
-    baseUrl: string;
-    version: string;
-    subPackageName: string;
+	source: Source;
+	baseUrl: string;
+	version: string;
+	subPackageName: string;
 }
 
 const packagesWithNamespace = ['connect'];
 
 export function SourceLink(props: SourceLinkProps) {
-    const src = props.source;
-    const url = props.baseUrl;
-    const pkg = props.subPackageName;
-    let tagPrefix = pkg;
-    if (_.includes(packagesWithNamespace, pkg)) {
-        tagPrefix = `@0xproject/${pkg}`;
-    }
-    const sourceCodeUrl = `${url}/blob/${tagPrefix}%40${props.version}/packages/${pkg}/${src.fileName}#L${src.line}`;
-    return (
-        <div className="pt2" style={{ fontSize: 14 }}>
-            <a href={sourceCodeUrl} target="_blank" className="underline" style={{ color: colors.grey }}>
-                Source
-            </a>
-        </div>
-    );
+	const src = props.source;
+	const url = props.baseUrl;
+	const pkg = props.subPackageName;
+	let tagPrefix = pkg;
+	if (_.includes(packagesWithNamespace, pkg)) {
+		tagPrefix = `@0xproject/${pkg}`;
+	}
+	const sourceCodeUrl = `${url}/blob/${tagPrefix}%40${props.version}/packages/${pkg}/${src.fileName}#L${src.line}`;
+	return (
+		<div className="pt2" style={{ fontSize: 14 }}>
+			<a href={sourceCodeUrl} target="_blank" className="underline" style={{ color: colors.grey }}>
+				Source
+			</a>
+		</div>
+	);
 }
diff --git a/packages/website/ts/pages/documentation/type.tsx b/packages/website/ts/pages/documentation/type.tsx
index e989e7129..9a2696e22 100644
--- a/packages/website/ts/pages/documentation/type.tsx
+++ b/packages/website/ts/pages/documentation/type.tsx
@@ -11,202 +11,202 @@ import { utils } from 'ts/utils/utils';
 
 // Some types reference other libraries. For these types, we want to link the user to the relevant documentation.
 const typeToUrl: { [typeName: string]: string } = {
-    Web3: constants.URL_WEB3_DOCS,
-    Provider: constants.URL_WEB3_PROVIDER_DOCS,
-    BigNumber: constants.URL_BIGNUMBERJS_GITHUB,
-    DecodedLogEntryEvent: constants.URL_WEB3_DECODED_LOG_ENTRY_EVENT,
-    LogEntryEvent: constants.URL_WEB3_LOG_ENTRY_EVENT,
+	Web3: constants.URL_WEB3_DOCS,
+	Provider: constants.URL_WEB3_PROVIDER_DOCS,
+	BigNumber: constants.URL_BIGNUMBERJS_GITHUB,
+	DecodedLogEntryEvent: constants.URL_WEB3_DECODED_LOG_ENTRY_EVENT,
+	LogEntryEvent: constants.URL_WEB3_LOG_ENTRY_EVENT,
 };
 
 const typePrefix: { [typeName: string]: string } = {
-    Provider: 'Web3',
-    DecodedLogEntryEvent: 'Web3',
-    LogEntryEvent: 'Web3',
+	Provider: 'Web3',
+	DecodedLogEntryEvent: 'Web3',
+	LogEntryEvent: 'Web3',
 };
 
 const typeToSection: { [typeName: string]: string } = {
-    ExchangeWrapper: 'exchange',
-    TokenWrapper: 'token',
-    TokenRegistryWrapper: 'tokenRegistry',
-    EtherTokenWrapper: 'etherToken',
-    ProxyWrapper: 'proxy',
-    TokenTransferProxyWrapper: 'proxy',
-    OrderStateWatcher: 'orderWatcher',
+	ExchangeWrapper: 'exchange',
+	TokenWrapper: 'token',
+	TokenRegistryWrapper: 'tokenRegistry',
+	EtherTokenWrapper: 'etherToken',
+	ProxyWrapper: 'proxy',
+	TokenTransferProxyWrapper: 'proxy',
+	OrderStateWatcher: 'orderWatcher',
 };
 
 interface TypeProps {
-    type: TypeDef;
-    docsInfo: DocsInfo;
-    sectionName: string;
-    typeDefinitionByName?: TypeDefinitionByName;
+	type: TypeDef;
+	docsInfo: DocsInfo;
+	sectionName: string;
+	typeDefinitionByName?: TypeDefinitionByName;
 }
 
 // The return type needs to be `any` here so that we can recursively define <Type /> components within
 // <Type /> components (e.g when rendering the union type).
 export function Type(props: TypeProps): any {
-    const type = props.type;
-    const isReference = type.typeDocType === TypeDocTypes.Reference;
-    const isArray = type.typeDocType === TypeDocTypes.Array;
-    let typeNameColor = 'inherit';
-    let typeName: string | React.ReactNode;
-    let typeArgs: React.ReactNode[] = [];
-    switch (type.typeDocType) {
-        case TypeDocTypes.Intrinsic:
-        case TypeDocTypes.Unknown:
-            typeName = type.name;
-            typeNameColor = colors.orange;
-            break;
+	const type = props.type;
+	const isReference = type.typeDocType === TypeDocTypes.Reference;
+	const isArray = type.typeDocType === TypeDocTypes.Array;
+	let typeNameColor = 'inherit';
+	let typeName: string | React.ReactNode;
+	let typeArgs: React.ReactNode[] = [];
+	switch (type.typeDocType) {
+		case TypeDocTypes.Intrinsic:
+		case TypeDocTypes.Unknown:
+			typeName = type.name;
+			typeNameColor = colors.orange;
+			break;
 
-        case TypeDocTypes.Reference:
-            typeName = type.name;
-            typeArgs = _.map(type.typeArguments, (arg: TypeDef) => {
-                if (arg.typeDocType === TypeDocTypes.Array) {
-                    const key = `type-${arg.elementType.name}-${arg.elementType.typeDocType}`;
-                    return (
-                        <span>
-                            <Type
-                                key={key}
-                                type={arg.elementType}
-                                sectionName={props.sectionName}
-                                typeDefinitionByName={props.typeDefinitionByName}
-                                docsInfo={props.docsInfo}
-                            />[]
-                        </span>
-                    );
-                } else {
-                    const subType = (
-                        <Type
-                            key={`type-${arg.name}-${arg.value}-${arg.typeDocType}`}
-                            type={arg}
-                            sectionName={props.sectionName}
-                            typeDefinitionByName={props.typeDefinitionByName}
-                            docsInfo={props.docsInfo}
-                        />
-                    );
-                    return subType;
-                }
-            });
-            break;
+		case TypeDocTypes.Reference:
+			typeName = type.name;
+			typeArgs = _.map(type.typeArguments, (arg: TypeDef) => {
+				if (arg.typeDocType === TypeDocTypes.Array) {
+					const key = `type-${arg.elementType.name}-${arg.elementType.typeDocType}`;
+					return (
+						<span>
+							<Type
+								key={key}
+								type={arg.elementType}
+								sectionName={props.sectionName}
+								typeDefinitionByName={props.typeDefinitionByName}
+								docsInfo={props.docsInfo}
+							/>[]
+						</span>
+					);
+				} else {
+					const subType = (
+						<Type
+							key={`type-${arg.name}-${arg.value}-${arg.typeDocType}`}
+							type={arg}
+							sectionName={props.sectionName}
+							typeDefinitionByName={props.typeDefinitionByName}
+							docsInfo={props.docsInfo}
+						/>
+					);
+					return subType;
+				}
+			});
+			break;
 
-        case TypeDocTypes.StringLiteral:
-            typeName = `'${type.value}'`;
-            typeNameColor = colors.green;
-            break;
+		case TypeDocTypes.StringLiteral:
+			typeName = `'${type.value}'`;
+			typeNameColor = colors.green;
+			break;
 
-        case TypeDocTypes.Array:
-            typeName = type.elementType.name;
-            break;
+		case TypeDocTypes.Array:
+			typeName = type.elementType.name;
+			break;
 
-        case TypeDocTypes.Union:
-            const unionTypes = _.map(type.types, t => {
-                return (
-                    <Type
-                        key={`type-${t.name}-${t.value}-${t.typeDocType}`}
-                        type={t}
-                        sectionName={props.sectionName}
-                        typeDefinitionByName={props.typeDefinitionByName}
-                        docsInfo={props.docsInfo}
-                    />
-                );
-            });
-            typeName = _.reduce(unionTypes, (prev: React.ReactNode, curr: React.ReactNode) => {
-                return [prev, '|', curr];
-            });
-            break;
+		case TypeDocTypes.Union:
+			const unionTypes = _.map(type.types, t => {
+				return (
+					<Type
+						key={`type-${t.name}-${t.value}-${t.typeDocType}`}
+						type={t}
+						sectionName={props.sectionName}
+						typeDefinitionByName={props.typeDefinitionByName}
+						docsInfo={props.docsInfo}
+					/>
+				);
+			});
+			typeName = _.reduce(unionTypes, (prev: React.ReactNode, curr: React.ReactNode) => {
+				return [prev, '|', curr];
+			});
+			break;
 
-        case TypeDocTypes.TypeParameter:
-            typeName = type.name;
-            break;
+		case TypeDocTypes.TypeParameter:
+			typeName = type.name;
+			break;
 
-        default:
-            throw utils.spawnSwitchErr('type.typeDocType', type.typeDocType);
-    }
-    // HACK: Normalize BigNumber to simply BigNumber. For some reason the type
-    // name is unpredictably one or the other.
-    if (typeName === 'BigNumber') {
-        typeName = 'BigNumber';
-    }
-    const commaSeparatedTypeArgs = _.reduce(typeArgs, (prev: React.ReactNode, curr: React.ReactNode) => {
-        return [prev, ', ', curr];
-    });
+		default:
+			throw utils.spawnSwitchErr('type.typeDocType', type.typeDocType);
+	}
+	// HACK: Normalize BigNumber to simply BigNumber. For some reason the type
+	// name is unpredictably one or the other.
+	if (typeName === 'BigNumber') {
+		typeName = 'BigNumber';
+	}
+	const commaSeparatedTypeArgs = _.reduce(typeArgs, (prev: React.ReactNode, curr: React.ReactNode) => {
+		return [prev, ', ', curr];
+	});
 
-    const typeNameUrlIfExists = typeToUrl[typeName as string];
-    const typePrefixIfExists = typePrefix[typeName as string];
-    const sectionNameIfExists = typeToSection[typeName as string];
-    if (!_.isUndefined(typeNameUrlIfExists)) {
-        typeName = (
-            <a
-                href={typeNameUrlIfExists}
-                target="_blank"
-                className="text-decoration-none"
-                style={{ color: colors.lightBlueA700 }}
-            >
-                {!_.isUndefined(typePrefixIfExists) ? `${typePrefixIfExists}.` : ''}
-                {typeName}
-            </a>
-        );
-    } else if (
-        (isReference || isArray) &&
-        (props.docsInfo.isPublicType(typeName as string) || !_.isUndefined(sectionNameIfExists))
-    ) {
-        const id = Math.random().toString();
-        const typeDefinitionAnchorId = _.isUndefined(sectionNameIfExists)
-            ? `${props.sectionName}-${typeName}`
-            : sectionNameIfExists;
-        let typeDefinition;
-        if (props.typeDefinitionByName) {
-            typeDefinition = props.typeDefinitionByName[typeName as string];
-        }
-        typeName = (
-            <ScrollLink
-                to={typeDefinitionAnchorId}
-                offset={0}
-                duration={constants.DOCS_SCROLL_DURATION_MS}
-                containerId={constants.DOCS_CONTAINER_ID}
-            >
-                {_.isUndefined(typeDefinition) || utils.isUserOnMobile() ? (
-                    <span
-                        onClick={utils.setUrlHash.bind(null, typeDefinitionAnchorId)}
-                        style={{ color: colors.lightBlueA700, cursor: 'pointer' }}
-                    >
-                        {typeName}
-                    </span>
-                ) : (
-                    <span
-                        data-tip={true}
-                        data-for={id}
-                        onClick={utils.setUrlHash.bind(null, typeDefinitionAnchorId)}
-                        style={{
-                            color: colors.lightBlueA700,
-                            cursor: 'pointer',
-                            display: 'inline-block',
-                        }}
-                    >
-                        {typeName}
-                        <ReactTooltip type="light" effect="solid" id={id} className="typeTooltip">
-                            <TypeDefinition
-                                sectionName={props.sectionName}
-                                customType={typeDefinition}
-                                shouldAddId={false}
-                                docsInfo={props.docsInfo}
-                            />
-                        </ReactTooltip>
-                    </span>
-                )}
-            </ScrollLink>
-        );
-    }
-    return (
-        <span>
-            <span style={{ color: typeNameColor }}>{typeName}</span>
-            {isArray && '[]'}
-            {!_.isEmpty(typeArgs) && (
-                <span>
-                    {'<'}
-                    {commaSeparatedTypeArgs}
-                    {'>'}
-                </span>
-            )}
-        </span>
-    );
+	const typeNameUrlIfExists = typeToUrl[typeName as string];
+	const typePrefixIfExists = typePrefix[typeName as string];
+	const sectionNameIfExists = typeToSection[typeName as string];
+	if (!_.isUndefined(typeNameUrlIfExists)) {
+		typeName = (
+			<a
+				href={typeNameUrlIfExists}
+				target="_blank"
+				className="text-decoration-none"
+				style={{ color: colors.lightBlueA700 }}
+			>
+				{!_.isUndefined(typePrefixIfExists) ? `${typePrefixIfExists}.` : ''}
+				{typeName}
+			</a>
+		);
+	} else if (
+		(isReference || isArray) &&
+		(props.docsInfo.isPublicType(typeName as string) || !_.isUndefined(sectionNameIfExists))
+	) {
+		const id = Math.random().toString();
+		const typeDefinitionAnchorId = _.isUndefined(sectionNameIfExists)
+			? `${props.sectionName}-${typeName}`
+			: sectionNameIfExists;
+		let typeDefinition;
+		if (props.typeDefinitionByName) {
+			typeDefinition = props.typeDefinitionByName[typeName as string];
+		}
+		typeName = (
+			<ScrollLink
+				to={typeDefinitionAnchorId}
+				offset={0}
+				duration={constants.DOCS_SCROLL_DURATION_MS}
+				containerId={constants.DOCS_CONTAINER_ID}
+			>
+				{_.isUndefined(typeDefinition) || utils.isUserOnMobile() ? (
+					<span
+						onClick={utils.setUrlHash.bind(null, typeDefinitionAnchorId)}
+						style={{ color: colors.lightBlueA700, cursor: 'pointer' }}
+					>
+						{typeName}
+					</span>
+				) : (
+					<span
+						data-tip={true}
+						data-for={id}
+						onClick={utils.setUrlHash.bind(null, typeDefinitionAnchorId)}
+						style={{
+							color: colors.lightBlueA700,
+							cursor: 'pointer',
+							display: 'inline-block',
+						}}
+					>
+						{typeName}
+						<ReactTooltip type="light" effect="solid" id={id} className="typeTooltip">
+							<TypeDefinition
+								sectionName={props.sectionName}
+								customType={typeDefinition}
+								shouldAddId={false}
+								docsInfo={props.docsInfo}
+							/>
+						</ReactTooltip>
+					</span>
+				)}
+			</ScrollLink>
+		);
+	}
+	return (
+		<span>
+			<span style={{ color: typeNameColor }}>{typeName}</span>
+			{isArray && '[]'}
+			{!_.isEmpty(typeArgs) && (
+				<span>
+					{'<'}
+					{commaSeparatedTypeArgs}
+					{'>'}
+				</span>
+			)}
+		</span>
+	);
 }
diff --git a/packages/website/ts/pages/documentation/type_definition.tsx b/packages/website/ts/pages/documentation/type_definition.tsx
index d46eec76c..356926157 100644
--- a/packages/website/ts/pages/documentation/type_definition.tsx
+++ b/packages/website/ts/pages/documentation/type_definition.tsx
@@ -13,113 +13,113 @@ import { colors } from 'ts/utils/colors';
 import { utils } from 'ts/utils/utils';
 
 interface TypeDefinitionProps {
-    sectionName: string;
-    customType: CustomType;
-    shouldAddId?: boolean;
-    docsInfo: DocsInfo;
+	sectionName: string;
+	customType: CustomType;
+	shouldAddId?: boolean;
+	docsInfo: DocsInfo;
 }
 
 interface TypeDefinitionState {
-    shouldShowAnchor: boolean;
+	shouldShowAnchor: boolean;
 }
 
 export class TypeDefinition extends React.Component<TypeDefinitionProps, TypeDefinitionState> {
-    public static defaultProps: Partial<TypeDefinitionProps> = {
-        shouldAddId: true,
-    };
-    constructor(props: TypeDefinitionProps) {
-        super(props);
-        this.state = {
-            shouldShowAnchor: false,
-        };
-    }
-    public render() {
-        const customType = this.props.customType;
-        if (!this.props.docsInfo.isPublicType(customType.name)) {
-            return null; // no-op
-        }
+	public static defaultProps: Partial<TypeDefinitionProps> = {
+		shouldAddId: true,
+	};
+	constructor(props: TypeDefinitionProps) {
+		super(props);
+		this.state = {
+			shouldShowAnchor: false,
+		};
+	}
+	public render() {
+		const customType = this.props.customType;
+		if (!this.props.docsInfo.isPublicType(customType.name)) {
+			return null; // no-op
+		}
 
-        let typePrefix: string;
-        let codeSnippet: React.ReactNode;
-        switch (customType.kindString) {
-            case KindString.Interface:
-                typePrefix = 'Interface';
-                codeSnippet = (
-                    <Interface type={customType} sectionName={this.props.sectionName} docsInfo={this.props.docsInfo} />
-                );
-                break;
+		let typePrefix: string;
+		let codeSnippet: React.ReactNode;
+		switch (customType.kindString) {
+			case KindString.Interface:
+				typePrefix = 'Interface';
+				codeSnippet = (
+					<Interface type={customType} sectionName={this.props.sectionName} docsInfo={this.props.docsInfo} />
+				);
+				break;
 
-            case KindString.Variable:
-                typePrefix = 'Enum';
-                codeSnippet = <CustomEnum type={customType} />;
-                break;
+			case KindString.Variable:
+				typePrefix = 'Enum';
+				codeSnippet = <CustomEnum type={customType} />;
+				break;
 
-            case KindString.Enumeration:
-                typePrefix = 'Enum';
-                const enumValues = _.map(customType.children, (c: CustomTypeChild) => {
-                    return {
-                        name: c.name,
-                        defaultValue: c.defaultValue,
-                    };
-                });
-                codeSnippet = <Enum values={enumValues} />;
-                break;
+			case KindString.Enumeration:
+				typePrefix = 'Enum';
+				const enumValues = _.map(customType.children, (c: CustomTypeChild) => {
+					return {
+						name: c.name,
+						defaultValue: c.defaultValue,
+					};
+				});
+				codeSnippet = <Enum values={enumValues} />;
+				break;
 
-            case KindString.TypeAlias:
-                typePrefix = 'Type Alias';
-                codeSnippet = (
-                    <span>
-                        <span style={{ color: colors.lightPurple }}>type</span> {customType.name} ={' '}
-                        {customType.type.typeDocType !== TypeDocTypes.Reflection ? (
-                            <Type
-                                type={customType.type}
-                                sectionName={this.props.sectionName}
-                                docsInfo={this.props.docsInfo}
-                            />
-                        ) : (
-                            <MethodSignature
-                                method={customType.type.method}
-                                sectionName={this.props.sectionName}
-                                shouldHideMethodName={true}
-                                shouldUseArrowSyntax={true}
-                                docsInfo={this.props.docsInfo}
-                            />
-                        )}
-                    </span>
-                );
-                break;
+			case KindString.TypeAlias:
+				typePrefix = 'Type Alias';
+				codeSnippet = (
+					<span>
+						<span style={{ color: colors.lightPurple }}>type</span> {customType.name} ={' '}
+						{customType.type.typeDocType !== TypeDocTypes.Reflection ? (
+							<Type
+								type={customType.type}
+								sectionName={this.props.sectionName}
+								docsInfo={this.props.docsInfo}
+							/>
+						) : (
+							<MethodSignature
+								method={customType.type.method}
+								sectionName={this.props.sectionName}
+								shouldHideMethodName={true}
+								shouldUseArrowSyntax={true}
+								docsInfo={this.props.docsInfo}
+							/>
+						)}
+					</span>
+				);
+				break;
 
-            default:
-                throw utils.spawnSwitchErr('type.kindString', customType.kindString);
-        }
+			default:
+				throw utils.spawnSwitchErr('type.kindString', customType.kindString);
+		}
 
-        const typeDefinitionAnchorId = `${this.props.sectionName}-${customType.name}`;
-        return (
-            <div
-                id={this.props.shouldAddId ? typeDefinitionAnchorId : ''}
-                className="pb2"
-                style={{ overflow: 'hidden', width: '100%' }}
-                onMouseOver={this._setAnchorVisibility.bind(this, true)}
-                onMouseOut={this._setAnchorVisibility.bind(this, false)}
-            >
-                <AnchorTitle
-                    headerSize={HeaderSizes.H3}
-                    title={`${typePrefix} ${customType.name}`}
-                    id={this.props.shouldAddId ? typeDefinitionAnchorId : ''}
-                    shouldShowAnchor={this.state.shouldShowAnchor}
-                />
-                <div style={{ fontSize: 16 }}>
-                    <pre>
-                        <code className="hljs">{codeSnippet}</code>
-                    </pre>
-                </div>
-                {customType.comment && <Comment comment={customType.comment} className="py2" />}
-            </div>
-        );
-    }
-    private _setAnchorVisibility(shouldShowAnchor: boolean) {
-        this.setState({
-            shouldShowAnchor,
-        });
-    }
+		const typeDefinitionAnchorId = `${this.props.sectionName}-${customType.name}`;
+		return (
+			<div
+				id={this.props.shouldAddId ? typeDefinitionAnchorId : ''}
+				className="pb2"
+				style={{ overflow: 'hidden', width: '100%' }}
+				onMouseOver={this._setAnchorVisibility.bind(this, true)}
+				onMouseOut={this._setAnchorVisibility.bind(this, false)}
+			>
+				<AnchorTitle
+					headerSize={HeaderSizes.H3}
+					title={`${typePrefix} ${customType.name}`}
+					id={this.props.shouldAddId ? typeDefinitionAnchorId : ''}
+					shouldShowAnchor={this.state.shouldShowAnchor}
+				/>
+				<div style={{ fontSize: 16 }}>
+					<pre>
+						<code className="hljs">{codeSnippet}</code>
+					</pre>
+				</div>
+				{customType.comment && <Comment comment={customType.comment} className="py2" />}
+			</div>
+		);
+	}
+	private _setAnchorVisibility(shouldShowAnchor: boolean) {
+		this.setState({
+			shouldShowAnchor,
+		});
+	}
 }
diff --git a/packages/website/ts/pages/faq/faq.tsx b/packages/website/ts/pages/faq/faq.tsx
index b4b5214a2..f437f5a8d 100644
--- a/packages/website/ts/pages/faq/faq.tsx
+++ b/packages/website/ts/pages/faq/faq.tsx
@@ -10,438 +10,438 @@ import { configs } from 'ts/utils/configs';
 import { constants } from 'ts/utils/constants';
 
 export interface FAQProps {
-    source: string;
-    location: Location;
+	source: string;
+	location: Location;
 }
 
 interface FAQState {}
 
 const styles: Styles = {
-    thin: {
-        fontWeight: 100,
-    },
+	thin: {
+		fontWeight: 100,
+	},
 };
 
 const sections: FAQSection[] = [
-    {
-        name: '0x Protocol',
-        questions: [
-            {
-                prompt: 'What is 0x?',
-                answer: (
-                    <div>
-                        At its core, 0x is an open and non-rent seeking protocol that facilitates trustless, low
-                        friction exchange of Ethereum-based assets. Developers can use 0x as a platform to build
-                        exchange applications on top of (<a
-                            href={`${configs.BASE_URL}${WebsitePaths.ZeroExJs}#introduction`}
-                            target="blank"
-                        >
-                            0x.js
-                        </a>{' '}
-                        is a Javascript library for interacting with the 0x protocol). For end users, 0x will be the
-                        infrastructure of a wide variety of user-facing applications i.e.{' '}
-                        <a href={`${configs.BASE_URL}${WebsitePaths.Portal}`} target="blank">
-                            0x Portal
-                        </a>, a decentralized application that facilitates trustless trading of Ethereum-based tokens
-                        between known counterparties.
-                    </div>
-                ),
-            },
-            {
-                prompt: 'What problem does 0x solve?',
-                answer: (
-                    <div>
-                        In the two years since the Ethereum blockchain’s genesis block, numerous decentralized
-                        applications (dApps) have created Ethereum smart contracts for peer-to-peer exchange. Rapid
-                        iteration and a lack of best practices have left the blockchain scattered with proprietary and
-                        application-specific implementations. As a result, end users are exposed to numerous smart
-                        contracts of varying quality and security, with unique configuration processes and learning
-                        curves, all of which implement the same functionality. This approach imposes unnecessary costs
-                        on the network by fragmenting end users according to the particular dApp each user happens to be
-                        using, eliminating valuable network effects around liquidity. 0x is the solution to this problem
-                        by acting as modular, unopinionated building blocks that may be assembled and reconfigured.
-                    </div>
-                ),
-            },
-            {
-                prompt: 'How is 0x different from a centralized exchange like Poloniex or ShapeShift?',
-                answer: (
-                    <div>
-                        <ul>
-                            <li>0x is a protocol for exchange, not a user-facing exchange application.</li>
-                            <li>
-                                0x is decentralized and trustless; there is no central party which can be hacked, run
-                                away with customer funds or be subjected to government regulations. Hacks of Mt. Gox,
-                                Shapeshift and Bitfinex have demonstrated that these types of systemic risks are
-                                palpable.
-                            </li>
-                            <li>
-                                Rather than a proprietary system that exists to extract rent for its owners, 0x is
-                                public infrastructure that is funded by a globally distributed community of
-                                stakeholders. While the protocol is free to use, it enables for-profit user-facing
-                                exchange applications to be built on top of the protocol.
-                            </li>
-                        </ul>
-                    </div>
-                ),
-            },
-            {
-                prompt: 'If 0x protocol is free to use, where do transaction fees come in?',
-                answer: (
-                    <div>
-                        0x protocol uses off-chain order books to massively reduce friction costs for market makers and
-                        ensure that the blockchain is only used for trade settlement. Hosting and maintaining an
-                        off-chain order book is a service; to incent “Relayers” to provide this service they must be
-                        able to charge transaction fees on trading activity. Relayers are free to set their transaction
-                        fees to any value they desire. We expect Relayers to be highly competitive and transaction fees
-                        to approach an efficient economic equilibrium over time.
-                    </div>
-                ),
-            },
-            {
-                prompt: 'What are the differences between 0x protocol and state channels?',
-                answer: (
-                    <div>
-                        <div>
-                            Participants in a state channel pass cryptographically signed messages back and forth,
-                            accumulating intermediate state changes without publishing them to the canonical chain until
-                            the channel is closed. State channels are ideal for “bar tab” applications where numerous
-                            intermediate state changes may be accumulated off-chain before being settled by a final
-                            on-chain transaction (i.e. day trading, poker, turn-based games).
-                        </div>
-                        <ul>
-                            <li>
-                                While state channels drastically reduce the number of on-chain transactions for specific
-                                use cases, numerous on-chain transactions and a security deposit are required to open
-                                and safely close a state channel making them less efficient than 0x for executing
-                                one-time trades.
-                            </li>
-                            <li>
-                                State channels are isolated from the Ethereum blockchain meaning that they cannot
-                                interact with smart contracts. 0x is designed to be integrated directly into smart
-                                contracts so trades can be executed programmatically in a single line of Solidity code.
-                            </li>
-                        </ul>
-                    </div>
-                ),
-            },
-            {
-                prompt: 'What types of digital assets are supported by 0x?',
-                answer: (
-                    <div>
-                        0x supports all Ethereum-based assets that adhere to the ERC20 token standard. There are many
-                        ERC20 tokens, worth a combined $2.2B, and more tokens are created each month. We believe that,
-                        by 2020, thousands of assets will be tokenized and moved onto the Ethereum blockchain including
-                        traditional securities such as equities, bonds and derivatives, fiat currencies and scarce
-                        digital goods such as video game items. In the future, cross-blockchain solutions such as{' '}
-                        <a href="https://cosmos.network/" target="_blank">
-                            Cosmos
-                        </a>{' '}
-                        and{' '}
-                        <a href="http://polkadot.io/" target="_blank">
-                            Polkadot
-                        </a>{' '}
-                        will allow cryptocurrencies to freely move between blockchains and, naturally, currencies such
-                        as Bitcoin will end up being represented as ERC20 tokens on the Ethereum blockchain.
-                    </div>
-                ),
-            },
-            {
-                prompt: '0x is open source: what prevents someone from forking the protocol?',
-                answer: (
-                    <div>
-                        Ethereum and Bitcoin are both open source protocols. Each protocol has been forked, but the
-                        resulting clone networks have seen little adoption (as measured by transaction count or market
-                        cap). This is because users have little to no incentive to switch over to a clone network if the
-                        original has initial network effects and a talented developer team behind it. An exception is in
-                        the case that a protocol includes a controversial feature such as a method of rent extraction or
-                        a monetary policy that favors one group of users over another (Zcash developer subsidy - for
-                        better or worse - resulted in Zclassic). Perceived inequality can provide a strong enough
-                        incentive that users will fork the original protocol’s codebase and spin up a new network that
-                        eliminates the controversial feature. In the case of 0x, there is no rent extraction and no
-                        users are given special permissions. 0x protocol is upgradable. Cutting-edge technical
-                        capabilities can be integrated into 0x via decentralized governance (see section below),
-                        eliminating incentives to fork off of the original protocol and sacrifice the network effects
-                        surrounding liquidity that result from the shared protocol and settlement layer.
-                    </div>
-                ),
-            },
-        ],
-    },
-    {
-        name: '0x Token (ZRX)',
-        questions: [
-            {
-                prompt: 'Explain how the 0x protocol token (zrx) works.',
-                answer: (
-                    <div>
-                        <div>
-                            0x protocol token (ZRX) is utilized in two ways: 1) to solve the{' '}
-                            <a href="https://en.wikipedia.org/wiki/Coordination_game" target="_blank">
-                                coordination problem
-                            </a>{' '}
-                            and drive network effects around liquidity, creating a feedback loop where early adopters of
-                            the protocol benefit from wider adoption and 2) to be used for decentralized governance over
-                            0x protocol's update mechanism. In more detail:
-                        </div>
-                        <ul>
-                            <li>
-                                ZRX tokens are used by Makers and Takers (market participants that generate and consume
-                                orders, respectively) to pay transaction fees to Relayers (entities that host and
-                                maintain public order books).
-                            </li>
-                            <li>
-                                ZRX tokens are used for decentralized governance over 0x protocol’s update mechanism
-                                which allows its underlying smart contracts to be replaced and improved over time. An
-                                update mechanism is needed because 0x is built upon Ethereum’s rapidly evolving
-                                technology stack, decentralized governance is needed because 0x protocol’s smart
-                                contracts will have access to user funds and numerous dApps will need to plug into 0x
-                                smart contracts. Decentralized governance ensures that this update process is secure and
-                                minimizes disruption to the network.
-                            </li>
-                        </ul>
-                    </div>
-                ),
-            },
-            {
-                prompt: 'Why must transaction fees be denominated in 0x token (ZRX) rather than ETH?',
-                answer: (
-                    <div>
-                        0x protocol’s decentralized update mechanism is analogous to proof-of-stake. To maximize the
-                        alignment of stakeholder and end user incentives, the staked asset must provide utility within
-                        the protocol.
-                    </div>
-                ),
-            },
-            {
-                prompt: 'How will decentralized governance work?',
-                answer: (
-                    <div>
-                        Decentralized governance is an ongoing focus of research; it will involve token voting with ZRX.
-                        Ultimately the solution will maximize security while also maximizing the protocol’s ability to
-                        absorb new innovations. Until the governance structure is formalized and encoded within 0x DAO,
-                        a multi-sig will be used as a placeholder.
-                    </div>
-                ),
-            },
-        ],
-    },
-    {
-        name: 'ZRX Token Launch and Fund Use',
-        questions: [
-            {
-                prompt: 'What is the total supply of ZRX tokens?',
-                answer: <div>1,000,000,000 ZRX. Fixed supply.</div>,
-            },
-            {
-                prompt: 'When is the Token Launch? will there be a pre-sale?',
-                answer: <div>The token launch will be on August 15th, 2017. There will not be a pre-sale.</div>,
-            },
-            {
-                prompt: 'What will the token launch proceeds be used for?',
-                answer: (
-                    <div>
-                        100% of the proceeds raised in the token launch will be used to fund the development of free and
-                        open source software, tools and infrastructure that support the protocol and surrounding
-                        ecosystem. Check out our{' '}
-                        <a
-                            href="https://docs.google.com/document/d/1_RVa-_bkU92fWRsC8eNy4vYjcTt-WC8GtqyyjbTd-oY"
-                            target="_blank"
-                        >
-                            development roadmap
-                        </a>.
-                    </div>
-                ),
-            },
-            {
-                prompt: 'What will be the initial distribution of ZRX tokens?',
-                answer: (
-                    <div>
-                        <div className="center" style={{ width: '100%' }}>
-                            <img style={{ width: 350 }} src="/images/zrx_pie_chart.png" />
-                        </div>
-                        <div className="py1">
-                            <div className="bold pb1">Token Launch (50%)</div>
-                            <div>
-                                ZRX is inherently a governance token that plays a critical role in the process of
-                                upgrading 0x protocol. We are fully committed to formulating a functional and
-                                theoretically sound governance model and we plan to dedicate significant resources to
-                                R&D.
-                            </div>
-                        </div>
-                        <div className="py1">
-                            <div className="bold pb1">Retained by 0x (15%)</div>
-                            <div>
-                                The 0x core development team will be able to sustain itself for approximately five years
-                                using funds raised through the token launch. If 0x protocol proves to be as foundational
-                                a technology as we believe it to be, the retained ZRX tokens will allow the 0x core
-                                development team to sustain operations beyond the first 5 years.
-                            </div>
-                        </div>
-                        <div className="py1">
-                            <div className="bold pb1">Developer Fund (15%)</div>
-                            <div>
-                                The Developer Fund will be used to make targeted capital injections into high potential
-                                projects and teams that are attempting to grow the 0x ecosystem, strategic partnerships,
-                                hackathon prizes and community development activities.
-                            </div>
-                        </div>
-                        <div className="py1">
-                            <div className="bold pb1">Founding Team (10%)</div>
-                            <div>
-                                The founding team’s allocation of ZRX will vest over a traditional 4 year vesting
-                                schedule with a one year cliff. We believe this should be standard practice for any team
-                                that is committed to making their project a long term success.
-                            </div>
-                        </div>
-                        <div className="py1">
-                            <div className="bold pb1">Early Backers & Advisors (10%)</div>
-                            <div>
-                                Our backers and advisors have provided capital, resources and guidance that have allowed
-                                us to fill out our team, setup a robust legal entity and build a fully functional
-                                product before launching a token. As a result, we have a proven track record and can
-                                offer a token that holds genuine utility.
-                            </div>
-                        </div>
-                    </div>
-                ),
-            },
-            {
-                prompt: 'Can I mine ZRX tokens?',
-                answer: (
-                    <div>
-                        No, the total supply of ZRX tokens is fixed and there is no continuous issuance model. Users
-                        that facilitate trading over 0x protocol by operating a Relayer earn transaction fees
-                        denominated in ZRX; as more trading activity is generated, more transaction fees are earned.
-                    </div>
-                ),
-            },
-            {
-                prompt: 'Will there be a lockup period for ZRX tokens sold in the token launch?',
-                answer: <div>No, ZRX tokens sold in the token launch will immediately be liquid.</div>,
-            },
-            {
-                prompt: 'Will there be a lockup period for tokens allocated to the founding team?',
-                answer: (
-                    <div>
-                        Yes. ZRX tokens allocated to founders, advisors and staff members will be released over a 4 year
-                        vesting schedule with a 25% cliff upon completion of the initial token launch and 25% released
-                        each subsequent year in monthly installments. Staff members hired after the token launch will
-                        have a 4 year vesting schedule with a one year cliff.
-                    </div>
-                ),
-            },
-            {
-                prompt: 'Which cryptocurrencies will be accepted in the token launch?',
-                answer: <div>ETH.</div>,
-            },
-            {
-                prompt: 'When will 0x be live?',
-                answer: (
-                    <div>
-                        An alpha version of 0x has been live on our private test network since January 2017. Version 1.0
-                        of 0x protocol will be deployed to the canonical Ethereum blockchain after a round of security
-                        audits and prior to the public token launch. 0x will be using the 0x protocol during our token
-                        launch.
-                    </div>
-                ),
-            },
-            {
-                prompt: 'Where can I find a development roadmap?',
-                answer: (
-                    <div>
-                        Check it out{' '}
-                        <a
-                            href="https://drive.google.com/open?id=14IP1N8mt3YdsAoqYTyruMnZswpklUs3THyS1VXx71fo"
-                            target="_blank"
-                        >
-                            here
-                        </a>.
-                    </div>
-                ),
-            },
-        ],
-    },
-    {
-        name: 'Team',
-        questions: [
-            {
-                prompt: 'Where is 0x based?',
-                answer: <div>0x was founded in SF and is driven by a diverse group of contributors.</div>,
-            },
-            {
-                prompt: 'How can I get involved?',
-                answer: (
-                    <div>
-                        Join our{' '}
-                        <a href={constants.URL_ZEROEX_CHAT} target="_blank">
-                            Rocket.chat
-                        </a>! As an open source project, 0x will rely on a worldwide community of passionate developers
-                        to contribute proposals, ideas and code.
-                    </div>
-                ),
-            },
-            {
-                prompt: 'Why the name 0x?',
-                answer: (
-                    <div>
-                        0x is the prefix for hexadecimal numeric constants including Ethereum addresses. In a more
-                        abstract context, as the first open protocol for exchange 0x represents the beginning of the end
-                        for the exchange industry’s rent seeking oligopoly: zero exchange.
-                    </div>
-                ),
-            },
-            {
-                prompt: 'How do you pronounce 0x?',
-                answer: <div>We pronounce 0x as “zero-ex,” but you are free to pronounce it however you please.</div>,
-            },
-        ],
-    },
+	{
+		name: '0x Protocol',
+		questions: [
+			{
+				prompt: 'What is 0x?',
+				answer: (
+					<div>
+						At its core, 0x is an open and non-rent seeking protocol that facilitates trustless, low
+						friction exchange of Ethereum-based assets. Developers can use 0x as a platform to build
+						exchange applications on top of (<a
+							href={`${configs.BASE_URL}${WebsitePaths.ZeroExJs}#introduction`}
+							target="blank"
+						>
+							0x.js
+						</a>{' '}
+						is a Javascript library for interacting with the 0x protocol). For end users, 0x will be the
+						infrastructure of a wide variety of user-facing applications i.e.{' '}
+						<a href={`${configs.BASE_URL}${WebsitePaths.Portal}`} target="blank">
+							0x Portal
+						</a>, a decentralized application that facilitates trustless trading of Ethereum-based tokens
+						between known counterparties.
+					</div>
+				),
+			},
+			{
+				prompt: 'What problem does 0x solve?',
+				answer: (
+					<div>
+						In the two years since the Ethereum blockchain’s genesis block, numerous decentralized
+						applications (dApps) have created Ethereum smart contracts for peer-to-peer exchange. Rapid
+						iteration and a lack of best practices have left the blockchain scattered with proprietary and
+						application-specific implementations. As a result, end users are exposed to numerous smart
+						contracts of varying quality and security, with unique configuration processes and learning
+						curves, all of which implement the same functionality. This approach imposes unnecessary costs
+						on the network by fragmenting end users according to the particular dApp each user happens to be
+						using, eliminating valuable network effects around liquidity. 0x is the solution to this problem
+						by acting as modular, unopinionated building blocks that may be assembled and reconfigured.
+					</div>
+				),
+			},
+			{
+				prompt: 'How is 0x different from a centralized exchange like Poloniex or ShapeShift?',
+				answer: (
+					<div>
+						<ul>
+							<li>0x is a protocol for exchange, not a user-facing exchange application.</li>
+							<li>
+								0x is decentralized and trustless; there is no central party which can be hacked, run
+								away with customer funds or be subjected to government regulations. Hacks of Mt. Gox,
+								Shapeshift and Bitfinex have demonstrated that these types of systemic risks are
+								palpable.
+							</li>
+							<li>
+								Rather than a proprietary system that exists to extract rent for its owners, 0x is
+								public infrastructure that is funded by a globally distributed community of
+								stakeholders. While the protocol is free to use, it enables for-profit user-facing
+								exchange applications to be built on top of the protocol.
+							</li>
+						</ul>
+					</div>
+				),
+			},
+			{
+				prompt: 'If 0x protocol is free to use, where do transaction fees come in?',
+				answer: (
+					<div>
+						0x protocol uses off-chain order books to massively reduce friction costs for market makers and
+						ensure that the blockchain is only used for trade settlement. Hosting and maintaining an
+						off-chain order book is a service; to incent “Relayers” to provide this service they must be
+						able to charge transaction fees on trading activity. Relayers are free to set their transaction
+						fees to any value they desire. We expect Relayers to be highly competitive and transaction fees
+						to approach an efficient economic equilibrium over time.
+					</div>
+				),
+			},
+			{
+				prompt: 'What are the differences between 0x protocol and state channels?',
+				answer: (
+					<div>
+						<div>
+							Participants in a state channel pass cryptographically signed messages back and forth,
+							accumulating intermediate state changes without publishing them to the canonical chain until
+							the channel is closed. State channels are ideal for “bar tab” applications where numerous
+							intermediate state changes may be accumulated off-chain before being settled by a final
+							on-chain transaction (i.e. day trading, poker, turn-based games).
+						</div>
+						<ul>
+							<li>
+								While state channels drastically reduce the number of on-chain transactions for specific
+								use cases, numerous on-chain transactions and a security deposit are required to open
+								and safely close a state channel making them less efficient than 0x for executing
+								one-time trades.
+							</li>
+							<li>
+								State channels are isolated from the Ethereum blockchain meaning that they cannot
+								interact with smart contracts. 0x is designed to be integrated directly into smart
+								contracts so trades can be executed programmatically in a single line of Solidity code.
+							</li>
+						</ul>
+					</div>
+				),
+			},
+			{
+				prompt: 'What types of digital assets are supported by 0x?',
+				answer: (
+					<div>
+						0x supports all Ethereum-based assets that adhere to the ERC20 token standard. There are many
+						ERC20 tokens, worth a combined $2.2B, and more tokens are created each month. We believe that,
+						by 2020, thousands of assets will be tokenized and moved onto the Ethereum blockchain including
+						traditional securities such as equities, bonds and derivatives, fiat currencies and scarce
+						digital goods such as video game items. In the future, cross-blockchain solutions such as{' '}
+						<a href="https://cosmos.network/" target="_blank">
+							Cosmos
+						</a>{' '}
+						and{' '}
+						<a href="http://polkadot.io/" target="_blank">
+							Polkadot
+						</a>{' '}
+						will allow cryptocurrencies to freely move between blockchains and, naturally, currencies such
+						as Bitcoin will end up being represented as ERC20 tokens on the Ethereum blockchain.
+					</div>
+				),
+			},
+			{
+				prompt: '0x is open source: what prevents someone from forking the protocol?',
+				answer: (
+					<div>
+						Ethereum and Bitcoin are both open source protocols. Each protocol has been forked, but the
+						resulting clone networks have seen little adoption (as measured by transaction count or market
+						cap). This is because users have little to no incentive to switch over to a clone network if the
+						original has initial network effects and a talented developer team behind it. An exception is in
+						the case that a protocol includes a controversial feature such as a method of rent extraction or
+						a monetary policy that favors one group of users over another (Zcash developer subsidy - for
+						better or worse - resulted in Zclassic). Perceived inequality can provide a strong enough
+						incentive that users will fork the original protocol’s codebase and spin up a new network that
+						eliminates the controversial feature. In the case of 0x, there is no rent extraction and no
+						users are given special permissions. 0x protocol is upgradable. Cutting-edge technical
+						capabilities can be integrated into 0x via decentralized governance (see section below),
+						eliminating incentives to fork off of the original protocol and sacrifice the network effects
+						surrounding liquidity that result from the shared protocol and settlement layer.
+					</div>
+				),
+			},
+		],
+	},
+	{
+		name: '0x Token (ZRX)',
+		questions: [
+			{
+				prompt: 'Explain how the 0x protocol token (zrx) works.',
+				answer: (
+					<div>
+						<div>
+							0x protocol token (ZRX) is utilized in two ways: 1) to solve the{' '}
+							<a href="https://en.wikipedia.org/wiki/Coordination_game" target="_blank">
+								coordination problem
+							</a>{' '}
+							and drive network effects around liquidity, creating a feedback loop where early adopters of
+							the protocol benefit from wider adoption and 2) to be used for decentralized governance over
+							0x protocol's update mechanism. In more detail:
+						</div>
+						<ul>
+							<li>
+								ZRX tokens are used by Makers and Takers (market participants that generate and consume
+								orders, respectively) to pay transaction fees to Relayers (entities that host and
+								maintain public order books).
+							</li>
+							<li>
+								ZRX tokens are used for decentralized governance over 0x protocol’s update mechanism
+								which allows its underlying smart contracts to be replaced and improved over time. An
+								update mechanism is needed because 0x is built upon Ethereum’s rapidly evolving
+								technology stack, decentralized governance is needed because 0x protocol’s smart
+								contracts will have access to user funds and numerous dApps will need to plug into 0x
+								smart contracts. Decentralized governance ensures that this update process is secure and
+								minimizes disruption to the network.
+							</li>
+						</ul>
+					</div>
+				),
+			},
+			{
+				prompt: 'Why must transaction fees be denominated in 0x token (ZRX) rather than ETH?',
+				answer: (
+					<div>
+						0x protocol’s decentralized update mechanism is analogous to proof-of-stake. To maximize the
+						alignment of stakeholder and end user incentives, the staked asset must provide utility within
+						the protocol.
+					</div>
+				),
+			},
+			{
+				prompt: 'How will decentralized governance work?',
+				answer: (
+					<div>
+						Decentralized governance is an ongoing focus of research; it will involve token voting with ZRX.
+						Ultimately the solution will maximize security while also maximizing the protocol’s ability to
+						absorb new innovations. Until the governance structure is formalized and encoded within 0x DAO,
+						a multi-sig will be used as a placeholder.
+					</div>
+				),
+			},
+		],
+	},
+	{
+		name: 'ZRX Token Launch and Fund Use',
+		questions: [
+			{
+				prompt: 'What is the total supply of ZRX tokens?',
+				answer: <div>1,000,000,000 ZRX. Fixed supply.</div>,
+			},
+			{
+				prompt: 'When is the Token Launch? will there be a pre-sale?',
+				answer: <div>The token launch will be on August 15th, 2017. There will not be a pre-sale.</div>,
+			},
+			{
+				prompt: 'What will the token launch proceeds be used for?',
+				answer: (
+					<div>
+						100% of the proceeds raised in the token launch will be used to fund the development of free and
+						open source software, tools and infrastructure that support the protocol and surrounding
+						ecosystem. Check out our{' '}
+						<a
+							href="https://docs.google.com/document/d/1_RVa-_bkU92fWRsC8eNy4vYjcTt-WC8GtqyyjbTd-oY"
+							target="_blank"
+						>
+							development roadmap
+						</a>.
+					</div>
+				),
+			},
+			{
+				prompt: 'What will be the initial distribution of ZRX tokens?',
+				answer: (
+					<div>
+						<div className="center" style={{ width: '100%' }}>
+							<img style={{ width: 350 }} src="/images/zrx_pie_chart.png" />
+						</div>
+						<div className="py1">
+							<div className="bold pb1">Token Launch (50%)</div>
+							<div>
+								ZRX is inherently a governance token that plays a critical role in the process of
+								upgrading 0x protocol. We are fully committed to formulating a functional and
+								theoretically sound governance model and we plan to dedicate significant resources to
+								R&D.
+							</div>
+						</div>
+						<div className="py1">
+							<div className="bold pb1">Retained by 0x (15%)</div>
+							<div>
+								The 0x core development team will be able to sustain itself for approximately five years
+								using funds raised through the token launch. If 0x protocol proves to be as foundational
+								a technology as we believe it to be, the retained ZRX tokens will allow the 0x core
+								development team to sustain operations beyond the first 5 years.
+							</div>
+						</div>
+						<div className="py1">
+							<div className="bold pb1">Developer Fund (15%)</div>
+							<div>
+								The Developer Fund will be used to make targeted capital injections into high potential
+								projects and teams that are attempting to grow the 0x ecosystem, strategic partnerships,
+								hackathon prizes and community development activities.
+							</div>
+						</div>
+						<div className="py1">
+							<div className="bold pb1">Founding Team (10%)</div>
+							<div>
+								The founding team’s allocation of ZRX will vest over a traditional 4 year vesting
+								schedule with a one year cliff. We believe this should be standard practice for any team
+								that is committed to making their project a long term success.
+							</div>
+						</div>
+						<div className="py1">
+							<div className="bold pb1">Early Backers & Advisors (10%)</div>
+							<div>
+								Our backers and advisors have provided capital, resources and guidance that have allowed
+								us to fill out our team, setup a robust legal entity and build a fully functional
+								product before launching a token. As a result, we have a proven track record and can
+								offer a token that holds genuine utility.
+							</div>
+						</div>
+					</div>
+				),
+			},
+			{
+				prompt: 'Can I mine ZRX tokens?',
+				answer: (
+					<div>
+						No, the total supply of ZRX tokens is fixed and there is no continuous issuance model. Users
+						that facilitate trading over 0x protocol by operating a Relayer earn transaction fees
+						denominated in ZRX; as more trading activity is generated, more transaction fees are earned.
+					</div>
+				),
+			},
+			{
+				prompt: 'Will there be a lockup period for ZRX tokens sold in the token launch?',
+				answer: <div>No, ZRX tokens sold in the token launch will immediately be liquid.</div>,
+			},
+			{
+				prompt: 'Will there be a lockup period for tokens allocated to the founding team?',
+				answer: (
+					<div>
+						Yes. ZRX tokens allocated to founders, advisors and staff members will be released over a 4 year
+						vesting schedule with a 25% cliff upon completion of the initial token launch and 25% released
+						each subsequent year in monthly installments. Staff members hired after the token launch will
+						have a 4 year vesting schedule with a one year cliff.
+					</div>
+				),
+			},
+			{
+				prompt: 'Which cryptocurrencies will be accepted in the token launch?',
+				answer: <div>ETH.</div>,
+			},
+			{
+				prompt: 'When will 0x be live?',
+				answer: (
+					<div>
+						An alpha version of 0x has been live on our private test network since January 2017. Version 1.0
+						of 0x protocol will be deployed to the canonical Ethereum blockchain after a round of security
+						audits and prior to the public token launch. 0x will be using the 0x protocol during our token
+						launch.
+					</div>
+				),
+			},
+			{
+				prompt: 'Where can I find a development roadmap?',
+				answer: (
+					<div>
+						Check it out{' '}
+						<a
+							href="https://drive.google.com/open?id=14IP1N8mt3YdsAoqYTyruMnZswpklUs3THyS1VXx71fo"
+							target="_blank"
+						>
+							here
+						</a>.
+					</div>
+				),
+			},
+		],
+	},
+	{
+		name: 'Team',
+		questions: [
+			{
+				prompt: 'Where is 0x based?',
+				answer: <div>0x was founded in SF and is driven by a diverse group of contributors.</div>,
+			},
+			{
+				prompt: 'How can I get involved?',
+				answer: (
+					<div>
+						Join our{' '}
+						<a href={constants.URL_ZEROEX_CHAT} target="_blank">
+							Rocket.chat
+						</a>! As an open source project, 0x will rely on a worldwide community of passionate developers
+						to contribute proposals, ideas and code.
+					</div>
+				),
+			},
+			{
+				prompt: 'Why the name 0x?',
+				answer: (
+					<div>
+						0x is the prefix for hexadecimal numeric constants including Ethereum addresses. In a more
+						abstract context, as the first open protocol for exchange 0x represents the beginning of the end
+						for the exchange industry’s rent seeking oligopoly: zero exchange.
+					</div>
+				),
+			},
+			{
+				prompt: 'How do you pronounce 0x?',
+				answer: <div>We pronounce 0x as “zero-ex,” but you are free to pronounce it however you please.</div>,
+			},
+		],
+	},
 ];
 
 export class FAQ extends React.Component<FAQProps, FAQState> {
-    public componentDidMount() {
-        window.scrollTo(0, 0);
-    }
-    public render() {
-        return (
-            <div>
-                <DocumentTitle title="0x FAQ" />
-                <TopBar blockchainIsLoaded={false} location={this.props.location} />
-                <div id="faq" className="mx-auto max-width-4 pt4" style={{ color: colors.grey800 }}>
-                    <h1 className="center" style={{ ...styles.thin }}>
-                        0x FAQ
-                    </h1>
-                    <div className="sm-px2 md-px2 lg-px0 pb4">{this._renderSections()}</div>
-                </div>
-                <Footer />
-            </div>
-        );
-    }
-    private _renderSections() {
-        const renderedSections = _.map(sections, (section: FAQSection, i: number) => {
-            const isFirstSection = i === 0;
-            return (
-                <div key={section.name}>
-                    <h3>{section.name}</h3>
-                    {this._renderQuestions(section.questions, isFirstSection)}
-                </div>
-            );
-        });
-        return renderedSections;
-    }
-    private _renderQuestions(questions: FAQQuestion[], isFirstSection: boolean) {
-        const renderedQuestions = _.map(questions, (question: FAQQuestion, i: number) => {
-            const isFirstQuestion = i === 0;
-            return (
-                <Question
-                    key={question.prompt}
-                    prompt={question.prompt}
-                    answer={question.answer}
-                    shouldDisplayExpanded={isFirstSection && isFirstQuestion}
-                />
-            );
-        });
-        return renderedQuestions;
-    }
+	public componentDidMount() {
+		window.scrollTo(0, 0);
+	}
+	public render() {
+		return (
+			<div>
+				<DocumentTitle title="0x FAQ" />
+				<TopBar blockchainIsLoaded={false} location={this.props.location} />
+				<div id="faq" className="mx-auto max-width-4 pt4" style={{ color: colors.grey800 }}>
+					<h1 className="center" style={{ ...styles.thin }}>
+						0x FAQ
+					</h1>
+					<div className="sm-px2 md-px2 lg-px0 pb4">{this._renderSections()}</div>
+				</div>
+				<Footer />
+			</div>
+		);
+	}
+	private _renderSections() {
+		const renderedSections = _.map(sections, (section: FAQSection, i: number) => {
+			const isFirstSection = i === 0;
+			return (
+				<div key={section.name}>
+					<h3>{section.name}</h3>
+					{this._renderQuestions(section.questions, isFirstSection)}
+				</div>
+			);
+		});
+		return renderedSections;
+	}
+	private _renderQuestions(questions: FAQQuestion[], isFirstSection: boolean) {
+		const renderedQuestions = _.map(questions, (question: FAQQuestion, i: number) => {
+			const isFirstQuestion = i === 0;
+			return (
+				<Question
+					key={question.prompt}
+					prompt={question.prompt}
+					answer={question.answer}
+					shouldDisplayExpanded={isFirstSection && isFirstQuestion}
+				/>
+			);
+		});
+		return renderedQuestions;
+	}
 }
diff --git a/packages/website/ts/pages/faq/question.tsx b/packages/website/ts/pages/faq/question.tsx
index 988c04bc9..58cf674ef 100644
--- a/packages/website/ts/pages/faq/question.tsx
+++ b/packages/website/ts/pages/faq/question.tsx
@@ -4,48 +4,48 @@ import * as React from 'react';
 import { colors } from 'ts/utils/colors';
 
 export interface QuestionProps {
-    prompt: string;
-    answer: React.ReactNode;
-    shouldDisplayExpanded: boolean;
+	prompt: string;
+	answer: React.ReactNode;
+	shouldDisplayExpanded: boolean;
 }
 
 interface QuestionState {
-    isExpanded: boolean;
+	isExpanded: boolean;
 }
 
 export class Question extends React.Component<QuestionProps, QuestionState> {
-    constructor(props: QuestionProps) {
-        super(props);
-        this.state = {
-            isExpanded: props.shouldDisplayExpanded,
-        };
-    }
-    public render() {
-        return (
-            <div className="py1">
-                <Card
-                    initiallyExpanded={this.props.shouldDisplayExpanded}
-                    onExpandChange={this._onExchangeChange.bind(this)}
-                >
-                    <CardHeader
-                        title={this.props.prompt}
-                        style={{
-                            borderBottom: this.state.isExpanded ? '1px solid rgba(0, 0, 0, 0.19)' : 'none',
-                        }}
-                        titleStyle={{ color: colors.darkerGrey }}
-                        actAsExpander={true}
-                        showExpandableButton={true}
-                    />
-                    <CardText expandable={true}>
-                        <div style={{ lineHeight: 1.4 }}>{this.props.answer}</div>
-                    </CardText>
-                </Card>
-            </div>
-        );
-    }
-    private _onExchangeChange() {
-        this.setState({
-            isExpanded: !this.state.isExpanded,
-        });
-    }
+	constructor(props: QuestionProps) {
+		super(props);
+		this.state = {
+			isExpanded: props.shouldDisplayExpanded,
+		};
+	}
+	public render() {
+		return (
+			<div className="py1">
+				<Card
+					initiallyExpanded={this.props.shouldDisplayExpanded}
+					onExpandChange={this._onExchangeChange.bind(this)}
+				>
+					<CardHeader
+						title={this.props.prompt}
+						style={{
+							borderBottom: this.state.isExpanded ? '1px solid rgba(0, 0, 0, 0.19)' : 'none',
+						}}
+						titleStyle={{ color: colors.darkerGrey }}
+						actAsExpander={true}
+						showExpandableButton={true}
+					/>
+					<CardText expandable={true}>
+						<div style={{ lineHeight: 1.4 }}>{this.props.answer}</div>
+					</CardText>
+				</Card>
+			</div>
+		);
+	}
+	private _onExchangeChange() {
+		this.setState({
+			isExpanded: !this.state.isExpanded,
+		});
+	}
 }
diff --git a/packages/website/ts/pages/landing/landing.tsx b/packages/website/ts/pages/landing/landing.tsx
index ca76497df..742d94a0f 100644
--- a/packages/website/ts/pages/landing/landing.tsx
+++ b/packages/website/ts/pages/landing/landing.tsx
@@ -11,755 +11,755 @@ import { constants } from 'ts/utils/constants';
 import { utils } from 'ts/utils/utils';
 
 interface BoxContent {
-    title: string;
-    description: string;
-    imageUrl: string;
-    classNames: string;
+	title: string;
+	description: string;
+	imageUrl: string;
+	classNames: string;
 }
 interface AssetType {
-    title: string;
-    imageUrl: string;
-    style?: React.CSSProperties;
+	title: string;
+	imageUrl: string;
+	style?: React.CSSProperties;
 }
 interface UseCase {
-    imageUrl: string;
-    type: string;
-    description: string;
-    classNames: string;
-    style?: React.CSSProperties;
-    projectIconUrls: string[];
+	imageUrl: string;
+	type: string;
+	description: string;
+	classNames: string;
+	style?: React.CSSProperties;
+	projectIconUrls: string[];
 }
 interface Project {
-    logoFileName: string;
-    projectUrl: string;
+	logoFileName: string;
+	projectUrl: string;
 }
 
 const THROTTLE_TIMEOUT = 100;
 
 const boxContents: BoxContent[] = [
-    {
-        title: 'Trustless exchange',
-        description:
-            "Built on Ethereum's distributed network with no centralized \
+	{
+		title: 'Trustless exchange',
+		description:
+			"Built on Ethereum's distributed network with no centralized \
                       point of failure and no down time, each trade is settled atomically \
                       and without counterparty risk.",
-        imageUrl: '/images/landing/distributed_network.png',
-        classNames: '',
-    },
-    {
-        title: 'Shared liquidity',
-        description:
-            'By sharing a standard API, relayers can easily aggregate liquidity pools, \
+		imageUrl: '/images/landing/distributed_network.png',
+		classNames: '',
+	},
+	{
+		title: 'Shared liquidity',
+		description:
+			'By sharing a standard API, relayers can easily aggregate liquidity pools, \
                       creating network effects around liquidity that compound as more relayers come online.',
-        imageUrl: '/images/landing/liquidity.png',
-        classNames: 'mx-auto',
-    },
-    {
-        title: 'Open source',
-        description:
-            '0x is open source, permissionless and free to use. Trade directly with a known \
+		imageUrl: '/images/landing/liquidity.png',
+		classNames: 'mx-auto',
+	},
+	{
+		title: 'Open source',
+		description:
+			'0x is open source, permissionless and free to use. Trade directly with a known \
                       counterparty for free or pay a relayer some ZRX tokens to access their liquidity \
                       pool.',
-        imageUrl: '/images/landing/open_source.png',
-        classNames: 'right',
-    },
+		imageUrl: '/images/landing/open_source.png',
+		classNames: 'right',
+	},
 ];
 
 const projects: Project[] = [
-    {
-        logoFileName: 'ethfinex-top.png',
-        projectUrl: constants.PROJECT_URL_ETHFINEX,
-    },
-    {
-        logoFileName: 'radar_relay_top.png',
-        projectUrl: constants.PROJECT_URL_RADAR_RELAY,
-    },
-    {
-        logoFileName: 'paradex_top.png',
-        projectUrl: constants.PROJECT_URL_PARADEX,
-    },
-    {
-        logoFileName: 'the_ocean.png',
-        projectUrl: constants.PROJECT_URL_0CEAN,
-    },
-    {
-        logoFileName: 'dydx.png',
-        projectUrl: constants.PROJECT_URL_DYDX,
-    },
-    {
-        logoFileName: 'melonport.png',
-        projectUrl: constants.PROJECT_URL_MELONPORT,
-    },
-    {
-        logoFileName: 'maker.png',
-        projectUrl: constants.PROJECT_URL_MAKER,
-    },
-    {
-        logoFileName: 'dharma.png',
-        projectUrl: constants.PROJECT_URL_DHARMA,
-    },
-    {
-        logoFileName: 'lendroid.png',
-        projectUrl: constants.PROJECT_URL_LENDROID,
-    },
-    {
-        logoFileName: 'district0x.png',
-        projectUrl: constants.PROJECT_URL_DISTRICT_0X,
-    },
-    {
-        logoFileName: 'aragon.png',
-        projectUrl: constants.PROJECT_URL_ARAGON,
-    },
-    {
-        logoFileName: 'blocknet.png',
-        projectUrl: constants.PROJECT_URL_BLOCKNET,
-    },
-    {
-        logoFileName: 'status.png',
-        projectUrl: constants.PROJECT_URL_STATUS,
-    },
-    {
-        logoFileName: 'augur.png',
-        projectUrl: constants.PROJECT_URL_AUGUR,
-    },
-    {
-        logoFileName: 'anx.png',
-        projectUrl: constants.PROJECT_URL_OPEN_ANX,
-    },
-    {
-        logoFileName: 'auctus.png',
-        projectUrl: constants.PROJECT_URL_AUCTUS,
-    },
+	{
+		logoFileName: 'ethfinex-top.png',
+		projectUrl: constants.PROJECT_URL_ETHFINEX,
+	},
+	{
+		logoFileName: 'radar_relay_top.png',
+		projectUrl: constants.PROJECT_URL_RADAR_RELAY,
+	},
+	{
+		logoFileName: 'paradex_top.png',
+		projectUrl: constants.PROJECT_URL_PARADEX,
+	},
+	{
+		logoFileName: 'the_ocean.png',
+		projectUrl: constants.PROJECT_URL_0CEAN,
+	},
+	{
+		logoFileName: 'dydx.png',
+		projectUrl: constants.PROJECT_URL_DYDX,
+	},
+	{
+		logoFileName: 'melonport.png',
+		projectUrl: constants.PROJECT_URL_MELONPORT,
+	},
+	{
+		logoFileName: 'maker.png',
+		projectUrl: constants.PROJECT_URL_MAKER,
+	},
+	{
+		logoFileName: 'dharma.png',
+		projectUrl: constants.PROJECT_URL_DHARMA,
+	},
+	{
+		logoFileName: 'lendroid.png',
+		projectUrl: constants.PROJECT_URL_LENDROID,
+	},
+	{
+		logoFileName: 'district0x.png',
+		projectUrl: constants.PROJECT_URL_DISTRICT_0X,
+	},
+	{
+		logoFileName: 'aragon.png',
+		projectUrl: constants.PROJECT_URL_ARAGON,
+	},
+	{
+		logoFileName: 'blocknet.png',
+		projectUrl: constants.PROJECT_URL_BLOCKNET,
+	},
+	{
+		logoFileName: 'status.png',
+		projectUrl: constants.PROJECT_URL_STATUS,
+	},
+	{
+		logoFileName: 'augur.png',
+		projectUrl: constants.PROJECT_URL_AUGUR,
+	},
+	{
+		logoFileName: 'anx.png',
+		projectUrl: constants.PROJECT_URL_OPEN_ANX,
+	},
+	{
+		logoFileName: 'auctus.png',
+		projectUrl: constants.PROJECT_URL_AUCTUS,
+	},
 ];
 
 export interface LandingProps {
-    location: Location;
+	location: Location;
 }
 
 interface LandingState {
-    screenWidth: ScreenWidths;
+	screenWidth: ScreenWidths;
 }
 
 export class Landing extends React.Component<LandingProps, LandingState> {
-    private _throttledScreenWidthUpdate: () => void;
-    constructor(props: LandingProps) {
-        super(props);
-        this.state = {
-            screenWidth: utils.getScreenWidth(),
-        };
-        this._throttledScreenWidthUpdate = _.throttle(this._updateScreenWidth.bind(this), THROTTLE_TIMEOUT);
-    }
-    public componentDidMount() {
-        window.addEventListener('resize', this._throttledScreenWidthUpdate);
-        window.scrollTo(0, 0);
-    }
-    public componentWillUnmount() {
-        window.removeEventListener('resize', this._throttledScreenWidthUpdate);
-    }
-    public render() {
-        return (
-            <div id="landing" className="clearfix" style={{ color: colors.grey500 }}>
-                <DocumentTitle title="0x Protocol" />
-                <TopBar
-                    blockchainIsLoaded={false}
-                    location={this.props.location}
-                    isNightVersion={true}
-                    style={{ backgroundColor: colors.heroGrey, position: 'relative' }}
-                />
-                {this._renderHero()}
-                {this._renderProjects()}
-                {this._renderTokenizationSection()}
-                {this._renderProtocolSection()}
-                {this._renderInfoBoxes()}
-                {this._renderBuildingBlocksSection()}
-                {this._renderUseCases()}
-                {this._renderCallToAction()}
-                <Footer />
-            </div>
-        );
-    }
-    private _renderHero() {
-        const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
-        const buttonLabelStyle: React.CSSProperties = {
-            textTransform: 'none',
-            fontSize: isSmallScreen ? 12 : 14,
-            fontWeight: 400,
-        };
-        const lightButtonStyle: React.CSSProperties = {
-            borderRadius: 6,
-            border: '1px solid #D8D8D8',
-            lineHeight: '33px',
-            height: 38,
-        };
-        const left = 'col lg-col-7 md-col-7 col-12 lg-pt4 md-pt4 sm-pt0 mt1 lg-pl4 md-pl4 sm-pl0 sm-px3 sm-center';
-        return (
-            <div className="clearfix py4" style={{ backgroundColor: colors.heroGrey }}>
-                <div className="mx-auto max-width-4 clearfix">
-                    <div className="lg-pt4 md-pt4 sm-pt2 lg-pb4 md-pb4 lg-my4 md-my4 sm-mt2 sm-mb4 clearfix">
-                        <div className="col lg-col-5 md-col-5 col-12 sm-center">
-                            <img src="/images/landing/hero_chip_image.png" height={isSmallScreen ? 300 : 395} />
-                        </div>
-                        <div className={left} style={{ color: colors.white }}>
-                            <div style={{ paddingLeft: isSmallScreen ? 0 : 12 }}>
-                                <div
-                                    className="sm-pb2"
-                                    style={{
-                                        fontFamily: 'Roboto Mono',
-                                        fontSize: isSmallScreen ? 26 : 34,
-                                    }}
-                                >
-                                    Powering decentralized exchange
-                                </div>
-                                <div
-                                    className="pt2 h5 sm-mx-auto"
-                                    style={{
-                                        maxWidth: 446,
-                                        fontFamily: 'Roboto Mono',
-                                        lineHeight: 1.7,
-                                        fontWeight: 300,
-                                    }}
-                                >
-                                    0x is an open, permissionless protocol allowing for ERC20 tokens to be traded on the
-                                    Ethereum blockchain.
-                                </div>
-                                <div className="pt3 clearfix sm-mx-auto" style={{ maxWidth: 342 }}>
-                                    <div className="lg-pr2 md-pr2 col col-6 sm-center">
-                                        <Link to={WebsitePaths.ZeroExJs} className="text-decoration-none">
-                                            <RaisedButton
-                                                style={{ borderRadius: 6, minWidth: 157.36 }}
-                                                buttonStyle={{ borderRadius: 6 }}
-                                                labelStyle={buttonLabelStyle}
-                                                label="Build on 0x"
-                                                onClick={_.noop}
-                                            />
-                                        </Link>
-                                    </div>
-                                    <div className="col col-6 sm-center">
-                                        <a
-                                            href={constants.URL_ZEROEX_CHAT}
-                                            target="_blank"
-                                            className="text-decoration-none"
-                                        >
-                                            <RaisedButton
-                                                style={{ borderRadius: 6, minWidth: 150 }}
-                                                buttonStyle={lightButtonStyle}
-                                                labelColor="white"
-                                                backgroundColor={colors.heroGrey}
-                                                labelStyle={buttonLabelStyle}
-                                                label="Join the community"
-                                                onClick={_.noop}
-                                            />
-                                        </a>
-                                    </div>
-                                </div>
-                            </div>
-                        </div>
-                    </div>
-                </div>
-            </div>
-        );
-    }
-    private _renderProjects() {
-        const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
-        const isMediumScreen = this.state.screenWidth === ScreenWidths.Md;
-        const projectList = _.map(projects, (project: Project, i: number) => {
-            const colWidth = isSmallScreen ? 3 : isMediumScreen ? 4 : 2 - i % 2;
-            return (
-                <div key={`project-${project.logoFileName}`} className={`col col-${colWidth} center`}>
-                    <div>
-                        <a href={project.projectUrl} target="_blank" className="text-decoration-none">
-                            <img
-                                src={`/images/landing/project_logos/${project.logoFileName}`}
-                                height={isSmallScreen ? 60 : 92}
-                            />
-                        </a>
-                    </div>
-                </div>
-            );
-        });
-        const titleStyle: React.CSSProperties = {
-            fontFamily: 'Roboto Mono',
-            color: colors.grey,
-            textTransform: 'uppercase',
-            fontWeight: 300,
-            letterSpacing: 3,
-        };
-        return (
-            <div className="clearfix py4" style={{ backgroundColor: colors.projectsGrey }}>
-                <div className="mx-auto max-width-4 clearfix sm-px3">
-                    <div className="h4 pb3 md-pl3 sm-pl2" style={titleStyle}>
-                        Projects building on 0x
-                    </div>
-                    <div className="clearfix">{projectList}</div>
-                    <div
-                        className="pt3 mx-auto center"
-                        style={{
-                            color: colors.landingLinkGrey,
-                            fontFamily: 'Roboto Mono',
-                            maxWidth: 300,
-                            fontSize: 14,
-                        }}
-                    >
-                        view the{' '}
-                        <Link
-                            to={`${WebsitePaths.Wiki}#List-of-Projects-Using-0x-Protocol`}
-                            className="text-decoration-none underline"
-                            style={{ color: colors.landingLinkGrey }}
-                        >
-                            full list
-                        </Link>
-                    </div>
-                </div>
-            </div>
-        );
-    }
-    private _renderTokenizationSection() {
-        const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
-        return (
-            <div className="clearfix lg-py4 md-py4 sm-pb4 sm-pt2" style={{ backgroundColor: colors.grey100 }}>
-                <div className="mx-auto max-width-4 py4 clearfix">
-                    {isSmallScreen && this._renderTokenCloud()}
-                    <div className="col lg-col-6 md-col-6 col-12">
-                        <div className="mx-auto" style={{ maxWidth: 385, paddingTop: 7 }}>
-                            <div className="lg-h1 md-h1 sm-h2 sm-center sm-pt3" style={{ fontFamily: 'Roboto Mono' }}>
-                                The world's value is becoming tokenized
-                            </div>
-                            <div
-                                className="pb2 lg-pt2 md-pt2 sm-pt3 sm-px3 h5 sm-center"
-                                style={{ fontFamily: 'Roboto Mono', lineHeight: 1.7 }}
-                            >
-                                {isSmallScreen ? (
-                                    <span>
-                                        The Ethereum blockchain is an open, borderless financial system that represents
-                                        a wide variety of assets as cryptographic tokens. In the future, most digital
-                                        assets and goods will be tokenized.
-                                    </span>
-                                ) : (
-                                    <div>
-                                        <div>
-                                            The Ethereum blockchain is an open, borderless financial system that
-                                            represents
-                                        </div>
-                                        <div>
-                                            a wide variety of assets as cryptographic tokens. In the future, most
-                                            digital assets and goods will be tokenized.
-                                        </div>
-                                    </div>
-                                )}
-                            </div>
-                            <div className="flex pt1 sm-px3">{this._renderAssetTypes()}</div>
-                        </div>
-                    </div>
-                    {!isSmallScreen && this._renderTokenCloud()}
-                </div>
-            </div>
-        );
-    }
-    private _renderProtocolSection() {
-        const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
-        return (
-            <div className="clearfix lg-py4 md-py4 sm-pt4" style={{ backgroundColor: colors.heroGrey }}>
-                <div className="mx-auto max-width-4 lg-py4 md-py4 sm-pt4 clearfix">
-                    <div className="col lg-col-6 md-col-6 col-12 sm-center">
-                        <img src="/images/landing/relayer_diagram.png" height={isSmallScreen ? 326 : 426} />
-                    </div>
-                    <div
-                        className="col lg-col-6 md-col-6 col-12 lg-pr3 md-pr3 sm-mx-auto"
-                        style={{
-                            color: colors.beigeWhite,
-                            paddingTop: 8,
-                            maxWidth: isSmallScreen ? 'none' : 445,
-                        }}
-                    >
-                        <div className="lg-h1 md-h1 sm-h2 pb1 sm-pt3 sm-center" style={{ fontFamily: 'Roboto Mono' }}>
-                            <div>Off-chain order relay</div>
-                            <div>On-chain settlement</div>
-                        </div>
-                        <div
-                            className="pb2 pt2 h5 sm-center sm-px3 sm-mx-auto"
-                            style={{
-                                fontFamily: 'Roboto Mono',
-                                lineHeight: 1.7,
-                                fontWeight: 300,
-                                maxWidth: 445,
-                            }}
-                        >
-                            In 0x protocol, orders are transported off-chain, massively reducing gas costs and
-                            eliminating blockchain bloat. Relayers help broadcast orders and collect a fee each time
-                            they facilitate a trade. Anyone can build a relayer.
-                        </div>
-                        <div
-                            className="pt3 sm-mx-auto sm-px3"
-                            style={{
-                                color: colors.landingLinkGrey,
-                                maxWidth: isSmallScreen ? 412 : 'none',
-                            }}
-                        >
-                            <div className="flex" style={{ fontSize: 18 }}>
-                                <div
-                                    className="lg-h4 md-h4 sm-h5"
-                                    style={{
-                                        letterSpacing: isSmallScreen ? 1 : 3,
-                                        fontFamily: 'Roboto Mono',
-                                    }}
-                                >
-                                    RELAYERS BUILDING ON 0X
-                                </div>
-                                <div className="h5" style={{ marginLeft: isSmallScreen ? 26 : 49 }}>
-                                    <Link
-                                        to={`${WebsitePaths.Wiki}#List-of-Projects-Using-0x-Protocol`}
-                                        className="text-decoration-none underline"
-                                        style={{
-                                            color: colors.landingLinkGrey,
-                                            fontFamily: 'Roboto Mono',
-                                        }}
-                                    >
-                                        view all
-                                    </Link>
-                                </div>
-                            </div>
-                            <div className="lg-flex md-flex sm-clearfix pt3" style={{ opacity: 0.4 }}>
-                                <div className="col col-4 sm-center">
-                                    <img
-                                        src="/images/landing/ethfinex.png"
-                                        style={{ height: isSmallScreen ? 85 : 107 }}
-                                    />
-                                </div>
-                                <div className="col col-4 center">
-                                    <img
-                                        src="/images/landing/radar_relay.png"
-                                        style={{ height: isSmallScreen ? 85 : 107 }}
-                                    />
-                                </div>
-                                <div className="col col-4 sm-center" style={{ textAlign: 'right' }}>
-                                    <img
-                                        src="/images/landing/paradex.png"
-                                        style={{ height: isSmallScreen ? 85 : 107 }}
-                                    />
-                                </div>
-                            </div>
-                        </div>
-                    </div>
-                </div>
-            </div>
-        );
-    }
-    private _renderBuildingBlocksSection() {
-        const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
-        const descriptionStyle: React.CSSProperties = {
-            fontFamily: 'Roboto Mono',
-            lineHeight: isSmallScreen ? 1.5 : 2,
-            fontWeight: 300,
-            fontSize: 15,
-            maxWidth: isSmallScreen ? 375 : 'none',
-        };
-        const callToActionStyle: React.CSSProperties = {
-            fontFamily: 'Roboto Mono',
-            fontSize: 15,
-            fontWeight: 300,
-            maxWidth: isSmallScreen ? 375 : 441,
-        };
-        return (
-            <div className="clearfix lg-pt4 md-pt4" style={{ backgroundColor: colors.heroGrey }}>
-                <div className="mx-auto max-width-4 lg-pt4 md-pt4 lg-mb4 md-mb4 sm-mb2 clearfix">
-                    {isSmallScreen && this._renderBlockChipImage()}
-                    <div
-                        className="col lg-col-6 md-col-6 col-12 lg-pr3 md-pr3 sm-px3"
-                        style={{ color: colors.beigeWhite }}
-                    >
-                        <div
-                            className="pb1 lg-pt4 md-pt4 sm-pt3 lg-h1 md-h1 sm-h2 sm-px3 sm-center"
-                            style={{ fontFamily: 'Roboto Mono' }}
-                        >
-                            A building block for dApps
-                        </div>
-                        <div className="pb3 pt2 sm-mx-auto sm-center" style={descriptionStyle}>
-                            0x protocol is a pluggable building block for dApps that require exchange functionality.
-                            Join the many developers that are already using 0x in their web applications and smart
-                            contracts.
-                        </div>
-                        <div className="sm-mx-auto sm-center" style={callToActionStyle}>
-                            Learn how in our{' '}
-                            <Link
-                                to={WebsitePaths.ZeroExJs}
-                                className="text-decoration-none underline"
-                                style={{ color: colors.beigeWhite, fontFamily: 'Roboto Mono' }}
-                            >
-                                0x.js
-                            </Link>{' '}
-                            and{' '}
-                            <Link
-                                to={WebsitePaths.SmartContracts}
-                                className="text-decoration-none underline"
-                                style={{ color: colors.beigeWhite, fontFamily: 'Roboto Mono' }}
-                            >
-                                smart contract
-                            </Link>{' '}
-                            docs
-                        </div>
-                    </div>
-                    {!isSmallScreen && this._renderBlockChipImage()}
-                </div>
-            </div>
-        );
-    }
-    private _renderBlockChipImage() {
-        const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
-        return (
-            <div className="col lg-col-6 md-col-6 col-12 sm-center">
-                <img src="/images/landing/0x_chips.png" height={isSmallScreen ? 240 : 368} />
-            </div>
-        );
-    }
-    private _renderTokenCloud() {
-        const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
-        return (
-            <div className="col lg-col-6 md-col-6 col-12 center">
-                <img src="/images/landing/tokenized_world.png" height={isSmallScreen ? 280 : 364.5} />
-            </div>
-        );
-    }
-    private _renderAssetTypes() {
-        const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
-        const assetTypes: AssetType[] = [
-            {
-                title: 'Currency',
-                imageUrl: '/images/landing/currency.png',
-            },
-            {
-                title: 'Traditional assets',
-                imageUrl: '/images/landing/stocks.png',
-                style: {
-                    paddingLeft: isSmallScreen ? 41 : 56,
-                    paddingRight: isSmallScreen ? 41 : 56,
-                },
-            },
-            {
-                title: 'Digital goods',
-                imageUrl: '/images/landing/digital_goods.png',
-            },
-        ];
-        const assets = _.map(assetTypes, (assetType: AssetType) => {
-            const style = _.isUndefined(assetType.style) ? {} : assetType.style;
-            return (
-                <div key={`asset-${assetType.title}`} className="center" style={{ opacity: 0.8, ...style }}>
-                    <div>
-                        <img src={assetType.imageUrl} height="80" />
-                    </div>
-                    <div
-                        style={{
-                            fontFamily: 'Roboto Mono',
-                            fontSize: 13.5,
-                            fontWeight: 400,
-                            opacity: 0.75,
-                        }}
-                    >
-                        {assetType.title}
-                    </div>
-                </div>
-            );
-        });
-        return assets;
-    }
-    private _renderInfoBoxes() {
-        const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
-        const boxStyle: React.CSSProperties = {
-            maxWidth: 252,
-            height: 386,
-            backgroundColor: colors.grey50,
-            borderRadius: 5,
-            padding: '10px 24px 24px',
-        };
-        const boxes = _.map(boxContents, (boxContent: BoxContent) => {
-            return (
-                <div key={`box-${boxContent.title}`} className="col lg-col-4 md-col-4 col-12 sm-pb4">
-                    <div className={`center sm-mx-auto ${!isSmallScreen && boxContent.classNames}`} style={boxStyle}>
-                        <div>
-                            <img src={boxContent.imageUrl} style={{ height: 210 }} />
-                        </div>
-                        <div className="h3" style={{ color: 'black', fontFamily: 'Roboto Mono' }}>
-                            {boxContent.title}
-                        </div>
-                        <div className="pt2 pb2" style={{ fontFamily: 'Roboto Mono', fontSize: 14 }}>
-                            {boxContent.description}
-                        </div>
-                    </div>
-                </div>
-            );
-        });
-        return (
-            <div className="clearfix" style={{ backgroundColor: colors.heroGrey }}>
-                <div className="mx-auto py4 sm-mt2 clearfix" style={{ maxWidth: '60em' }}>
-                    {boxes}
-                </div>
-            </div>
-        );
-    }
-    private _renderUseCases() {
-        const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
+	private _throttledScreenWidthUpdate: () => void;
+	constructor(props: LandingProps) {
+		super(props);
+		this.state = {
+			screenWidth: utils.getScreenWidth(),
+		};
+		this._throttledScreenWidthUpdate = _.throttle(this._updateScreenWidth.bind(this), THROTTLE_TIMEOUT);
+	}
+	public componentDidMount() {
+		window.addEventListener('resize', this._throttledScreenWidthUpdate);
+		window.scrollTo(0, 0);
+	}
+	public componentWillUnmount() {
+		window.removeEventListener('resize', this._throttledScreenWidthUpdate);
+	}
+	public render() {
+		return (
+			<div id="landing" className="clearfix" style={{ color: colors.grey500 }}>
+				<DocumentTitle title="0x Protocol" />
+				<TopBar
+					blockchainIsLoaded={false}
+					location={this.props.location}
+					isNightVersion={true}
+					style={{ backgroundColor: colors.heroGrey, position: 'relative' }}
+				/>
+				{this._renderHero()}
+				{this._renderProjects()}
+				{this._renderTokenizationSection()}
+				{this._renderProtocolSection()}
+				{this._renderInfoBoxes()}
+				{this._renderBuildingBlocksSection()}
+				{this._renderUseCases()}
+				{this._renderCallToAction()}
+				<Footer />
+			</div>
+		);
+	}
+	private _renderHero() {
+		const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
+		const buttonLabelStyle: React.CSSProperties = {
+			textTransform: 'none',
+			fontSize: isSmallScreen ? 12 : 14,
+			fontWeight: 400,
+		};
+		const lightButtonStyle: React.CSSProperties = {
+			borderRadius: 6,
+			border: '1px solid #D8D8D8',
+			lineHeight: '33px',
+			height: 38,
+		};
+		const left = 'col lg-col-7 md-col-7 col-12 lg-pt4 md-pt4 sm-pt0 mt1 lg-pl4 md-pl4 sm-pl0 sm-px3 sm-center';
+		return (
+			<div className="clearfix py4" style={{ backgroundColor: colors.heroGrey }}>
+				<div className="mx-auto max-width-4 clearfix">
+					<div className="lg-pt4 md-pt4 sm-pt2 lg-pb4 md-pb4 lg-my4 md-my4 sm-mt2 sm-mb4 clearfix">
+						<div className="col lg-col-5 md-col-5 col-12 sm-center">
+							<img src="/images/landing/hero_chip_image.png" height={isSmallScreen ? 300 : 395} />
+						</div>
+						<div className={left} style={{ color: colors.white }}>
+							<div style={{ paddingLeft: isSmallScreen ? 0 : 12 }}>
+								<div
+									className="sm-pb2"
+									style={{
+										fontFamily: 'Roboto Mono',
+										fontSize: isSmallScreen ? 26 : 34,
+									}}
+								>
+									Powering decentralized exchange
+								</div>
+								<div
+									className="pt2 h5 sm-mx-auto"
+									style={{
+										maxWidth: 446,
+										fontFamily: 'Roboto Mono',
+										lineHeight: 1.7,
+										fontWeight: 300,
+									}}
+								>
+									0x is an open, permissionless protocol allowing for ERC20 tokens to be traded on the
+									Ethereum blockchain.
+								</div>
+								<div className="pt3 clearfix sm-mx-auto" style={{ maxWidth: 342 }}>
+									<div className="lg-pr2 md-pr2 col col-6 sm-center">
+										<Link to={WebsitePaths.ZeroExJs} className="text-decoration-none">
+											<RaisedButton
+												style={{ borderRadius: 6, minWidth: 157.36 }}
+												buttonStyle={{ borderRadius: 6 }}
+												labelStyle={buttonLabelStyle}
+												label="Build on 0x"
+												onClick={_.noop}
+											/>
+										</Link>
+									</div>
+									<div className="col col-6 sm-center">
+										<a
+											href={constants.URL_ZEROEX_CHAT}
+											target="_blank"
+											className="text-decoration-none"
+										>
+											<RaisedButton
+												style={{ borderRadius: 6, minWidth: 150 }}
+												buttonStyle={lightButtonStyle}
+												labelColor="white"
+												backgroundColor={colors.heroGrey}
+												labelStyle={buttonLabelStyle}
+												label="Join the community"
+												onClick={_.noop}
+											/>
+										</a>
+									</div>
+								</div>
+							</div>
+						</div>
+					</div>
+				</div>
+			</div>
+		);
+	}
+	private _renderProjects() {
+		const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
+		const isMediumScreen = this.state.screenWidth === ScreenWidths.Md;
+		const projectList = _.map(projects, (project: Project, i: number) => {
+			const colWidth = isSmallScreen ? 3 : isMediumScreen ? 4 : 2 - i % 2;
+			return (
+				<div key={`project-${project.logoFileName}`} className={`col col-${colWidth} center`}>
+					<div>
+						<a href={project.projectUrl} target="_blank" className="text-decoration-none">
+							<img
+								src={`/images/landing/project_logos/${project.logoFileName}`}
+								height={isSmallScreen ? 60 : 92}
+							/>
+						</a>
+					</div>
+				</div>
+			);
+		});
+		const titleStyle: React.CSSProperties = {
+			fontFamily: 'Roboto Mono',
+			color: colors.grey,
+			textTransform: 'uppercase',
+			fontWeight: 300,
+			letterSpacing: 3,
+		};
+		return (
+			<div className="clearfix py4" style={{ backgroundColor: colors.projectsGrey }}>
+				<div className="mx-auto max-width-4 clearfix sm-px3">
+					<div className="h4 pb3 md-pl3 sm-pl2" style={titleStyle}>
+						Projects building on 0x
+					</div>
+					<div className="clearfix">{projectList}</div>
+					<div
+						className="pt3 mx-auto center"
+						style={{
+							color: colors.landingLinkGrey,
+							fontFamily: 'Roboto Mono',
+							maxWidth: 300,
+							fontSize: 14,
+						}}
+					>
+						view the{' '}
+						<Link
+							to={`${WebsitePaths.Wiki}#List-of-Projects-Using-0x-Protocol`}
+							className="text-decoration-none underline"
+							style={{ color: colors.landingLinkGrey }}
+						>
+							full list
+						</Link>
+					</div>
+				</div>
+			</div>
+		);
+	}
+	private _renderTokenizationSection() {
+		const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
+		return (
+			<div className="clearfix lg-py4 md-py4 sm-pb4 sm-pt2" style={{ backgroundColor: colors.grey100 }}>
+				<div className="mx-auto max-width-4 py4 clearfix">
+					{isSmallScreen && this._renderTokenCloud()}
+					<div className="col lg-col-6 md-col-6 col-12">
+						<div className="mx-auto" style={{ maxWidth: 385, paddingTop: 7 }}>
+							<div className="lg-h1 md-h1 sm-h2 sm-center sm-pt3" style={{ fontFamily: 'Roboto Mono' }}>
+								The world's value is becoming tokenized
+							</div>
+							<div
+								className="pb2 lg-pt2 md-pt2 sm-pt3 sm-px3 h5 sm-center"
+								style={{ fontFamily: 'Roboto Mono', lineHeight: 1.7 }}
+							>
+								{isSmallScreen ? (
+									<span>
+										The Ethereum blockchain is an open, borderless financial system that represents
+										a wide variety of assets as cryptographic tokens. In the future, most digital
+										assets and goods will be tokenized.
+									</span>
+								) : (
+									<div>
+										<div>
+											The Ethereum blockchain is an open, borderless financial system that
+											represents
+										</div>
+										<div>
+											a wide variety of assets as cryptographic tokens. In the future, most
+											digital assets and goods will be tokenized.
+										</div>
+									</div>
+								)}
+							</div>
+							<div className="flex pt1 sm-px3">{this._renderAssetTypes()}</div>
+						</div>
+					</div>
+					{!isSmallScreen && this._renderTokenCloud()}
+				</div>
+			</div>
+		);
+	}
+	private _renderProtocolSection() {
+		const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
+		return (
+			<div className="clearfix lg-py4 md-py4 sm-pt4" style={{ backgroundColor: colors.heroGrey }}>
+				<div className="mx-auto max-width-4 lg-py4 md-py4 sm-pt4 clearfix">
+					<div className="col lg-col-6 md-col-6 col-12 sm-center">
+						<img src="/images/landing/relayer_diagram.png" height={isSmallScreen ? 326 : 426} />
+					</div>
+					<div
+						className="col lg-col-6 md-col-6 col-12 lg-pr3 md-pr3 sm-mx-auto"
+						style={{
+							color: colors.beigeWhite,
+							paddingTop: 8,
+							maxWidth: isSmallScreen ? 'none' : 445,
+						}}
+					>
+						<div className="lg-h1 md-h1 sm-h2 pb1 sm-pt3 sm-center" style={{ fontFamily: 'Roboto Mono' }}>
+							<div>Off-chain order relay</div>
+							<div>On-chain settlement</div>
+						</div>
+						<div
+							className="pb2 pt2 h5 sm-center sm-px3 sm-mx-auto"
+							style={{
+								fontFamily: 'Roboto Mono',
+								lineHeight: 1.7,
+								fontWeight: 300,
+								maxWidth: 445,
+							}}
+						>
+							In 0x protocol, orders are transported off-chain, massively reducing gas costs and
+							eliminating blockchain bloat. Relayers help broadcast orders and collect a fee each time
+							they facilitate a trade. Anyone can build a relayer.
+						</div>
+						<div
+							className="pt3 sm-mx-auto sm-px3"
+							style={{
+								color: colors.landingLinkGrey,
+								maxWidth: isSmallScreen ? 412 : 'none',
+							}}
+						>
+							<div className="flex" style={{ fontSize: 18 }}>
+								<div
+									className="lg-h4 md-h4 sm-h5"
+									style={{
+										letterSpacing: isSmallScreen ? 1 : 3,
+										fontFamily: 'Roboto Mono',
+									}}
+								>
+									RELAYERS BUILDING ON 0X
+								</div>
+								<div className="h5" style={{ marginLeft: isSmallScreen ? 26 : 49 }}>
+									<Link
+										to={`${WebsitePaths.Wiki}#List-of-Projects-Using-0x-Protocol`}
+										className="text-decoration-none underline"
+										style={{
+											color: colors.landingLinkGrey,
+											fontFamily: 'Roboto Mono',
+										}}
+									>
+										view all
+									</Link>
+								</div>
+							</div>
+							<div className="lg-flex md-flex sm-clearfix pt3" style={{ opacity: 0.4 }}>
+								<div className="col col-4 sm-center">
+									<img
+										src="/images/landing/ethfinex.png"
+										style={{ height: isSmallScreen ? 85 : 107 }}
+									/>
+								</div>
+								<div className="col col-4 center">
+									<img
+										src="/images/landing/radar_relay.png"
+										style={{ height: isSmallScreen ? 85 : 107 }}
+									/>
+								</div>
+								<div className="col col-4 sm-center" style={{ textAlign: 'right' }}>
+									<img
+										src="/images/landing/paradex.png"
+										style={{ height: isSmallScreen ? 85 : 107 }}
+									/>
+								</div>
+							</div>
+						</div>
+					</div>
+				</div>
+			</div>
+		);
+	}
+	private _renderBuildingBlocksSection() {
+		const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
+		const descriptionStyle: React.CSSProperties = {
+			fontFamily: 'Roboto Mono',
+			lineHeight: isSmallScreen ? 1.5 : 2,
+			fontWeight: 300,
+			fontSize: 15,
+			maxWidth: isSmallScreen ? 375 : 'none',
+		};
+		const callToActionStyle: React.CSSProperties = {
+			fontFamily: 'Roboto Mono',
+			fontSize: 15,
+			fontWeight: 300,
+			maxWidth: isSmallScreen ? 375 : 441,
+		};
+		return (
+			<div className="clearfix lg-pt4 md-pt4" style={{ backgroundColor: colors.heroGrey }}>
+				<div className="mx-auto max-width-4 lg-pt4 md-pt4 lg-mb4 md-mb4 sm-mb2 clearfix">
+					{isSmallScreen && this._renderBlockChipImage()}
+					<div
+						className="col lg-col-6 md-col-6 col-12 lg-pr3 md-pr3 sm-px3"
+						style={{ color: colors.beigeWhite }}
+					>
+						<div
+							className="pb1 lg-pt4 md-pt4 sm-pt3 lg-h1 md-h1 sm-h2 sm-px3 sm-center"
+							style={{ fontFamily: 'Roboto Mono' }}
+						>
+							A building block for dApps
+						</div>
+						<div className="pb3 pt2 sm-mx-auto sm-center" style={descriptionStyle}>
+							0x protocol is a pluggable building block for dApps that require exchange functionality.
+							Join the many developers that are already using 0x in their web applications and smart
+							contracts.
+						</div>
+						<div className="sm-mx-auto sm-center" style={callToActionStyle}>
+							Learn how in our{' '}
+							<Link
+								to={WebsitePaths.ZeroExJs}
+								className="text-decoration-none underline"
+								style={{ color: colors.beigeWhite, fontFamily: 'Roboto Mono' }}
+							>
+								0x.js
+							</Link>{' '}
+							and{' '}
+							<Link
+								to={WebsitePaths.SmartContracts}
+								className="text-decoration-none underline"
+								style={{ color: colors.beigeWhite, fontFamily: 'Roboto Mono' }}
+							>
+								smart contract
+							</Link>{' '}
+							docs
+						</div>
+					</div>
+					{!isSmallScreen && this._renderBlockChipImage()}
+				</div>
+			</div>
+		);
+	}
+	private _renderBlockChipImage() {
+		const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
+		return (
+			<div className="col lg-col-6 md-col-6 col-12 sm-center">
+				<img src="/images/landing/0x_chips.png" height={isSmallScreen ? 240 : 368} />
+			</div>
+		);
+	}
+	private _renderTokenCloud() {
+		const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
+		return (
+			<div className="col lg-col-6 md-col-6 col-12 center">
+				<img src="/images/landing/tokenized_world.png" height={isSmallScreen ? 280 : 364.5} />
+			</div>
+		);
+	}
+	private _renderAssetTypes() {
+		const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
+		const assetTypes: AssetType[] = [
+			{
+				title: 'Currency',
+				imageUrl: '/images/landing/currency.png',
+			},
+			{
+				title: 'Traditional assets',
+				imageUrl: '/images/landing/stocks.png',
+				style: {
+					paddingLeft: isSmallScreen ? 41 : 56,
+					paddingRight: isSmallScreen ? 41 : 56,
+				},
+			},
+			{
+				title: 'Digital goods',
+				imageUrl: '/images/landing/digital_goods.png',
+			},
+		];
+		const assets = _.map(assetTypes, (assetType: AssetType) => {
+			const style = _.isUndefined(assetType.style) ? {} : assetType.style;
+			return (
+				<div key={`asset-${assetType.title}`} className="center" style={{ opacity: 0.8, ...style }}>
+					<div>
+						<img src={assetType.imageUrl} height="80" />
+					</div>
+					<div
+						style={{
+							fontFamily: 'Roboto Mono',
+							fontSize: 13.5,
+							fontWeight: 400,
+							opacity: 0.75,
+						}}
+					>
+						{assetType.title}
+					</div>
+				</div>
+			);
+		});
+		return assets;
+	}
+	private _renderInfoBoxes() {
+		const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
+		const boxStyle: React.CSSProperties = {
+			maxWidth: 252,
+			height: 386,
+			backgroundColor: colors.grey50,
+			borderRadius: 5,
+			padding: '10px 24px 24px',
+		};
+		const boxes = _.map(boxContents, (boxContent: BoxContent) => {
+			return (
+				<div key={`box-${boxContent.title}`} className="col lg-col-4 md-col-4 col-12 sm-pb4">
+					<div className={`center sm-mx-auto ${!isSmallScreen && boxContent.classNames}`} style={boxStyle}>
+						<div>
+							<img src={boxContent.imageUrl} style={{ height: 210 }} />
+						</div>
+						<div className="h3" style={{ color: 'black', fontFamily: 'Roboto Mono' }}>
+							{boxContent.title}
+						</div>
+						<div className="pt2 pb2" style={{ fontFamily: 'Roboto Mono', fontSize: 14 }}>
+							{boxContent.description}
+						</div>
+					</div>
+				</div>
+			);
+		});
+		return (
+			<div className="clearfix" style={{ backgroundColor: colors.heroGrey }}>
+				<div className="mx-auto py4 sm-mt2 clearfix" style={{ maxWidth: '60em' }}>
+					{boxes}
+				</div>
+			</div>
+		);
+	}
+	private _renderUseCases() {
+		const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
 
-        const useCases: UseCase[] = [
-            {
-                imageUrl: '/images/landing/governance_icon.png',
-                type: 'Decentralized governance',
-                description:
-                    'Decentralized organizations use tokens to represent ownership and \
+		const useCases: UseCase[] = [
+			{
+				imageUrl: '/images/landing/governance_icon.png',
+				type: 'Decentralized governance',
+				description:
+					'Decentralized organizations use tokens to represent ownership and \
                               guide their governance logic. 0x allows decentralized organizations \
                               to seamlessly and safely trade ownership for startup capital.',
-                projectIconUrls: ['/images/landing/aragon.png'],
-                classNames: 'lg-px2 md-px2',
-            },
-            {
-                imageUrl: '/images/landing/prediction_market_icon.png',
-                type: 'Prediction markets',
-                description:
-                    'Decentralized prediction market platforms generate sets of tokens that \
+				projectIconUrls: ['/images/landing/aragon.png'],
+				classNames: 'lg-px2 md-px2',
+			},
+			{
+				imageUrl: '/images/landing/prediction_market_icon.png',
+				type: 'Prediction markets',
+				description:
+					'Decentralized prediction market platforms generate sets of tokens that \
                               represent a financial stake in the outcomes of real-world events. 0x allows \
                               these tokens to be instantly tradable.',
-                projectIconUrls: ['/images/landing/augur.png'],
-                classNames: 'lg-px2 md-px2',
-            },
-            {
-                imageUrl: '/images/landing/stable_tokens_icon.png',
-                type: 'Stable tokens',
-                description:
-                    'Novel economic constructs such as stable coins require efficient, liquid \
+				projectIconUrls: ['/images/landing/augur.png'],
+				classNames: 'lg-px2 md-px2',
+			},
+			{
+				imageUrl: '/images/landing/stable_tokens_icon.png',
+				type: 'Stable tokens',
+				description:
+					'Novel economic constructs such as stable coins require efficient, liquid \
                               markets to succeed. 0x will facilitate the underlying economic mechanisms \
                               that allow these tokens to remain stable.',
-                projectIconUrls: ['/images/landing/maker.png'],
-                classNames: 'lg-px2 md-px2',
-            },
-            {
-                imageUrl: '/images/landing/loans_icon.png',
-                type: 'Decentralized loans',
-                description:
-                    'Efficient lending requires liquid markets where investors can buy and re-sell loans. \
+				projectIconUrls: ['/images/landing/maker.png'],
+				classNames: 'lg-px2 md-px2',
+			},
+			{
+				imageUrl: '/images/landing/loans_icon.png',
+				type: 'Decentralized loans',
+				description:
+					'Efficient lending requires liquid markets where investors can buy and re-sell loans. \
                               0x enables an ecosystem of lenders to self-organize and efficiently determine \
                               market prices for all outstanding loans.',
-                projectIconUrls: ['/images/landing/dharma.png', '/images/landing/lendroid.png'],
-                classNames: 'lg-pr2 md-pr2 lg-col-6 md-col-6',
-                style: {
-                    width: 291,
-                    float: 'right',
-                    marginTop: !isSmallScreen ? 38 : 0,
-                },
-            },
-            {
-                imageUrl: '/images/landing/fund_management_icon.png',
-                type: 'Fund management',
-                description:
-                    'Decentralized fund management limits fund managers to investing in pre-agreed \
+				projectIconUrls: ['/images/landing/dharma.png', '/images/landing/lendroid.png'],
+				classNames: 'lg-pr2 md-pr2 lg-col-6 md-col-6',
+				style: {
+					width: 291,
+					float: 'right',
+					marginTop: !isSmallScreen ? 38 : 0,
+				},
+			},
+			{
+				imageUrl: '/images/landing/fund_management_icon.png',
+				type: 'Fund management',
+				description:
+					'Decentralized fund management limits fund managers to investing in pre-agreed \
                               upon asset classes. Embedding 0x into fund management smart contracts enables \
                               them to enforce these security constraints.',
-                projectIconUrls: ['/images/landing/melonport.png'],
-                classNames: 'lg-pl2 md-pl2 lg-col-6 md-col-6',
-                style: { width: 291, marginTop: !isSmallScreen ? 38 : 0 },
-            },
-        ];
+				projectIconUrls: ['/images/landing/melonport.png'],
+				classNames: 'lg-pl2 md-pl2 lg-col-6 md-col-6',
+				style: { width: 291, marginTop: !isSmallScreen ? 38 : 0 },
+			},
+		];
 
-        const cases = _.map(useCases, (useCase: UseCase) => {
-            const style = _.isUndefined(useCase.style) || isSmallScreen ? {} : useCase.style;
-            const useCaseBoxStyle = {
-                color: colors.grey,
-                border: '1px solid #565656',
-                borderRadius: 4,
-                maxWidth: isSmallScreen ? 375 : 'none',
-                ...style,
-            };
-            const typeStyle: React.CSSProperties = {
-                color: colors.lightGrey,
-                fontSize: 13,
-                textTransform: 'uppercase',
-                fontFamily: 'Roboto Mono',
-                fontWeight: 300,
-            };
-            return (
-                <div
-                    key={`useCase-${useCase.type}`}
-                    className={`col lg-col-4 md-col-4 col-12 sm-pt3 sm-px3 sm-pb3 ${useCase.classNames}`}
-                >
-                    <div className="relative p2 pb2 sm-mx-auto" style={useCaseBoxStyle}>
-                        <div className="absolute center" style={{ top: -35, width: 'calc(100% - 32px)' }}>
-                            <img src={useCase.imageUrl} style={{ height: 50 }} />
-                        </div>
-                        <div className="pt2 center" style={typeStyle}>
-                            {useCase.type}
-                        </div>
-                        <div
-                            className="pt2"
-                            style={{
-                                lineHeight: 1.5,
-                                fontSize: 14,
-                                overflow: 'hidden',
-                                height: 104,
-                            }}
-                        >
-                            {useCase.description}
-                        </div>
-                    </div>
-                </div>
-            );
-        });
-        return (
-            <div className="clearfix pb4 lg-pt2 md-pt2 sm-pt4" style={{ backgroundColor: colors.heroGrey }}>
-                <div className="mx-auto pb4 pt3 mt1 sm-mt2 clearfix" style={{ maxWidth: '67em' }}>
-                    {cases}
-                </div>
-            </div>
-        );
-    }
-    private _renderCallToAction() {
-        const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
-        const buttonLabelStyle: React.CSSProperties = {
-            textTransform: 'none',
-            fontSize: 15,
-            fontWeight: 400,
-        };
-        const lightButtonStyle: React.CSSProperties = {
-            borderRadius: 6,
-            border: '1px solid #a0a0a0',
-            lineHeight: '33px',
-            height: 49,
-        };
-        const callToActionClassNames =
-            'col lg-col-8 md-col-8 col-12 lg-pr3 md-pr3 \
+		const cases = _.map(useCases, (useCase: UseCase) => {
+			const style = _.isUndefined(useCase.style) || isSmallScreen ? {} : useCase.style;
+			const useCaseBoxStyle = {
+				color: colors.grey,
+				border: '1px solid #565656',
+				borderRadius: 4,
+				maxWidth: isSmallScreen ? 375 : 'none',
+				...style,
+			};
+			const typeStyle: React.CSSProperties = {
+				color: colors.lightGrey,
+				fontSize: 13,
+				textTransform: 'uppercase',
+				fontFamily: 'Roboto Mono',
+				fontWeight: 300,
+			};
+			return (
+				<div
+					key={`useCase-${useCase.type}`}
+					className={`col lg-col-4 md-col-4 col-12 sm-pt3 sm-px3 sm-pb3 ${useCase.classNames}`}
+				>
+					<div className="relative p2 pb2 sm-mx-auto" style={useCaseBoxStyle}>
+						<div className="absolute center" style={{ top: -35, width: 'calc(100% - 32px)' }}>
+							<img src={useCase.imageUrl} style={{ height: 50 }} />
+						</div>
+						<div className="pt2 center" style={typeStyle}>
+							{useCase.type}
+						</div>
+						<div
+							className="pt2"
+							style={{
+								lineHeight: 1.5,
+								fontSize: 14,
+								overflow: 'hidden',
+								height: 104,
+							}}
+						>
+							{useCase.description}
+						</div>
+					</div>
+				</div>
+			);
+		});
+		return (
+			<div className="clearfix pb4 lg-pt2 md-pt2 sm-pt4" style={{ backgroundColor: colors.heroGrey }}>
+				<div className="mx-auto pb4 pt3 mt1 sm-mt2 clearfix" style={{ maxWidth: '67em' }}>
+					{cases}
+				</div>
+			</div>
+		);
+	}
+	private _renderCallToAction() {
+		const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
+		const buttonLabelStyle: React.CSSProperties = {
+			textTransform: 'none',
+			fontSize: 15,
+			fontWeight: 400,
+		};
+		const lightButtonStyle: React.CSSProperties = {
+			borderRadius: 6,
+			border: '1px solid #a0a0a0',
+			lineHeight: '33px',
+			height: 49,
+		};
+		const callToActionClassNames =
+			'col lg-col-8 md-col-8 col-12 lg-pr3 md-pr3 \
                                         lg-right-align md-right-align sm-center sm-px3 h4';
-        return (
-            <div className="clearfix pb4" style={{ backgroundColor: colors.heroGrey }}>
-                <div className="mx-auto max-width-4 pb4 mb3 clearfix">
-                    <div
-                        className={callToActionClassNames}
-                        style={{
-                            fontFamily: 'Roboto Mono',
-                            color: colors.white,
-                            lineHeight: isSmallScreen ? 1.7 : 3,
-                        }}
-                    >
-                        Get started on building the decentralized future
-                    </div>
-                    <div className="col lg-col-4 md-col-4 col-12 sm-center sm-pt2">
-                        <Link to={WebsitePaths.ZeroExJs} className="text-decoration-none">
-                            <RaisedButton
-                                style={{ borderRadius: 6, minWidth: 150 }}
-                                buttonStyle={lightButtonStyle}
-                                labelColor={colors.white}
-                                backgroundColor={colors.heroGrey}
-                                labelStyle={buttonLabelStyle}
-                                label="Build on 0x"
-                                onClick={_.noop}
-                            />
-                        </Link>
-                    </div>
-                </div>
-            </div>
-        );
-    }
-    private _updateScreenWidth() {
-        const newScreenWidth = utils.getScreenWidth();
-        if (newScreenWidth !== this.state.screenWidth) {
-            this.setState({
-                screenWidth: newScreenWidth,
-            });
-        }
-    }
+		return (
+			<div className="clearfix pb4" style={{ backgroundColor: colors.heroGrey }}>
+				<div className="mx-auto max-width-4 pb4 mb3 clearfix">
+					<div
+						className={callToActionClassNames}
+						style={{
+							fontFamily: 'Roboto Mono',
+							color: colors.white,
+							lineHeight: isSmallScreen ? 1.7 : 3,
+						}}
+					>
+						Get started on building the decentralized future
+					</div>
+					<div className="col lg-col-4 md-col-4 col-12 sm-center sm-pt2">
+						<Link to={WebsitePaths.ZeroExJs} className="text-decoration-none">
+							<RaisedButton
+								style={{ borderRadius: 6, minWidth: 150 }}
+								buttonStyle={lightButtonStyle}
+								labelColor={colors.white}
+								backgroundColor={colors.heroGrey}
+								labelStyle={buttonLabelStyle}
+								label="Build on 0x"
+								onClick={_.noop}
+							/>
+						</Link>
+					</div>
+				</div>
+			</div>
+		);
+	}
+	private _updateScreenWidth() {
+		const newScreenWidth = utils.getScreenWidth();
+		if (newScreenWidth !== this.state.screenWidth) {
+			this.setState({
+				screenWidth: newScreenWidth,
+			});
+		}
+	}
 } // tslint:disable:max-file-line-count
diff --git a/packages/website/ts/pages/not_found.tsx b/packages/website/ts/pages/not_found.tsx
index ff277c377..9d8d4142d 100644
--- a/packages/website/ts/pages/not_found.tsx
+++ b/packages/website/ts/pages/not_found.tsx
@@ -5,38 +5,38 @@ import { TopBar } from 'ts/components/top_bar';
 import { Styles } from 'ts/types';
 
 export interface NotFoundProps {
-    location: Location;
+	location: Location;
 }
 
 interface NotFoundState {}
 
 const styles: Styles = {
-    thin: {
-        fontWeight: 100,
-    },
+	thin: {
+		fontWeight: 100,
+	},
 };
 
 export class NotFound extends React.Component<NotFoundProps, NotFoundState> {
-    public render() {
-        return (
-            <div>
-                <TopBar blockchainIsLoaded={false} location={this.props.location} />
-                <div className="mx-auto max-width-4 py4">
-                    <div className="center py4">
-                        <div className="py4">
-                            <div className="py4">
-                                <h1 style={{ ...styles.thin }}>404 Not Found</h1>
-                                <div className="py1">
-                                    <div className="py3">
-                                        Hm... looks like we couldn't find what you are looking for.
-                                    </div>
-                                </div>
-                            </div>
-                        </div>
-                    </div>
-                </div>
-                <Footer />
-            </div>
-        );
-    }
+	public render() {
+		return (
+			<div>
+				<TopBar blockchainIsLoaded={false} location={this.props.location} />
+				<div className="mx-auto max-width-4 py4">
+					<div className="center py4">
+						<div className="py4">
+							<div className="py4">
+								<h1 style={{ ...styles.thin }}>404 Not Found</h1>
+								<div className="py1">
+									<div className="py3">
+										Hm... looks like we couldn't find what you are looking for.
+									</div>
+								</div>
+							</div>
+						</div>
+					</div>
+				</div>
+				<Footer />
+			</div>
+		);
+	}
 }
diff --git a/packages/website/ts/pages/shared/anchor_title.tsx b/packages/website/ts/pages/shared/anchor_title.tsx
index db5be1f59..118aa0ea5 100644
--- a/packages/website/ts/pages/shared/anchor_title.tsx
+++ b/packages/website/ts/pages/shared/anchor_title.tsx
@@ -5,87 +5,87 @@ import { constants } from 'ts/utils/constants';
 import { utils } from 'ts/utils/utils';
 
 const headerSizeToScrollOffset: { [headerSize: string]: number } = {
-    h2: -20,
-    h3: 0,
+	h2: -20,
+	h3: 0,
 };
 
 interface AnchorTitleProps {
-    title: string | React.ReactNode;
-    id: string;
-    headerSize: HeaderSizes;
-    shouldShowAnchor: boolean;
+	title: string | React.ReactNode;
+	id: string;
+	headerSize: HeaderSizes;
+	shouldShowAnchor: boolean;
 }
 
 interface AnchorTitleState {
-    isHovering: boolean;
+	isHovering: boolean;
 }
 
 const styles: Styles = {
-    anchor: {
-        fontSize: 20,
-        transform: 'rotate(45deg)',
-        cursor: 'pointer',
-    },
-    headers: {
-        WebkitMarginStart: 0,
-        WebkitMarginEnd: 0,
-        fontWeight: 'bold',
-        display: 'block',
-    },
-    h1: {
-        fontSize: '1.8em',
-        WebkitMarginBefore: '0.83em',
-        WebkitMarginAfter: '0.83em',
-    },
-    h2: {
-        fontSize: '1.5em',
-        WebkitMarginBefore: '0.83em',
-        WebkitMarginAfter: '0.83em',
-    },
-    h3: {
-        fontSize: '1.17em',
-        WebkitMarginBefore: '1em',
-        WebkitMarginAfter: '1em',
-    },
+	anchor: {
+		fontSize: 20,
+		transform: 'rotate(45deg)',
+		cursor: 'pointer',
+	},
+	headers: {
+		WebkitMarginStart: 0,
+		WebkitMarginEnd: 0,
+		fontWeight: 'bold',
+		display: 'block',
+	},
+	h1: {
+		fontSize: '1.8em',
+		WebkitMarginBefore: '0.83em',
+		WebkitMarginAfter: '0.83em',
+	},
+	h2: {
+		fontSize: '1.5em',
+		WebkitMarginBefore: '0.83em',
+		WebkitMarginAfter: '0.83em',
+	},
+	h3: {
+		fontSize: '1.17em',
+		WebkitMarginBefore: '1em',
+		WebkitMarginAfter: '1em',
+	},
 };
 
 export class AnchorTitle extends React.Component<AnchorTitleProps, AnchorTitleState> {
-    constructor(props: AnchorTitleProps) {
-        super(props);
-        this.state = {
-            isHovering: false,
-        };
-    }
-    public render() {
-        let opacity = 0;
-        if (this.props.shouldShowAnchor) {
-            opacity = this.state.isHovering ? 0.6 : 1;
-        }
-        return (
-            <div className="relative flex" style={{ ...styles[this.props.headerSize], ...styles.headers }}>
-                <div className="inline-block" style={{ paddingRight: 4 }}>
-                    {this.props.title}
-                </div>
-                <ScrollLink
-                    to={this.props.id}
-                    offset={headerSizeToScrollOffset[this.props.headerSize]}
-                    duration={constants.DOCS_SCROLL_DURATION_MS}
-                    containerId={constants.DOCS_CONTAINER_ID}
-                >
-                    <i
-                        className="zmdi zmdi-link"
-                        onClick={utils.setUrlHash.bind(utils, this.props.id)}
-                        style={{ ...styles.anchor, opacity }}
-                        onMouseOver={this._setHoverState.bind(this, true)}
-                        onMouseOut={this._setHoverState.bind(this, false)}
-                    />
-                </ScrollLink>
-            </div>
-        );
-    }
-    private _setHoverState(isHovering: boolean) {
-        this.setState({
-            isHovering,
-        });
-    }
+	constructor(props: AnchorTitleProps) {
+		super(props);
+		this.state = {
+			isHovering: false,
+		};
+	}
+	public render() {
+		let opacity = 0;
+		if (this.props.shouldShowAnchor) {
+			opacity = this.state.isHovering ? 0.6 : 1;
+		}
+		return (
+			<div className="relative flex" style={{ ...styles[this.props.headerSize], ...styles.headers }}>
+				<div className="inline-block" style={{ paddingRight: 4 }}>
+					{this.props.title}
+				</div>
+				<ScrollLink
+					to={this.props.id}
+					offset={headerSizeToScrollOffset[this.props.headerSize]}
+					duration={constants.DOCS_SCROLL_DURATION_MS}
+					containerId={constants.DOCS_CONTAINER_ID}
+				>
+					<i
+						className="zmdi zmdi-link"
+						onClick={utils.setUrlHash.bind(utils, this.props.id)}
+						style={{ ...styles.anchor, opacity }}
+						onMouseOver={this._setHoverState.bind(this, true)}
+						onMouseOut={this._setHoverState.bind(this, false)}
+					/>
+				</ScrollLink>
+			</div>
+		);
+	}
+	private _setHoverState(isHovering: boolean) {
+		this.setState({
+			isHovering,
+		});
+	}
 }
diff --git a/packages/website/ts/pages/shared/markdown_code_block.tsx b/packages/website/ts/pages/shared/markdown_code_block.tsx
index be96fda16..a9d95979b 100644
--- a/packages/website/ts/pages/shared/markdown_code_block.tsx
+++ b/packages/website/ts/pages/shared/markdown_code_block.tsx
@@ -3,23 +3,23 @@ import * as React from 'react';
 import * as HighLight from 'react-highlight';
 
 interface MarkdownCodeBlockProps {
-    literal: string;
-    language: string;
+	literal: string;
+	language: string;
 }
 
 interface MarkdownCodeBlockState {}
 
 export class MarkdownCodeBlock extends React.Component<MarkdownCodeBlockProps, MarkdownCodeBlockState> {
-    // Re-rendering a codeblock causes any use selection to become de-selected. This is annoying when trying
-    // to copy-paste code examples. We therefore noop re-renders on this component if it's props haven't changed.
-    public shouldComponentUpdate(nextProps: MarkdownCodeBlockProps, nextState: MarkdownCodeBlockState) {
-        return nextProps.literal !== this.props.literal || nextProps.language !== this.props.language;
-    }
-    public render() {
-        return (
-            <span style={{ fontSize: 16 }}>
-                <HighLight className={this.props.language || 'javascript'}>{this.props.literal}</HighLight>
-            </span>
-        );
-    }
+	// Re-rendering a codeblock causes any use selection to become de-selected. This is annoying when trying
+	// to copy-paste code examples. We therefore noop re-renders on this component if it's props haven't changed.
+	public shouldComponentUpdate(nextProps: MarkdownCodeBlockProps, nextState: MarkdownCodeBlockState) {
+		return nextProps.literal !== this.props.literal || nextProps.language !== this.props.language;
+	}
+	public render() {
+		return (
+			<span style={{ fontSize: 16 }}>
+				<HighLight className={this.props.language || 'javascript'}>{this.props.literal}</HighLight>
+			</span>
+		);
+	}
 }
diff --git a/packages/website/ts/pages/shared/markdown_section.tsx b/packages/website/ts/pages/shared/markdown_section.tsx
index 5487dc8cc..c875ab736 100644
--- a/packages/website/ts/pages/shared/markdown_section.tsx
+++ b/packages/website/ts/pages/shared/markdown_section.tsx
@@ -9,66 +9,66 @@ import { HeaderSizes } from 'ts/types';
 import { utils } from 'ts/utils/utils';
 
 interface MarkdownSectionProps {
-    sectionName: string;
-    markdownContent: string;
-    headerSize?: HeaderSizes;
-    githubLink?: string;
+	sectionName: string;
+	markdownContent: string;
+	headerSize?: HeaderSizes;
+	githubLink?: string;
 }
 
 interface MarkdownSectionState {
-    shouldShowAnchor: boolean;
+	shouldShowAnchor: boolean;
 }
 
 export class MarkdownSection extends React.Component<MarkdownSectionProps, MarkdownSectionState> {
-    public static defaultProps: Partial<MarkdownSectionProps> = {
-        headerSize: HeaderSizes.H3,
-    };
-    constructor(props: MarkdownSectionProps) {
-        super(props);
-        this.state = {
-            shouldShowAnchor: false,
-        };
-    }
-    public render() {
-        const sectionName = this.props.sectionName;
-        const id = utils.getIdFromName(sectionName);
-        return (
-            <div
-                className="pt2 pr3 md-pl2 sm-pl3 overflow-hidden"
-                onMouseOver={this._setAnchorVisibility.bind(this, true)}
-                onMouseOut={this._setAnchorVisibility.bind(this, false)}
-            >
-                <ScrollElement name={id}>
-                    <div className="clearfix">
-                        <div className="col lg-col-8 md-col-8 sm-col-12">
-                            <span style={{ textTransform: 'capitalize' }}>
-                                <AnchorTitle
-                                    headerSize={this.props.headerSize}
-                                    title={sectionName}
-                                    id={id}
-                                    shouldShowAnchor={this.state.shouldShowAnchor}
-                                />
-                            </span>
-                        </div>
-                        <div className="col col-4 sm-hide xs-hide py2 right-align">
-                            {!_.isUndefined(this.props.githubLink) && (
-                                <RaisedButton
-                                    href={this.props.githubLink}
-                                    target="_blank"
-                                    label="Edit on Github"
-                                    icon={<i className="zmdi zmdi-github" style={{ fontSize: 23 }} />}
-                                />
-                            )}
-                        </div>
-                    </div>
-                    <ReactMarkdown source={this.props.markdownContent} renderers={{ CodeBlock: MarkdownCodeBlock }} />
-                </ScrollElement>
-            </div>
-        );
-    }
-    private _setAnchorVisibility(shouldShowAnchor: boolean) {
-        this.setState({
-            shouldShowAnchor,
-        });
-    }
+	public static defaultProps: Partial<MarkdownSectionProps> = {
+		headerSize: HeaderSizes.H3,
+	};
+	constructor(props: MarkdownSectionProps) {
+		super(props);
+		this.state = {
+			shouldShowAnchor: false,
+		};
+	}
+	public render() {
+		const sectionName = this.props.sectionName;
+		const id = utils.getIdFromName(sectionName);
+		return (
+			<div
+				className="pt2 pr3 md-pl2 sm-pl3 overflow-hidden"
+				onMouseOver={this._setAnchorVisibility.bind(this, true)}
+				onMouseOut={this._setAnchorVisibility.bind(this, false)}
+			>
+				<ScrollElement name={id}>
+					<div className="clearfix">
+						<div className="col lg-col-8 md-col-8 sm-col-12">
+							<span style={{ textTransform: 'capitalize' }}>
+								<AnchorTitle
+									headerSize={this.props.headerSize}
+									title={sectionName}
+									id={id}
+									shouldShowAnchor={this.state.shouldShowAnchor}
+								/>
+							</span>
+						</div>
+						<div className="col col-4 sm-hide xs-hide py2 right-align">
+							{!_.isUndefined(this.props.githubLink) && (
+								<RaisedButton
+									href={this.props.githubLink}
+									target="_blank"
+									label="Edit on Github"
+									icon={<i className="zmdi zmdi-github" style={{ fontSize: 23 }} />}
+								/>
+							)}
+						</div>
+					</div>
+					<ReactMarkdown source={this.props.markdownContent} renderers={{ CodeBlock: MarkdownCodeBlock }} />
+				</ScrollElement>
+			</div>
+		);
+	}
+	private _setAnchorVisibility(shouldShowAnchor: boolean) {
+		this.setState({
+			shouldShowAnchor,
+		});
+	}
 }
diff --git a/packages/website/ts/pages/shared/nested_sidebar_menu.tsx b/packages/website/ts/pages/shared/nested_sidebar_menu.tsx
index 849c33504..cd7ea68e6 100644
--- a/packages/website/ts/pages/shared/nested_sidebar_menu.tsx
+++ b/packages/website/ts/pages/shared/nested_sidebar_menu.tsx
@@ -9,146 +9,146 @@ import { constants } from 'ts/utils/constants';
 import { utils } from 'ts/utils/utils';
 
 interface NestedSidebarMenuProps {
-    topLevelMenu: { [topLevel: string]: string[] };
-    menuSubsectionsBySection: MenuSubsectionsBySection;
-    shouldDisplaySectionHeaders?: boolean;
-    onMenuItemClick?: () => void;
-    selectedVersion?: string;
-    versions?: string[];
-    docPath?: string;
-    isSectionHeaderClickable?: boolean;
+	topLevelMenu: { [topLevel: string]: string[] };
+	menuSubsectionsBySection: MenuSubsectionsBySection;
+	shouldDisplaySectionHeaders?: boolean;
+	onMenuItemClick?: () => void;
+	selectedVersion?: string;
+	versions?: string[];
+	docPath?: string;
+	isSectionHeaderClickable?: boolean;
 }
 
 interface NestedSidebarMenuState {}
 
 const styles: Styles = {
-    menuItemWithHeaders: {
-        minHeight: 0,
-    },
-    menuItemWithoutHeaders: {
-        minHeight: 48,
-    },
-    menuItemInnerDivWithHeaders: {
-        lineHeight: 2,
-    },
+	menuItemWithHeaders: {
+		minHeight: 0,
+	},
+	menuItemWithoutHeaders: {
+		minHeight: 48,
+	},
+	menuItemInnerDivWithHeaders: {
+		lineHeight: 2,
+	},
 };
 
 export class NestedSidebarMenu extends React.Component<NestedSidebarMenuProps, NestedSidebarMenuState> {
-    public static defaultProps: Partial<NestedSidebarMenuProps> = {
-        shouldDisplaySectionHeaders: true,
-        onMenuItemClick: _.noop,
-    };
-    public render() {
-        const navigation = _.map(this.props.topLevelMenu, (menuItems: string[], sectionName: string) => {
-            const finalSectionName = sectionName.replace(/-/g, ' ');
-            if (this.props.shouldDisplaySectionHeaders) {
-                const id = utils.getIdFromName(sectionName);
-                return (
-                    <div key={`section-${sectionName}`} className="py1">
-                        <ScrollLink
-                            to={id}
-                            offset={-20}
-                            duration={constants.DOCS_SCROLL_DURATION_MS}
-                            containerId={constants.DOCS_CONTAINER_ID}
-                        >
-                            <div style={{ color: colors.grey, cursor: 'pointer' }} className="pb1">
-                                {finalSectionName.toUpperCase()}
-                            </div>
-                        </ScrollLink>
-                        {this._renderMenuItems(menuItems)}
-                    </div>
-                );
-            } else {
-                return <div key={`section-${sectionName}`}>{this._renderMenuItems(menuItems)}</div>;
-            }
-        });
-        return (
-            <div>
-                {!_.isUndefined(this.props.versions) &&
-                    !_.isUndefined(this.props.selectedVersion) &&
-                    !_.isUndefined(this.props.docPath) && (
-                        <VersionDropDown
-                            selectedVersion={this.props.selectedVersion}
-                            versions={this.props.versions}
-                            docPath={this.props.docPath}
-                        />
-                    )}
-                {navigation}
-            </div>
-        );
-    }
-    private _renderMenuItems(menuItemNames: string[]): React.ReactNode[] {
-        const menuItemStyles = this.props.shouldDisplaySectionHeaders
-            ? styles.menuItemWithHeaders
-            : styles.menuItemWithoutHeaders;
-        const menuItemInnerDivStyles = this.props.shouldDisplaySectionHeaders ? styles.menuItemInnerDivWithHeaders : {};
-        const menuItems = _.map(menuItemNames, menuItemName => {
-            const id = utils.getIdFromName(menuItemName);
-            return (
-                <div key={menuItemName}>
-                    <ScrollLink
-                        key={`menuItem-${menuItemName}`}
-                        to={id}
-                        offset={-10}
-                        duration={constants.DOCS_SCROLL_DURATION_MS}
-                        containerId={constants.DOCS_CONTAINER_ID}
-                    >
-                        <MenuItem
-                            onTouchTap={this._onMenuItemClick.bind(this, menuItemName)}
-                            style={menuItemStyles}
-                            innerDivStyle={menuItemInnerDivStyles}
-                        >
-                            <span style={{ textTransform: 'capitalize' }}>{menuItemName}</span>
-                        </MenuItem>
-                    </ScrollLink>
-                    {this._renderMenuItemSubsections(menuItemName)}
-                </div>
-            );
-        });
-        return menuItems;
-    }
-    private _renderMenuItemSubsections(menuItemName: string): React.ReactNode {
-        if (_.isUndefined(this.props.menuSubsectionsBySection[menuItemName])) {
-            return null;
-        }
-        return this._renderMenuSubsectionsBySection(menuItemName, this.props.menuSubsectionsBySection[menuItemName]);
-    }
-    private _renderMenuSubsectionsBySection(menuItemName: string, entityNames: string[]): React.ReactNode {
-        return (
-            <ul style={{ margin: 0, listStyleType: 'none', paddingLeft: 0 }} key={menuItemName}>
-                {_.map(entityNames, entityName => {
-                    const name = `${menuItemName}-${entityName}`;
-                    const id = utils.getIdFromName(name);
-                    return (
-                        <li key={`menuItem-${entityName}`}>
-                            <ScrollLink
-                                to={id}
-                                offset={0}
-                                duration={constants.DOCS_SCROLL_DURATION_MS}
-                                containerId={constants.DOCS_CONTAINER_ID}
-                                onTouchTap={this._onMenuItemClick.bind(this, name)}
-                            >
-                                <MenuItem
-                                    onTouchTap={this._onMenuItemClick.bind(this, name)}
-                                    style={{ minHeight: 35 }}
-                                    innerDivStyle={{
-                                        paddingLeft: 36,
-                                        fontSize: 14,
-                                        lineHeight: '35px',
-                                    }}
-                                >
-                                    {entityName}
-                                </MenuItem>
-                            </ScrollLink>
-                        </li>
-                    );
-                })}
-            </ul>
-        );
-    }
-    private _onMenuItemClick(name: string): void {
-        const id = utils.getIdFromName(name);
-        utils.setUrlHash(id);
-        this.props.onMenuItemClick();
-    }
+	public static defaultProps: Partial<NestedSidebarMenuProps> = {
+		shouldDisplaySectionHeaders: true,
+		onMenuItemClick: _.noop,
+	};
+	public render() {
+		const navigation = _.map(this.props.topLevelMenu, (menuItems: string[], sectionName: string) => {
+			const finalSectionName = sectionName.replace(/-/g, ' ');
+			if (this.props.shouldDisplaySectionHeaders) {
+				const id = utils.getIdFromName(sectionName);
+				return (
+					<div key={`section-${sectionName}`} className="py1">
+						<ScrollLink
+							to={id}
+							offset={-20}
+							duration={constants.DOCS_SCROLL_DURATION_MS}
+							containerId={constants.DOCS_CONTAINER_ID}
+						>
+							<div style={{ color: colors.grey, cursor: 'pointer' }} className="pb1">
+								{finalSectionName.toUpperCase()}
+							</div>
+						</ScrollLink>
+						{this._renderMenuItems(menuItems)}
+					</div>
+				);
+			} else {
+				return <div key={`section-${sectionName}`}>{this._renderMenuItems(menuItems)}</div>;
+			}
+		});
+		return (
+			<div>
+				{!_.isUndefined(this.props.versions) &&
+					!_.isUndefined(this.props.selectedVersion) &&
+					!_.isUndefined(this.props.docPath) && (
+						<VersionDropDown
+							selectedVersion={this.props.selectedVersion}
+							versions={this.props.versions}
+							docPath={this.props.docPath}
+						/>
+					)}
+				{navigation}
+			</div>
+		);
+	}
+	private _renderMenuItems(menuItemNames: string[]): React.ReactNode[] {
+		const menuItemStyles = this.props.shouldDisplaySectionHeaders
+			? styles.menuItemWithHeaders
+			: styles.menuItemWithoutHeaders;
+		const menuItemInnerDivStyles = this.props.shouldDisplaySectionHeaders ? styles.menuItemInnerDivWithHeaders : {};
+		const menuItems = _.map(menuItemNames, menuItemName => {
+			const id = utils.getIdFromName(menuItemName);
+			return (
+				<div key={menuItemName}>
+					<ScrollLink
+						key={`menuItem-${menuItemName}`}
+						to={id}
+						offset={-10}
+						duration={constants.DOCS_SCROLL_DURATION_MS}
+						containerId={constants.DOCS_CONTAINER_ID}
+					>
+						<MenuItem
+							onTouchTap={this._onMenuItemClick.bind(this, menuItemName)}
+							style={menuItemStyles}
+							innerDivStyle={menuItemInnerDivStyles}
+						>
+							<span style={{ textTransform: 'capitalize' }}>{menuItemName}</span>
+						</MenuItem>
+					</ScrollLink>
+					{this._renderMenuItemSubsections(menuItemName)}
+				</div>
+			);
+		});
+		return menuItems;
+	}
+	private _renderMenuItemSubsections(menuItemName: string): React.ReactNode {
+		if (_.isUndefined(this.props.menuSubsectionsBySection[menuItemName])) {
+			return null;
+		}
+		return this._renderMenuSubsectionsBySection(menuItemName, this.props.menuSubsectionsBySection[menuItemName]);
+	}
+	private _renderMenuSubsectionsBySection(menuItemName: string, entityNames: string[]): React.ReactNode {
+		return (
+			<ul style={{ margin: 0, listStyleType: 'none', paddingLeft: 0 }} key={menuItemName}>
+				{_.map(entityNames, entityName => {
+					const name = `${menuItemName}-${entityName}`;
+					const id = utils.getIdFromName(name);
+					return (
+						<li key={`menuItem-${entityName}`}>
+							<ScrollLink
+								to={id}
+								offset={0}
+								duration={constants.DOCS_SCROLL_DURATION_MS}
+								containerId={constants.DOCS_CONTAINER_ID}
+								onTouchTap={this._onMenuItemClick.bind(this, name)}
+							>
+								<MenuItem
+									onTouchTap={this._onMenuItemClick.bind(this, name)}
+									style={{ minHeight: 35 }}
+									innerDivStyle={{
+										paddingLeft: 36,
+										fontSize: 14,
+										lineHeight: '35px',
+									}}
+								>
+									{entityName}
+								</MenuItem>
+							</ScrollLink>
+						</li>
+					);
+				})}
+			</ul>
+		);
+	}
+	private _onMenuItemClick(name: string): void {
+		const id = utils.getIdFromName(name);
+		utils.setUrlHash(id);
+		this.props.onMenuItemClick();
+	}
 }
diff --git a/packages/website/ts/pages/shared/section_header.tsx b/packages/website/ts/pages/shared/section_header.tsx
index a5f5f52cf..f9aa1a5e6 100644
--- a/packages/website/ts/pages/shared/section_header.tsx
+++ b/packages/website/ts/pages/shared/section_header.tsx
@@ -5,46 +5,46 @@ import { HeaderSizes } from 'ts/types';
 import { utils } from 'ts/utils/utils';
 
 interface SectionHeaderProps {
-    sectionName: string;
-    headerSize?: HeaderSizes;
+	sectionName: string;
+	headerSize?: HeaderSizes;
 }
 
 interface SectionHeaderState {
-    shouldShowAnchor: boolean;
+	shouldShowAnchor: boolean;
 }
 
 export class SectionHeader extends React.Component<SectionHeaderProps, SectionHeaderState> {
-    public static defaultProps: Partial<SectionHeaderProps> = {
-        headerSize: HeaderSizes.H2,
-    };
-    constructor(props: SectionHeaderProps) {
-        super(props);
-        this.state = {
-            shouldShowAnchor: false,
-        };
-    }
-    public render() {
-        const sectionName = this.props.sectionName.replace(/-/g, ' ');
-        const id = utils.getIdFromName(sectionName);
-        return (
-            <div
-                onMouseOver={this._setAnchorVisibility.bind(this, true)}
-                onMouseOut={this._setAnchorVisibility.bind(this, false)}
-            >
-                <ScrollElement name={id}>
-                    <AnchorTitle
-                        headerSize={this.props.headerSize}
-                        title={<span style={{ textTransform: 'capitalize' }}>{sectionName}</span>}
-                        id={id}
-                        shouldShowAnchor={this.state.shouldShowAnchor}
-                    />
-                </ScrollElement>
-            </div>
-        );
-    }
-    private _setAnchorVisibility(shouldShowAnchor: boolean) {
-        this.setState({
-            shouldShowAnchor,
-        });
-    }
+	public static defaultProps: Partial<SectionHeaderProps> = {
+		headerSize: HeaderSizes.H2,
+	};
+	constructor(props: SectionHeaderProps) {
+		super(props);
+		this.state = {
+			shouldShowAnchor: false,
+		};
+	}
+	public render() {
+		const sectionName = this.props.sectionName.replace(/-/g, ' ');
+		const id = utils.getIdFromName(sectionName);
+		return (
+			<div
+				onMouseOver={this._setAnchorVisibility.bind(this, true)}
+				onMouseOut={this._setAnchorVisibility.bind(this, false)}
+			>
+				<ScrollElement name={id}>
+					<AnchorTitle
+						headerSize={this.props.headerSize}
+						title={<span style={{ textTransform: 'capitalize' }}>{sectionName}</span>}
+						id={id}
+						shouldShowAnchor={this.state.shouldShowAnchor}
+					/>
+				</ScrollElement>
+			</div>
+		);
+	}
+	private _setAnchorVisibility(shouldShowAnchor: boolean) {
+		this.setState({
+			shouldShowAnchor,
+		});
+	}
 }
diff --git a/packages/website/ts/pages/shared/version_drop_down.tsx b/packages/website/ts/pages/shared/version_drop_down.tsx
index b922e1048..a647252ba 100644
--- a/packages/website/ts/pages/shared/version_drop_down.tsx
+++ b/packages/website/ts/pages/shared/version_drop_down.tsx
@@ -4,34 +4,34 @@ import MenuItem from 'material-ui/MenuItem';
 import * as React from 'react';
 
 interface VersionDropDownProps {
-    selectedVersion: string;
-    versions: string[];
-    docPath: string;
+	selectedVersion: string;
+	versions: string[];
+	docPath: string;
 }
 
 interface VersionDropDownState {}
 
 export class VersionDropDown extends React.Component<VersionDropDownProps, VersionDropDownState> {
-    public render() {
-        return (
-            <div className="mx-auto" style={{ width: 120 }}>
-                <DropDownMenu
-                    maxHeight={300}
-                    value={this.props.selectedVersion}
-                    onChange={this._updateSelectedVersion.bind(this)}
-                >
-                    {this._renderDropDownItems()}
-                </DropDownMenu>
-            </div>
-        );
-    }
-    private _renderDropDownItems() {
-        const items = _.map(this.props.versions, version => {
-            return <MenuItem key={version} value={version} primaryText={`v${version}`} />;
-        });
-        return items;
-    }
-    private _updateSelectedVersion(e: any, index: number, value: string) {
-        window.location.href = `${this.props.docPath}/${value}${window.location.hash}`;
-    }
+	public render() {
+		return (
+			<div className="mx-auto" style={{ width: 120 }}>
+				<DropDownMenu
+					maxHeight={300}
+					value={this.props.selectedVersion}
+					onChange={this._updateSelectedVersion.bind(this)}
+				>
+					{this._renderDropDownItems()}
+				</DropDownMenu>
+			</div>
+		);
+	}
+	private _renderDropDownItems() {
+		const items = _.map(this.props.versions, version => {
+			return <MenuItem key={version} value={version} primaryText={`v${version}`} />;
+		});
+		return items;
+	}
+	private _updateSelectedVersion(e: any, index: number, value: string) {
+		window.location.href = `${this.props.docPath}/${value}${window.location.hash}`;
+	}
 }
diff --git a/packages/website/ts/pages/wiki/wiki.tsx b/packages/website/ts/pages/wiki/wiki.tsx
index d065614ba..dba5ed6a0 100644
--- a/packages/website/ts/pages/wiki/wiki.tsx
+++ b/packages/website/ts/pages/wiki/wiki.tsx
@@ -16,186 +16,186 @@ import { utils } from 'ts/utils/utils';
 const WIKI_NOT_READY_BACKOUT_TIMEOUT_MS = 5000;
 
 export interface WikiProps {
-    source: string;
-    location: Location;
+	source: string;
+	location: Location;
 }
 
 interface WikiState {
-    articlesBySection: ArticlesBySection;
+	articlesBySection: ArticlesBySection;
 }
 
 const styles: Styles = {
-    mainContainers: {
-        position: 'absolute',
-        top: 1,
-        left: 0,
-        bottom: 0,
-        right: 0,
-        overflowZ: 'hidden',
-        overflowY: 'scroll',
-        minHeight: 'calc(100vh - 1px)',
-        WebkitOverflowScrolling: 'touch',
-    },
-    menuContainer: {
-        borderColor: colors.grey300,
-        maxWidth: 330,
-        marginLeft: 20,
-    },
+	mainContainers: {
+		position: 'absolute',
+		top: 1,
+		left: 0,
+		bottom: 0,
+		right: 0,
+		overflowZ: 'hidden',
+		overflowY: 'scroll',
+		minHeight: 'calc(100vh - 1px)',
+		WebkitOverflowScrolling: 'touch',
+	},
+	menuContainer: {
+		borderColor: colors.grey300,
+		maxWidth: 330,
+		marginLeft: 20,
+	},
 };
 
 export class Wiki extends React.Component<WikiProps, WikiState> {
-    private _wikiBackoffTimeoutId: number;
-    constructor(props: WikiProps) {
-        super(props);
-        this.state = {
-            articlesBySection: undefined,
-        };
-    }
-    public componentWillMount() {
-        // tslint:disable-next-line:no-floating-promises
-        this._fetchArticlesBySectionAsync();
-    }
-    public componentWillUnmount() {
-        clearTimeout(this._wikiBackoffTimeoutId);
-    }
-    public render() {
-        const menuSubsectionsBySection = _.isUndefined(this.state.articlesBySection)
-            ? {}
-            : this._getMenuSubsectionsBySection(this.state.articlesBySection);
-        return (
-            <div>
-                <DocumentTitle title="0x Protocol Wiki" />
-                <TopBar
-                    blockchainIsLoaded={false}
-                    location={this.props.location}
-                    menuSubsectionsBySection={menuSubsectionsBySection}
-                    shouldFullWidth={true}
-                />
-                {_.isUndefined(this.state.articlesBySection) ? (
-                    <div className="col col-12" style={styles.mainContainers}>
-                        <div
-                            className="relative sm-px2 sm-pt2 sm-m1"
-                            style={{ height: 122, top: '50%', transform: 'translateY(-50%)' }}
-                        >
-                            <div className="center pb2">
-                                <CircularProgress size={40} thickness={5} />
-                            </div>
-                            <div className="center pt2" style={{ paddingBottom: 11 }}>
-                                Loading wiki...
-                            </div>
-                        </div>
-                    </div>
-                ) : (
-                    <div className="mx-auto flex" style={{ color: colors.grey800, height: 43 }}>
-                        <div className="relative col md-col-3 lg-col-3 lg-pl0 md-pl1 sm-hide xs-hide">
-                            <div
-                                className="border-right absolute pt2"
-                                style={{ ...styles.menuContainer, ...styles.mainContainers }}
-                            >
-                                <NestedSidebarMenu
-                                    topLevelMenu={menuSubsectionsBySection}
-                                    menuSubsectionsBySection={menuSubsectionsBySection}
-                                    isSectionHeaderClickable={true}
-                                />
-                            </div>
-                        </div>
-                        <div className="relative col lg-col-9 md-col-9 sm-col-12 col-12">
-                            <div id="documentation" style={styles.mainContainers} className="absolute">
-                                <div id="0xProtocolWiki" />
-                                <h1 className="md-pl2 sm-pl3">
-                                    <a href={constants.URL_GITHUB_WIKI} target="_blank">
-                                        0x Protocol Wiki
-                                    </a>
-                                </h1>
-                                <div id="wiki">{this._renderWikiArticles()}</div>
-                            </div>
-                        </div>
-                    </div>
-                )}
-            </div>
-        );
-    }
-    private _renderWikiArticles(): React.ReactNode {
-        const sectionNames = _.keys(this.state.articlesBySection);
-        const sections = _.map(sectionNames, sectionName => this._renderSection(sectionName));
-        return sections;
-    }
-    private _renderSection(sectionName: string) {
-        const articles = this.state.articlesBySection[sectionName];
-        const renderedArticles = _.map(articles, (article: Article) => {
-            const githubLink = `${constants.URL_GITHUB_WIKI}/edit/master/${sectionName}/${article.fileName}`;
-            return (
-                <div key={`markdown-section-${article.title}`}>
-                    <MarkdownSection
-                        sectionName={article.title}
-                        markdownContent={article.content}
-                        headerSize={HeaderSizes.H2}
-                        githubLink={githubLink}
-                    />
-                    <div className="mb4 mt3 p3 center" style={{ backgroundColor: colors.lightestGrey }}>
-                        See a way to make this article better?{' '}
-                        <a href={githubLink} target="_blank">
-                            Edit here →
-                        </a>
-                    </div>
-                </div>
-            );
-        });
-        return (
-            <div key={`section-${sectionName}`} className="py2 pr3 md-pl2 sm-pl3">
-                <SectionHeader sectionName={sectionName} headerSize={HeaderSizes.H1} />
-                {renderedArticles}
-            </div>
-        );
-    }
-    private _scrollToHash(): void {
-        const hashWithPrefix = this.props.location.hash;
-        let hash = hashWithPrefix.slice(1);
-        if (_.isEmpty(hash)) {
-            hash = '0xProtocolWiki'; // scroll to the top
-        }
+	private _wikiBackoffTimeoutId: number;
+	constructor(props: WikiProps) {
+		super(props);
+		this.state = {
+			articlesBySection: undefined,
+		};
+	}
+	public componentWillMount() {
+		// tslint:disable-next-line:no-floating-promises
+		this._fetchArticlesBySectionAsync();
+	}
+	public componentWillUnmount() {
+		clearTimeout(this._wikiBackoffTimeoutId);
+	}
+	public render() {
+		const menuSubsectionsBySection = _.isUndefined(this.state.articlesBySection)
+			? {}
+			: this._getMenuSubsectionsBySection(this.state.articlesBySection);
+		return (
+			<div>
+				<DocumentTitle title="0x Protocol Wiki" />
+				<TopBar
+					blockchainIsLoaded={false}
+					location={this.props.location}
+					menuSubsectionsBySection={menuSubsectionsBySection}
+					shouldFullWidth={true}
+				/>
+				{_.isUndefined(this.state.articlesBySection) ? (
+					<div className="col col-12" style={styles.mainContainers}>
+						<div
+							className="relative sm-px2 sm-pt2 sm-m1"
+							style={{ height: 122, top: '50%', transform: 'translateY(-50%)' }}
+						>
+							<div className="center pb2">
+								<CircularProgress size={40} thickness={5} />
+							</div>
+							<div className="center pt2" style={{ paddingBottom: 11 }}>
+								Loading wiki...
+							</div>
+						</div>
+					</div>
+				) : (
+					<div className="mx-auto flex" style={{ color: colors.grey800, height: 43 }}>
+						<div className="relative col md-col-3 lg-col-3 lg-pl0 md-pl1 sm-hide xs-hide">
+							<div
+								className="border-right absolute pt2"
+								style={{ ...styles.menuContainer, ...styles.mainContainers }}
+							>
+								<NestedSidebarMenu
+									topLevelMenu={menuSubsectionsBySection}
+									menuSubsectionsBySection={menuSubsectionsBySection}
+									isSectionHeaderClickable={true}
+								/>
+							</div>
+						</div>
+						<div className="relative col lg-col-9 md-col-9 sm-col-12 col-12">
+							<div id="documentation" style={styles.mainContainers} className="absolute">
+								<div id="0xProtocolWiki" />
+								<h1 className="md-pl2 sm-pl3">
+									<a href={constants.URL_GITHUB_WIKI} target="_blank">
+										0x Protocol Wiki
+									</a>
+								</h1>
+								<div id="wiki">{this._renderWikiArticles()}</div>
+							</div>
+						</div>
+					</div>
+				)}
+			</div>
+		);
+	}
+	private _renderWikiArticles(): React.ReactNode {
+		const sectionNames = _.keys(this.state.articlesBySection);
+		const sections = _.map(sectionNames, sectionName => this._renderSection(sectionName));
+		return sections;
+	}
+	private _renderSection(sectionName: string) {
+		const articles = this.state.articlesBySection[sectionName];
+		const renderedArticles = _.map(articles, (article: Article) => {
+			const githubLink = `${constants.URL_GITHUB_WIKI}/edit/master/${sectionName}/${article.fileName}`;
+			return (
+				<div key={`markdown-section-${article.title}`}>
+					<MarkdownSection
+						sectionName={article.title}
+						markdownContent={article.content}
+						headerSize={HeaderSizes.H2}
+						githubLink={githubLink}
+					/>
+					<div className="mb4 mt3 p3 center" style={{ backgroundColor: colors.lightestGrey }}>
+						See a way to make this article better?{' '}
+						<a href={githubLink} target="_blank">
+							Edit here →
+						</a>
+					</div>
+				</div>
+			);
+		});
+		return (
+			<div key={`section-${sectionName}`} className="py2 pr3 md-pl2 sm-pl3">
+				<SectionHeader sectionName={sectionName} headerSize={HeaderSizes.H1} />
+				{renderedArticles}
+			</div>
+		);
+	}
+	private _scrollToHash(): void {
+		const hashWithPrefix = this.props.location.hash;
+		let hash = hashWithPrefix.slice(1);
+		if (_.isEmpty(hash)) {
+			hash = '0xProtocolWiki'; // scroll to the top
+		}
 
-        scroller.scrollTo(hash, {
-            duration: 0,
-            offset: 0,
-            containerId: 'documentation',
-        });
-    }
-    private async _fetchArticlesBySectionAsync(): Promise<void> {
-        const endpoint = `${configs.BACKEND_BASE_URL}${WebsitePaths.Wiki}`;
-        const response = await fetch(endpoint);
-        if (response.status === constants.HTTP_NO_CONTENT_STATUS_CODE) {
-            // We need to backoff and try fetching again later
-            this._wikiBackoffTimeoutId = window.setTimeout(() => {
-                // tslint:disable-next-line:no-floating-promises
-                this._fetchArticlesBySectionAsync();
-            }, WIKI_NOT_READY_BACKOUT_TIMEOUT_MS);
-            return;
-        }
-        if (response.status !== 200) {
-            // TODO: Show the user an error message when the wiki fail to load
-            const errMsg = await response.text();
-            utils.consoleLog(`Failed to load wiki: ${response.status} ${errMsg}`);
-            return;
-        }
-        const articlesBySection = await response.json();
-        this.setState(
-            {
-                articlesBySection,
-            },
-            () => {
-                this._scrollToHash();
-            },
-        );
-    }
-    private _getMenuSubsectionsBySection(articlesBySection: ArticlesBySection) {
-        const sectionNames = _.keys(articlesBySection);
-        const menuSubsectionsBySection: { [section: string]: string[] } = {};
-        for (const sectionName of sectionNames) {
-            const articles = articlesBySection[sectionName];
-            const articleNames = _.map(articles, article => article.title);
-            menuSubsectionsBySection[sectionName] = articleNames;
-        }
-        return menuSubsectionsBySection;
-    }
+		scroller.scrollTo(hash, {
+			duration: 0,
+			offset: 0,
+			containerId: 'documentation',
+		});
+	}
+	private async _fetchArticlesBySectionAsync(): Promise<void> {
+		const endpoint = `${configs.BACKEND_BASE_URL}${WebsitePaths.Wiki}`;
+		const response = await fetch(endpoint);
+		if (response.status === constants.HTTP_NO_CONTENT_STATUS_CODE) {
+			// We need to backoff and try fetching again later
+			this._wikiBackoffTimeoutId = window.setTimeout(() => {
+				// tslint:disable-next-line:no-floating-promises
+				this._fetchArticlesBySectionAsync();
+			}, WIKI_NOT_READY_BACKOUT_TIMEOUT_MS);
+			return;
+		}
+		if (response.status !== 200) {
+			// TODO: Show the user an error message when the wiki fail to load
+			const errMsg = await response.text();
+			utils.consoleLog(`Failed to load wiki: ${response.status} ${errMsg}`);
+			return;
+		}
+		const articlesBySection = await response.json();
+		this.setState(
+			{
+				articlesBySection,
+			},
+			() => {
+				this._scrollToHash();
+			},
+		);
+	}
+	private _getMenuSubsectionsBySection(articlesBySection: ArticlesBySection) {
+		const sectionNames = _.keys(articlesBySection);
+		const menuSubsectionsBySection: { [section: string]: string[] } = {};
+		for (const sectionName of sectionNames) {
+			const articles = articlesBySection[sectionName];
+			const articleNames = _.map(articles, article => article.title);
+			menuSubsectionsBySection[sectionName] = articleNames;
+		}
+		return menuSubsectionsBySection;
+	}
 }
diff --git a/packages/website/ts/redux/dispatcher.ts b/packages/website/ts/redux/dispatcher.ts
index 42989e5e1..19300e242 100644
--- a/packages/website/ts/redux/dispatcher.ts
+++ b/packages/website/ts/redux/dispatcher.ts
@@ -2,235 +2,235 @@ import { BigNumber } from '@0xproject/utils';
 import { Dispatch } from 'redux';
 import { State } from 'ts/redux/reducer';
 import {
-    ActionTypes,
-    AssetToken,
-    BlockchainErrs,
-    Order,
-    ProviderType,
-    ScreenWidths,
-    Side,
-    SignatureData,
-    Token,
-    TokenStateByAddress,
+	ActionTypes,
+	AssetToken,
+	BlockchainErrs,
+	Order,
+	ProviderType,
+	ScreenWidths,
+	Side,
+	SignatureData,
+	Token,
+	TokenStateByAddress,
 } from 'ts/types';
 
 export class Dispatcher {
-    private _dispatch: Dispatch<State>;
-    constructor(dispatch: Dispatch<State>) {
-        this._dispatch = dispatch;
-    }
-    // Portal
-    public resetState() {
-        this._dispatch({
-            type: ActionTypes.ResetState,
-        });
-    }
-    public updateNodeVersion(nodeVersion: string) {
-        this._dispatch({
-            data: nodeVersion,
-            type: ActionTypes.UpdateNodeVersion,
-        });
-    }
-    public updateScreenWidth(screenWidth: ScreenWidths) {
-        this._dispatch({
-            data: screenWidth,
-            type: ActionTypes.UpdateScreenWidth,
-        });
-    }
-    public swapAssetTokenSymbols() {
-        this._dispatch({
-            type: ActionTypes.SwapAssetTokens,
-        });
-    }
-    public updateOrderSalt(salt: BigNumber) {
-        this._dispatch({
-            data: salt,
-            type: ActionTypes.UpdateOrderSalt,
-        });
-    }
-    public updateUserSuppliedOrderCache(order: Order) {
-        this._dispatch({
-            data: order,
-            type: ActionTypes.UpdateUserSuppliedOrderCache,
-        });
-    }
-    public updateShouldBlockchainErrDialogBeOpen(shouldBeOpen: boolean) {
-        this._dispatch({
-            data: shouldBeOpen,
-            type: ActionTypes.UpdateShouldBlockchainErrDialogBeOpen,
-        });
-    }
-    public updateChosenAssetToken(side: Side, token: AssetToken) {
-        this._dispatch({
-            data: {
-                side,
-                token,
-            },
-            type: ActionTypes.UpdateChosenAssetToken,
-        });
-    }
-    public updateChosenAssetTokenAddress(side: Side, address: string) {
-        this._dispatch({
-            data: {
-                address,
-                side,
-            },
-            type: ActionTypes.UpdateChosenAssetTokenAddress,
-        });
-    }
-    public updateOrderTakerAddress(address: string) {
-        this._dispatch({
-            data: address,
-            type: ActionTypes.UpdateOrderTakerAddress,
-        });
-    }
-    public updateUserAddress(address: string) {
-        this._dispatch({
-            data: address,
-            type: ActionTypes.UpdateUserAddress,
-        });
-    }
-    public updateOrderExpiry(unixTimestampSec: BigNumber) {
-        this._dispatch({
-            data: unixTimestampSec,
-            type: ActionTypes.UpdateOrderExpiry,
-        });
-    }
-    public encounteredBlockchainError(err: BlockchainErrs) {
-        this._dispatch({
-            data: err,
-            type: ActionTypes.BlockchainErrEncountered,
-        });
-    }
-    public updateBlockchainIsLoaded(isLoaded: boolean) {
-        this._dispatch({
-            data: isLoaded,
-            type: ActionTypes.UpdateBlockchainIsLoaded,
-        });
-    }
-    public addTokenToTokenByAddress(token: Token) {
-        this._dispatch({
-            data: token,
-            type: ActionTypes.AddTokenToTokenByAddress,
-        });
-    }
-    public removeTokenToTokenByAddress(token: Token) {
-        this._dispatch({
-            data: token,
-            type: ActionTypes.RemoveTokenFromTokenByAddress,
-        });
-    }
-    public clearTokenByAddress() {
-        this._dispatch({
-            type: ActionTypes.ClearTokenByAddress,
-        });
-    }
-    public updateTokenByAddress(tokens: Token[]) {
-        this._dispatch({
-            data: tokens,
-            type: ActionTypes.UpdateTokenByAddress,
-        });
-    }
-    public updateTokenStateByAddress(tokenStateByAddress: TokenStateByAddress) {
-        this._dispatch({
-            data: tokenStateByAddress,
-            type: ActionTypes.UpdateTokenStateByAddress,
-        });
-    }
-    public removeFromTokenStateByAddress(tokenAddress: string) {
-        this._dispatch({
-            data: tokenAddress,
-            type: ActionTypes.RemoveFromTokenStateByAddress,
-        });
-    }
-    public replaceTokenAllowanceByAddress(address: string, allowance: BigNumber) {
-        this._dispatch({
-            data: {
-                address,
-                allowance,
-            },
-            type: ActionTypes.ReplaceTokenAllowanceByAddress,
-        });
-    }
-    public replaceTokenBalanceByAddress(address: string, balance: BigNumber) {
-        this._dispatch({
-            data: {
-                address,
-                balance,
-            },
-            type: ActionTypes.ReplaceTokenBalanceByAddress,
-        });
-    }
-    public updateTokenBalanceByAddress(address: string, balanceDelta: BigNumber) {
-        this._dispatch({
-            data: {
-                address,
-                balanceDelta,
-            },
-            type: ActionTypes.UpdateTokenBalanceByAddress,
-        });
-    }
-    public updateSignatureData(signatureData: SignatureData) {
-        this._dispatch({
-            data: signatureData,
-            type: ActionTypes.UpdateOrderSignatureData,
-        });
-    }
-    public updateUserEtherBalance(balance: BigNumber) {
-        this._dispatch({
-            data: balance,
-            type: ActionTypes.UpdateUserEtherBalance,
-        });
-    }
-    public updateNetworkId(networkId: number) {
-        this._dispatch({
-            data: networkId,
-            type: ActionTypes.UpdateNetworkId,
-        });
-    }
-    public updateOrderFillAmount(amount: BigNumber) {
-        this._dispatch({
-            data: amount,
-            type: ActionTypes.UpdateOrderFillAmount,
-        });
-    }
+	private _dispatch: Dispatch<State>;
+	constructor(dispatch: Dispatch<State>) {
+		this._dispatch = dispatch;
+	}
+	// Portal
+	public resetState() {
+		this._dispatch({
+			type: ActionTypes.ResetState,
+		});
+	}
+	public updateNodeVersion(nodeVersion: string) {
+		this._dispatch({
+			data: nodeVersion,
+			type: ActionTypes.UpdateNodeVersion,
+		});
+	}
+	public updateScreenWidth(screenWidth: ScreenWidths) {
+		this._dispatch({
+			data: screenWidth,
+			type: ActionTypes.UpdateScreenWidth,
+		});
+	}
+	public swapAssetTokenSymbols() {
+		this._dispatch({
+			type: ActionTypes.SwapAssetTokens,
+		});
+	}
+	public updateOrderSalt(salt: BigNumber) {
+		this._dispatch({
+			data: salt,
+			type: ActionTypes.UpdateOrderSalt,
+		});
+	}
+	public updateUserSuppliedOrderCache(order: Order) {
+		this._dispatch({
+			data: order,
+			type: ActionTypes.UpdateUserSuppliedOrderCache,
+		});
+	}
+	public updateShouldBlockchainErrDialogBeOpen(shouldBeOpen: boolean) {
+		this._dispatch({
+			data: shouldBeOpen,
+			type: ActionTypes.UpdateShouldBlockchainErrDialogBeOpen,
+		});
+	}
+	public updateChosenAssetToken(side: Side, token: AssetToken) {
+		this._dispatch({
+			data: {
+				side,
+				token,
+			},
+			type: ActionTypes.UpdateChosenAssetToken,
+		});
+	}
+	public updateChosenAssetTokenAddress(side: Side, address: string) {
+		this._dispatch({
+			data: {
+				address,
+				side,
+			},
+			type: ActionTypes.UpdateChosenAssetTokenAddress,
+		});
+	}
+	public updateOrderTakerAddress(address: string) {
+		this._dispatch({
+			data: address,
+			type: ActionTypes.UpdateOrderTakerAddress,
+		});
+	}
+	public updateUserAddress(address: string) {
+		this._dispatch({
+			data: address,
+			type: ActionTypes.UpdateUserAddress,
+		});
+	}
+	public updateOrderExpiry(unixTimestampSec: BigNumber) {
+		this._dispatch({
+			data: unixTimestampSec,
+			type: ActionTypes.UpdateOrderExpiry,
+		});
+	}
+	public encounteredBlockchainError(err: BlockchainErrs) {
+		this._dispatch({
+			data: err,
+			type: ActionTypes.BlockchainErrEncountered,
+		});
+	}
+	public updateBlockchainIsLoaded(isLoaded: boolean) {
+		this._dispatch({
+			data: isLoaded,
+			type: ActionTypes.UpdateBlockchainIsLoaded,
+		});
+	}
+	public addTokenToTokenByAddress(token: Token) {
+		this._dispatch({
+			data: token,
+			type: ActionTypes.AddTokenToTokenByAddress,
+		});
+	}
+	public removeTokenToTokenByAddress(token: Token) {
+		this._dispatch({
+			data: token,
+			type: ActionTypes.RemoveTokenFromTokenByAddress,
+		});
+	}
+	public clearTokenByAddress() {
+		this._dispatch({
+			type: ActionTypes.ClearTokenByAddress,
+		});
+	}
+	public updateTokenByAddress(tokens: Token[]) {
+		this._dispatch({
+			data: tokens,
+			type: ActionTypes.UpdateTokenByAddress,
+		});
+	}
+	public updateTokenStateByAddress(tokenStateByAddress: TokenStateByAddress) {
+		this._dispatch({
+			data: tokenStateByAddress,
+			type: ActionTypes.UpdateTokenStateByAddress,
+		});
+	}
+	public removeFromTokenStateByAddress(tokenAddress: string) {
+		this._dispatch({
+			data: tokenAddress,
+			type: ActionTypes.RemoveFromTokenStateByAddress,
+		});
+	}
+	public replaceTokenAllowanceByAddress(address: string, allowance: BigNumber) {
+		this._dispatch({
+			data: {
+				address,
+				allowance,
+			},
+			type: ActionTypes.ReplaceTokenAllowanceByAddress,
+		});
+	}
+	public replaceTokenBalanceByAddress(address: string, balance: BigNumber) {
+		this._dispatch({
+			data: {
+				address,
+				balance,
+			},
+			type: ActionTypes.ReplaceTokenBalanceByAddress,
+		});
+	}
+	public updateTokenBalanceByAddress(address: string, balanceDelta: BigNumber) {
+		this._dispatch({
+			data: {
+				address,
+				balanceDelta,
+			},
+			type: ActionTypes.UpdateTokenBalanceByAddress,
+		});
+	}
+	public updateSignatureData(signatureData: SignatureData) {
+		this._dispatch({
+			data: signatureData,
+			type: ActionTypes.UpdateOrderSignatureData,
+		});
+	}
+	public updateUserEtherBalance(balance: BigNumber) {
+		this._dispatch({
+			data: balance,
+			type: ActionTypes.UpdateUserEtherBalance,
+		});
+	}
+	public updateNetworkId(networkId: number) {
+		this._dispatch({
+			data: networkId,
+			type: ActionTypes.UpdateNetworkId,
+		});
+	}
+	public updateOrderFillAmount(amount: BigNumber) {
+		this._dispatch({
+			data: amount,
+			type: ActionTypes.UpdateOrderFillAmount,
+		});
+	}
 
-    // Docs
-    public updateCurrentDocsVersion(version: string) {
-        this._dispatch({
-            data: version,
-            type: ActionTypes.UpdateLibraryVersion,
-        });
-    }
-    public updateAvailableDocVersions(versions: string[]) {
-        this._dispatch({
-            data: versions,
-            type: ActionTypes.UpdateAvailableLibraryVersions,
-        });
-    }
+	// Docs
+	public updateCurrentDocsVersion(version: string) {
+		this._dispatch({
+			data: version,
+			type: ActionTypes.UpdateLibraryVersion,
+		});
+	}
+	public updateAvailableDocVersions(versions: string[]) {
+		this._dispatch({
+			data: versions,
+			type: ActionTypes.UpdateAvailableLibraryVersions,
+		});
+	}
 
-    // Shared
-    public showFlashMessage(msg: string | React.ReactNode) {
-        this._dispatch({
-            data: msg,
-            type: ActionTypes.ShowFlashMessage,
-        });
-    }
-    public hideFlashMessage() {
-        this._dispatch({
-            type: ActionTypes.HideFlashMessage,
-        });
-    }
-    public updateProviderType(providerType: ProviderType) {
-        this._dispatch({
-            type: ActionTypes.UpdateProviderType,
-            data: providerType,
-        });
-    }
-    public updateInjectedProviderName(injectedProviderName: string) {
-        this._dispatch({
-            type: ActionTypes.UpdateInjectedProviderName,
-            data: injectedProviderName,
-        });
-    }
+	// Shared
+	public showFlashMessage(msg: string | React.ReactNode) {
+		this._dispatch({
+			data: msg,
+			type: ActionTypes.ShowFlashMessage,
+		});
+	}
+	public hideFlashMessage() {
+		this._dispatch({
+			type: ActionTypes.HideFlashMessage,
+		});
+	}
+	public updateProviderType(providerType: ProviderType) {
+		this._dispatch({
+			type: ActionTypes.UpdateProviderType,
+			data: providerType,
+		});
+	}
+	public updateInjectedProviderName(injectedProviderName: string) {
+		this._dispatch({
+			type: ActionTypes.UpdateInjectedProviderName,
+			data: injectedProviderName,
+		});
+	}
 }
diff --git a/packages/website/ts/redux/reducer.ts b/packages/website/ts/redux/reducer.ts
index 06ac8b670..cc467eadd 100644
--- a/packages/website/ts/redux/reducer.ts
+++ b/packages/website/ts/redux/reducer.ts
@@ -2,18 +2,18 @@ import { ZeroEx } from '0x.js';
 import { BigNumber } from '@0xproject/utils';
 import * as _ from 'lodash';
 import {
-    Action,
-    ActionTypes,
-    BlockchainErrs,
-    Order,
-    ProviderType,
-    ScreenWidths,
-    Side,
-    SideToAssetToken,
-    SignatureData,
-    TokenByAddress,
-    TokenState,
-    TokenStateByAddress,
+	Action,
+	ActionTypes,
+	BlockchainErrs,
+	Order,
+	ProviderType,
+	ScreenWidths,
+	Side,
+	SideToAssetToken,
+	SignatureData,
+	TokenByAddress,
+	TokenState,
+	TokenStateByAddress,
 } from 'ts/types';
 import { utils } from 'ts/utils/utils';
 
@@ -23,367 +23,367 @@ import { utils } from 'ts/utils/utils';
 const DEFAULT_DOCS_VERSION = '0.0.0';
 
 export interface State {
-    // Portal
-    blockchainErr: BlockchainErrs;
-    blockchainIsLoaded: boolean;
-    networkId: number;
-    orderExpiryTimestamp: BigNumber;
-    orderFillAmount: BigNumber;
-    orderTakerAddress: string;
-    orderSignatureData: SignatureData;
-    orderSalt: BigNumber;
-    nodeVersion: string;
-    screenWidth: ScreenWidths;
-    shouldBlockchainErrDialogBeOpen: boolean;
-    sideToAssetToken: SideToAssetToken;
-    tokenByAddress: TokenByAddress;
-    tokenStateByAddress: TokenStateByAddress;
-    userAddress: string;
-    userEtherBalance: BigNumber;
-    // Note: cache of supplied orderJSON in fill order step. Do not use for anything else.
-    userSuppliedOrderCache: Order;
-
-    // Docs
-    docsVersion: string;
-    availableDocVersions: string[];
-
-    // Shared
-    flashMessage: string | React.ReactNode;
-    providerType: ProviderType;
-    injectedProviderName: string;
+	// Portal
+	blockchainErr: BlockchainErrs;
+	blockchainIsLoaded: boolean;
+	networkId: number;
+	orderExpiryTimestamp: BigNumber;
+	orderFillAmount: BigNumber;
+	orderTakerAddress: string;
+	orderSignatureData: SignatureData;
+	orderSalt: BigNumber;
+	nodeVersion: string;
+	screenWidth: ScreenWidths;
+	shouldBlockchainErrDialogBeOpen: boolean;
+	sideToAssetToken: SideToAssetToken;
+	tokenByAddress: TokenByAddress;
+	tokenStateByAddress: TokenStateByAddress;
+	userAddress: string;
+	userEtherBalance: BigNumber;
+	// Note: cache of supplied orderJSON in fill order step. Do not use for anything else.
+	userSuppliedOrderCache: Order;
+
+	// Docs
+	docsVersion: string;
+	availableDocVersions: string[];
+
+	// Shared
+	flashMessage: string | React.ReactNode;
+	providerType: ProviderType;
+	injectedProviderName: string;
 }
 
 const INITIAL_STATE: State = {
-    // Portal
-    blockchainErr: BlockchainErrs.NoError,
-    blockchainIsLoaded: false,
-    networkId: undefined,
-    orderExpiryTimestamp: utils.initialOrderExpiryUnixTimestampSec(),
-    orderFillAmount: undefined,
-    orderSignatureData: {
-        hash: '',
-        r: '',
-        s: '',
-        v: 27,
-    },
-    orderTakerAddress: '',
-    orderSalt: ZeroEx.generatePseudoRandomSalt(),
-    nodeVersion: undefined,
-    screenWidth: utils.getScreenWidth(),
-    shouldBlockchainErrDialogBeOpen: false,
-    sideToAssetToken: {
-        [Side.Deposit]: {},
-        [Side.Receive]: {},
-    },
-    tokenByAddress: {},
-    tokenStateByAddress: {},
-    userAddress: '',
-    userEtherBalance: new BigNumber(0),
-    userSuppliedOrderCache: undefined,
-
-    // Docs
-    docsVersion: DEFAULT_DOCS_VERSION,
-    availableDocVersions: [DEFAULT_DOCS_VERSION],
-
-    // Shared
-    flashMessage: undefined,
-    providerType: ProviderType.Injected,
-    injectedProviderName: '',
+	// Portal
+	blockchainErr: BlockchainErrs.NoError,
+	blockchainIsLoaded: false,
+	networkId: undefined,
+	orderExpiryTimestamp: utils.initialOrderExpiryUnixTimestampSec(),
+	orderFillAmount: undefined,
+	orderSignatureData: {
+		hash: '',
+		r: '',
+		s: '',
+		v: 27,
+	},
+	orderTakerAddress: '',
+	orderSalt: ZeroEx.generatePseudoRandomSalt(),
+	nodeVersion: undefined,
+	screenWidth: utils.getScreenWidth(),
+	shouldBlockchainErrDialogBeOpen: false,
+	sideToAssetToken: {
+		[Side.Deposit]: {},
+		[Side.Receive]: {},
+	},
+	tokenByAddress: {},
+	tokenStateByAddress: {},
+	userAddress: '',
+	userEtherBalance: new BigNumber(0),
+	userSuppliedOrderCache: undefined,
+
+	// Docs
+	docsVersion: DEFAULT_DOCS_VERSION,
+	availableDocVersions: [DEFAULT_DOCS_VERSION],
+
+	// Shared
+	flashMessage: undefined,
+	providerType: ProviderType.Injected,
+	injectedProviderName: '',
 };
 
 export function reducer(state: State = INITIAL_STATE, action: Action) {
-    switch (action.type) {
-        // Portal
-        case ActionTypes.ResetState:
-            return INITIAL_STATE;
-
-        case ActionTypes.UpdateOrderSalt: {
-            return {
-                ...state,
-                orderSalt: action.data,
-            };
-        }
-
-        case ActionTypes.UpdateNodeVersion: {
-            return {
-                ...state,
-                nodeVersion: action.data,
-            };
-        }
-
-        case ActionTypes.UpdateOrderFillAmount: {
-            return {
-                ...state,
-                orderFillAmount: action.data,
-            };
-        }
-
-        case ActionTypes.UpdateShouldBlockchainErrDialogBeOpen: {
-            return {
-                ...state,
-                shouldBlockchainErrDialogBeOpen: action.data,
-            };
-        }
-
-        case ActionTypes.UpdateUserEtherBalance: {
-            return {
-                ...state,
-                userEtherBalance: action.data,
-            };
-        }
-
-        case ActionTypes.UpdateUserSuppliedOrderCache: {
-            return {
-                ...state,
-                userSuppliedOrderCache: action.data,
-            };
-        }
-
-        case ActionTypes.ClearTokenByAddress: {
-            return {
-                ...state,
-                tokenByAddress: {},
-            };
-        }
-
-        case ActionTypes.AddTokenToTokenByAddress: {
-            const newTokenByAddress = state.tokenByAddress;
-            newTokenByAddress[action.data.address] = action.data;
-            return {
-                ...state,
-                tokenByAddress: newTokenByAddress,
-            };
-        }
-
-        case ActionTypes.RemoveTokenFromTokenByAddress: {
-            const newTokenByAddress = state.tokenByAddress;
-            delete newTokenByAddress[action.data.address];
-            return {
-                ...state,
-                tokenByAddress: newTokenByAddress,
-            };
-        }
-
-        case ActionTypes.UpdateTokenByAddress: {
-            const tokenByAddress = state.tokenByAddress;
-            const tokens = action.data;
-            _.each(tokens, token => {
-                const updatedToken = {
-                    ...tokenByAddress[token.address],
-                    ...token,
-                };
-                tokenByAddress[token.address] = updatedToken;
-            });
-            return {
-                ...state,
-                tokenByAddress,
-            };
-        }
-
-        case ActionTypes.UpdateTokenStateByAddress: {
-            const tokenStateByAddress = state.tokenStateByAddress;
-            const updatedTokenStateByAddress = action.data;
-            _.each(updatedTokenStateByAddress, (tokenState: TokenState, address: string) => {
-                const updatedTokenState = {
-                    ...tokenStateByAddress[address],
-                    ...tokenState,
-                };
-                tokenStateByAddress[address] = updatedTokenState;
-            });
-            return {
-                ...state,
-                tokenStateByAddress,
-            };
-        }
-
-        case ActionTypes.RemoveFromTokenStateByAddress: {
-            const tokenStateByAddress = state.tokenStateByAddress;
-            const tokenAddress = action.data;
-            delete tokenStateByAddress[tokenAddress];
-            return {
-                ...state,
-                tokenStateByAddress,
-            };
-        }
-
-        case ActionTypes.ReplaceTokenAllowanceByAddress: {
-            const tokenStateByAddress = state.tokenStateByAddress;
-            const allowance = action.data.allowance;
-            const tokenAddress = action.data.address;
-            tokenStateByAddress[tokenAddress] = {
-                ...tokenStateByAddress[tokenAddress],
-                allowance,
-            };
-            return {
-                ...state,
-                tokenStateByAddress,
-            };
-        }
-
-        case ActionTypes.ReplaceTokenBalanceByAddress: {
-            const tokenStateByAddress = state.tokenStateByAddress;
-            const balance = action.data.balance;
-            const tokenAddress = action.data.address;
-            tokenStateByAddress[tokenAddress] = {
-                ...tokenStateByAddress[tokenAddress],
-                balance,
-            };
-            return {
-                ...state,
-                tokenStateByAddress,
-            };
-        }
-
-        case ActionTypes.UpdateTokenBalanceByAddress: {
-            const tokenStateByAddress = state.tokenStateByAddress;
-            const balanceDelta = action.data.balanceDelta;
-            const tokenAddress = action.data.address;
-            const currBalance = tokenStateByAddress[tokenAddress].balance;
-            tokenStateByAddress[tokenAddress] = {
-                ...tokenStateByAddress[tokenAddress],
-                balance: currBalance.plus(balanceDelta),
-            };
-            return {
-                ...state,
-                tokenStateByAddress,
-            };
-        }
-
-        case ActionTypes.UpdateOrderSignatureData: {
-            return {
-                ...state,
-                orderSignatureData: action.data,
-            };
-        }
-
-        case ActionTypes.UpdateScreenWidth: {
-            return {
-                ...state,
-                screenWidth: action.data,
-            };
-        }
-
-        case ActionTypes.UpdateBlockchainIsLoaded: {
-            return {
-                ...state,
-                blockchainIsLoaded: action.data,
-            };
-        }
-
-        case ActionTypes.BlockchainErrEncountered: {
-            return {
-                ...state,
-                blockchainErr: action.data,
-            };
-        }
-
-        case ActionTypes.UpdateNetworkId: {
-            return {
-                ...state,
-                networkId: action.data,
-            };
-        }
-
-        case ActionTypes.UpdateChosenAssetToken: {
-            const newSideToAssetToken = {
-                ...state.sideToAssetToken,
-                [action.data.side]: action.data.token,
-            };
-            return {
-                ...state,
-                sideToAssetToken: newSideToAssetToken,
-            };
-        }
-
-        case ActionTypes.UpdateChosenAssetTokenAddress: {
-            const newAssetToken = state.sideToAssetToken[action.data.side];
-            newAssetToken.address = action.data.address;
-            const newSideToAssetToken = {
-                ...state.sideToAssetToken,
-                [action.data.side]: newAssetToken,
-            };
-            return {
-                ...state,
-                sideToAssetToken: newSideToAssetToken,
-            };
-        }
-
-        case ActionTypes.SwapAssetTokens: {
-            const newSideToAssetToken = {
-                [Side.Deposit]: state.sideToAssetToken[Side.Receive],
-                [Side.Receive]: state.sideToAssetToken[Side.Deposit],
-            };
-            return {
-                ...state,
-                sideToAssetToken: newSideToAssetToken,
-            };
-        }
-
-        case ActionTypes.UpdateOrderExpiry: {
-            return {
-                ...state,
-                orderExpiryTimestamp: action.data,
-            };
-        }
-
-        case ActionTypes.UpdateOrderTakerAddress: {
-            return {
-                ...state,
-                orderTakerAddress: action.data,
-            };
-        }
-
-        case ActionTypes.UpdateUserAddress: {
-            return {
-                ...state,
-                userAddress: action.data,
-            };
-        }
-
-        // Docs
-        case ActionTypes.UpdateLibraryVersion: {
-            return {
-                ...state,
-                docsVersion: action.data,
-            };
-        }
-        case ActionTypes.UpdateAvailableLibraryVersions: {
-            return {
-                ...state,
-                availableDocVersions: action.data,
-            };
-        }
-
-        // Shared
-        case ActionTypes.ShowFlashMessage: {
-            return {
-                ...state,
-                flashMessage: action.data,
-            };
-        }
-
-        case ActionTypes.HideFlashMessage: {
-            return {
-                ...state,
-                flashMessage: undefined,
-            };
-        }
-
-        case ActionTypes.UpdateProviderType: {
-            return {
-                ...state,
-                providerType: action.data,
-            };
-        }
-
-        case ActionTypes.UpdateInjectedProviderName: {
-            return {
-                ...state,
-                injectedProviderName: action.data,
-            };
-        }
-
-        default:
-            return state;
-    }
+	switch (action.type) {
+		// Portal
+		case ActionTypes.ResetState:
+			return INITIAL_STATE;
+
+		case ActionTypes.UpdateOrderSalt: {
+			return {
+				...state,
+				orderSalt: action.data,
+			};
+		}
+
+		case ActionTypes.UpdateNodeVersion: {
+			return {
+				...state,
+				nodeVersion: action.data,
+			};
+		}
+
+		case ActionTypes.UpdateOrderFillAmount: {
+			return {
+				...state,
+				orderFillAmount: action.data,
+			};
+		}
+
+		case ActionTypes.UpdateShouldBlockchainErrDialogBeOpen: {
+			return {
+				...state,
+				shouldBlockchainErrDialogBeOpen: action.data,
+			};
+		}
+
+		case ActionTypes.UpdateUserEtherBalance: {
+			return {
+				...state,
+				userEtherBalance: action.data,
+			};
+		}
+
+		case ActionTypes.UpdateUserSuppliedOrderCache: {
+			return {
+				...state,
+				userSuppliedOrderCache: action.data,
+			};
+		}
+
+		case ActionTypes.ClearTokenByAddress: {
+			return {
+				...state,
+				tokenByAddress: {},
+			};
+		}
+
+		case ActionTypes.AddTokenToTokenByAddress: {
+			const newTokenByAddress = state.tokenByAddress;
+			newTokenByAddress[action.data.address] = action.data;
+			return {
+				...state,
+				tokenByAddress: newTokenByAddress,
+			};
+		}
+
+		case ActionTypes.RemoveTokenFromTokenByAddress: {
+			const newTokenByAddress = state.tokenByAddress;
+			delete newTokenByAddress[action.data.address];
+			return {
+				...state,
+				tokenByAddress: newTokenByAddress,
+			};
+		}
+
+		case ActionTypes.UpdateTokenByAddress: {
+			const tokenByAddress = state.tokenByAddress;
+			const tokens = action.data;
+			_.each(tokens, token => {
+				const updatedToken = {
+					...tokenByAddress[token.address],
+					...token,
+				};
+				tokenByAddress[token.address] = updatedToken;
+			});
+			return {
+				...state,
+				tokenByAddress,
+			};
+		}
+
+		case ActionTypes.UpdateTokenStateByAddress: {
+			const tokenStateByAddress = state.tokenStateByAddress;
+			const updatedTokenStateByAddress = action.data;
+			_.each(updatedTokenStateByAddress, (tokenState: TokenState, address: string) => {
+				const updatedTokenState = {
+					...tokenStateByAddress[address],
+					...tokenState,
+				};
+				tokenStateByAddress[address] = updatedTokenState;
+			});
+			return {
+				...state,
+				tokenStateByAddress,
+			};
+		}
+
+		case ActionTypes.RemoveFromTokenStateByAddress: {
+			const tokenStateByAddress = state.tokenStateByAddress;
+			const tokenAddress = action.data;
+			delete tokenStateByAddress[tokenAddress];
+			return {
+				...state,
+				tokenStateByAddress,
+			};
+		}
+
+		case ActionTypes.ReplaceTokenAllowanceByAddress: {
+			const tokenStateByAddress = state.tokenStateByAddress;
+			const allowance = action.data.allowance;
+			const tokenAddress = action.data.address;
+			tokenStateByAddress[tokenAddress] = {
+				...tokenStateByAddress[tokenAddress],
+				allowance,
+			};
+			return {
+				...state,
+				tokenStateByAddress,
+			};
+		}
+
+		case ActionTypes.ReplaceTokenBalanceByAddress: {
+			const tokenStateByAddress = state.tokenStateByAddress;
+			const balance = action.data.balance;
+			const tokenAddress = action.data.address;
+			tokenStateByAddress[tokenAddress] = {
+				...tokenStateByAddress[tokenAddress],
+				balance,
+			};
+			return {
+				...state,
+				tokenStateByAddress,
+			};
+		}
+
+		case ActionTypes.UpdateTokenBalanceByAddress: {
+			const tokenStateByAddress = state.tokenStateByAddress;
+			const balanceDelta = action.data.balanceDelta;
+			const tokenAddress = action.data.address;
+			const currBalance = tokenStateByAddress[tokenAddress].balance;
+			tokenStateByAddress[tokenAddress] = {
+				...tokenStateByAddress[tokenAddress],
+				balance: currBalance.plus(balanceDelta),
+			};
+			return {
+				...state,
+				tokenStateByAddress,
+			};
+		}
+
+		case ActionTypes.UpdateOrderSignatureData: {
+			return {
+				...state,
+				orderSignatureData: action.data,
+			};
+		}
+
+		case ActionTypes.UpdateScreenWidth: {
+			return {
+				...state,
+				screenWidth: action.data,
+			};
+		}
+
+		case ActionTypes.UpdateBlockchainIsLoaded: {
+			return {
+				...state,
+				blockchainIsLoaded: action.data,
+			};
+		}
+
+		case ActionTypes.BlockchainErrEncountered: {
+			return {
+				...state,
+				blockchainErr: action.data,
+			};
+		}
+
+		case ActionTypes.UpdateNetworkId: {
+			return {
+				...state,
+				networkId: action.data,
+			};
+		}
+
+		case ActionTypes.UpdateChosenAssetToken: {
+			const newSideToAssetToken = {
+				...state.sideToAssetToken,
+				[action.data.side]: action.data.token,
+			};
+			return {
+				...state,
+				sideToAssetToken: newSideToAssetToken,
+			};
+		}
+
+		case ActionTypes.UpdateChosenAssetTokenAddress: {
+			const newAssetToken = state.sideToAssetToken[action.data.side];
+			newAssetToken.address = action.data.address;
+			const newSideToAssetToken = {
+				...state.sideToAssetToken,
+				[action.data.side]: newAssetToken,
+			};
+			return {
+				...state,
+				sideToAssetToken: newSideToAssetToken,
+			};
+		}
+
+		case ActionTypes.SwapAssetTokens: {
+			const newSideToAssetToken = {
+				[Side.Deposit]: state.sideToAssetToken[Side.Receive],
+				[Side.Receive]: state.sideToAssetToken[Side.Deposit],
+			};
+			return {
+				...state,
+				sideToAssetToken: newSideToAssetToken,
+			};
+		}
+
+		case ActionTypes.UpdateOrderExpiry: {
+			return {
+				...state,
+				orderExpiryTimestamp: action.data,
+			};
+		}
+
+		case ActionTypes.UpdateOrderTakerAddress: {
+			return {
+				...state,
+				orderTakerAddress: action.data,
+			};
+		}
+
+		case ActionTypes.UpdateUserAddress: {
+			return {
+				...state,
+				userAddress: action.data,
+			};
+		}
+
+		// Docs
+		case ActionTypes.UpdateLibraryVersion: {
+			return {
+				...state,
+				docsVersion: action.data,
+			};
+		}
+		case ActionTypes.UpdateAvailableLibraryVersions: {
+			return {
+				...state,
+				availableDocVersions: action.data,
+			};
+		}
+
+		// Shared
+		case ActionTypes.ShowFlashMessage: {
+			return {
+				...state,
+				flashMessage: action.data,
+			};
+		}
+
+		case ActionTypes.HideFlashMessage: {
+			return {
+				...state,
+				flashMessage: undefined,
+			};
+		}
+
+		case ActionTypes.UpdateProviderType: {
+			return {
+				...state,
+				providerType: action.data,
+			};
+		}
+
+		case ActionTypes.UpdateInjectedProviderName: {
+			return {
+				...state,
+				injectedProviderName: action.data,
+			};
+		}
+
+		default:
+			return state;
+	}
 }
diff --git a/packages/website/ts/schemas/order_schema.ts b/packages/website/ts/schemas/order_schema.ts
index bfbf9eb8b..fd0bf113a 100644
--- a/packages/website/ts/schemas/order_schema.ts
+++ b/packages/website/ts/schemas/order_schema.ts
@@ -1,15 +1,15 @@
 export const orderSchema = {
-    id: '/Order',
-    properties: {
-        maker: { $ref: '/OrderTaker' },
-        taker: { $ref: '/OrderTaker' },
-        salt: { type: 'string' },
-        signature: { $ref: '/SignatureData' },
-        expiration: { type: 'string' },
-        feeRecipient: { type: 'string' },
-        exchangeContract: { type: 'string' },
-        networkId: { type: 'number' },
-    },
-    required: ['maker', 'taker', 'salt', 'signature', 'expiration', 'feeRecipient', 'exchangeContract', 'networkId'],
-    type: 'object',
+	id: '/Order',
+	properties: {
+		maker: { $ref: '/OrderTaker' },
+		taker: { $ref: '/OrderTaker' },
+		salt: { type: 'string' },
+		signature: { $ref: '/SignatureData' },
+		expiration: { type: 'string' },
+		feeRecipient: { type: 'string' },
+		exchangeContract: { type: 'string' },
+		networkId: { type: 'number' },
+	},
+	required: ['maker', 'taker', 'salt', 'signature', 'expiration', 'feeRecipient', 'exchangeContract', 'networkId'],
+	type: 'object',
 };
diff --git a/packages/website/ts/schemas/order_taker_schema.ts b/packages/website/ts/schemas/order_taker_schema.ts
index c784c29c5..c84ec4a9f 100644
--- a/packages/website/ts/schemas/order_taker_schema.ts
+++ b/packages/website/ts/schemas/order_taker_schema.ts
@@ -1,11 +1,11 @@
 export const orderTakerSchema = {
-    id: '/OrderTaker',
-    properties: {
-        address: { type: 'string' },
-        token: { $ref: '/Token' },
-        amount: { type: 'string' },
-        feeAmount: { type: 'string' },
-    },
-    required: ['address', 'token', 'amount', 'feeAmount'],
-    type: 'object',
+	id: '/OrderTaker',
+	properties: {
+		address: { type: 'string' },
+		token: { $ref: '/Token' },
+		amount: { type: 'string' },
+		feeAmount: { type: 'string' },
+	},
+	required: ['address', 'token', 'amount', 'feeAmount'],
+	type: 'object',
 };
diff --git a/packages/website/ts/schemas/signature_data_schema.ts b/packages/website/ts/schemas/signature_data_schema.ts
index 8d3f15926..8cafff9e8 100644
--- a/packages/website/ts/schemas/signature_data_schema.ts
+++ b/packages/website/ts/schemas/signature_data_schema.ts
@@ -1,11 +1,11 @@
 export const signatureDataSchema = {
-    id: '/SignatureData',
-    properties: {
-        hash: { type: 'string' },
-        r: { type: 'string' },
-        s: { type: 'string' },
-        v: { type: 'number' },
-    },
-    required: ['hash', 'r', 's', 'v'],
-    type: 'object',
+	id: '/SignatureData',
+	properties: {
+		hash: { type: 'string' },
+		r: { type: 'string' },
+		s: { type: 'string' },
+		v: { type: 'number' },
+	},
+	required: ['hash', 'r', 's', 'v'],
+	type: 'object',
 };
diff --git a/packages/website/ts/schemas/token_schema.ts b/packages/website/ts/schemas/token_schema.ts
index 92b53a463..6a3bed786 100644
--- a/packages/website/ts/schemas/token_schema.ts
+++ b/packages/website/ts/schemas/token_schema.ts
@@ -1,11 +1,11 @@
 export const tokenSchema = {
-    id: '/Token',
-    properties: {
-        name: { type: 'string' },
-        symbol: { type: 'string' },
-        decimals: { type: 'number' },
-        address: { type: 'string' },
-    },
-    required: ['name', 'symbol', 'decimals', 'address'],
-    type: 'object',
+	id: '/Token',
+	properties: {
+		name: { type: 'string' },
+		symbol: { type: 'string' },
+		decimals: { type: 'number' },
+		address: { type: 'string' },
+	},
+	required: ['name', 'symbol', 'decimals', 'address'],
+	type: 'object',
 };
diff --git a/packages/website/ts/schemas/validator.ts b/packages/website/ts/schemas/validator.ts
index 5177501c6..a3aaafc98 100644
--- a/packages/website/ts/schemas/validator.ts
+++ b/packages/website/ts/schemas/validator.ts
@@ -5,15 +5,15 @@ import { signatureDataSchema } from 'ts/schemas/signature_data_schema';
 import { tokenSchema } from 'ts/schemas/token_schema';
 
 export class SchemaValidator {
-    private _validator: Validator;
-    constructor() {
-        this._validator = new Validator();
-        this._validator.addSchema(signatureDataSchema as JSONSchema, signatureDataSchema.id);
-        this._validator.addSchema(tokenSchema as JSONSchema, tokenSchema.id);
-        this._validator.addSchema(orderTakerSchema as JSONSchema, orderTakerSchema.id);
-        this._validator.addSchema(orderSchema as JSONSchema, orderSchema.id);
-    }
-    public validate(instance: object, schema: Schema) {
-        return this._validator.validate(instance, schema);
-    }
+	private _validator: Validator;
+	constructor() {
+		this._validator = new Validator();
+		this._validator.addSchema(signatureDataSchema as JSONSchema, signatureDataSchema.id);
+		this._validator.addSchema(tokenSchema as JSONSchema, tokenSchema.id);
+		this._validator.addSchema(orderTakerSchema as JSONSchema, orderTakerSchema.id);
+		this._validator.addSchema(orderSchema as JSONSchema, orderSchema.id);
+	}
+	public validate(instance: object, schema: Schema) {
+		return this._validator.validate(instance, schema);
+	}
 }
diff --git a/packages/website/ts/types.ts b/packages/website/ts/types.ts
index f873f95fa..a853792cb 100644
--- a/packages/website/ts/types.ts
+++ b/packages/website/ts/types.ts
@@ -2,680 +2,680 @@ import { BigNumber } from '@0xproject/utils';
 import * as _ from 'lodash';
 
 export enum Side {
-    Receive = 'RECEIVE',
-    Deposit = 'DEPOSIT',
+	Receive = 'RECEIVE',
+	Deposit = 'DEPOSIT',
 }
 
 export interface Token {
-    iconUrl?: string;
-    name: string;
-    address: string;
-    symbol: string;
-    decimals: number;
-    isTracked: boolean;
-    isRegistered: boolean;
+	iconUrl?: string;
+	name: string;
+	address: string;
+	symbol: string;
+	decimals: number;
+	isTracked: boolean;
+	isRegistered: boolean;
 }
 
 export interface TokenByAddress {
-    [address: string]: Token;
+	[address: string]: Token;
 }
 
 export interface TokenState {
-    allowance: BigNumber;
-    balance: BigNumber;
+	allowance: BigNumber;
+	balance: BigNumber;
 }
 
 export interface TokenStateByAddress {
-    [address: string]: TokenState;
+	[address: string]: TokenState;
 }
 
 export interface AssetToken {
-    address?: string;
-    amount?: BigNumber;
+	address?: string;
+	amount?: BigNumber;
 }
 
 export interface SideToAssetToken {
-    [side: string]: AssetToken;
+	[side: string]: AssetToken;
 }
 
 export interface SignatureData {
-    hash: string;
-    r: string;
-    s: string;
-    v: number;
+	hash: string;
+	r: string;
+	s: string;
+	v: number;
 }
 
 export interface HashData {
-    depositAmount: BigNumber;
-    depositTokenContractAddr: string;
-    feeRecipientAddress: string;
-    makerFee: BigNumber;
-    orderExpiryTimestamp: BigNumber;
-    orderMakerAddress: string;
-    orderTakerAddress: string;
-    receiveAmount: BigNumber;
-    receiveTokenContractAddr: string;
-    takerFee: BigNumber;
-    orderSalt: BigNumber;
+	depositAmount: BigNumber;
+	depositTokenContractAddr: string;
+	feeRecipientAddress: string;
+	makerFee: BigNumber;
+	orderExpiryTimestamp: BigNumber;
+	orderMakerAddress: string;
+	orderTakerAddress: string;
+	receiveAmount: BigNumber;
+	receiveTokenContractAddr: string;
+	takerFee: BigNumber;
+	orderSalt: BigNumber;
 }
 
 export interface OrderToken {
-    name: string;
-    symbol: string;
-    decimals: number;
-    address: string;
+	name: string;
+	symbol: string;
+	decimals: number;
+	address: string;
 }
 
 export interface OrderParty {
-    address: string;
-    token: OrderToken;
-    amount: string;
-    feeAmount: string;
+	address: string;
+	token: OrderToken;
+	amount: string;
+	feeAmount: string;
 }
 
 export interface Order {
-    maker: OrderParty;
-    taker: OrderParty;
-    expiration: string;
-    feeRecipient: string;
-    salt: string;
-    signature: SignatureData;
-    exchangeContract: string;
-    networkId: number;
+	maker: OrderParty;
+	taker: OrderParty;
+	expiration: string;
+	feeRecipient: string;
+	salt: string;
+	signature: SignatureData;
+	exchangeContract: string;
+	networkId: number;
 }
 
 export interface Fill {
-    logIndex: number;
-    maker: string;
-    taker: string;
-    makerToken: string;
-    takerToken: string;
-    filledMakerTokenAmount: BigNumber;
-    filledTakerTokenAmount: BigNumber;
-    paidMakerFee: BigNumber;
-    paidTakerFee: BigNumber;
-    orderHash: string;
-    transactionHash: string;
-    blockTimestamp: number;
+	logIndex: number;
+	maker: string;
+	taker: string;
+	makerToken: string;
+	takerToken: string;
+	filledMakerTokenAmount: BigNumber;
+	filledTakerTokenAmount: BigNumber;
+	paidMakerFee: BigNumber;
+	paidTakerFee: BigNumber;
+	orderHash: string;
+	transactionHash: string;
+	blockTimestamp: number;
 }
 
 export enum BalanceErrs {
-    incorrectNetworkForFaucet,
-    faucetRequestFailed,
-    faucetQueueIsFull,
-    mintingFailed,
-    sendFailed,
-    allowanceSettingFailed,
+	incorrectNetworkForFaucet,
+	faucetRequestFailed,
+	faucetQueueIsFull,
+	mintingFailed,
+	sendFailed,
+	allowanceSettingFailed,
 }
 
 export enum ActionTypes {
-    // Portal
-    UpdateScreenWidth = 'UPDATE_SCREEN_WIDTH',
-    UpdateNodeVersion = 'UPDATE_NODE_VERSION',
-    ResetState = 'RESET_STATE',
-    AddTokenToTokenByAddress = 'ADD_TOKEN_TO_TOKEN_BY_ADDRESS',
-    BlockchainErrEncountered = 'BLOCKCHAIN_ERR_ENCOUNTERED',
-    ClearTokenByAddress = 'CLEAR_TOKEN_BY_ADDRESS',
-    UpdateBlockchainIsLoaded = 'UPDATE_BLOCKCHAIN_IS_LOADED',
-    UpdateNetworkId = 'UPDATE_NETWORK_ID',
-    UpdateChosenAssetToken = 'UPDATE_CHOSEN_ASSET_TOKEN',
-    UpdateChosenAssetTokenAddress = 'UPDATE_CHOSEN_ASSET_TOKEN_ADDRESS',
-    UpdateOrderTakerAddress = 'UPDATE_ORDER_TAKER_ADDRESS',
-    UpdateOrderSalt = 'UPDATE_ORDER_SALT',
-    UpdateOrderSignatureData = 'UPDATE_ORDER_SIGNATURE_DATA',
-    UpdateTokenByAddress = 'UPDATE_TOKEN_BY_ADDRESS',
-    RemoveTokenFromTokenByAddress = 'REMOVE_TOKEN_FROM_TOKEN_BY_ADDRESS',
-    UpdateTokenStateByAddress = 'UPDATE_TOKEN_STATE_BY_ADDRESS',
-    RemoveFromTokenStateByAddress = 'REMOVE_FROM_TOKEN_STATE_BY_ADDRESS',
-    ReplaceTokenAllowanceByAddress = 'REPLACE_TOKEN_ALLOWANCE_BY_ADDRESS',
-    ReplaceTokenBalanceByAddress = 'REPLACE_TOKEN_BALANCE_BY_ADDRESS',
-    UpdateTokenBalanceByAddress = 'UPDATE_TOKEN_BALANCE_BY_ADDRESS',
-    UpdateOrderExpiry = 'UPDATE_ORDER_EXPIRY',
-    SwapAssetTokens = 'SWAP_ASSET_TOKENS',
-    UpdateUserAddress = 'UPDATE_USER_ADDRESS',
-    UpdateUserEtherBalance = 'UPDATE_USER_ETHER_BALANCE',
-    UpdateUserSuppliedOrderCache = 'UPDATE_USER_SUPPLIED_ORDER_CACHE',
-    UpdateOrderFillAmount = 'UPDATE_ORDER_FILL_AMOUNT',
-    UpdateShouldBlockchainErrDialogBeOpen = 'UPDATE_SHOULD_BLOCKCHAIN_ERR_DIALOG_BE_OPEN',
-
-    // Docs
-    UpdateLibraryVersion = 'UPDATE_LIBRARY_VERSION',
-    UpdateAvailableLibraryVersions = 'UPDATE_AVAILABLE_LIBRARY_VERSIONS',
-
-    // Shared
-    ShowFlashMessage = 'SHOW_FLASH_MESSAGE',
-    HideFlashMessage = 'HIDE_FLASH_MESSAGE',
-    UpdateProviderType = 'UPDATE_PROVIDER_TYPE',
-    UpdateInjectedProviderName = 'UPDATE_INJECTED_PROVIDER_NAME',
+	// Portal
+	UpdateScreenWidth = 'UPDATE_SCREEN_WIDTH',
+	UpdateNodeVersion = 'UPDATE_NODE_VERSION',
+	ResetState = 'RESET_STATE',
+	AddTokenToTokenByAddress = 'ADD_TOKEN_TO_TOKEN_BY_ADDRESS',
+	BlockchainErrEncountered = 'BLOCKCHAIN_ERR_ENCOUNTERED',
+	ClearTokenByAddress = 'CLEAR_TOKEN_BY_ADDRESS',
+	UpdateBlockchainIsLoaded = 'UPDATE_BLOCKCHAIN_IS_LOADED',
+	UpdateNetworkId = 'UPDATE_NETWORK_ID',
+	UpdateChosenAssetToken = 'UPDATE_CHOSEN_ASSET_TOKEN',
+	UpdateChosenAssetTokenAddress = 'UPDATE_CHOSEN_ASSET_TOKEN_ADDRESS',
+	UpdateOrderTakerAddress = 'UPDATE_ORDER_TAKER_ADDRESS',
+	UpdateOrderSalt = 'UPDATE_ORDER_SALT',
+	UpdateOrderSignatureData = 'UPDATE_ORDER_SIGNATURE_DATA',
+	UpdateTokenByAddress = 'UPDATE_TOKEN_BY_ADDRESS',
+	RemoveTokenFromTokenByAddress = 'REMOVE_TOKEN_FROM_TOKEN_BY_ADDRESS',
+	UpdateTokenStateByAddress = 'UPDATE_TOKEN_STATE_BY_ADDRESS',
+	RemoveFromTokenStateByAddress = 'REMOVE_FROM_TOKEN_STATE_BY_ADDRESS',
+	ReplaceTokenAllowanceByAddress = 'REPLACE_TOKEN_ALLOWANCE_BY_ADDRESS',
+	ReplaceTokenBalanceByAddress = 'REPLACE_TOKEN_BALANCE_BY_ADDRESS',
+	UpdateTokenBalanceByAddress = 'UPDATE_TOKEN_BALANCE_BY_ADDRESS',
+	UpdateOrderExpiry = 'UPDATE_ORDER_EXPIRY',
+	SwapAssetTokens = 'SWAP_ASSET_TOKENS',
+	UpdateUserAddress = 'UPDATE_USER_ADDRESS',
+	UpdateUserEtherBalance = 'UPDATE_USER_ETHER_BALANCE',
+	UpdateUserSuppliedOrderCache = 'UPDATE_USER_SUPPLIED_ORDER_CACHE',
+	UpdateOrderFillAmount = 'UPDATE_ORDER_FILL_AMOUNT',
+	UpdateShouldBlockchainErrDialogBeOpen = 'UPDATE_SHOULD_BLOCKCHAIN_ERR_DIALOG_BE_OPEN',
+
+	// Docs
+	UpdateLibraryVersion = 'UPDATE_LIBRARY_VERSION',
+	UpdateAvailableLibraryVersions = 'UPDATE_AVAILABLE_LIBRARY_VERSIONS',
+
+	// Shared
+	ShowFlashMessage = 'SHOW_FLASH_MESSAGE',
+	HideFlashMessage = 'HIDE_FLASH_MESSAGE',
+	UpdateProviderType = 'UPDATE_PROVIDER_TYPE',
+	UpdateInjectedProviderName = 'UPDATE_INJECTED_PROVIDER_NAME',
 }
 
 export interface Action {
-    type: ActionTypes;
-    data?: any;
+	type: ActionTypes;
+	data?: any;
 }
 
 export interface TrackedTokensByNetworkId {
-    [networkId: number]: Token[];
+	[networkId: number]: Token[];
 }
 
 export interface TrackedTokensByUserAddress {
-    [userAddress: string]: TrackedTokensByNetworkId;
+	[userAddress: string]: TrackedTokensByNetworkId;
 }
 
 export interface Styles {
-    [name: string]: React.CSSProperties;
+	[name: string]: React.CSSProperties;
 }
 
 export interface ProfileInfo {
-    name: string;
-    title?: string;
-    description: string;
-    image: string;
-    linkedIn?: string;
-    github?: string;
-    angellist?: string;
-    medium?: string;
-    twitter?: string;
+	name: string;
+	title?: string;
+	description: string;
+	image: string;
+	linkedIn?: string;
+	github?: string;
+	angellist?: string;
+	medium?: string;
+	twitter?: string;
 }
 
 export interface Partner {
-    name: string;
-    logo: string;
-    url: string;
+	name: string;
+	logo: string;
+	url: string;
 }
 
 export interface Statistic {
-    title: string;
-    figure: string;
+	title: string;
+	figure: string;
 }
 
 export interface StatisticByKey {
-    [key: string]: Statistic;
+	[key: string]: Statistic;
 }
 
 export interface ERC20MarketInfo {
-    etherMarketCapUsd: number;
-    numLiquidERC20Tokens: number;
-    marketCapERC20TokensUsd: number;
+	etherMarketCapUsd: number;
+	numLiquidERC20Tokens: number;
+	marketCapERC20TokensUsd: number;
 }
 
 export enum ExchangeContractErrs {
-    OrderFillExpired = 'ORDER_FILL_EXPIRED',
-    OrderAlreadyCancelledOrFilled = 'ORDER_ALREADY_CANCELLED_OR_FILLED',
-    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',
-    TransactionSenderIsNotFillOrderTaker = 'TRANSACTION_SENDER_IS_NOT_FILL_ORDER_TAKER',
-    InsufficientRemainingFillAmount = 'INSUFFICIENT_REMAINING_FILL_AMOUNT',
+	OrderFillExpired = 'ORDER_FILL_EXPIRED',
+	OrderAlreadyCancelledOrFilled = 'ORDER_ALREADY_CANCELLED_OR_FILLED',
+	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',
+	TransactionSenderIsNotFillOrderTaker = 'TRANSACTION_SENDER_IS_NOT_FILL_ORDER_TAKER',
+	InsufficientRemainingFillAmount = 'INSUFFICIENT_REMAINING_FILL_AMOUNT',
 }
 
 export interface ContractResponse {
-    logs: ContractEvent[];
+	logs: ContractEvent[];
 }
 
 export interface ContractEvent {
-    event: string;
-    args: any;
+	event: string;
+	args: any;
 }
 
 export type InputErrMsg = React.ReactNode | string | undefined;
 export type ValidatedBigNumberCallback = (isValid: boolean, amount?: BigNumber) => void;
 export enum ScreenWidths {
-    Sm = 'SM',
-    Md = 'MD',
-    Lg = 'LG',
+	Sm = 'SM',
+	Md = 'MD',
+	Lg = 'LG',
 }
 
 export enum AlertTypes {
-    ERROR,
-    SUCCESS,
+	ERROR,
+	SUCCESS,
 }
 
 export enum EtherscanLinkSuffixes {
-    Address = 'address',
-    Tx = 'tx',
+	Address = 'address',
+	Tx = 'tx',
 }
 
 export enum BlockchainErrs {
-    AContractNotDeployedOnNetwork = 'A_CONTRACT_NOT_DEPLOYED_ON_NETWORK',
-    DisconnectedFromEthereumNode = 'DISCONNECTED_FROM_ETHEREUM_NODE',
-    NoError = 'NO_ERROR',
+	AContractNotDeployedOnNetwork = 'A_CONTRACT_NOT_DEPLOYED_ON_NETWORK',
+	DisconnectedFromEthereumNode = 'DISCONNECTED_FROM_ETHEREUM_NODE',
+	NoError = 'NO_ERROR',
 }
 
 export enum BlockchainCallErrs {
-    ContractDoesNotExist = 'CONTRACT_DOES_NOT_EXIST',
-    UserHasNoAssociatedAddresses = 'USER_HAS_NO_ASSOCIATED_ADDRESSES',
-    UnhandledError = 'UNHANDLED_ERROR',
-    TokenAddressIsInvalid = 'TOKEN_ADDRESS_IS_INVALID',
+	ContractDoesNotExist = 'CONTRACT_DOES_NOT_EXIST',
+	UserHasNoAssociatedAddresses = 'USER_HAS_NO_ASSOCIATED_ADDRESSES',
+	UnhandledError = 'UNHANDLED_ERROR',
+	TokenAddressIsInvalid = 'TOKEN_ADDRESS_IS_INVALID',
 }
 
 // Exception: We don't make the values uppercase because these KindString's need to
 // match up those returned by TypeDoc
 export enum KindString {
-    Constructor = 'Constructor',
-    Property = 'Property',
-    Method = 'Method',
-    Interface = 'Interface',
-    TypeAlias = 'Type alias',
-    Variable = 'Variable',
-    Function = 'Function',
-    Enumeration = 'Enumeration',
+	Constructor = 'Constructor',
+	Property = 'Property',
+	Method = 'Method',
+	Interface = 'Interface',
+	TypeAlias = 'Type alias',
+	Variable = 'Variable',
+	Function = 'Function',
+	Enumeration = 'Enumeration',
 }
 
 export interface EnumValue {
-    name: string;
-    defaultValue?: string;
+	name: string;
+	defaultValue?: string;
 }
 
 export enum Environments {
-    DEVELOPMENT,
-    PRODUCTION,
+	DEVELOPMENT,
+	PRODUCTION,
 }
 
 export type ContractInstance = any; // TODO: add type definition for Contract
 
 export interface TypeDocType {
-    type: TypeDocTypes;
-    value: string;
-    name: string;
-    types: TypeDocType[];
-    typeArguments?: TypeDocType[];
-    declaration: TypeDocNode;
-    elementType?: TypeDocType;
+	type: TypeDocTypes;
+	value: string;
+	name: string;
+	types: TypeDocType[];
+	typeArguments?: TypeDocType[];
+	declaration: TypeDocNode;
+	elementType?: TypeDocType;
 }
 
 export interface TypeDocFlags {
-    isStatic?: boolean;
-    isOptional?: boolean;
-    isPublic?: boolean;
+	isStatic?: boolean;
+	isOptional?: boolean;
+	isPublic?: boolean;
 }
 
 export interface TypeDocGroup {
-    title: string;
-    children: number[];
+	title: string;
+	children: number[];
 }
 
 export interface TypeDocNode {
-    id?: number;
-    name?: string;
-    kind?: string;
-    defaultValue?: string;
-    kindString?: string;
-    type?: TypeDocType;
-    fileName?: string;
-    line?: number;
-    comment?: TypeDocNode;
-    text?: string;
-    shortText?: string;
-    returns?: string;
-    declaration: TypeDocNode;
-    flags?: TypeDocFlags;
-    indexSignature?: TypeDocNode[];
-    signatures?: TypeDocNode[];
-    parameters?: TypeDocNode[];
-    typeParameter?: TypeDocNode[];
-    sources?: TypeDocNode[];
-    children?: TypeDocNode[];
-    groups?: TypeDocGroup[];
+	id?: number;
+	name?: string;
+	kind?: string;
+	defaultValue?: string;
+	kindString?: string;
+	type?: TypeDocType;
+	fileName?: string;
+	line?: number;
+	comment?: TypeDocNode;
+	text?: string;
+	shortText?: string;
+	returns?: string;
+	declaration: TypeDocNode;
+	flags?: TypeDocFlags;
+	indexSignature?: TypeDocNode[];
+	signatures?: TypeDocNode[];
+	parameters?: TypeDocNode[];
+	typeParameter?: TypeDocNode[];
+	sources?: TypeDocNode[];
+	children?: TypeDocNode[];
+	groups?: TypeDocGroup[];
 }
 
 export enum TypeDocTypes {
-    Intrinsic = 'intrinsic',
-    Reference = 'reference',
-    Array = 'array',
-    StringLiteral = 'stringLiteral',
-    Reflection = 'reflection',
-    Union = 'union',
-    TypeParameter = 'typeParameter',
-    Unknown = 'unknown',
+	Intrinsic = 'intrinsic',
+	Reference = 'reference',
+	Array = 'array',
+	StringLiteral = 'stringLiteral',
+	Reflection = 'reflection',
+	Union = 'union',
+	TypeParameter = 'typeParameter',
+	Unknown = 'unknown',
 }
 
 export interface DocAgnosticFormat {
-    [sectionName: string]: DocSection;
+	[sectionName: string]: DocSection;
 }
 
 export interface DocSection {
-    comment: string;
-    constructors: Array<TypescriptMethod | SolidityMethod>;
-    methods: Array<TypescriptMethod | SolidityMethod>;
-    properties: Property[];
-    types: CustomType[];
-    events?: Event[];
+	comment: string;
+	constructors: Array<TypescriptMethod | SolidityMethod>;
+	methods: Array<TypescriptMethod | SolidityMethod>;
+	properties: Property[];
+	types: CustomType[];
+	events?: Event[];
 }
 
 export interface Event {
-    name: string;
-    eventArgs: EventArg[];
+	name: string;
+	eventArgs: EventArg[];
 }
 
 export interface EventArg {
-    isIndexed: boolean;
-    name: string;
-    type: Type;
+	isIndexed: boolean;
+	name: string;
+	type: Type;
 }
 
 export interface Property {
-    name: string;
-    type: Type;
-    source?: Source;
-    comment?: string;
+	name: string;
+	type: Type;
+	source?: Source;
+	comment?: string;
 }
 
 export interface BaseMethod {
-    isConstructor: boolean;
-    name: string;
-    returnComment?: string | undefined;
-    callPath: string;
-    parameters: Parameter[];
-    returnType: Type;
-    comment?: string;
+	isConstructor: boolean;
+	name: string;
+	returnComment?: string | undefined;
+	callPath: string;
+	parameters: Parameter[];
+	returnType: Type;
+	comment?: string;
 }
 
 export interface TypescriptMethod extends BaseMethod {
-    source?: Source;
-    isStatic?: boolean;
-    typeParameter?: TypeParameter;
+	source?: Source;
+	isStatic?: boolean;
+	typeParameter?: TypeParameter;
 }
 
 export interface SolidityMethod extends BaseMethod {
-    isConstant?: boolean;
-    isPayable?: boolean;
+	isConstant?: boolean;
+	isPayable?: boolean;
 }
 
 export interface Source {
-    fileName: string;
-    line: number;
+	fileName: string;
+	line: number;
 }
 
 export interface Parameter {
-    name: string;
-    comment: string;
-    isOptional: boolean;
-    type: Type;
+	name: string;
+	comment: string;
+	isOptional: boolean;
+	type: Type;
 }
 
 export interface TypeParameter {
-    name: string;
-    type: Type;
+	name: string;
+	type: Type;
 }
 
 export interface Type {
-    name: string;
-    typeDocType: TypeDocTypes;
-    value?: string;
-    typeArguments?: Type[];
-    elementType?: ElementType;
-    types?: Type[];
-    method?: TypescriptMethod;
+	name: string;
+	typeDocType: TypeDocTypes;
+	value?: string;
+	typeArguments?: Type[];
+	elementType?: ElementType;
+	types?: Type[];
+	method?: TypescriptMethod;
 }
 
 export interface ElementType {
-    name: string;
-    typeDocType: TypeDocTypes;
+	name: string;
+	typeDocType: TypeDocTypes;
 }
 
 export interface IndexSignature {
-    keyName: string;
-    keyType: Type;
-    valueName: string;
+	keyName: string;
+	keyType: Type;
+	valueName: string;
 }
 
 export interface CustomType {
-    name: string;
-    kindString: string;
-    type?: Type;
-    method?: TypescriptMethod;
-    indexSignature?: IndexSignature;
-    defaultValue?: string;
-    comment?: string;
-    children?: CustomTypeChild[];
+	name: string;
+	kindString: string;
+	type?: Type;
+	method?: TypescriptMethod;
+	indexSignature?: IndexSignature;
+	defaultValue?: string;
+	comment?: string;
+	children?: CustomTypeChild[];
 }
 
 export interface CustomTypeChild {
-    name: string;
-    type?: Type;
-    defaultValue?: string;
+	name: string;
+	type?: Type;
+	defaultValue?: string;
 }
 
 export interface FAQQuestion {
-    prompt: string;
-    answer: React.ReactNode;
+	prompt: string;
+	answer: React.ReactNode;
 }
 export interface FAQSection {
-    name: string;
-    questions: FAQQuestion[];
+	name: string;
+	questions: FAQQuestion[];
 }
 
 export interface S3FileObject {
-    Key: {
-        _text: string;
-    };
+	Key: {
+		_text: string;
+	};
 }
 
 export interface MenuSubsectionsBySection {
-    [section: string]: string[];
+	[section: string]: string[];
 }
 
 export enum ProviderType {
-    Injected = 'INJECTED',
-    Ledger = 'LEDGER',
+	Injected = 'INJECTED',
+	Ledger = 'LEDGER',
 }
 
 export interface Fact {
-    title: string;
-    explanation: string;
-    image: string;
+	title: string;
+	explanation: string;
+	image: string;
 }
 
 interface LedgerGetAddressResult {
-    address: string;
+	address: string;
 }
 interface LedgerSignResult {
-    v: string;
-    r: string;
-    s: string;
+	v: string;
+	r: string;
+	s: string;
 }
 interface LedgerCommunication {
-    close_async: () => Promise<void>;
+	close_async: () => Promise<void>;
 }
 export interface LedgerEthConnection {
-    getAddress_async: (
-        derivationPath: string,
-        askForDeviceConfirmation: boolean,
-        shouldGetChainCode: boolean,
-    ) => Promise<LedgerGetAddressResult>;
-    signPersonalMessage_async: (derivationPath: string, messageHex: string) => Promise<LedgerSignResult>;
-    signTransaction_async: (derivationPath: string, txHex: string) => Promise<LedgerSignResult>;
-    comm: LedgerCommunication;
+	getAddress_async: (
+		derivationPath: string,
+		askForDeviceConfirmation: boolean,
+		shouldGetChainCode: boolean,
+	) => Promise<LedgerGetAddressResult>;
+	signPersonalMessage_async: (derivationPath: string, messageHex: string) => Promise<LedgerSignResult>;
+	signTransaction_async: (derivationPath: string, txHex: string) => Promise<LedgerSignResult>;
+	comm: LedgerCommunication;
 }
 export interface SignPersonalMessageParams {
-    data: string;
+	data: string;
 }
 
 export interface TxParams {
-    nonce: string;
-    gasPrice?: number;
-    gasLimit: string;
-    to: string;
-    value?: string;
-    data?: string;
-    chainId: number; // EIP 155 chainId - mainnet: 1, ropsten: 3
+	nonce: string;
+	gasPrice?: number;
+	gasLimit: string;
+	to: string;
+	value?: string;
+	data?: string;
+	chainId: number; // EIP 155 chainId - mainnet: 1, ropsten: 3
 }
 
 export interface PublicNodeUrlsByNetworkId {
-    [networkId: number]: string[];
+	[networkId: number]: string[];
 }
 
 export interface JSONRPCPayload {
-    params: any[];
-    method: string;
+	params: any[];
+	method: string;
 }
 
 export interface BlogPost {
-    image: string;
-    date: string;
-    title: string;
-    description: string;
-    url: string;
+	image: string;
+	date: string;
+	title: string;
+	description: string;
+	url: string;
 }
 
 export interface TypeDefinitionByName {
-    [typeName: string]: CustomType;
+	[typeName: string]: CustomType;
 }
 
 export interface Article {
-    section: string;
-    title: string;
-    content: string;
-    fileName: string;
+	section: string;
+	title: string;
+	content: string;
+	fileName: string;
 }
 
 export interface ArticlesBySection {
-    [section: string]: Article[];
+	[section: string]: Article[];
 }
 
 export interface DialogConfigs {
-    title: string;
-    isModal: boolean;
-    actions: any[];
+	title: string;
+	isModal: boolean;
+	actions: any[];
 }
 
 export enum TokenVisibility {
-    ALL = 'ALL',
-    UNTRACKED = 'UNTRACKED',
-    TRACKED = 'TRACKED',
+	ALL = 'ALL',
+	UNTRACKED = 'UNTRACKED',
+	TRACKED = 'TRACKED',
 }
 
 export enum HeaderSizes {
-    H1 = 'h1',
-    H2 = 'h2',
-    H3 = 'h3',
+	H1 = 'h1',
+	H2 = 'h2',
+	H3 = 'h3',
 }
 
 export interface DoxityDocObj {
-    [contractName: string]: DoxityContractObj;
+	[contractName: string]: DoxityContractObj;
 }
 
 export interface DoxityContractObj {
-    title: string;
-    fileName: string;
-    name: string;
-    abiDocs: DoxityAbiDoc[];
+	title: string;
+	fileName: string;
+	name: string;
+	abiDocs: DoxityAbiDoc[];
 }
 
 export interface DoxityAbiDoc {
-    constant: boolean;
-    inputs: DoxityInput[];
-    name: string;
-    outputs: DoxityOutput[];
-    payable: boolean;
-    type: string;
-    details?: string;
-    return?: string;
+	constant: boolean;
+	inputs: DoxityInput[];
+	name: string;
+	outputs: DoxityOutput[];
+	payable: boolean;
+	type: string;
+	details?: string;
+	return?: string;
 }
 
 export interface DoxityOutput {
-    name: string;
-    type: string;
+	name: string;
+	type: string;
 }
 
 export interface DoxityInput {
-    name: string;
-    type: string;
-    description: string;
-    indexed?: boolean;
+	name: string;
+	type: string;
+	description: string;
+	indexed?: boolean;
 }
 
 export interface VersionToFileName {
-    [version: string]: string;
+	[version: string]: string;
 }
 
 export enum Docs {
-    ZeroExJs,
-    SmartContracts,
+	ZeroExJs,
+	SmartContracts,
 }
 
 export interface ContractAddresses {
-    [version: string]: {
-        [network: string]: AddressByContractName;
-    };
+	[version: string]: {
+		[network: string]: AddressByContractName;
+	};
 }
 
 export interface AddressByContractName {
-    [contractName: string]: string;
+	[contractName: string]: string;
 }
 
 export enum Networks {
-    mainnet = 'Mainnet',
-    kovan = 'Kovan',
-    ropsten = 'Ropsten',
-    rinkeby = 'Rinkeby',
+	mainnet = 'Mainnet',
+	kovan = 'Kovan',
+	ropsten = 'Ropsten',
+	rinkeby = 'Rinkeby',
 }
 
 export enum AbiTypes {
-    Constructor = 'constructor',
-    Function = 'function',
-    Event = 'event',
+	Constructor = 'constructor',
+	Function = 'function',
+	Event = 'event',
 }
 
 export enum WebsitePaths {
-    Portal = '/portal',
-    Wiki = '/wiki',
-    ZeroExJs = '/docs/0xjs',
-    Home = '/',
-    FAQ = '/faq',
-    About = '/about',
-    Whitepaper = '/pdfs/0x_white_paper.pdf',
-    SmartContracts = '/docs/contracts',
-    Connect = '/docs/connect',
+	Portal = '/portal',
+	Wiki = '/wiki',
+	ZeroExJs = '/docs/0xjs',
+	Home = '/',
+	FAQ = '/faq',
+	About = '/about',
+	Whitepaper = '/pdfs/0x_white_paper.pdf',
+	SmartContracts = '/docs/contracts',
+	Connect = '/docs/connect',
 }
 
 export interface DocsMenu {
-    [sectionName: string]: string[];
+	[sectionName: string]: string[];
 }
 
 export interface SectionsMap {
-    [sectionName: string]: string;
+	[sectionName: string]: string;
 }
 
 export interface DocsInfoConfig {
-    displayName: string;
-    packageUrl: string;
-    websitePath: string;
-    docsJsonRoot: string;
-    menu: DocsMenu;
-    sections: SectionsMap;
-    sectionNameToMarkdown: { [sectionName: string]: string };
-    visibleConstructors: string[];
-    convertToDocAgnosticFormatFn: (docObj: DoxityDocObj | TypeDocNode, docsInfo?: any) => DocAgnosticFormat;
-    subPackageName?: string;
-    publicTypes?: string[];
-    sectionNameToModulePath?: { [sectionName: string]: string[] };
-    menuSubsectionToVersionWhenIntroduced?: { [sectionName: string]: string };
+	displayName: string;
+	packageUrl: string;
+	websitePath: string;
+	docsJsonRoot: string;
+	menu: DocsMenu;
+	sections: SectionsMap;
+	sectionNameToMarkdown: { [sectionName: string]: string };
+	visibleConstructors: string[];
+	convertToDocAgnosticFormatFn: (docObj: DoxityDocObj | TypeDocNode, docsInfo?: any) => DocAgnosticFormat;
+	subPackageName?: string;
+	publicTypes?: string[];
+	sectionNameToModulePath?: { [sectionName: string]: string[] };
+	menuSubsectionToVersionWhenIntroduced?: { [sectionName: string]: string };
 }
 
 export interface TimestampMsRange {
-    startTimestampMs: number;
-    endTimestampMs: number;
+	startTimestampMs: number;
+	endTimestampMs: number;
 }
 
 export interface OutdatedWrappedEtherByNetworkId {
-    [networkId: number]: {
-        address: string;
-        timestampMsRange: TimestampMsRange;
-    };
+	[networkId: number]: {
+		address: string;
+		timestampMsRange: TimestampMsRange;
+	};
 }
 
 export enum SmartContractDocSections {
-    Introduction = 'Introduction',
-    Exchange = 'Exchange',
-    TokenTransferProxy = 'TokenTransferProxy',
-    TokenRegistry = 'TokenRegistry',
-    ZRXToken = 'ZRXToken',
+	Introduction = 'Introduction',
+	Exchange = 'Exchange',
+	TokenTransferProxy = 'TokenTransferProxy',
+	TokenRegistry = 'TokenRegistry',
+	ZRXToken = 'ZRXToken',
 }
 
 // tslint:disable:max-file-line-count
diff --git a/packages/website/ts/utils/colors.ts b/packages/website/ts/utils/colors.ts
index 58ce667e3..dabc1fd54 100644
--- a/packages/website/ts/utils/colors.ts
+++ b/packages/website/ts/utils/colors.ts
@@ -1,43 +1,43 @@
 import { colors as materialUiColors } from 'material-ui/styles';
 
 export const colors = {
-    ...materialUiColors,
-    grey50: '#FAFAFA',
-    grey100: '#F5F5F5',
-    lightestGrey: '#F0F0F0',
-    greyishPink: '#E6E5E5',
-    grey300: '#E0E0E0',
-    beigeWhite: '#E4E4E4',
-    grey400: '#BDBDBD',
-    lightGrey: '#BBBBBB',
-    grey500: '#9E9E9E',
-    grey: '#A5A5A5',
-    darkGrey: '#818181',
-    landingLinkGrey: '#919191',
-    grey700: '#616161',
-    grey800: '#424242',
-    darkerGrey: '#393939',
-    heroGrey: '#404040',
-    projectsGrey: '#343333',
-    darkestGrey: '#272727',
-    dharmaDarkGrey: '#252525',
-    lightBlue: '#60A4F4',
-    lightBlueA700: '#0091EA',
-    darkBlue: '#4D5481',
-    turquois: '#058789',
-    lightPurple: '#A81CA6',
-    purple: '#690596',
-    red200: '#EF9A9A',
-    red: '#E91751',
-    red500: '#F44336',
-    red600: '#E53935',
-    limeGreen: '#66DE75',
-    lightGreen: '#4DC55C',
-    lightestGreen: '#89C774',
-    brightGreen: '#00C33E',
-    green400: '#66BB6A',
-    green: '#4DA24B',
-    amber600: '#FFB300',
-    orange: '#E69D00',
-    amber800: '#FF8F00',
+	...materialUiColors,
+	grey50: '#FAFAFA',
+	grey100: '#F5F5F5',
+	lightestGrey: '#F0F0F0',
+	greyishPink: '#E6E5E5',
+	grey300: '#E0E0E0',
+	beigeWhite: '#E4E4E4',
+	grey400: '#BDBDBD',
+	lightGrey: '#BBBBBB',
+	grey500: '#9E9E9E',
+	grey: '#A5A5A5',
+	darkGrey: '#818181',
+	landingLinkGrey: '#919191',
+	grey700: '#616161',
+	grey800: '#424242',
+	darkerGrey: '#393939',
+	heroGrey: '#404040',
+	projectsGrey: '#343333',
+	darkestGrey: '#272727',
+	dharmaDarkGrey: '#252525',
+	lightBlue: '#60A4F4',
+	lightBlueA700: '#0091EA',
+	darkBlue: '#4D5481',
+	turquois: '#058789',
+	lightPurple: '#A81CA6',
+	purple: '#690596',
+	red200: '#EF9A9A',
+	red: '#E91751',
+	red500: '#F44336',
+	red600: '#E53935',
+	limeGreen: '#66DE75',
+	lightGreen: '#4DC55C',
+	lightestGreen: '#89C774',
+	brightGreen: '#00C33E',
+	green400: '#66BB6A',
+	green: '#4DA24B',
+	amber600: '#FFB300',
+	orange: '#E69D00',
+	amber800: '#FF8F00',
 };
diff --git a/packages/website/ts/utils/configs.ts b/packages/website/ts/utils/configs.ts
index 3d37a89ab..6327ea05a 100644
--- a/packages/website/ts/utils/configs.ts
+++ b/packages/website/ts/utils/configs.ts
@@ -1,126 +1,126 @@
 import * as _ from 'lodash';
 import {
-    ContractAddresses,
-    Environments,
-    Networks,
-    OutdatedWrappedEtherByNetworkId,
-    PublicNodeUrlsByNetworkId,
-    SmartContractDocSections,
+	ContractAddresses,
+	Environments,
+	Networks,
+	OutdatedWrappedEtherByNetworkId,
+	PublicNodeUrlsByNetworkId,
+	SmartContractDocSections,
 } from 'ts/types';
 
 const BASE_URL = window.location.origin;
 const isDevelopment = _.includes(
-    ['https://0xproject.localhost:3572', 'https://localhost:3572', 'https://127.0.0.1'],
-    BASE_URL,
+	['https://0xproject.localhost:3572', 'https://localhost:3572', 'https://127.0.0.1'],
+	BASE_URL,
 );
 const INFURA_API_KEY = 'T5WSC8cautR4KXyYgsRs';
 
 export const configs = {
-    BACKEND_BASE_URL: isDevelopment ? 'https://localhost:3001' : 'https://website-api.0xproject.com',
-    BASE_URL,
-    BITLY_ACCESS_TOKEN: 'ffc4c1a31e5143848fb7c523b39f91b9b213d208',
-    CONTRACT_ADDRESS: {
-        '1.0.0': {
-            [Networks.mainnet]: {
-                [SmartContractDocSections.Exchange]: '0x12459c951127e0c374ff9105dda097662a027093',
-                [SmartContractDocSections.TokenTransferProxy]: '0x8da0d80f5007ef1e431dd2127178d224e32c2ef4',
-                [SmartContractDocSections.ZRXToken]: '0xe41d2489571d322189246dafa5ebde1f4699f498',
-                [SmartContractDocSections.TokenRegistry]: '0x926a74c5c36adf004c87399e65f75628b0f98d2c',
-            },
-            [Networks.ropsten]: {
-                [SmartContractDocSections.Exchange]: '0x479cc461fecd078f766ecc58533d6f69580cf3ac',
-                [SmartContractDocSections.TokenTransferProxy]: '0x4e9aad8184de8833365fea970cd9149372fdf1e6',
-                [SmartContractDocSections.ZRXToken]: '0xa8e9fa8f91e5ae138c74648c9c304f1c75003a8d',
-                [SmartContractDocSections.TokenRegistry]: '0x6b1a50f0bb5a7995444bd3877b22dc89c62843ed',
-            },
-            [Networks.kovan]: {
-                [SmartContractDocSections.Exchange]: '0x90fe2af704b34e0224bf2299c838e04d4dcf1364',
-                [SmartContractDocSections.TokenTransferProxy]: '0x087Eed4Bc1ee3DE49BeFbd66C662B434B15d49d4',
-                [SmartContractDocSections.ZRXToken]: '0x6ff6c0ff1d68b964901f986d4c9fa3ac68346570',
-                [SmartContractDocSections.TokenRegistry]: '0xf18e504561f4347bea557f3d4558f559dddbae7f',
-            },
-        },
-    } as ContractAddresses,
-    DEFAULT_DERIVATION_PATH: `44'/60'/0'`,
-    // WARNING: ZRX & WETH MUST always be default trackedTokens
-    DEFAULT_TRACKED_TOKEN_SYMBOLS: ['WETH', 'ZRX'],
-    DOMAIN_STAGING: 'staging-0xproject.s3-website-us-east-1.amazonaws.com',
-    DOMAIN_DEVELOPMENT: '0xproject.localhost:3572',
-    DOMAIN_PRODUCTION: '0xproject.com',
-    ENVIRONMENT: isDevelopment ? Environments.DEVELOPMENT : Environments.PRODUCTION,
-    ICON_URL_BY_SYMBOL: {
-        REP: '/images/token_icons/augur.png',
-        DGD: '/images/token_icons/digixdao.png',
-        WETH: '/images/token_icons/ether_erc20.png',
-        MLN: '/images/token_icons/melon.png',
-        GNT: '/images/token_icons/golem.png',
-        MKR: '/images/token_icons/makerdao.png',
-        ZRX: '/images/token_icons/zero_ex.png',
-        ANT: '/images/token_icons/aragon.png',
-        BNT: '/images/token_icons/bancor.png',
-        BAT: '/images/token_icons/basicattentiontoken.png',
-        CVC: '/images/token_icons/civic.png',
-        EOS: '/images/token_icons/eos.png',
-        FUN: '/images/token_icons/funfair.png',
-        GNO: '/images/token_icons/gnosis.png',
-        ICN: '/images/token_icons/iconomi.png',
-        OMG: '/images/token_icons/omisego.png',
-        SNT: '/images/token_icons/status.png',
-        STORJ: '/images/token_icons/storjcoinx.png',
-        PAY: '/images/token_icons/tenx.png',
-        QTUM: '/images/token_icons/qtum.png',
-        DNT: '/images/token_icons/district0x.png',
-        SNGLS: '/images/token_icons/singularity.png',
-        EDG: '/images/token_icons/edgeless.png',
-        '1ST': '/images/token_icons/firstblood.jpg',
-        WINGS: '/images/token_icons/wings.png',
-        BQX: '/images/token_icons/bitquence.png',
-        LUN: '/images/token_icons/lunyr.png',
-        RLC: '/images/token_icons/iexec.png',
-        MCO: '/images/token_icons/monaco.png',
-        ADT: '/images/token_icons/adtoken.png',
-        CFI: '/images/token_icons/cofound-it.png',
-        ROL: '/images/token_icons/etheroll.png',
-        WGNT: '/images/token_icons/golem.png',
-        MTL: '/images/token_icons/metal.png',
-        NMR: '/images/token_icons/numeraire.png',
-        SAN: '/images/token_icons/santiment.png',
-        TAAS: '/images/token_icons/taas.png',
-        TKN: '/images/token_icons/tokencard.png',
-        TRST: '/images/token_icons/trust.png',
-    } as { [symbol: string]: string },
-    IS_MAINNET_ENABLED: true,
-    LAST_LOCAL_STORAGE_FILL_CLEARANCE_DATE: '2017-11-22',
-    LAST_LOCAL_STORAGE_TRACKED_TOKEN_CLEARANCE_DATE: '2017-12-19',
-    // NEW_WRAPPED_ETHERS is temporary until we remove the SHOULD_DEPRECATE_OLD_WETH_TOKEN flag
-    // and add the new WETHs to the tokenRegistry
-    NEW_WRAPPED_ETHERS: {
-        1: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
-        42: '0xd0a1e359811322d97991e03f863a0c30c2cf029c',
-    } as { [networkId: string]: string },
-    OUTDATED_WRAPPED_ETHERS: [
-        {
-            42: {
-                address: '0x05d090b51c40b020eab3bfcb6a2dff130df22e9c',
-                timestampMsRange: {
-                    startTimestampMs: 1502455607000,
-                    endTimestampMs: 1513790926000,
-                },
-            },
-            1: {
-                address: '0x2956356cd2a2bf3202f771f50d3d14a367b48070',
-                timestampMsRange: {
-                    startTimestampMs: 1502455607000,
-                    endTimestampMs: 1513790926000,
-                },
-            },
-        },
-    ] as OutdatedWrappedEtherByNetworkId[],
-    // The order matters. We first try first node and only then fall back to others.
-    PUBLIC_NODE_URLS_BY_NETWORK_ID: {
-        [1]: [`https://mainnet.infura.io/${INFURA_API_KEY}`, 'https://mainnet.0xproject.com'],
-        [42]: [`https://kovan.infura.io/${INFURA_API_KEY}`, 'https://kovan.0xproject.com'],
-    } as PublicNodeUrlsByNetworkId,
-    SHOULD_DEPRECATE_OLD_WETH_TOKEN: true,
-    SYMBOLS_OF_MINTABLE_TOKENS: ['MKR', 'MLN', 'GNT', 'DGD', 'REP'],
+	BACKEND_BASE_URL: isDevelopment ? 'https://localhost:3001' : 'https://website-api.0xproject.com',
+	BASE_URL,
+	BITLY_ACCESS_TOKEN: 'ffc4c1a31e5143848fb7c523b39f91b9b213d208',
+	CONTRACT_ADDRESS: {
+		'1.0.0': {
+			[Networks.mainnet]: {
+				[SmartContractDocSections.Exchange]: '0x12459c951127e0c374ff9105dda097662a027093',
+				[SmartContractDocSections.TokenTransferProxy]: '0x8da0d80f5007ef1e431dd2127178d224e32c2ef4',
+				[SmartContractDocSections.ZRXToken]: '0xe41d2489571d322189246dafa5ebde1f4699f498',
+				[SmartContractDocSections.TokenRegistry]: '0x926a74c5c36adf004c87399e65f75628b0f98d2c',
+			},
+			[Networks.ropsten]: {
+				[SmartContractDocSections.Exchange]: '0x479cc461fecd078f766ecc58533d6f69580cf3ac',
+				[SmartContractDocSections.TokenTransferProxy]: '0x4e9aad8184de8833365fea970cd9149372fdf1e6',
+				[SmartContractDocSections.ZRXToken]: '0xa8e9fa8f91e5ae138c74648c9c304f1c75003a8d',
+				[SmartContractDocSections.TokenRegistry]: '0x6b1a50f0bb5a7995444bd3877b22dc89c62843ed',
+			},
+			[Networks.kovan]: {
+				[SmartContractDocSections.Exchange]: '0x90fe2af704b34e0224bf2299c838e04d4dcf1364',
+				[SmartContractDocSections.TokenTransferProxy]: '0x087Eed4Bc1ee3DE49BeFbd66C662B434B15d49d4',
+				[SmartContractDocSections.ZRXToken]: '0x6ff6c0ff1d68b964901f986d4c9fa3ac68346570',
+				[SmartContractDocSections.TokenRegistry]: '0xf18e504561f4347bea557f3d4558f559dddbae7f',
+			},
+		},
+	} as ContractAddresses,
+	DEFAULT_DERIVATION_PATH: `44'/60'/0'`,
+	// WARNING: ZRX & WETH MUST always be default trackedTokens
+	DEFAULT_TRACKED_TOKEN_SYMBOLS: ['WETH', 'ZRX'],
+	DOMAIN_STAGING: 'staging-0xproject.s3-website-us-east-1.amazonaws.com',
+	DOMAIN_DEVELOPMENT: '0xproject.localhost:3572',
+	DOMAIN_PRODUCTION: '0xproject.com',
+	ENVIRONMENT: isDevelopment ? Environments.DEVELOPMENT : Environments.PRODUCTION,
+	ICON_URL_BY_SYMBOL: {
+		REP: '/images/token_icons/augur.png',
+		DGD: '/images/token_icons/digixdao.png',
+		WETH: '/images/token_icons/ether_erc20.png',
+		MLN: '/images/token_icons/melon.png',
+		GNT: '/images/token_icons/golem.png',
+		MKR: '/images/token_icons/makerdao.png',
+		ZRX: '/images/token_icons/zero_ex.png',
+		ANT: '/images/token_icons/aragon.png',
+		BNT: '/images/token_icons/bancor.png',
+		BAT: '/images/token_icons/basicattentiontoken.png',
+		CVC: '/images/token_icons/civic.png',
+		EOS: '/images/token_icons/eos.png',
+		FUN: '/images/token_icons/funfair.png',
+		GNO: '/images/token_icons/gnosis.png',
+		ICN: '/images/token_icons/iconomi.png',
+		OMG: '/images/token_icons/omisego.png',
+		SNT: '/images/token_icons/status.png',
+		STORJ: '/images/token_icons/storjcoinx.png',
+		PAY: '/images/token_icons/tenx.png',
+		QTUM: '/images/token_icons/qtum.png',
+		DNT: '/images/token_icons/district0x.png',
+		SNGLS: '/images/token_icons/singularity.png',
+		EDG: '/images/token_icons/edgeless.png',
+		'1ST': '/images/token_icons/firstblood.jpg',
+		WINGS: '/images/token_icons/wings.png',
+		BQX: '/images/token_icons/bitquence.png',
+		LUN: '/images/token_icons/lunyr.png',
+		RLC: '/images/token_icons/iexec.png',
+		MCO: '/images/token_icons/monaco.png',
+		ADT: '/images/token_icons/adtoken.png',
+		CFI: '/images/token_icons/cofound-it.png',
+		ROL: '/images/token_icons/etheroll.png',
+		WGNT: '/images/token_icons/golem.png',
+		MTL: '/images/token_icons/metal.png',
+		NMR: '/images/token_icons/numeraire.png',
+		SAN: '/images/token_icons/santiment.png',
+		TAAS: '/images/token_icons/taas.png',
+		TKN: '/images/token_icons/tokencard.png',
+		TRST: '/images/token_icons/trust.png',
+	} as { [symbol: string]: string },
+	IS_MAINNET_ENABLED: true,
+	LAST_LOCAL_STORAGE_FILL_CLEARANCE_DATE: '2017-11-22',
+	LAST_LOCAL_STORAGE_TRACKED_TOKEN_CLEARANCE_DATE: '2017-12-19',
+	// NEW_WRAPPED_ETHERS is temporary until we remove the SHOULD_DEPRECATE_OLD_WETH_TOKEN flag
+	// and add the new WETHs to the tokenRegistry
+	NEW_WRAPPED_ETHERS: {
+		1: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
+		42: '0xd0a1e359811322d97991e03f863a0c30c2cf029c',
+	} as { [networkId: string]: string },
+	OUTDATED_WRAPPED_ETHERS: [
+		{
+			42: {
+				address: '0x05d090b51c40b020eab3bfcb6a2dff130df22e9c',
+				timestampMsRange: {
+					startTimestampMs: 1502455607000,
+					endTimestampMs: 1513790926000,
+				},
+			},
+			1: {
+				address: '0x2956356cd2a2bf3202f771f50d3d14a367b48070',
+				timestampMsRange: {
+					startTimestampMs: 1502455607000,
+					endTimestampMs: 1513790926000,
+				},
+			},
+		},
+	] as OutdatedWrappedEtherByNetworkId[],
+	// The order matters. We first try first node and only then fall back to others.
+	PUBLIC_NODE_URLS_BY_NETWORK_ID: {
+		[1]: [`https://mainnet.infura.io/${INFURA_API_KEY}`, 'https://mainnet.0xproject.com'],
+		[42]: [`https://kovan.infura.io/${INFURA_API_KEY}`, 'https://kovan.0xproject.com'],
+	} as PublicNodeUrlsByNetworkId,
+	SHOULD_DEPRECATE_OLD_WETH_TOKEN: true,
+	SYMBOLS_OF_MINTABLE_TOKENS: ['MKR', 'MLN', 'GNT', 'DGD', 'REP'],
 };
diff --git a/packages/website/ts/utils/constants.ts b/packages/website/ts/utils/constants.ts
index dded82114..bb6407ec5 100644
--- a/packages/website/ts/utils/constants.ts
+++ b/packages/website/ts/utils/constants.ts
@@ -2,86 +2,86 @@ import { BigNumber } from '@0xproject/utils';
 import { Networks } from 'ts/types';
 
 export const constants = {
-    DECIMAL_PLACES_ETH: 18,
-    DECIMAL_PLACES_ZRX: 18,
-    DOCS_SCROLL_DURATION_MS: 0,
-    DOCS_CONTAINER_ID: 'documentation',
-    GENESIS_ORDER_BLOCK_BY_NETWORK_ID: {
-        1: 4145578,
-        42: 3117574,
-        50: 0,
-    } as { [networkId: number]: number },
-    HOME_SCROLL_DURATION_MS: 500,
-    HTTP_NO_CONTENT_STATUS_CODE: 204,
-    LOCAL_STORAGE_KEY_ACCEPT_DISCLAIMER: 'didAcceptPortalDisclaimer',
-    LOCAL_STORAGE_KEY_DISMISS_WETH_NOTICE: 'hasDismissedWethNotice',
-    MAKER_FEE: new BigNumber(0),
-    MAINNET_NAME: 'Main network',
-    MINT_AMOUNT: new BigNumber('100000000000000000000'),
-    NETWORK_ID_MAINNET: 1,
-    NETWORK_ID_TESTNET: 42,
-    NETWORK_ID_TESTRPC: 50,
-    NETWORK_NAME_BY_ID: {
-        1: Networks.mainnet,
-        3: Networks.ropsten,
-        4: Networks.rinkeby,
-        42: Networks.kovan,
-    } as { [symbol: number]: string },
-    NETWORK_ID_BY_NAME: {
-        [Networks.mainnet]: 1,
-        [Networks.ropsten]: 3,
-        [Networks.rinkeby]: 4,
-        [Networks.kovan]: 42,
-    } as { [networkName: string]: number },
-    NULL_ADDRESS: '0x0000000000000000000000000000000000000000',
-    PROVIDER_NAME_LEDGER: 'Ledger',
-    PROVIDER_NAME_METAMASK: 'Metamask',
-    PROVIDER_NAME_PARITY_SIGNER: 'Parity Signer',
-    PROVIDER_NAME_GENERIC: 'Injected Web3',
-    PROVIDER_NAME_PUBLIC: '0x Public',
-    ROLLBAR_ACCESS_TOKEN: 'a6619002b51c4464928201e6ea94de65',
-    SUCCESS_STATUS: 200,
-    UNAVAILABLE_STATUS: 503,
-    TAKER_FEE: new BigNumber(0),
-    TESTNET_NAME: 'Kovan',
-    TYPES_SECTION_NAME: 'types',
-    PROJECT_URL_ETHFINEX: 'https://www.bitfinex.com/ethfinex',
-    PROJECT_URL_RADAR_RELAY: 'https://radarrelay.com',
-    PROJECT_URL_PARADEX: 'https://paradex.io',
-    PROJECT_URL_DYDX: 'https://dydx.exchange',
-    PROJECT_URL_MELONPORT: 'https://melonport.com',
-    PROJECT_URL_DISTRICT_0X: 'https://district0x.io',
-    PROJECT_URL_DHARMA: 'https://dharma.io',
-    PROJECT_URL_LENDROID: 'https://lendroid.com',
-    PROJECT_URL_MAKER: 'https://makerdao.com',
-    PROJECT_URL_ARAGON: 'https://aragon.one',
-    PROJECT_URL_BLOCKNET: 'https://blocknet.co',
-    PROJECT_URL_0CEAN: 'http://the0cean.com',
-    PROJECT_URL_STATUS: 'https://status.im',
-    PROJECT_URL_AUGUR: 'https://augur.net',
-    PROJECT_URL_AUCTUS: 'https://auctus.org',
-    PROJECT_URL_OPEN_ANX: 'https://www.openanx.org',
-    URL_ANGELLIST: 'https://angel.co/0xproject/jobs',
-    URL_BIGNUMBERJS_GITHUB: 'http://mikemcl.github.io/bignumber.js',
-    URL_BITLY_API: 'https://api-ssl.bitly.com',
-    URL_BLOG: 'https://blog.0xproject.com/latest',
-    URL_DISCOURSE_FORUM: 'https://forum.0xproject.com',
-    URL_FIREFOX_U2F_ADDON: 'https://addons.mozilla.org/en-US/firefox/addon/u2f-support-add-on/',
-    URL_ETHER_FAUCET: 'https://faucet.0xproject.com',
-    URL_GITHUB_ORG: 'https://github.com/0xProject',
-    URL_GITHUB_WIKI: 'https://github.com/0xProject/wiki',
-    URL_METAMASK_CHROME_STORE: 'https://chrome.google.com/webstore/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn',
-    URL_MIST_DOWNLOAD: 'https://github.com/ethereum/mist/releases',
-    URL_PARITY_CHROME_STORE:
-        'https://chrome.google.com/webstore/detail/parity-ethereum-integrati/himekenlppkgeaoeddcliojfddemadig',
-    URL_REDDIT: 'https://reddit.com/r/0xproject',
-    URL_STANDARD_RELAYER_API_GITHUB: 'https://github.com/0xProject/standard-relayer-api/blob/master/README.md',
-    URL_TWITTER: 'https://twitter.com/0xproject',
-    URL_WEB3_DOCS: 'https://github.com/ethereum/wiki/wiki/JavaScript-API',
-    URL_WEB3_DECODED_LOG_ENTRY_EVENT:
-        'https://github.com/0xProject/web3-typescript-typings/blob/f5bcb96/index.d.ts#L123',
-    URL_WEB3_LOG_ENTRY_EVENT: 'https://github.com/0xProject/web3-typescript-typings/blob/f5bcb96/index.d.ts#L127',
-    URL_WEB3_PROVIDER_DOCS: 'https://github.com/0xProject/web3-typescript-typings/blob/f5bcb96/index.d.ts#L150',
-    URL_WETH_IO: 'https://weth.io/',
-    URL_ZEROEX_CHAT: 'https://chat.0xproject.com',
+	DECIMAL_PLACES_ETH: 18,
+	DECIMAL_PLACES_ZRX: 18,
+	DOCS_SCROLL_DURATION_MS: 0,
+	DOCS_CONTAINER_ID: 'documentation',
+	GENESIS_ORDER_BLOCK_BY_NETWORK_ID: {
+		1: 4145578,
+		42: 3117574,
+		50: 0,
+	} as { [networkId: number]: number },
+	HOME_SCROLL_DURATION_MS: 500,
+	HTTP_NO_CONTENT_STATUS_CODE: 204,
+	LOCAL_STORAGE_KEY_ACCEPT_DISCLAIMER: 'didAcceptPortalDisclaimer',
+	LOCAL_STORAGE_KEY_DISMISS_WETH_NOTICE: 'hasDismissedWethNotice',
+	MAKER_FEE: new BigNumber(0),
+	MAINNET_NAME: 'Main network',
+	MINT_AMOUNT: new BigNumber('100000000000000000000'),
+	NETWORK_ID_MAINNET: 1,
+	NETWORK_ID_TESTNET: 42,
+	NETWORK_ID_TESTRPC: 50,
+	NETWORK_NAME_BY_ID: {
+		1: Networks.mainnet,
+		3: Networks.ropsten,
+		4: Networks.rinkeby,
+		42: Networks.kovan,
+	} as { [symbol: number]: string },
+	NETWORK_ID_BY_NAME: {
+		[Networks.mainnet]: 1,
+		[Networks.ropsten]: 3,
+		[Networks.rinkeby]: 4,
+		[Networks.kovan]: 42,
+	} as { [networkName: string]: number },
+	NULL_ADDRESS: '0x0000000000000000000000000000000000000000',
+	PROVIDER_NAME_LEDGER: 'Ledger',
+	PROVIDER_NAME_METAMASK: 'Metamask',
+	PROVIDER_NAME_PARITY_SIGNER: 'Parity Signer',
+	PROVIDER_NAME_GENERIC: 'Injected Web3',
+	PROVIDER_NAME_PUBLIC: '0x Public',
+	ROLLBAR_ACCESS_TOKEN: 'a6619002b51c4464928201e6ea94de65',
+	SUCCESS_STATUS: 200,
+	UNAVAILABLE_STATUS: 503,
+	TAKER_FEE: new BigNumber(0),
+	TESTNET_NAME: 'Kovan',
+	TYPES_SECTION_NAME: 'types',
+	PROJECT_URL_ETHFINEX: 'https://www.bitfinex.com/ethfinex',
+	PROJECT_URL_RADAR_RELAY: 'https://radarrelay.com',
+	PROJECT_URL_PARADEX: 'https://paradex.io',
+	PROJECT_URL_DYDX: 'https://dydx.exchange',
+	PROJECT_URL_MELONPORT: 'https://melonport.com',
+	PROJECT_URL_DISTRICT_0X: 'https://district0x.io',
+	PROJECT_URL_DHARMA: 'https://dharma.io',
+	PROJECT_URL_LENDROID: 'https://lendroid.com',
+	PROJECT_URL_MAKER: 'https://makerdao.com',
+	PROJECT_URL_ARAGON: 'https://aragon.one',
+	PROJECT_URL_BLOCKNET: 'https://blocknet.co',
+	PROJECT_URL_0CEAN: 'http://the0cean.com',
+	PROJECT_URL_STATUS: 'https://status.im',
+	PROJECT_URL_AUGUR: 'https://augur.net',
+	PROJECT_URL_AUCTUS: 'https://auctus.org',
+	PROJECT_URL_OPEN_ANX: 'https://www.openanx.org',
+	URL_ANGELLIST: 'https://angel.co/0xproject/jobs',
+	URL_BIGNUMBERJS_GITHUB: 'http://mikemcl.github.io/bignumber.js',
+	URL_BITLY_API: 'https://api-ssl.bitly.com',
+	URL_BLOG: 'https://blog.0xproject.com/latest',
+	URL_DISCOURSE_FORUM: 'https://forum.0xproject.com',
+	URL_FIREFOX_U2F_ADDON: 'https://addons.mozilla.org/en-US/firefox/addon/u2f-support-add-on/',
+	URL_ETHER_FAUCET: 'https://faucet.0xproject.com',
+	URL_GITHUB_ORG: 'https://github.com/0xProject',
+	URL_GITHUB_WIKI: 'https://github.com/0xProject/wiki',
+	URL_METAMASK_CHROME_STORE: 'https://chrome.google.com/webstore/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn',
+	URL_MIST_DOWNLOAD: 'https://github.com/ethereum/mist/releases',
+	URL_PARITY_CHROME_STORE:
+		'https://chrome.google.com/webstore/detail/parity-ethereum-integrati/himekenlppkgeaoeddcliojfddemadig',
+	URL_REDDIT: 'https://reddit.com/r/0xproject',
+	URL_STANDARD_RELAYER_API_GITHUB: 'https://github.com/0xProject/standard-relayer-api/blob/master/README.md',
+	URL_TWITTER: 'https://twitter.com/0xproject',
+	URL_WEB3_DOCS: 'https://github.com/ethereum/wiki/wiki/JavaScript-API',
+	URL_WEB3_DECODED_LOG_ENTRY_EVENT:
+		'https://github.com/0xProject/web3-typescript-typings/blob/f5bcb96/index.d.ts#L123',
+	URL_WEB3_LOG_ENTRY_EVENT: 'https://github.com/0xProject/web3-typescript-typings/blob/f5bcb96/index.d.ts#L127',
+	URL_WEB3_PROVIDER_DOCS: 'https://github.com/0xProject/web3-typescript-typings/blob/f5bcb96/index.d.ts#L150',
+	URL_WETH_IO: 'https://weth.io/',
+	URL_ZEROEX_CHAT: 'https://chat.0xproject.com',
 };
diff --git a/packages/website/ts/utils/doc_utils.ts b/packages/website/ts/utils/doc_utils.ts
index 1f5f75ee2..18bf276b4 100644
--- a/packages/website/ts/utils/doc_utils.ts
+++ b/packages/website/ts/utils/doc_utils.ts
@@ -5,47 +5,47 @@ import { utils } from 'ts/utils/utils';
 import convert = require('xml-js');
 
 export const docUtils = {
-    async getVersionToFileNameAsync(s3DocJsonRoot: string): Promise<VersionToFileName> {
-        const versionFileNames = await this.getVersionFileNamesAsync(s3DocJsonRoot);
-        const versionToFileName: VersionToFileName = {};
-        _.each(versionFileNames, fileName => {
-            const [version] = findVersions(fileName);
-            versionToFileName[version] = fileName;
-        });
-        return versionToFileName;
-    },
-    async getVersionFileNamesAsync(s3DocJsonRoot: string): Promise<string[]> {
-        const response = await fetch(s3DocJsonRoot);
-        if (response.status !== 200) {
-            // TODO: Show the user an error message when the docs fail to load
-            const errMsg = await response.text();
-            utils.consoleLog(`Failed to load JSON file list: ${response.status} ${errMsg}`);
-            throw new Error(errMsg);
-        }
-        const responseXML = await response.text();
-        const responseJSONString = convert.xml2json(responseXML, {
-            compact: true,
-        });
-        const responseObj = JSON.parse(responseJSONString);
-        const fileObjs: S3FileObject[] = _.isArray(responseObj.ListBucketResult.Contents)
-            ? (responseObj.ListBucketResult.Contents as S3FileObject[])
-            : [responseObj.ListBucketResult.Contents];
+	async getVersionToFileNameAsync(s3DocJsonRoot: string): Promise<VersionToFileName> {
+		const versionFileNames = await this.getVersionFileNamesAsync(s3DocJsonRoot);
+		const versionToFileName: VersionToFileName = {};
+		_.each(versionFileNames, fileName => {
+			const [version] = findVersions(fileName);
+			versionToFileName[version] = fileName;
+		});
+		return versionToFileName;
+	},
+	async getVersionFileNamesAsync(s3DocJsonRoot: string): Promise<string[]> {
+		const response = await fetch(s3DocJsonRoot);
+		if (response.status !== 200) {
+			// TODO: Show the user an error message when the docs fail to load
+			const errMsg = await response.text();
+			utils.consoleLog(`Failed to load JSON file list: ${response.status} ${errMsg}`);
+			throw new Error(errMsg);
+		}
+		const responseXML = await response.text();
+		const responseJSONString = convert.xml2json(responseXML, {
+			compact: true,
+		});
+		const responseObj = JSON.parse(responseJSONString);
+		const fileObjs: S3FileObject[] = _.isArray(responseObj.ListBucketResult.Contents)
+			? (responseObj.ListBucketResult.Contents as S3FileObject[])
+			: [responseObj.ListBucketResult.Contents];
 
-        const versionFileNames = _.map(fileObjs, fileObj => {
-            return fileObj.Key._text;
-        });
-        return versionFileNames;
-    },
-    async getJSONDocFileAsync(fileName: string, s3DocJsonRoot: string): Promise<TypeDocNode | DoxityDocObj> {
-        const endpoint = `${s3DocJsonRoot}/${fileName}`;
-        const response = await fetch(endpoint);
-        if (response.status !== 200) {
-            // TODO: Show the user an error message when the docs fail to load
-            const errMsg = await response.text();
-            utils.consoleLog(`Failed to load Doc JSON: ${response.status} ${errMsg}`);
-            throw new Error(errMsg);
-        }
-        const jsonDocObj = await response.json();
-        return jsonDocObj;
-    },
+		const versionFileNames = _.map(fileObjs, fileObj => {
+			return fileObj.Key._text;
+		});
+		return versionFileNames;
+	},
+	async getJSONDocFileAsync(fileName: string, s3DocJsonRoot: string): Promise<TypeDocNode | DoxityDocObj> {
+		const endpoint = `${s3DocJsonRoot}/${fileName}`;
+		const response = await fetch(endpoint);
+		if (response.status !== 200) {
+			// TODO: Show the user an error message when the docs fail to load
+			const errMsg = await response.text();
+			utils.consoleLog(`Failed to load Doc JSON: ${response.status} ${errMsg}`);
+			throw new Error(errMsg);
+		}
+		const jsonDocObj = await response.json();
+		return jsonDocObj;
+	},
 };
diff --git a/packages/website/ts/utils/doxity_utils.ts b/packages/website/ts/utils/doxity_utils.ts
index 5f1d02132..f26534d51 100644
--- a/packages/website/ts/utils/doxity_utils.ts
+++ b/packages/website/ts/utils/doxity_utils.ts
@@ -1,168 +1,168 @@
 import * as _ from 'lodash';
 import {
-    AbiTypes,
-    DocAgnosticFormat,
-    DocSection,
-    DoxityAbiDoc,
-    DoxityContractObj,
-    DoxityDocObj,
-    DoxityInput,
-    EventArg,
-    Parameter,
-    Property,
-    SolidityMethod,
-    Type,
-    TypeDocTypes,
+	AbiTypes,
+	DocAgnosticFormat,
+	DocSection,
+	DoxityAbiDoc,
+	DoxityContractObj,
+	DoxityDocObj,
+	DoxityInput,
+	EventArg,
+	Parameter,
+	Property,
+	SolidityMethod,
+	Type,
+	TypeDocTypes,
 } from 'ts/types';
 
 export const doxityUtils = {
-    convertToDocAgnosticFormat(doxityDocObj: DoxityDocObj): DocAgnosticFormat {
-        const docAgnosticFormat: DocAgnosticFormat = {};
-        _.each(doxityDocObj, (doxityContractObj: DoxityContractObj, contractName: string) => {
-            const doxityConstructor = _.find(doxityContractObj.abiDocs, (abiDoc: DoxityAbiDoc) => {
-                return abiDoc.type === AbiTypes.Constructor;
-            });
-            const constructors = [];
-            if (!_.isUndefined(doxityConstructor)) {
-                const constructor = {
-                    isConstructor: true,
-                    name: doxityContractObj.name,
-                    comment: doxityConstructor.details,
-                    returnComment: doxityConstructor.return,
-                    callPath: '',
-                    parameters: this._convertParameters(doxityConstructor.inputs),
-                    returnType: this._convertType(doxityContractObj.name),
-                };
-                constructors.push(constructor);
-            }
+	convertToDocAgnosticFormat(doxityDocObj: DoxityDocObj): DocAgnosticFormat {
+		const docAgnosticFormat: DocAgnosticFormat = {};
+		_.each(doxityDocObj, (doxityContractObj: DoxityContractObj, contractName: string) => {
+			const doxityConstructor = _.find(doxityContractObj.abiDocs, (abiDoc: DoxityAbiDoc) => {
+				return abiDoc.type === AbiTypes.Constructor;
+			});
+			const constructors = [];
+			if (!_.isUndefined(doxityConstructor)) {
+				const constructor = {
+					isConstructor: true,
+					name: doxityContractObj.name,
+					comment: doxityConstructor.details,
+					returnComment: doxityConstructor.return,
+					callPath: '',
+					parameters: this._convertParameters(doxityConstructor.inputs),
+					returnType: this._convertType(doxityContractObj.name),
+				};
+				constructors.push(constructor);
+			}
 
-            const doxityMethods: DoxityAbiDoc[] = _.filter<DoxityAbiDoc>(
-                doxityContractObj.abiDocs,
-                (abiDoc: DoxityAbiDoc) => {
-                    return this._isMethod(abiDoc);
-                },
-            );
-            const methods: SolidityMethod[] = _.map<DoxityAbiDoc, SolidityMethod>(
-                doxityMethods,
-                (doxityMethod: DoxityAbiDoc) => {
-                    // We assume that none of our functions returns more then a single value
-                    const outputIfExists = !_.isUndefined(doxityMethod.outputs) ? doxityMethod.outputs[0] : undefined;
-                    const returnTypeIfExists = !_.isUndefined(outputIfExists)
-                        ? this._convertType(outputIfExists.type)
-                        : undefined;
-                    // For ZRXToken, we want to convert it to zrxToken, rather then simply zRXToken
-                    const callPath =
-                        contractName !== 'ZRXToken'
-                            ? `${contractName[0].toLowerCase()}${contractName.slice(1)}.`
-                            : `${contractName.slice(0, 3).toLowerCase()}${contractName.slice(3)}.`;
-                    const method = {
-                        isConstructor: false,
-                        isConstant: doxityMethod.constant,
-                        isPayable: doxityMethod.payable,
-                        name: doxityMethod.name,
-                        comment: doxityMethod.details,
-                        returnComment: doxityMethod.return,
-                        callPath,
-                        parameters: this._convertParameters(doxityMethod.inputs),
-                        returnType: returnTypeIfExists,
-                    };
-                    return method;
-                },
-            );
+			const doxityMethods: DoxityAbiDoc[] = _.filter<DoxityAbiDoc>(
+				doxityContractObj.abiDocs,
+				(abiDoc: DoxityAbiDoc) => {
+					return this._isMethod(abiDoc);
+				},
+			);
+			const methods: SolidityMethod[] = _.map<DoxityAbiDoc, SolidityMethod>(
+				doxityMethods,
+				(doxityMethod: DoxityAbiDoc) => {
+					// We assume that none of our functions returns more then a single value
+					const outputIfExists = !_.isUndefined(doxityMethod.outputs) ? doxityMethod.outputs[0] : undefined;
+					const returnTypeIfExists = !_.isUndefined(outputIfExists)
+						? this._convertType(outputIfExists.type)
+						: undefined;
+					// For ZRXToken, we want to convert it to zrxToken, rather then simply zRXToken
+					const callPath =
+						contractName !== 'ZRXToken'
+							? `${contractName[0].toLowerCase()}${contractName.slice(1)}.`
+							: `${contractName.slice(0, 3).toLowerCase()}${contractName.slice(3)}.`;
+					const method = {
+						isConstructor: false,
+						isConstant: doxityMethod.constant,
+						isPayable: doxityMethod.payable,
+						name: doxityMethod.name,
+						comment: doxityMethod.details,
+						returnComment: doxityMethod.return,
+						callPath,
+						parameters: this._convertParameters(doxityMethod.inputs),
+						returnType: returnTypeIfExists,
+					};
+					return method;
+				},
+			);
 
-            const doxityProperties: DoxityAbiDoc[] = _.filter<DoxityAbiDoc>(
-                doxityContractObj.abiDocs,
-                (abiDoc: DoxityAbiDoc) => {
-                    return this._isProperty(abiDoc);
-                },
-            );
-            const properties = _.map<DoxityAbiDoc, Property>(doxityProperties, (doxityProperty: DoxityAbiDoc) => {
-                // We assume that none of our functions return more then a single return value
-                let typeName = doxityProperty.outputs[0].type;
-                if (!_.isEmpty(doxityProperty.inputs)) {
-                    // Properties never have more then a single input
-                    typeName = `(${doxityProperty.inputs[0].type} => ${typeName})`;
-                }
-                const property = {
-                    name: doxityProperty.name,
-                    type: this._convertType(typeName),
-                    comment: doxityProperty.details,
-                };
-                return property;
-            });
+			const doxityProperties: DoxityAbiDoc[] = _.filter<DoxityAbiDoc>(
+				doxityContractObj.abiDocs,
+				(abiDoc: DoxityAbiDoc) => {
+					return this._isProperty(abiDoc);
+				},
+			);
+			const properties = _.map<DoxityAbiDoc, Property>(doxityProperties, (doxityProperty: DoxityAbiDoc) => {
+				// We assume that none of our functions return more then a single return value
+				let typeName = doxityProperty.outputs[0].type;
+				if (!_.isEmpty(doxityProperty.inputs)) {
+					// Properties never have more then a single input
+					typeName = `(${doxityProperty.inputs[0].type} => ${typeName})`;
+				}
+				const property = {
+					name: doxityProperty.name,
+					type: this._convertType(typeName),
+					comment: doxityProperty.details,
+				};
+				return property;
+			});
 
-            const doxityEvents = _.filter(
-                doxityContractObj.abiDocs,
-                (abiDoc: DoxityAbiDoc) => abiDoc.type === AbiTypes.Event,
-            );
-            const events = _.map(doxityEvents, doxityEvent => {
-                const event = {
-                    name: doxityEvent.name,
-                    eventArgs: this._convertEventArgs(doxityEvent.inputs),
-                };
-                return event;
-            });
+			const doxityEvents = _.filter(
+				doxityContractObj.abiDocs,
+				(abiDoc: DoxityAbiDoc) => abiDoc.type === AbiTypes.Event,
+			);
+			const events = _.map(doxityEvents, doxityEvent => {
+				const event = {
+					name: doxityEvent.name,
+					eventArgs: this._convertEventArgs(doxityEvent.inputs),
+				};
+				return event;
+			});
 
-            const docSection: DocSection = {
-                comment: doxityContractObj.title,
-                constructors,
-                methods,
-                properties,
-                types: [],
-                events,
-            };
-            docAgnosticFormat[contractName] = docSection;
-        });
-        return docAgnosticFormat;
-    },
-    _convertParameters(inputs: DoxityInput[]): Parameter[] {
-        const parameters = _.map(inputs, input => {
-            const parameter = {
-                name: input.name,
-                comment: input.description,
-                isOptional: false,
-                type: this._convertType(input.type),
-            };
-            return parameter;
-        });
-        return parameters;
-    },
-    _convertType(typeName: string): Type {
-        const type = {
-            name: typeName,
-            typeDocType: TypeDocTypes.Intrinsic,
-        };
-        return type;
-    },
-    _isMethod(abiDoc: DoxityAbiDoc) {
-        if (abiDoc.type !== AbiTypes.Function) {
-            return false;
-        }
-        const hasInputs = !_.isEmpty(abiDoc.inputs);
-        const hasNamedOutputIfExists = !hasInputs || !_.isEmpty(abiDoc.inputs[0].name);
-        const isNameAllCaps = abiDoc.name === abiDoc.name.toUpperCase();
-        const isMethod = hasNamedOutputIfExists && !isNameAllCaps;
-        return isMethod;
-    },
-    _isProperty(abiDoc: DoxityAbiDoc) {
-        if (abiDoc.type !== AbiTypes.Function) {
-            return false;
-        }
-        const hasInputs = !_.isEmpty(abiDoc.inputs);
-        const hasNamedOutputIfExists = !hasInputs || !_.isEmpty(abiDoc.inputs[0].name);
-        const isNameAllCaps = abiDoc.name === abiDoc.name.toUpperCase();
-        const isProperty = !hasNamedOutputIfExists || isNameAllCaps;
-        return isProperty;
-    },
-    _convertEventArgs(inputs: DoxityInput[]): EventArg[] {
-        const eventArgs = _.map(inputs, input => {
-            const eventArg = {
-                isIndexed: input.indexed,
-                name: input.name,
-                type: this._convertType(input.type),
-            };
-            return eventArg;
-        });
-        return eventArgs;
-    },
+			const docSection: DocSection = {
+				comment: doxityContractObj.title,
+				constructors,
+				methods,
+				properties,
+				types: [],
+				events,
+			};
+			docAgnosticFormat[contractName] = docSection;
+		});
+		return docAgnosticFormat;
+	},
+	_convertParameters(inputs: DoxityInput[]): Parameter[] {
+		const parameters = _.map(inputs, input => {
+			const parameter = {
+				name: input.name,
+				comment: input.description,
+				isOptional: false,
+				type: this._convertType(input.type),
+			};
+			return parameter;
+		});
+		return parameters;
+	},
+	_convertType(typeName: string): Type {
+		const type = {
+			name: typeName,
+			typeDocType: TypeDocTypes.Intrinsic,
+		};
+		return type;
+	},
+	_isMethod(abiDoc: DoxityAbiDoc) {
+		if (abiDoc.type !== AbiTypes.Function) {
+			return false;
+		}
+		const hasInputs = !_.isEmpty(abiDoc.inputs);
+		const hasNamedOutputIfExists = !hasInputs || !_.isEmpty(abiDoc.inputs[0].name);
+		const isNameAllCaps = abiDoc.name === abiDoc.name.toUpperCase();
+		const isMethod = hasNamedOutputIfExists && !isNameAllCaps;
+		return isMethod;
+	},
+	_isProperty(abiDoc: DoxityAbiDoc) {
+		if (abiDoc.type !== AbiTypes.Function) {
+			return false;
+		}
+		const hasInputs = !_.isEmpty(abiDoc.inputs);
+		const hasNamedOutputIfExists = !hasInputs || !_.isEmpty(abiDoc.inputs[0].name);
+		const isNameAllCaps = abiDoc.name === abiDoc.name.toUpperCase();
+		const isProperty = !hasNamedOutputIfExists || isNameAllCaps;
+		return isProperty;
+	},
+	_convertEventArgs(inputs: DoxityInput[]): EventArg[] {
+		const eventArgs = _.map(inputs, input => {
+			const eventArg = {
+				isIndexed: input.indexed,
+				name: input.name,
+				type: this._convertType(input.type),
+			};
+			return eventArg;
+		});
+		return eventArgs;
+	},
 };
diff --git a/packages/website/ts/utils/error_reporter.ts b/packages/website/ts/utils/error_reporter.ts
index 0bd247c5b..08d99e405 100644
--- a/packages/website/ts/utils/error_reporter.ts
+++ b/packages/website/ts/utils/error_reporter.ts
@@ -6,47 +6,47 @@ import { utils } from 'ts/utils/utils';
 // Suggested way to include Rollbar with Webpack
 // https://github.com/rollbar/rollbar.js/tree/master/examples/webpack
 const rollbarConfig = {
-    accessToken: constants.ROLLBAR_ACCESS_TOKEN,
-    captureUncaught: true,
-    captureUnhandledRejections: true,
-    itemsPerMinute: 10,
-    maxItems: 500,
-    payload: {
-        environment: configs.ENVIRONMENT,
-    },
-    uncaughtErrorLevel: 'error',
-    hostWhiteList: [configs.DOMAIN_PRODUCTION, configs.DOMAIN_STAGING],
-    ignoredMessages: [
-        // Errors from the third-party scripts
-        'Script error',
-        // Network errors or ad-blockers
-        'TypeError: Failed to fetch',
-        'Exchange has not been deployed to detected network (network/artifact mismatch)',
-        // Source: https://groups.google.com/a/chromium.org/forum/#!topic/chromium-discuss/7VU0_VvC7mE
-        "undefined is not an object (evaluating '__gCrWeb.autofill.extractForms')",
-        // Source: http://stackoverflow.com/questions/43399818/securityerror-from-facebook-and-cross-domain-messaging
-        'SecurityError (DOM Exception 18)',
-    ],
+	accessToken: constants.ROLLBAR_ACCESS_TOKEN,
+	captureUncaught: true,
+	captureUnhandledRejections: true,
+	itemsPerMinute: 10,
+	maxItems: 500,
+	payload: {
+		environment: configs.ENVIRONMENT,
+	},
+	uncaughtErrorLevel: 'error',
+	hostWhiteList: [configs.DOMAIN_PRODUCTION, configs.DOMAIN_STAGING],
+	ignoredMessages: [
+		// Errors from the third-party scripts
+		'Script error',
+		// Network errors or ad-blockers
+		'TypeError: Failed to fetch',
+		'Exchange has not been deployed to detected network (network/artifact mismatch)',
+		// Source: https://groups.google.com/a/chromium.org/forum/#!topic/chromium-discuss/7VU0_VvC7mE
+		"undefined is not an object (evaluating '__gCrWeb.autofill.extractForms')",
+		// Source: http://stackoverflow.com/questions/43399818/securityerror-from-facebook-and-cross-domain-messaging
+		'SecurityError (DOM Exception 18)',
+	],
 };
 import Rollbar = require('../../public/js/rollbar.umd.nojson.min.js');
 const rollbar = Rollbar.init(rollbarConfig);
 
 export const errorReporter = {
-    async reportAsync(err: Error): Promise<any> {
-        if (configs.ENVIRONMENT === Environments.DEVELOPMENT) {
-            return; // Let's not log development errors to rollbar
-        }
+	async reportAsync(err: Error): Promise<any> {
+		if (configs.ENVIRONMENT === Environments.DEVELOPMENT) {
+			return; // Let's not log development errors to rollbar
+		}
 
-        return new Promise((resolve, reject) => {
-            rollbar.error(err, (rollbarErr: Error) => {
-                if (rollbarErr) {
-                    utils.consoleLog(`Error reporting to rollbar, ignoring: ${rollbarErr}`);
-                    // We never want to reject and cause the app to throw because of rollbar
-                    resolve();
-                } else {
-                    resolve();
-                }
-            });
-        });
-    },
+		return new Promise((resolve, reject) => {
+			rollbar.error(err, (rollbarErr: Error) => {
+				if (rollbarErr) {
+					utils.consoleLog(`Error reporting to rollbar, ignoring: ${rollbarErr}`);
+					// We never want to reject and cause the app to throw because of rollbar
+					resolve();
+				} else {
+					resolve();
+				}
+			});
+		});
+	},
 };
diff --git a/packages/website/ts/utils/mui_theme.ts b/packages/website/ts/utils/mui_theme.ts
index d73e80606..565d1ae4f 100644
--- a/packages/website/ts/utils/mui_theme.ts
+++ b/packages/website/ts/utils/mui_theme.ts
@@ -2,34 +2,34 @@ import { getMuiTheme } from 'material-ui/styles';
 import { colors } from 'ts/utils/colors';
 
 export const muiTheme = getMuiTheme({
-    appBar: {
-        height: 45,
-        color: colors.white,
-        textColor: colors.black,
-    },
-    palette: {
-        pickerHeaderColor: colors.lightBlue,
-        primary1Color: colors.lightBlue,
-        primary2Color: colors.lightBlue,
-        textColor: colors.grey700,
-    },
-    datePicker: {
-        color: colors.grey700,
-        textColor: colors.white,
-        calendarTextColor: colors.white,
-        selectColor: colors.darkestGrey,
-        selectTextColor: colors.white,
-    },
-    timePicker: {
-        color: colors.grey700,
-        textColor: colors.white,
-        accentColor: colors.white,
-        headerColor: colors.darkestGrey,
-        selectColor: colors.darkestGrey,
-        selectTextColor: colors.darkestGrey,
-    },
-    toggle: {
-        thumbOnColor: colors.limeGreen,
-        trackOnColor: colors.lightGreen,
-    },
+	appBar: {
+		height: 45,
+		color: colors.white,
+		textColor: colors.black,
+	},
+	palette: {
+		pickerHeaderColor: colors.lightBlue,
+		primary1Color: colors.lightBlue,
+		primary2Color: colors.lightBlue,
+		textColor: colors.grey700,
+	},
+	datePicker: {
+		color: colors.grey700,
+		textColor: colors.white,
+		calendarTextColor: colors.white,
+		selectColor: colors.darkestGrey,
+		selectTextColor: colors.white,
+	},
+	timePicker: {
+		color: colors.grey700,
+		textColor: colors.white,
+		accentColor: colors.white,
+		headerColor: colors.darkestGrey,
+		selectColor: colors.darkestGrey,
+		selectTextColor: colors.darkestGrey,
+	},
+	toggle: {
+		thumbOnColor: colors.limeGreen,
+		trackOnColor: colors.lightGreen,
+	},
 });
diff --git a/packages/website/ts/utils/typedoc_utils.ts b/packages/website/ts/utils/typedoc_utils.ts
index 11ec8da58..b0c152891 100644
--- a/packages/website/ts/utils/typedoc_utils.ts
+++ b/packages/website/ts/utils/typedoc_utils.ts
@@ -1,365 +1,365 @@
 import * as _ from 'lodash';
 import { DocsInfo } from 'ts/pages/documentation/docs_info';
 import {
-    CustomType,
-    CustomTypeChild,
-    DocAgnosticFormat,
-    DocSection,
-    IndexSignature,
-    KindString,
-    Parameter,
-    Property,
-    SectionsMap,
-    Type,
-    TypeDocNode,
-    TypeDocType,
-    TypeParameter,
-    TypescriptMethod,
+	CustomType,
+	CustomTypeChild,
+	DocAgnosticFormat,
+	DocSection,
+	IndexSignature,
+	KindString,
+	Parameter,
+	Property,
+	SectionsMap,
+	Type,
+	TypeDocNode,
+	TypeDocType,
+	TypeParameter,
+	TypescriptMethod,
 } from 'ts/types';
 import { utils } from 'ts/utils/utils';
 
 export const typeDocUtils = {
-    isType(entity: TypeDocNode): boolean {
-        return (
-            entity.kindString === KindString.Interface ||
-            entity.kindString === KindString.Function ||
-            entity.kindString === KindString.TypeAlias ||
-            entity.kindString === KindString.Variable ||
-            entity.kindString === KindString.Enumeration
-        );
-    },
-    isMethod(entity: TypeDocNode): boolean {
-        return entity.kindString === KindString.Method;
-    },
-    isConstructor(entity: TypeDocNode): boolean {
-        return entity.kindString === KindString.Constructor;
-    },
-    isProperty(entity: TypeDocNode): boolean {
-        return entity.kindString === KindString.Property;
-    },
-    isPrivateOrProtectedProperty(propertyName: string): boolean {
-        return _.startsWith(propertyName, '_');
-    },
-    getModuleDefinitionBySectionNameIfExists(
-        versionDocObj: TypeDocNode,
-        modulePaths: string[],
-    ): TypeDocNode | undefined {
-        const modules = versionDocObj.children;
-        for (const mod of modules) {
-            if (_.includes(modulePaths, mod.name)) {
-                const moduleWithName = mod;
-                return moduleWithName;
-            }
-        }
-        return undefined;
-    },
-    convertToDocAgnosticFormat(typeDocJson: TypeDocNode, docsInfo: DocsInfo): DocAgnosticFormat {
-        const subMenus = _.values(docsInfo.getMenu());
-        const orderedSectionNames = _.flatten(subMenus);
-        const docAgnosticFormat: DocAgnosticFormat = {};
-        _.each(orderedSectionNames, sectionName => {
-            const modulePathsIfExists = docsInfo.getModulePathsIfExists(sectionName);
-            if (_.isUndefined(modulePathsIfExists)) {
-                return; // no-op
-            }
-            const packageDefinitionIfExists = typeDocUtils.getModuleDefinitionBySectionNameIfExists(
-                typeDocJson,
-                modulePathsIfExists,
-            );
-            if (_.isUndefined(packageDefinitionIfExists)) {
-                return; // no-op
-            }
+	isType(entity: TypeDocNode): boolean {
+		return (
+			entity.kindString === KindString.Interface ||
+			entity.kindString === KindString.Function ||
+			entity.kindString === KindString.TypeAlias ||
+			entity.kindString === KindString.Variable ||
+			entity.kindString === KindString.Enumeration
+		);
+	},
+	isMethod(entity: TypeDocNode): boolean {
+		return entity.kindString === KindString.Method;
+	},
+	isConstructor(entity: TypeDocNode): boolean {
+		return entity.kindString === KindString.Constructor;
+	},
+	isProperty(entity: TypeDocNode): boolean {
+		return entity.kindString === KindString.Property;
+	},
+	isPrivateOrProtectedProperty(propertyName: string): boolean {
+		return _.startsWith(propertyName, '_');
+	},
+	getModuleDefinitionBySectionNameIfExists(
+		versionDocObj: TypeDocNode,
+		modulePaths: string[],
+	): TypeDocNode | undefined {
+		const modules = versionDocObj.children;
+		for (const mod of modules) {
+			if (_.includes(modulePaths, mod.name)) {
+				const moduleWithName = mod;
+				return moduleWithName;
+			}
+		}
+		return undefined;
+	},
+	convertToDocAgnosticFormat(typeDocJson: TypeDocNode, docsInfo: DocsInfo): DocAgnosticFormat {
+		const subMenus = _.values(docsInfo.getMenu());
+		const orderedSectionNames = _.flatten(subMenus);
+		const docAgnosticFormat: DocAgnosticFormat = {};
+		_.each(orderedSectionNames, sectionName => {
+			const modulePathsIfExists = docsInfo.getModulePathsIfExists(sectionName);
+			if (_.isUndefined(modulePathsIfExists)) {
+				return; // no-op
+			}
+			const packageDefinitionIfExists = typeDocUtils.getModuleDefinitionBySectionNameIfExists(
+				typeDocJson,
+				modulePathsIfExists,
+			);
+			if (_.isUndefined(packageDefinitionIfExists)) {
+				return; // no-op
+			}
 
-            // Since the `types.ts` file is the only file that does not export a module/class but
-            // instead has each type export itself, we do not need to go down two levels of nesting
-            // for it.
-            let entities;
-            let packageComment = '';
-            if (sectionName === docsInfo.sections.types) {
-                entities = packageDefinitionIfExists.children;
-            } else {
-                entities = packageDefinitionIfExists.children[0].children;
-                const commentObj = packageDefinitionIfExists.children[0].comment;
-                packageComment = !_.isUndefined(commentObj) ? commentObj.shortText : packageComment;
-            }
+			// Since the `types.ts` file is the only file that does not export a module/class but
+			// instead has each type export itself, we do not need to go down two levels of nesting
+			// for it.
+			let entities;
+			let packageComment = '';
+			if (sectionName === docsInfo.sections.types) {
+				entities = packageDefinitionIfExists.children;
+			} else {
+				entities = packageDefinitionIfExists.children[0].children;
+				const commentObj = packageDefinitionIfExists.children[0].comment;
+				packageComment = !_.isUndefined(commentObj) ? commentObj.shortText : packageComment;
+			}
 
-            const docSection = typeDocUtils._convertEntitiesToDocSection(entities, docsInfo, sectionName);
-            docSection.comment = packageComment;
-            docAgnosticFormat[sectionName] = docSection;
-        });
-        return docAgnosticFormat;
-    },
-    _convertEntitiesToDocSection(entities: TypeDocNode[], docsInfo: DocsInfo, sectionName: string) {
-        const docSection: DocSection = {
-            comment: '',
-            constructors: [],
-            methods: [],
-            properties: [],
-            types: [],
-        };
+			const docSection = typeDocUtils._convertEntitiesToDocSection(entities, docsInfo, sectionName);
+			docSection.comment = packageComment;
+			docAgnosticFormat[sectionName] = docSection;
+		});
+		return docAgnosticFormat;
+	},
+	_convertEntitiesToDocSection(entities: TypeDocNode[], docsInfo: DocsInfo, sectionName: string) {
+		const docSection: DocSection = {
+			comment: '',
+			constructors: [],
+			methods: [],
+			properties: [],
+			types: [],
+		};
 
-        let isConstructor;
-        _.each(entities, entity => {
-            switch (entity.kindString) {
-                case KindString.Constructor:
-                    isConstructor = true;
-                    const constructor = typeDocUtils._convertMethod(
-                        entity,
-                        isConstructor,
-                        docsInfo.sections,
-                        sectionName,
-                        docsInfo.subPackageName,
-                    );
-                    docSection.constructors.push(constructor);
-                    break;
+		let isConstructor;
+		_.each(entities, entity => {
+			switch (entity.kindString) {
+				case KindString.Constructor:
+					isConstructor = true;
+					const constructor = typeDocUtils._convertMethod(
+						entity,
+						isConstructor,
+						docsInfo.sections,
+						sectionName,
+						docsInfo.subPackageName,
+					);
+					docSection.constructors.push(constructor);
+					break;
 
-                case KindString.Method:
-                    if (entity.flags.isPublic) {
-                        isConstructor = false;
-                        const method = typeDocUtils._convertMethod(
-                            entity,
-                            isConstructor,
-                            docsInfo.sections,
-                            sectionName,
-                            docsInfo.subPackageName,
-                        );
-                        docSection.methods.push(method);
-                    }
-                    break;
+				case KindString.Method:
+					if (entity.flags.isPublic) {
+						isConstructor = false;
+						const method = typeDocUtils._convertMethod(
+							entity,
+							isConstructor,
+							docsInfo.sections,
+							sectionName,
+							docsInfo.subPackageName,
+						);
+						docSection.methods.push(method);
+					}
+					break;
 
-                case KindString.Property:
-                    if (!typeDocUtils.isPrivateOrProtectedProperty(entity.name)) {
-                        const property = typeDocUtils._convertProperty(
-                            entity,
-                            docsInfo.sections,
-                            sectionName,
-                            docsInfo.subPackageName,
-                        );
-                        docSection.properties.push(property);
-                    }
-                    break;
+				case KindString.Property:
+					if (!typeDocUtils.isPrivateOrProtectedProperty(entity.name)) {
+						const property = typeDocUtils._convertProperty(
+							entity,
+							docsInfo.sections,
+							sectionName,
+							docsInfo.subPackageName,
+						);
+						docSection.properties.push(property);
+					}
+					break;
 
-                case KindString.Interface:
-                case KindString.Function:
-                case KindString.Variable:
-                case KindString.Enumeration:
-                case KindString.TypeAlias:
-                    if (docsInfo.isPublicType(entity.name)) {
-                        const customType = typeDocUtils._convertCustomType(
-                            entity,
-                            docsInfo.sections,
-                            sectionName,
-                            docsInfo.subPackageName,
-                        );
-                        docSection.types.push(customType);
-                    }
-                    break;
+				case KindString.Interface:
+				case KindString.Function:
+				case KindString.Variable:
+				case KindString.Enumeration:
+				case KindString.TypeAlias:
+					if (docsInfo.isPublicType(entity.name)) {
+						const customType = typeDocUtils._convertCustomType(
+							entity,
+							docsInfo.sections,
+							sectionName,
+							docsInfo.subPackageName,
+						);
+						docSection.types.push(customType);
+					}
+					break;
 
-                default:
-                    throw utils.spawnSwitchErr('kindString', entity.kindString);
-            }
-        });
-        return docSection;
-    },
-    _convertCustomType(
-        entity: TypeDocNode,
-        sections: SectionsMap,
-        sectionName: string,
-        subPackageName: string,
-    ): CustomType {
-        const typeIfExists = !_.isUndefined(entity.type)
-            ? typeDocUtils._convertType(entity.type, sections, sectionName, subPackageName)
-            : undefined;
-        const isConstructor = false;
-        const methodIfExists = !_.isUndefined(entity.declaration)
-            ? typeDocUtils._convertMethod(entity.declaration, isConstructor, sections, sectionName, subPackageName)
-            : undefined;
-        const indexSignatureIfExists = !_.isUndefined(entity.indexSignature)
-            ? typeDocUtils._convertIndexSignature(entity.indexSignature[0], sections, sectionName, subPackageName)
-            : undefined;
-        const commentIfExists =
-            !_.isUndefined(entity.comment) && !_.isUndefined(entity.comment.shortText)
-                ? entity.comment.shortText
-                : undefined;
+				default:
+					throw utils.spawnSwitchErr('kindString', entity.kindString);
+			}
+		});
+		return docSection;
+	},
+	_convertCustomType(
+		entity: TypeDocNode,
+		sections: SectionsMap,
+		sectionName: string,
+		subPackageName: string,
+	): CustomType {
+		const typeIfExists = !_.isUndefined(entity.type)
+			? typeDocUtils._convertType(entity.type, sections, sectionName, subPackageName)
+			: undefined;
+		const isConstructor = false;
+		const methodIfExists = !_.isUndefined(entity.declaration)
+			? typeDocUtils._convertMethod(entity.declaration, isConstructor, sections, sectionName, subPackageName)
+			: undefined;
+		const indexSignatureIfExists = !_.isUndefined(entity.indexSignature)
+			? typeDocUtils._convertIndexSignature(entity.indexSignature[0], sections, sectionName, subPackageName)
+			: undefined;
+		const commentIfExists =
+			!_.isUndefined(entity.comment) && !_.isUndefined(entity.comment.shortText)
+				? entity.comment.shortText
+				: undefined;
 
-        const childrenIfExist = !_.isUndefined(entity.children)
-            ? _.map(entity.children, (child: TypeDocNode) => {
-                  const childTypeIfExists = !_.isUndefined(child.type)
-                      ? typeDocUtils._convertType(child.type, sections, sectionName, subPackageName)
-                      : undefined;
-                  const c: CustomTypeChild = {
-                      name: child.name,
-                      type: childTypeIfExists,
-                      defaultValue: child.defaultValue,
-                  };
-                  return c;
-              })
-            : undefined;
+		const childrenIfExist = !_.isUndefined(entity.children)
+			? _.map(entity.children, (child: TypeDocNode) => {
+					const childTypeIfExists = !_.isUndefined(child.type)
+						? typeDocUtils._convertType(child.type, sections, sectionName, subPackageName)
+						: undefined;
+					const c: CustomTypeChild = {
+						name: child.name,
+						type: childTypeIfExists,
+						defaultValue: child.defaultValue,
+					};
+					return c;
+				})
+			: undefined;
 
-        const customType = {
-            name: entity.name,
-            kindString: entity.kindString,
-            type: typeIfExists,
-            method: methodIfExists,
-            indexSignature: indexSignatureIfExists,
-            defaultValue: entity.defaultValue,
-            comment: commentIfExists,
-            children: childrenIfExist,
-        };
-        return customType;
-    },
-    _convertIndexSignature(
-        entity: TypeDocNode,
-        sections: SectionsMap,
-        sectionName: string,
-        subPackageName: string,
-    ): IndexSignature {
-        const key = entity.parameters[0];
-        const indexSignature = {
-            keyName: key.name,
-            keyType: typeDocUtils._convertType(key.type, sections, sectionName, subPackageName),
-            valueName: entity.type.name,
-        };
-        return indexSignature;
-    },
-    _convertProperty(
-        entity: TypeDocNode,
-        sections: SectionsMap,
-        sectionName: string,
-        subPackageName: string,
-    ): Property {
-        const source = entity.sources[0];
-        const commentIfExists = !_.isUndefined(entity.comment) ? entity.comment.shortText : undefined;
-        const property = {
-            name: entity.name,
-            type: typeDocUtils._convertType(entity.type, sections, sectionName, subPackageName),
-            source: {
-                fileName: source.fileName,
-                line: source.line,
-            },
-            comment: commentIfExists,
-        };
-        return property;
-    },
-    _convertMethod(
-        entity: TypeDocNode,
-        isConstructor: boolean,
-        sections: SectionsMap,
-        sectionName: string,
-        subPackageName: string,
-    ): TypescriptMethod {
-        const signature = entity.signatures[0];
-        const source = entity.sources[0];
-        const hasComment = !_.isUndefined(signature.comment);
-        const isStatic = _.isUndefined(entity.flags.isStatic) ? false : entity.flags.isStatic;
+		const customType = {
+			name: entity.name,
+			kindString: entity.kindString,
+			type: typeIfExists,
+			method: methodIfExists,
+			indexSignature: indexSignatureIfExists,
+			defaultValue: entity.defaultValue,
+			comment: commentIfExists,
+			children: childrenIfExist,
+		};
+		return customType;
+	},
+	_convertIndexSignature(
+		entity: TypeDocNode,
+		sections: SectionsMap,
+		sectionName: string,
+		subPackageName: string,
+	): IndexSignature {
+		const key = entity.parameters[0];
+		const indexSignature = {
+			keyName: key.name,
+			keyType: typeDocUtils._convertType(key.type, sections, sectionName, subPackageName),
+			valueName: entity.type.name,
+		};
+		return indexSignature;
+	},
+	_convertProperty(
+		entity: TypeDocNode,
+		sections: SectionsMap,
+		sectionName: string,
+		subPackageName: string,
+	): Property {
+		const source = entity.sources[0];
+		const commentIfExists = !_.isUndefined(entity.comment) ? entity.comment.shortText : undefined;
+		const property = {
+			name: entity.name,
+			type: typeDocUtils._convertType(entity.type, sections, sectionName, subPackageName),
+			source: {
+				fileName: source.fileName,
+				line: source.line,
+			},
+			comment: commentIfExists,
+		};
+		return property;
+	},
+	_convertMethod(
+		entity: TypeDocNode,
+		isConstructor: boolean,
+		sections: SectionsMap,
+		sectionName: string,
+		subPackageName: string,
+	): TypescriptMethod {
+		const signature = entity.signatures[0];
+		const source = entity.sources[0];
+		const hasComment = !_.isUndefined(signature.comment);
+		const isStatic = _.isUndefined(entity.flags.isStatic) ? false : entity.flags.isStatic;
 
-        // HACK: we use the fact that the sectionName is the same as the property name at the top-level
-        // of the public interface. In the future, we shouldn't use this hack but rather get it from the JSON.
-        let callPath;
-        if (isConstructor || entity.name === '__type') {
-            callPath = '';
-        } else if (subPackageName === '0x.js') {
-            const topLevelInterface = isStatic ? 'ZeroEx.' : 'zeroEx.';
-            callPath =
-                !_.isUndefined(sections.zeroEx) && sectionName !== sections.zeroEx
-                    ? `${topLevelInterface}${sectionName}.`
-                    : topLevelInterface;
-        } else {
-            callPath = `${sectionName}.`;
-        }
+		// HACK: we use the fact that the sectionName is the same as the property name at the top-level
+		// of the public interface. In the future, we shouldn't use this hack but rather get it from the JSON.
+		let callPath;
+		if (isConstructor || entity.name === '__type') {
+			callPath = '';
+		} else if (subPackageName === '0x.js') {
+			const topLevelInterface = isStatic ? 'ZeroEx.' : 'zeroEx.';
+			callPath =
+				!_.isUndefined(sections.zeroEx) && sectionName !== sections.zeroEx
+					? `${topLevelInterface}${sectionName}.`
+					: topLevelInterface;
+		} else {
+			callPath = `${sectionName}.`;
+		}
 
-        const parameters = _.map(signature.parameters, param => {
-            return typeDocUtils._convertParameter(param, sections, sectionName, subPackageName);
-        });
-        const returnType = typeDocUtils._convertType(signature.type, sections, sectionName, subPackageName);
-        const typeParameter = _.isUndefined(signature.typeParameter)
-            ? undefined
-            : typeDocUtils._convertTypeParameter(signature.typeParameter[0], sections, sectionName, subPackageName);
+		const parameters = _.map(signature.parameters, param => {
+			return typeDocUtils._convertParameter(param, sections, sectionName, subPackageName);
+		});
+		const returnType = typeDocUtils._convertType(signature.type, sections, sectionName, subPackageName);
+		const typeParameter = _.isUndefined(signature.typeParameter)
+			? undefined
+			: typeDocUtils._convertTypeParameter(signature.typeParameter[0], sections, sectionName, subPackageName);
 
-        const method = {
-            isConstructor,
-            isStatic,
-            name: signature.name,
-            comment: hasComment ? signature.comment.shortText : undefined,
-            returnComment: hasComment && signature.comment.returns ? signature.comment.returns : undefined,
-            source: {
-                fileName: source.fileName,
-                line: source.line,
-            },
-            callPath,
-            parameters,
-            returnType,
-            typeParameter,
-        };
-        return method;
-    },
-    _convertTypeParameter(
-        entity: TypeDocNode,
-        sections: SectionsMap,
-        sectionName: string,
-        subPackageName: string,
-    ): TypeParameter {
-        const type = typeDocUtils._convertType(entity.type, sections, sectionName, subPackageName);
-        const parameter = {
-            name: entity.name,
-            type,
-        };
-        return parameter;
-    },
-    _convertParameter(
-        entity: TypeDocNode,
-        sections: SectionsMap,
-        sectionName: string,
-        subPackageName: string,
-    ): Parameter {
-        let comment = '<No comment>';
-        if (entity.comment && entity.comment.shortText) {
-            comment = entity.comment.shortText;
-        } else if (entity.comment && entity.comment.text) {
-            comment = entity.comment.text;
-        }
+		const method = {
+			isConstructor,
+			isStatic,
+			name: signature.name,
+			comment: hasComment ? signature.comment.shortText : undefined,
+			returnComment: hasComment && signature.comment.returns ? signature.comment.returns : undefined,
+			source: {
+				fileName: source.fileName,
+				line: source.line,
+			},
+			callPath,
+			parameters,
+			returnType,
+			typeParameter,
+		};
+		return method;
+	},
+	_convertTypeParameter(
+		entity: TypeDocNode,
+		sections: SectionsMap,
+		sectionName: string,
+		subPackageName: string,
+	): TypeParameter {
+		const type = typeDocUtils._convertType(entity.type, sections, sectionName, subPackageName);
+		const parameter = {
+			name: entity.name,
+			type,
+		};
+		return parameter;
+	},
+	_convertParameter(
+		entity: TypeDocNode,
+		sections: SectionsMap,
+		sectionName: string,
+		subPackageName: string,
+	): Parameter {
+		let comment = '<No comment>';
+		if (entity.comment && entity.comment.shortText) {
+			comment = entity.comment.shortText;
+		} else if (entity.comment && entity.comment.text) {
+			comment = entity.comment.text;
+		}
 
-        const isOptional = !_.isUndefined(entity.flags.isOptional) ? entity.flags.isOptional : false;
+		const isOptional = !_.isUndefined(entity.flags.isOptional) ? entity.flags.isOptional : false;
 
-        const type = typeDocUtils._convertType(entity.type, sections, sectionName, subPackageName);
+		const type = typeDocUtils._convertType(entity.type, sections, sectionName, subPackageName);
 
-        const parameter = {
-            name: entity.name,
-            comment,
-            isOptional,
-            type,
-        };
-        return parameter;
-    },
-    _convertType(entity: TypeDocType, sections: SectionsMap, sectionName: string, subPackageName: string): Type {
-        const typeArguments = _.map(entity.typeArguments, typeArgument => {
-            return typeDocUtils._convertType(typeArgument, sections, sectionName, subPackageName);
-        });
-        const types = _.map(entity.types, t => {
-            return typeDocUtils._convertType(t, sections, sectionName, subPackageName);
-        });
+		const parameter = {
+			name: entity.name,
+			comment,
+			isOptional,
+			type,
+		};
+		return parameter;
+	},
+	_convertType(entity: TypeDocType, sections: SectionsMap, sectionName: string, subPackageName: string): Type {
+		const typeArguments = _.map(entity.typeArguments, typeArgument => {
+			return typeDocUtils._convertType(typeArgument, sections, sectionName, subPackageName);
+		});
+		const types = _.map(entity.types, t => {
+			return typeDocUtils._convertType(t, sections, sectionName, subPackageName);
+		});
 
-        const isConstructor = false;
-        const methodIfExists = !_.isUndefined(entity.declaration)
-            ? typeDocUtils._convertMethod(entity.declaration, isConstructor, sections, sectionName, subPackageName)
-            : undefined;
+		const isConstructor = false;
+		const methodIfExists = !_.isUndefined(entity.declaration)
+			? typeDocUtils._convertMethod(entity.declaration, isConstructor, sections, sectionName, subPackageName)
+			: undefined;
 
-        const elementTypeIfExists = !_.isUndefined(entity.elementType)
-            ? {
-                  name: entity.elementType.name,
-                  typeDocType: entity.elementType.type,
-              }
-            : undefined;
+		const elementTypeIfExists = !_.isUndefined(entity.elementType)
+			? {
+					name: entity.elementType.name,
+					typeDocType: entity.elementType.type,
+				}
+			: undefined;
 
-        const type = {
-            name: entity.name,
-            value: entity.value,
-            typeDocType: entity.type,
-            typeArguments,
-            elementType: elementTypeIfExists,
-            types,
-            method: methodIfExists,
-        };
-        return type;
-    },
+		const type = {
+			name: entity.name,
+			value: entity.value,
+			typeDocType: entity.type,
+			typeArguments,
+			elementType: elementTypeIfExists,
+			types,
+			method: methodIfExists,
+		};
+		return type;
+	},
 };
diff --git a/packages/website/ts/utils/utils.ts b/packages/website/ts/utils/utils.ts
index 13a6d6ae2..ea5b689ae 100644
--- a/packages/website/ts/utils/utils.ts
+++ b/packages/website/ts/utils/utils.ts
@@ -5,15 +5,15 @@ import isMobile = require('is-mobile');
 import * as _ from 'lodash';
 import * as moment from 'moment';
 import {
-    EtherscanLinkSuffixes,
-    Networks,
-    Order,
-    ScreenWidths,
-    Side,
-    SideToAssetToken,
-    SignatureData,
-    Token,
-    TokenByAddress,
+	EtherscanLinkSuffixes,
+	Networks,
+	Order,
+	ScreenWidths,
+	Side,
+	SideToAssetToken,
+	SignatureData,
+	Token,
+	TokenByAddress,
 } from 'ts/types';
 import { configs } from 'ts/utils/configs';
 import { constants } from 'ts/utils/constants';
@@ -23,257 +23,257 @@ const LG_MIN_EM = 64;
 const MD_MIN_EM = 52;
 
 export const utils = {
-    assert(condition: boolean, message: string) {
-        if (!condition) {
-            throw new Error(message);
-        }
-    },
-    spawnSwitchErr(name: string, value: any) {
-        return new Error(`Unexpected switch value: ${value} encountered for ${name}`);
-    },
-    isNumeric(n: string) {
-        return !isNaN(parseFloat(n)) && isFinite(Number(n));
-    },
-    // This default unix timestamp is used for orders where the user does not specify an expiry date.
-    // It is a fixed constant so that both the redux store's INITIAL_STATE and components can check for
-    // whether a user has set an expiry date or not. It is set unrealistically high so as not to collide
-    // with actual values a user would select.
-    initialOrderExpiryUnixTimestampSec(): BigNumber {
-        const m = moment('2050-01-01');
-        return new BigNumber(m.unix());
-    },
-    convertToUnixTimestampSeconds(date: moment.Moment, time?: moment.Moment): BigNumber {
-        const finalMoment = date;
-        if (!_.isUndefined(time)) {
-            finalMoment.hours(time.hours());
-            finalMoment.minutes(time.minutes());
-        }
-        return new BigNumber(finalMoment.unix());
-    },
-    convertToMomentFromUnixTimestamp(unixTimestampSec: BigNumber): moment.Moment {
-        return moment.unix(unixTimestampSec.toNumber());
-    },
-    convertToReadableDateTimeFromUnixTimestamp(unixTimestampSec: BigNumber): string {
-        const m = this.convertToMomentFromUnixTimestamp(unixTimestampSec);
-        const formattedDate: string = m.format('h:MMa MMMM D YYYY');
-        return formattedDate;
-    },
-    generateOrder(
-        networkId: number,
-        exchangeContract: string,
-        sideToAssetToken: SideToAssetToken,
-        orderExpiryTimestamp: BigNumber,
-        orderTakerAddress: string,
-        orderMakerAddress: string,
-        makerFee: BigNumber,
-        takerFee: BigNumber,
-        feeRecipient: string,
-        signatureData: SignatureData,
-        tokenByAddress: TokenByAddress,
-        orderSalt: BigNumber,
-    ): Order {
-        const makerToken = tokenByAddress[sideToAssetToken[Side.Deposit].address];
-        const takerToken = tokenByAddress[sideToAssetToken[Side.Receive].address];
-        const order = {
-            maker: {
-                address: orderMakerAddress,
-                token: {
-                    name: makerToken.name,
-                    symbol: makerToken.symbol,
-                    decimals: makerToken.decimals,
-                    address: makerToken.address,
-                },
-                amount: sideToAssetToken[Side.Deposit].amount.toString(),
-                feeAmount: makerFee.toString(),
-            },
-            taker: {
-                address: orderTakerAddress,
-                token: {
-                    name: takerToken.name,
-                    symbol: takerToken.symbol,
-                    decimals: takerToken.decimals,
-                    address: takerToken.address,
-                },
-                amount: sideToAssetToken[Side.Receive].amount.toString(),
-                feeAmount: takerFee.toString(),
-            },
-            expiration: orderExpiryTimestamp.toString(),
-            feeRecipient,
-            salt: orderSalt.toString(),
-            signature: signatureData,
-            exchangeContract,
-            networkId,
-        };
-        return order;
-    },
-    consoleLog(message: string) {
-        /* tslint:disable */
-        console.log(message);
-        /* tslint:enable */
-    },
-    async sleepAsync(ms: number) {
-        return new Promise(resolve => setTimeout(resolve, ms));
-    },
-    deepEqual(actual: any, expected: any, opts?: { strict: boolean }) {
-        return deepEqual(actual, expected, opts);
-    },
-    getColSize(items: number) {
-        const bassCssGridSize = 12; // Source: http://basscss.com/#basscss-grid
-        const colSize = bassCssGridSize / items;
-        if (!_.isInteger(colSize)) {
-            throw new Error(`Number of cols must be divisible by ${bassCssGridSize}`);
-        }
-        return colSize;
-    },
-    getScreenWidth() {
-        const documentEl = document.documentElement;
-        const body = document.getElementsByTagName('body')[0];
-        const widthInPx = window.innerWidth || documentEl.clientWidth || body.clientWidth;
-        const bodyStyles: any = window.getComputedStyle(document.querySelector('body'));
-        const widthInEm = widthInPx / parseFloat(bodyStyles['font-size']);
+	assert(condition: boolean, message: string) {
+		if (!condition) {
+			throw new Error(message);
+		}
+	},
+	spawnSwitchErr(name: string, value: any) {
+		return new Error(`Unexpected switch value: ${value} encountered for ${name}`);
+	},
+	isNumeric(n: string) {
+		return !isNaN(parseFloat(n)) && isFinite(Number(n));
+	},
+	// This default unix timestamp is used for orders where the user does not specify an expiry date.
+	// It is a fixed constant so that both the redux store's INITIAL_STATE and components can check for
+	// whether a user has set an expiry date or not. It is set unrealistically high so as not to collide
+	// with actual values a user would select.
+	initialOrderExpiryUnixTimestampSec(): BigNumber {
+		const m = moment('2050-01-01');
+		return new BigNumber(m.unix());
+	},
+	convertToUnixTimestampSeconds(date: moment.Moment, time?: moment.Moment): BigNumber {
+		const finalMoment = date;
+		if (!_.isUndefined(time)) {
+			finalMoment.hours(time.hours());
+			finalMoment.minutes(time.minutes());
+		}
+		return new BigNumber(finalMoment.unix());
+	},
+	convertToMomentFromUnixTimestamp(unixTimestampSec: BigNumber): moment.Moment {
+		return moment.unix(unixTimestampSec.toNumber());
+	},
+	convertToReadableDateTimeFromUnixTimestamp(unixTimestampSec: BigNumber): string {
+		const m = this.convertToMomentFromUnixTimestamp(unixTimestampSec);
+		const formattedDate: string = m.format('h:MMa MMMM D YYYY');
+		return formattedDate;
+	},
+	generateOrder(
+		networkId: number,
+		exchangeContract: string,
+		sideToAssetToken: SideToAssetToken,
+		orderExpiryTimestamp: BigNumber,
+		orderTakerAddress: string,
+		orderMakerAddress: string,
+		makerFee: BigNumber,
+		takerFee: BigNumber,
+		feeRecipient: string,
+		signatureData: SignatureData,
+		tokenByAddress: TokenByAddress,
+		orderSalt: BigNumber,
+	): Order {
+		const makerToken = tokenByAddress[sideToAssetToken[Side.Deposit].address];
+		const takerToken = tokenByAddress[sideToAssetToken[Side.Receive].address];
+		const order = {
+			maker: {
+				address: orderMakerAddress,
+				token: {
+					name: makerToken.name,
+					symbol: makerToken.symbol,
+					decimals: makerToken.decimals,
+					address: makerToken.address,
+				},
+				amount: sideToAssetToken[Side.Deposit].amount.toString(),
+				feeAmount: makerFee.toString(),
+			},
+			taker: {
+				address: orderTakerAddress,
+				token: {
+					name: takerToken.name,
+					symbol: takerToken.symbol,
+					decimals: takerToken.decimals,
+					address: takerToken.address,
+				},
+				amount: sideToAssetToken[Side.Receive].amount.toString(),
+				feeAmount: takerFee.toString(),
+			},
+			expiration: orderExpiryTimestamp.toString(),
+			feeRecipient,
+			salt: orderSalt.toString(),
+			signature: signatureData,
+			exchangeContract,
+			networkId,
+		};
+		return order;
+	},
+	consoleLog(message: string) {
+		/* tslint:disable */
+		console.log(message);
+		/* tslint:enable */
+	},
+	async sleepAsync(ms: number) {
+		return new Promise(resolve => setTimeout(resolve, ms));
+	},
+	deepEqual(actual: any, expected: any, opts?: { strict: boolean }) {
+		return deepEqual(actual, expected, opts);
+	},
+	getColSize(items: number) {
+		const bassCssGridSize = 12; // Source: http://basscss.com/#basscss-grid
+		const colSize = bassCssGridSize / items;
+		if (!_.isInteger(colSize)) {
+			throw new Error(`Number of cols must be divisible by ${bassCssGridSize}`);
+		}
+		return colSize;
+	},
+	getScreenWidth() {
+		const documentEl = document.documentElement;
+		const body = document.getElementsByTagName('body')[0];
+		const widthInPx = window.innerWidth || documentEl.clientWidth || body.clientWidth;
+		const bodyStyles: any = window.getComputedStyle(document.querySelector('body'));
+		const widthInEm = widthInPx / parseFloat(bodyStyles['font-size']);
 
-        // This logic mirrors the CSS media queries in BassCSS for the `lg-`, `md-` and `sm-` CSS
-        // class prefixes. Do not edit these.
-        if (widthInEm > LG_MIN_EM) {
-            return ScreenWidths.Lg;
-        } else if (widthInEm > MD_MIN_EM) {
-            return ScreenWidths.Md;
-        } else {
-            return ScreenWidths.Sm;
-        }
-    },
-    isUserOnMobile(): boolean {
-        const isUserOnMobile = isMobile();
-        return isUserOnMobile;
-    },
-    getEtherScanLinkIfExists(addressOrTxHash: string, networkId: number, suffix: EtherscanLinkSuffixes): string {
-        const networkName = constants.NETWORK_NAME_BY_ID[networkId];
-        if (_.isUndefined(networkName)) {
-            return undefined;
-        }
-        const etherScanPrefix = networkName === Networks.mainnet ? '' : `${networkName.toLowerCase()}.`;
-        return `https://${etherScanPrefix}etherscan.io/${suffix}/${addressOrTxHash}`;
-    },
-    setUrlHash(anchorId: string) {
-        window.location.hash = anchorId;
-    },
-    async isU2FSupportedAsync(): Promise<boolean> {
-        const w = window as any;
-        return new Promise((resolve: (isSupported: boolean) => void) => {
-            if (w.u2f && !w.u2f.getApiVersion) {
-                // u2f object was found (Firefox with extension)
-                resolve(true);
-            } else {
-                // u2f object was not found. Using Google polyfill
-                // HACK: u2f.getApiVersion will simply not return a version if the
-                // U2F call fails for any reason. Because of this, we set a hard 3sec
-                // timeout to the request on our end.
-                const getApiVersionTimeoutMs = 3000;
-                const intervalId = setTimeout(() => {
-                    resolve(false);
-                }, getApiVersionTimeoutMs);
-                u2f.getApiVersion((version: number) => {
-                    clearTimeout(intervalId);
-                    resolve(true);
-                });
-            }
-        });
-    },
-    // This checks the error message returned from an injected Web3 instance on the page
-    // after a user was prompted to sign a message or send a transaction and decided to
-    // reject the request.
-    didUserDenyWeb3Request(errMsg: string) {
-        const metamaskDenialErrMsg = 'User denied message';
-        const paritySignerDenialErrMsg = 'Request has been rejected';
-        const ledgerDenialErrMsg = 'Invalid status 6985';
-        const isUserDeniedErrMsg =
-            _.includes(errMsg, metamaskDenialErrMsg) ||
-            _.includes(errMsg, paritySignerDenialErrMsg) ||
-            _.includes(errMsg, ledgerDenialErrMsg);
-        return isUserDeniedErrMsg;
-    },
-    getCurrentEnvironment() {
-        switch (location.host) {
-            case configs.DOMAIN_DEVELOPMENT:
-                return 'development';
-            case configs.DOMAIN_STAGING:
-                return 'staging';
-            case configs.DOMAIN_PRODUCTION:
-                return 'production';
-            default:
-                return 'production';
-        }
-    },
-    getIdFromName(name: string) {
-        const id = name.replace(/ /g, '-');
-        return id;
-    },
-    getAddressBeginAndEnd(address: string): string {
-        const truncatedAddress = `${address.substring(0, 6)}...${address.substr(-4)}`; // 0x3d5a...b287
-        return truncatedAddress;
-    },
-    hasUniqueNameAndSymbol(tokens: Token[], token: Token) {
-        if (token.isRegistered) {
-            return true; // Since it's registered, it is the canonical token
-        }
-        const registeredTokens = _.filter(tokens, t => t.isRegistered);
-        const tokenWithSameNameIfExists = _.find(registeredTokens, {
-            name: token.name,
-        });
-        const isUniqueName = _.isUndefined(tokenWithSameNameIfExists);
-        const tokenWithSameSymbolIfExists = _.find(registeredTokens, {
-            name: token.symbol,
-        });
-        const isUniqueSymbol = _.isUndefined(tokenWithSameSymbolIfExists);
-        return isUniqueName && isUniqueSymbol;
-    },
-    zeroExErrToHumanReadableErrMsg(error: ZeroExError | ExchangeContractErrs, takerAddress: string): string {
-        const ZeroExErrorToHumanReadableError: { [error: string]: string } = {
-            [ZeroExError.ExchangeContractDoesNotExist]: 'Exchange contract does not exist',
-            [ZeroExError.EtherTokenContractDoesNotExist]: 'EtherToken contract does not exist',
-            [ZeroExError.TokenTransferProxyContractDoesNotExist]: 'TokenTransferProxy contract does not exist',
-            [ZeroExError.TokenRegistryContractDoesNotExist]: 'TokenRegistry contract does not exist',
-            [ZeroExError.TokenContractDoesNotExist]: 'Token contract does not exist',
-            [ZeroExError.ZRXContractDoesNotExist]: 'ZRX contract does not exist',
-            [ZeroExError.UnhandledError]: 'Unhandled error occured',
-            [ZeroExError.UserHasNoAssociatedAddress]: 'User has no addresses available',
-            [ZeroExError.InvalidSignature]: 'Order signature is not valid',
-            [ZeroExError.ContractNotDeployedOnNetwork]: 'Contract is not deployed on the detected network',
-            [ZeroExError.InvalidJump]: 'Invalid jump occured while executing the transaction',
-            [ZeroExError.OutOfGas]: 'Transaction ran out of gas',
-            [ZeroExError.NoNetworkId]: 'No network id detected',
-        };
-        const exchangeContractErrorToHumanReadableError: {
-            [error: string]: string;
-        } = {
-            [ExchangeContractErrs.OrderFillExpired]: 'This order has expired',
-            [ExchangeContractErrs.OrderCancelExpired]: 'This order has expired',
-            [ExchangeContractErrs.OrderCancelAmountZero]: "Order cancel amount can't be 0",
-            [ExchangeContractErrs.OrderAlreadyCancelledOrFilled]:
-                'This order has already been completely filled or cancelled',
-            [ExchangeContractErrs.OrderFillAmountZero]: "Order fill amount can't be 0",
-            [ExchangeContractErrs.OrderRemainingFillAmountZero]:
-                'This order has already been completely filled or cancelled',
-            [ExchangeContractErrs.OrderFillRoundingError]: 'Rounding error will occur when filling this order',
-            [ExchangeContractErrs.InsufficientTakerBalance]:
-                'Taker no longer has a sufficient balance to complete this order',
-            [ExchangeContractErrs.InsufficientTakerAllowance]:
-                'Taker no longer has a sufficient allowance to complete this order',
-            [ExchangeContractErrs.InsufficientMakerBalance]:
-                'Maker no longer has a sufficient balance to complete this order',
-            [ExchangeContractErrs.InsufficientMakerAllowance]:
-                'Maker no longer has a sufficient allowance to complete this order',
-            [ExchangeContractErrs.InsufficientTakerFeeBalance]: 'Taker no longer has a sufficient balance to pay fees',
-            [ExchangeContractErrs.InsufficientTakerFeeAllowance]:
-                'Taker no longer has a sufficient allowance to pay fees',
-            [ExchangeContractErrs.InsufficientMakerFeeBalance]: 'Maker no longer has a sufficient balance to pay fees',
-            [ExchangeContractErrs.InsufficientMakerFeeAllowance]:
-                'Maker no longer has a sufficient allowance to pay fees',
-            [ExchangeContractErrs.TransactionSenderIsNotFillOrderTaker]: `This order can only be filled by ${takerAddress}`,
-            [ExchangeContractErrs.InsufficientRemainingFillAmount]: 'Insufficient remaining fill amount',
-        };
-        const humanReadableErrorMsg =
-            exchangeContractErrorToHumanReadableError[error] || ZeroExErrorToHumanReadableError[error];
-        return humanReadableErrorMsg;
-    },
+		// This logic mirrors the CSS media queries in BassCSS for the `lg-`, `md-` and `sm-` CSS
+		// class prefixes. Do not edit these.
+		if (widthInEm > LG_MIN_EM) {
+			return ScreenWidths.Lg;
+		} else if (widthInEm > MD_MIN_EM) {
+			return ScreenWidths.Md;
+		} else {
+			return ScreenWidths.Sm;
+		}
+	},
+	isUserOnMobile(): boolean {
+		const isUserOnMobile = isMobile();
+		return isUserOnMobile;
+	},
+	getEtherScanLinkIfExists(addressOrTxHash: string, networkId: number, suffix: EtherscanLinkSuffixes): string {
+		const networkName = constants.NETWORK_NAME_BY_ID[networkId];
+		if (_.isUndefined(networkName)) {
+			return undefined;
+		}
+		const etherScanPrefix = networkName === Networks.mainnet ? '' : `${networkName.toLowerCase()}.`;
+		return `https://${etherScanPrefix}etherscan.io/${suffix}/${addressOrTxHash}`;
+	},
+	setUrlHash(anchorId: string) {
+		window.location.hash = anchorId;
+	},
+	async isU2FSupportedAsync(): Promise<boolean> {
+		const w = window as any;
+		return new Promise((resolve: (isSupported: boolean) => void) => {
+			if (w.u2f && !w.u2f.getApiVersion) {
+				// u2f object was found (Firefox with extension)
+				resolve(true);
+			} else {
+				// u2f object was not found. Using Google polyfill
+				// HACK: u2f.getApiVersion will simply not return a version if the
+				// U2F call fails for any reason. Because of this, we set a hard 3sec
+				// timeout to the request on our end.
+				const getApiVersionTimeoutMs = 3000;
+				const intervalId = setTimeout(() => {
+					resolve(false);
+				}, getApiVersionTimeoutMs);
+				u2f.getApiVersion((version: number) => {
+					clearTimeout(intervalId);
+					resolve(true);
+				});
+			}
+		});
+	},
+	// This checks the error message returned from an injected Web3 instance on the page
+	// after a user was prompted to sign a message or send a transaction and decided to
+	// reject the request.
+	didUserDenyWeb3Request(errMsg: string) {
+		const metamaskDenialErrMsg = 'User denied message';
+		const paritySignerDenialErrMsg = 'Request has been rejected';
+		const ledgerDenialErrMsg = 'Invalid status 6985';
+		const isUserDeniedErrMsg =
+			_.includes(errMsg, metamaskDenialErrMsg) ||
+			_.includes(errMsg, paritySignerDenialErrMsg) ||
+			_.includes(errMsg, ledgerDenialErrMsg);
+		return isUserDeniedErrMsg;
+	},
+	getCurrentEnvironment() {
+		switch (location.host) {
+			case configs.DOMAIN_DEVELOPMENT:
+				return 'development';
+			case configs.DOMAIN_STAGING:
+				return 'staging';
+			case configs.DOMAIN_PRODUCTION:
+				return 'production';
+			default:
+				return 'production';
+		}
+	},
+	getIdFromName(name: string) {
+		const id = name.replace(/ /g, '-');
+		return id;
+	},
+	getAddressBeginAndEnd(address: string): string {
+		const truncatedAddress = `${address.substring(0, 6)}...${address.substr(-4)}`; // 0x3d5a...b287
+		return truncatedAddress;
+	},
+	hasUniqueNameAndSymbol(tokens: Token[], token: Token) {
+		if (token.isRegistered) {
+			return true; // Since it's registered, it is the canonical token
+		}
+		const registeredTokens = _.filter(tokens, t => t.isRegistered);
+		const tokenWithSameNameIfExists = _.find(registeredTokens, {
+			name: token.name,
+		});
+		const isUniqueName = _.isUndefined(tokenWithSameNameIfExists);
+		const tokenWithSameSymbolIfExists = _.find(registeredTokens, {
+			name: token.symbol,
+		});
+		const isUniqueSymbol = _.isUndefined(tokenWithSameSymbolIfExists);
+		return isUniqueName && isUniqueSymbol;
+	},
+	zeroExErrToHumanReadableErrMsg(error: ZeroExError | ExchangeContractErrs, takerAddress: string): string {
+		const ZeroExErrorToHumanReadableError: { [error: string]: string } = {
+			[ZeroExError.ExchangeContractDoesNotExist]: 'Exchange contract does not exist',
+			[ZeroExError.EtherTokenContractDoesNotExist]: 'EtherToken contract does not exist',
+			[ZeroExError.TokenTransferProxyContractDoesNotExist]: 'TokenTransferProxy contract does not exist',
+			[ZeroExError.TokenRegistryContractDoesNotExist]: 'TokenRegistry contract does not exist',
+			[ZeroExError.TokenContractDoesNotExist]: 'Token contract does not exist',
+			[ZeroExError.ZRXContractDoesNotExist]: 'ZRX contract does not exist',
+			[ZeroExError.UnhandledError]: 'Unhandled error occured',
+			[ZeroExError.UserHasNoAssociatedAddress]: 'User has no addresses available',
+			[ZeroExError.InvalidSignature]: 'Order signature is not valid',
+			[ZeroExError.ContractNotDeployedOnNetwork]: 'Contract is not deployed on the detected network',
+			[ZeroExError.InvalidJump]: 'Invalid jump occured while executing the transaction',
+			[ZeroExError.OutOfGas]: 'Transaction ran out of gas',
+			[ZeroExError.NoNetworkId]: 'No network id detected',
+		};
+		const exchangeContractErrorToHumanReadableError: {
+			[error: string]: string;
+		} = {
+			[ExchangeContractErrs.OrderFillExpired]: 'This order has expired',
+			[ExchangeContractErrs.OrderCancelExpired]: 'This order has expired',
+			[ExchangeContractErrs.OrderCancelAmountZero]: "Order cancel amount can't be 0",
+			[ExchangeContractErrs.OrderAlreadyCancelledOrFilled]:
+				'This order has already been completely filled or cancelled',
+			[ExchangeContractErrs.OrderFillAmountZero]: "Order fill amount can't be 0",
+			[ExchangeContractErrs.OrderRemainingFillAmountZero]:
+				'This order has already been completely filled or cancelled',
+			[ExchangeContractErrs.OrderFillRoundingError]: 'Rounding error will occur when filling this order',
+			[ExchangeContractErrs.InsufficientTakerBalance]:
+				'Taker no longer has a sufficient balance to complete this order',
+			[ExchangeContractErrs.InsufficientTakerAllowance]:
+				'Taker no longer has a sufficient allowance to complete this order',
+			[ExchangeContractErrs.InsufficientMakerBalance]:
+				'Maker no longer has a sufficient balance to complete this order',
+			[ExchangeContractErrs.InsufficientMakerAllowance]:
+				'Maker no longer has a sufficient allowance to complete this order',
+			[ExchangeContractErrs.InsufficientTakerFeeBalance]: 'Taker no longer has a sufficient balance to pay fees',
+			[ExchangeContractErrs.InsufficientTakerFeeAllowance]:
+				'Taker no longer has a sufficient allowance to pay fees',
+			[ExchangeContractErrs.InsufficientMakerFeeBalance]: 'Maker no longer has a sufficient balance to pay fees',
+			[ExchangeContractErrs.InsufficientMakerFeeAllowance]:
+				'Maker no longer has a sufficient allowance to pay fees',
+			[ExchangeContractErrs.TransactionSenderIsNotFillOrderTaker]: `This order can only be filled by ${takerAddress}`,
+			[ExchangeContractErrs.InsufficientRemainingFillAmount]: 'Insufficient remaining fill amount',
+		};
+		const humanReadableErrorMsg =
+			exchangeContractErrorToHumanReadableError[error] || ZeroExErrorToHumanReadableError[error];
+		return humanReadableErrorMsg;
+	},
 };
diff --git a/packages/website/ts/web3_wrapper.ts b/packages/website/ts/web3_wrapper.ts
index 415df6e8b..0cd2a5cc2 100644
--- a/packages/website/ts/web3_wrapper.ts
+++ b/packages/website/ts/web3_wrapper.ts
@@ -5,154 +5,154 @@ import { utils } from 'ts/utils/utils';
 import * as Web3 from 'web3';
 
 export class Web3Wrapper {
-    private _dispatcher: Dispatcher;
-    private _web3: Web3;
-    private _prevNetworkId: number;
-    private _shouldPollUserAddress: boolean;
-    private _watchNetworkAndBalanceIntervalId: NodeJS.Timer;
-    private _prevUserEtherBalanceInEth: BigNumber;
-    private _prevUserAddress: string;
-    constructor(
-        dispatcher: Dispatcher,
-        provider: Web3.Provider,
-        networkIdIfExists: number,
-        shouldPollUserAddress: boolean,
-    ) {
-        this._dispatcher = dispatcher;
-        this._prevNetworkId = networkIdIfExists;
-        this._shouldPollUserAddress = shouldPollUserAddress;
+	private _dispatcher: Dispatcher;
+	private _web3: Web3;
+	private _prevNetworkId: number;
+	private _shouldPollUserAddress: boolean;
+	private _watchNetworkAndBalanceIntervalId: NodeJS.Timer;
+	private _prevUserEtherBalanceInEth: BigNumber;
+	private _prevUserAddress: string;
+	constructor(
+		dispatcher: Dispatcher,
+		provider: Web3.Provider,
+		networkIdIfExists: number,
+		shouldPollUserAddress: boolean,
+	) {
+		this._dispatcher = dispatcher;
+		this._prevNetworkId = networkIdIfExists;
+		this._shouldPollUserAddress = shouldPollUserAddress;
 
-        this._web3 = new Web3();
-        this._web3.setProvider(provider);
+		this._web3 = new Web3();
+		this._web3.setProvider(provider);
 
-        // tslint:disable-next-line:no-floating-promises
-        this._startEmittingNetworkConnectionAndUserBalanceStateAsync();
-    }
-    public isAddress(address: string) {
-        return this._web3.isAddress(address);
-    }
-    public async getAccountsAsync(): Promise<string[]> {
-        const addresses = await promisify<string[]>(this._web3.eth.getAccounts)();
-        return addresses;
-    }
-    public async getFirstAccountIfExistsAsync() {
-        const addresses = await this.getAccountsAsync();
-        if (_.isEmpty(addresses)) {
-            return '';
-        }
-        return addresses[0];
-    }
-    public async getNodeVersionAsync(): Promise<string> {
-        const nodeVersion = await promisify<string>(this._web3.version.getNode)();
-        return nodeVersion;
-    }
-    public getProviderObj() {
-        return this._web3.currentProvider;
-    }
-    public async getNetworkIdIfExists() {
-        try {
-            const networkId = await this._getNetworkAsync();
-            return Number(networkId);
-        } catch (err) {
-            return undefined;
-        }
-    }
-    public async getBalanceInEthAsync(owner: string): Promise<BigNumber> {
-        const balanceInWei: BigNumber = await promisify<BigNumber>(this._web3.eth.getBalance)(owner);
-        const balanceEthOldBigNumber = this._web3.fromWei(balanceInWei, 'ether');
-        const balanceEth = new BigNumber(balanceEthOldBigNumber);
-        return balanceEth;
-    }
-    public async doesContractExistAtAddressAsync(address: string): Promise<boolean> {
-        const code = await promisify<string>(this._web3.eth.getCode)(address);
-        // Regex matches 0x0, 0x00, 0x in order to accomodate poorly implemented clients
-        const zeroHexAddressRegex = /^0[xX][0]*$/;
-        const didFindCode = _.isNull(code.match(zeroHexAddressRegex));
-        return didFindCode;
-    }
-    public async signTransactionAsync(address: string, message: string): Promise<string> {
-        const signData = await promisify<string>(this._web3.eth.sign)(address, message);
-        return signData;
-    }
-    public async getBlockTimestampAsync(blockHash: string): Promise<number> {
-        const { timestamp } = await promisify<Web3.BlockWithoutTransactionData>(this._web3.eth.getBlock)(blockHash);
-        return timestamp;
-    }
-    public destroy() {
-        this._stopEmittingNetworkConnectionAndUserBalanceStateAsync();
-        // HACK: stop() is only available on providerEngine instances
-        const provider = this._web3.currentProvider;
-        if (!_.isUndefined((provider as any).stop)) {
-            (provider as any).stop();
-        }
-    }
-    // This should only be called from the LedgerConfigDialog
-    public updatePrevUserAddress(userAddress: string) {
-        this._prevUserAddress = userAddress;
-    }
-    private async _getNetworkAsync() {
-        const networkId = await promisify(this._web3.version.getNetwork)();
-        return networkId;
-    }
-    private async _startEmittingNetworkConnectionAndUserBalanceStateAsync() {
-        if (!_.isUndefined(this._watchNetworkAndBalanceIntervalId)) {
-            return; // we are already emitting the state
-        }
+		// tslint:disable-next-line:no-floating-promises
+		this._startEmittingNetworkConnectionAndUserBalanceStateAsync();
+	}
+	public isAddress(address: string) {
+		return this._web3.isAddress(address);
+	}
+	public async getAccountsAsync(): Promise<string[]> {
+		const addresses = await promisify<string[]>(this._web3.eth.getAccounts)();
+		return addresses;
+	}
+	public async getFirstAccountIfExistsAsync() {
+		const addresses = await this.getAccountsAsync();
+		if (_.isEmpty(addresses)) {
+			return '';
+		}
+		return addresses[0];
+	}
+	public async getNodeVersionAsync(): Promise<string> {
+		const nodeVersion = await promisify<string>(this._web3.version.getNode)();
+		return nodeVersion;
+	}
+	public getProviderObj() {
+		return this._web3.currentProvider;
+	}
+	public async getNetworkIdIfExists() {
+		try {
+			const networkId = await this._getNetworkAsync();
+			return Number(networkId);
+		} catch (err) {
+			return undefined;
+		}
+	}
+	public async getBalanceInEthAsync(owner: string): Promise<BigNumber> {
+		const balanceInWei: BigNumber = await promisify<BigNumber>(this._web3.eth.getBalance)(owner);
+		const balanceEthOldBigNumber = this._web3.fromWei(balanceInWei, 'ether');
+		const balanceEth = new BigNumber(balanceEthOldBigNumber);
+		return balanceEth;
+	}
+	public async doesContractExistAtAddressAsync(address: string): Promise<boolean> {
+		const code = await promisify<string>(this._web3.eth.getCode)(address);
+		// Regex matches 0x0, 0x00, 0x in order to accomodate poorly implemented clients
+		const zeroHexAddressRegex = /^0[xX][0]*$/;
+		const didFindCode = _.isNull(code.match(zeroHexAddressRegex));
+		return didFindCode;
+	}
+	public async signTransactionAsync(address: string, message: string): Promise<string> {
+		const signData = await promisify<string>(this._web3.eth.sign)(address, message);
+		return signData;
+	}
+	public async getBlockTimestampAsync(blockHash: string): Promise<number> {
+		const { timestamp } = await promisify<Web3.BlockWithoutTransactionData>(this._web3.eth.getBlock)(blockHash);
+		return timestamp;
+	}
+	public destroy() {
+		this._stopEmittingNetworkConnectionAndUserBalanceStateAsync();
+		// HACK: stop() is only available on providerEngine instances
+		const provider = this._web3.currentProvider;
+		if (!_.isUndefined((provider as any).stop)) {
+			(provider as any).stop();
+		}
+	}
+	// This should only be called from the LedgerConfigDialog
+	public updatePrevUserAddress(userAddress: string) {
+		this._prevUserAddress = userAddress;
+	}
+	private async _getNetworkAsync() {
+		const networkId = await promisify(this._web3.version.getNetwork)();
+		return networkId;
+	}
+	private async _startEmittingNetworkConnectionAndUserBalanceStateAsync() {
+		if (!_.isUndefined(this._watchNetworkAndBalanceIntervalId)) {
+			return; // we are already emitting the state
+		}
 
-        let prevNodeVersion: string;
-        this._prevUserEtherBalanceInEth = new BigNumber(0);
-        this._dispatcher.updateNetworkId(this._prevNetworkId);
-        this._watchNetworkAndBalanceIntervalId = intervalUtils.setAsyncExcludingInterval(
-            async () => {
-                // Check for network state changes
-                const currentNetworkId = await this.getNetworkIdIfExists();
-                if (currentNetworkId !== this._prevNetworkId) {
-                    this._prevNetworkId = currentNetworkId;
-                    this._dispatcher.updateNetworkId(currentNetworkId);
-                }
+		let prevNodeVersion: string;
+		this._prevUserEtherBalanceInEth = new BigNumber(0);
+		this._dispatcher.updateNetworkId(this._prevNetworkId);
+		this._watchNetworkAndBalanceIntervalId = intervalUtils.setAsyncExcludingInterval(
+			async () => {
+				// Check for network state changes
+				const currentNetworkId = await this.getNetworkIdIfExists();
+				if (currentNetworkId !== this._prevNetworkId) {
+					this._prevNetworkId = currentNetworkId;
+					this._dispatcher.updateNetworkId(currentNetworkId);
+				}
 
-                // Check for node version changes
-                const currentNodeVersion = await this.getNodeVersionAsync();
-                if (currentNodeVersion !== prevNodeVersion) {
-                    prevNodeVersion = currentNodeVersion;
-                    this._dispatcher.updateNodeVersion(currentNodeVersion);
-                }
+				// Check for node version changes
+				const currentNodeVersion = await this.getNodeVersionAsync();
+				if (currentNodeVersion !== prevNodeVersion) {
+					prevNodeVersion = currentNodeVersion;
+					this._dispatcher.updateNodeVersion(currentNodeVersion);
+				}
 
-                if (this._shouldPollUserAddress) {
-                    const userAddressIfExists = await this.getFirstAccountIfExistsAsync();
-                    // Update makerAddress on network change
-                    if (this._prevUserAddress !== userAddressIfExists) {
-                        this._prevUserAddress = userAddressIfExists;
-                        this._dispatcher.updateUserAddress(userAddressIfExists);
-                    }
+				if (this._shouldPollUserAddress) {
+					const userAddressIfExists = await this.getFirstAccountIfExistsAsync();
+					// Update makerAddress on network change
+					if (this._prevUserAddress !== userAddressIfExists) {
+						this._prevUserAddress = userAddressIfExists;
+						this._dispatcher.updateUserAddress(userAddressIfExists);
+					}
 
-                    // Check for user ether balance changes
-                    if (userAddressIfExists !== '') {
-                        await this._updateUserEtherBalanceAsync(userAddressIfExists);
-                    }
-                } else {
-                    // This logic is primarily for the Ledger, since we don't regularly poll for the address
-                    // we simply update the balance for the last fetched address.
-                    if (!_.isEmpty(this._prevUserAddress)) {
-                        await this._updateUserEtherBalanceAsync(this._prevUserAddress);
-                    }
-                }
-            },
-            5000,
-            (err: Error) => {
-                utils.consoleLog(`Watching network and balances failed: ${err}`);
-                this._stopEmittingNetworkConnectionAndUserBalanceStateAsync();
-            },
-        );
-    }
-    private async _updateUserEtherBalanceAsync(userAddress: string) {
-        const balance = await this.getBalanceInEthAsync(userAddress);
-        if (!balance.eq(this._prevUserEtherBalanceInEth)) {
-            this._prevUserEtherBalanceInEth = balance;
-            this._dispatcher.updateUserEtherBalance(balance);
-        }
-    }
-    private _stopEmittingNetworkConnectionAndUserBalanceStateAsync() {
-        intervalUtils.clearAsyncExcludingInterval(this._watchNetworkAndBalanceIntervalId);
-    }
+					// Check for user ether balance changes
+					if (userAddressIfExists !== '') {
+						await this._updateUserEtherBalanceAsync(userAddressIfExists);
+					}
+				} else {
+					// This logic is primarily for the Ledger, since we don't regularly poll for the address
+					// we simply update the balance for the last fetched address.
+					if (!_.isEmpty(this._prevUserAddress)) {
+						await this._updateUserEtherBalanceAsync(this._prevUserAddress);
+					}
+				}
+			},
+			5000,
+			(err: Error) => {
+				utils.consoleLog(`Watching network and balances failed: ${err}`);
+				this._stopEmittingNetworkConnectionAndUserBalanceStateAsync();
+			},
+		);
+	}
+	private async _updateUserEtherBalanceAsync(userAddress: string) {
+		const balance = await this.getBalanceInEthAsync(userAddress);
+		if (!balance.eq(this._prevUserEtherBalanceInEth)) {
+			this._prevUserEtherBalanceInEth = balance;
+			this._dispatcher.updateUserEtherBalance(balance);
+		}
+	}
+	private _stopEmittingNetworkConnectionAndUserBalanceStateAsync() {
+		intervalUtils.clearAsyncExcludingInterval(this._watchNetworkAndBalanceIntervalId);
+	}
 }
diff --git a/packages/website/tsconfig.json b/packages/website/tsconfig.json
index 38b177d0b..0ed2794d8 100644
--- a/packages/website/tsconfig.json
+++ b/packages/website/tsconfig.json
@@ -1,17 +1,17 @@
 {
-    "extends": "../../tsconfig",
-    "compilerOptions": {
-        "allowSyntheticDefaultImports": true,
-        "outDir": "./transpiled/",
-        "jsx": "react",
-        "baseUrl": "./",
-        "allowJs": true,
-        "strictNullChecks": false,
-        "noImplicitThis": false,
-        "declaration": false,
-        "paths": {
-            "*": ["node_modules/@types/*", "*"]
-        }
-    },
-    "include": ["./ts/**/*", "../../node_modules/web3-typescript-typings/index.d.ts"]
+	"extends": "../../tsconfig",
+	"compilerOptions": {
+		"allowSyntheticDefaultImports": true,
+		"outDir": "./transpiled/",
+		"jsx": "react",
+		"baseUrl": "./",
+		"allowJs": true,
+		"strictNullChecks": false,
+		"noImplicitThis": false,
+		"declaration": false,
+		"paths": {
+			"*": ["node_modules/@types/*", "*"]
+		}
+	},
+	"include": ["./ts/**/*", "../../node_modules/web3-typescript-typings/index.d.ts"]
 }
diff --git a/packages/website/tslint.json b/packages/website/tslint.json
index d6a5f5031..fcbd0391e 100644
--- a/packages/website/tslint.json
+++ b/packages/website/tslint.json
@@ -1,9 +1,9 @@
 {
-    "extends": ["@0xproject/tslint-config"],
-    "rules": {
-        "no-implicit-dependencies": false,
-        "no-object-literal-type-assertion": false,
-        "completed-docs": false,
-        "prefer-function-over-method": false
-    }
+	"extends": ["@0xproject/tslint-config"],
+	"rules": {
+		"no-implicit-dependencies": false,
+		"no-object-literal-type-assertion": false,
+		"completed-docs": false,
+		"prefer-function-over-method": false
+	}
 }
diff --git a/tsconfig.json b/tsconfig.json
index b6f95e64d..937240b76 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,13 +1,13 @@
 {
-    "compilerOptions": {
-        "module": "commonjs",
-        "target": "es5",
-        "lib": ["es2017", "dom"],
-        "sourceMap": true,
-        "declaration": true,
-        "experimentalDecorators": true,
-        "noImplicitReturns": true,
-        "pretty": true,
-        "strict": true
-    }
+	"compilerOptions": {
+		"module": "commonjs",
+		"target": "es5",
+		"lib": ["es2017", "dom"],
+		"sourceMap": true,
+		"declaration": true,
+		"experimentalDecorators": true,
+		"noImplicitReturns": true,
+		"pretty": true,
+		"strict": true
+	}
 }
-- 
cgit v1.2.3


From c6dece6bd1e5f5afa56b290557eb7a6245c76cb6 Mon Sep 17 00:00:00 2001
From: Fabio Berger <me@fabioberger.com>
Date: Tue, 30 Jan 2018 13:26:46 +0100
Subject: Add config file specifically in prettier command and fix files

---
 lerna.json                                         |   10 +-
 package.json                                       |   48 +-
 packages/0x.js/package.json                        |  184 +-
 packages/0x.js/src/0x.ts                           |  608 ++---
 packages/0x.js/src/artifacts.ts                    |   14 +-
 packages/0x.js/src/artifacts/DummyToken.json       |   40 +-
 packages/0x.js/src/artifacts/EtherToken.json       |  570 ++---
 packages/0x.js/src/artifacts/Exchange.json         | 1216 +++++-----
 packages/0x.js/src/artifacts/Token.json            |  340 +--
 packages/0x.js/src/artifacts/TokenRegistry.json    | 1090 ++++-----
 .../0x.js/src/artifacts/TokenTransferProxy.json    |  370 +--
 packages/0x.js/src/artifacts/ZRX.json              |   36 +-
 .../src/contract_wrappers/contract_wrapper.ts      |  378 +--
 .../src/contract_wrappers/ether_token_wrapper.ts   |  318 +--
 .../src/contract_wrappers/exchange_wrapper.ts      | 1718 +++++++-------
 .../contract_wrappers/token_registry_wrapper.ts    |  224 +-
 .../token_transfer_proxy_wrapper.ts                |  110 +-
 .../0x.js/src/contract_wrappers/token_wrapper.ts   |  720 +++---
 packages/0x.js/src/globals.d.ts                    |   50 +-
 packages/0x.js/src/globalsAugment.d.ts             |   34 +-
 packages/0x.js/src/index.ts                        |   88 +-
 packages/0x.js/src/order_watcher/event_watcher.ts  |  148 +-
 .../0x.js/src/order_watcher/expiration_watcher.ts  |  118 +-
 .../0x.js/src/order_watcher/order_state_watcher.ts |  670 +++---
 .../order_watcher/remaining_fillable_calculator.ts |  180 +-
 .../0x.js/src/schemas/zero_ex_config_schema.ts     |   50 +-
 .../stores/balance_proxy_allowance_lazy_store.ts   |  150 +-
 .../stores/order_filled_cancelled_lazy_store.ts    |  100 +-
 packages/0x.js/src/types.ts                        |  390 ++--
 packages/0x.js/src/utils/abi_decoder.ts            |  118 +-
 packages/0x.js/src/utils/assert.ts                 |   42 +-
 packages/0x.js/src/utils/constants.ts              |   16 +-
 packages/0x.js/src/utils/decorators.ts             |  114 +-
 .../0x.js/src/utils/exchange_transfer_simulator.ts |  182 +-
 packages/0x.js/src/utils/filter_utils.ts           |  150 +-
 packages/0x.js/src/utils/order_state_utils.ts      |  254 +-
 packages/0x.js/src/utils/order_validation_utils.ts |  404 ++--
 packages/0x.js/src/utils/signature_utils.ts        |   80 +-
 packages/0x.js/src/utils/utils.ts                  |  116 +-
 packages/0x.js/test/0x.js_test.ts                  |  538 ++---
 packages/0x.js/test/artifacts_test.ts              |   80 +-
 packages/0x.js/test/assert_test.ts                 |   60 +-
 packages/0x.js/test/ether_token_wrapper_test.ts    |  668 +++---
 packages/0x.js/test/event_watcher_test.ts          |  212 +-
 .../0x.js/test/exchange_transfer_simulator_test.ts |  198 +-
 packages/0x.js/test/exchange_wrapper_test.ts       | 2234 +++++++++---------
 packages/0x.js/test/expiration_watcher_test.ts     |  266 +--
 packages/0x.js/test/order_state_watcher_test.ts    | 1022 ++++----
 packages/0x.js/test/order_validation_test.ts       |  900 +++----
 .../test/remaining_fillable_calculator_test.ts     |  436 ++--
 packages/0x.js/test/subscription_test.ts           |  130 +-
 packages/0x.js/test/token_registry_wrapper_test.ts |  212 +-
 .../test/token_transfer_proxy_wrapper_test.ts      |   46 +-
 packages/0x.js/test/token_wrapper_test.ts          |  994 ++++----
 packages/0x.js/test/utils/chai_setup.ts            |   12 +-
 packages/0x.js/test/utils/constants.ts             |   18 +-
 packages/0x.js/test/utils/fill_scenarios.ts        |  374 +--
 packages/0x.js/test/utils/order_factory.ts         |   74 +-
 .../0x.js/test/utils/report_callback_errors.ts     |  102 +-
 .../utils/subproviders/empty_wallet_subprovider.ts |   34 +-
 .../subproviders/fake_gas_estimate_subprovider.ts  |   42 +-
 packages/0x.js/test/utils/token_utils.ts           |   48 +-
 packages/0x.js/test/utils/web3_factory.ts          |   40 +-
 packages/0x.js/tsconfig.json                       |   28 +-
 packages/0x.js/tslint.json                         |    2 +-
 packages/abi-gen/package.json                      |   92 +-
 packages/abi-gen/src/globals.d.ts                  |    2 +-
 packages/abi-gen/src/index.ts                      |  130 +-
 packages/abi-gen/src/types.ts                      |   20 +-
 packages/abi-gen/src/utils.ts                      |  128 +-
 packages/abi-gen/tsconfig.json                     |   10 +-
 packages/abi-gen/tslint.json                       |    2 +-
 packages/assert/package.json                       |   86 +-
 packages/assert/src/index.ts                       |  166 +-
 packages/assert/test/assert_test.ts                |  478 ++--
 packages/assert/tsconfig.json                      |   10 +-
 packages/assert/tslint.json                        |    2 +-
 .../chai-as-promised-typescript-typings/index.d.ts |  466 ++--
 .../package.json                                   |   38 +-
 .../tslint.json                                    |    2 +-
 packages/chai-typescript-typings/index.d.ts        | 2462 ++++++++++----------
 packages/chai-typescript-typings/package.json      |   28 +-
 packages/chai-typescript-typings/tslint.json       |    2 +-
 packages/connect/package.json                      |  124 +-
 packages/connect/src/globals.d.ts                  |    4 +-
 packages/connect/src/http_client.ts                |  268 +--
 packages/connect/src/index.ts                      |   30 +-
 .../src/schemas/relayer_fees_request_schema.ts     |   12 +-
 .../schemas/relayer_orderbook_request_schema.ts    |   12 +-
 .../src/schemas/relayer_orders_request_schema.ts   |   28 +-
 .../schemas/relayer_token_pairs_request_schema.ts  |   12 +-
 packages/connect/src/schemas/schemas.ts            |    6 +-
 packages/connect/src/types.ts                      |  192 +-
 .../src/utils/orderbook_channel_message_parser.ts  |   54 +-
 .../src/utils/relayer_response_json_parsers.ts     |   54 +-
 packages/connect/src/utils/type_converters.ts      |   50 +-
 packages/connect/src/ws_orderbook_channel.ts       |  238 +-
 .../test/fixtures/standard_relayer_api/fees.json   |    6 +-
 .../test/fixtures/standard_relayer_api/fees.ts     |    6 +-
 ...77fa9ac94a50f016026fd13f42990861238897721f.json |   34 +-
 ...f977fa9ac94a50f016026fd13f42990861238897721f.ts |   34 +-
 .../fixtures/standard_relayer_api/orderbook.json   |   84 +-
 .../fixtures/standard_relayer_api/orderbook.ts     |   84 +-
 .../test/fixtures/standard_relayer_api/orders.json |   38 +-
 .../test/fixtures/standard_relayer_api/orders.ts   |   38 +-
 .../fixtures/standard_relayer_api/token_pairs.json |   28 +-
 .../fixtures/standard_relayer_api/token_pairs.ts   |   28 +-
 packages/connect/test/http_client_test.ts          |  248 +-
 .../test/orderbook_channel_message_parsers_test.ts |   94 +-
 packages/connect/test/ws_orderbook_channel_test.ts |   96 +-
 packages/connect/tsconfig.json                     |   20 +-
 packages/connect/tslint.json                       |    2 +-
 packages/contracts/globals.d.ts                    |   24 +-
 packages/contracts/globalsAugment.d.ts             |   26 +-
 .../contracts/migrations/1_initial_migration.ts    |    2 +-
 .../migrations/2_deploy_independent_contracts.ts   |   60 +-
 packages/contracts/migrations/3_register_tokens.ts |  166 +-
 packages/contracts/migrations/4_configure_proxy.ts |   30 +-
 .../contracts/migrations/5_transfer_ownership.ts   |   26 +-
 .../contracts/migrations/config/multisig_sample.ts |   10 +-
 packages/contracts/migrations/config/token_info.ts |  188 +-
 packages/contracts/package.json                    |  144 +-
 packages/contracts/test/ts/ether_token.ts          |  206 +-
 packages/contracts/test/ts/exchange/core.ts        | 1610 ++++++-------
 packages/contracts/test/ts/exchange/helpers.ts     |  298 +--
 packages/contracts/test/ts/exchange/wrapper.ts     |  656 +++---
 .../contracts/test/ts/multi_sig_with_time_lock.ts  |  178 +-
 ...i_sig_with_time_lock_except_remove_auth_addr.ts |  264 +--
 packages/contracts/test/ts/token_registry.ts       |  432 ++--
 .../contracts/test/ts/token_transfer_proxy/auth.ts |  150 +-
 .../test/ts/token_transfer_proxy/transfer_from.ts  |  102 +-
 .../contracts/test/ts/unlimited_allowance_token.ts |  218 +-
 .../test/ts/unlimited_allowance_token_v2.ts        |  246 +-
 packages/contracts/test/ts/utils/chai_setup.ts     |   12 +-
 packages/contracts/test/ts/zrx_token.ts            |  314 +--
 packages/contracts/tsconfig.json                   |   46 +-
 packages/contracts/tslint.json                     |    2 +-
 packages/contracts/util/artifacts.ts               |   52 +-
 packages/contracts/util/balances.ts                |   40 +-
 packages/contracts/util/constants.ts               |   14 +-
 packages/contracts/util/crypto.ts                  |   46 +-
 packages/contracts/util/exchange_wrapper.ts        |  358 +--
 packages/contracts/util/formatters.ts              |  206 +-
 packages/contracts/util/multi_sig_wrapper.ts       |   60 +-
 packages/contracts/util/order.ts                   |  188 +-
 packages/contracts/util/order_factory.ts           |   40 +-
 packages/contracts/util/token_registry_wrapper.ts  |  104 +-
 packages/contracts/util/types.ts                   |  150 +-
 packages/deployer/package.json                     |   82 +-
 packages/deployer/src/cli.ts                       |  218 +-
 packages/deployer/src/commands.ts                  |   24 +-
 packages/deployer/src/compiler.ts                  |  450 ++--
 packages/deployer/src/deployer.ts                  |  326 +--
 packages/deployer/src/globals.d.ts                 |    6 +-
 .../src/migrations/config/multisig_sample.ts       |   10 +-
 .../deployer/src/migrations/config/token_info.ts   |   70 +-
 packages/deployer/src/migrations/migrate.ts        |  154 +-
 packages/deployer/src/solc/bin_paths.ts            |   20 +-
 packages/deployer/src/types.ts                     |   24 +-
 packages/deployer/src/utils/constants.ts           |    2 +-
 packages/deployer/src/utils/contract.ts            |  144 +-
 packages/deployer/src/utils/encoder.ts             |   24 +-
 packages/deployer/src/utils/fs_wrapper.ts          |   12 +-
 packages/deployer/src/utils/types.ts               |  110 +-
 packages/deployer/src/utils/utils.ts               |   22 +-
 packages/deployer/test/deploy_test.ts              |  122 +-
 packages/deployer/test/fixtures/exchange_bin.ts    |    4 +-
 packages/deployer/test/util/constants.ts           |   14 +-
 packages/deployer/tsconfig.json                    |   28 +-
 packages/dev-utils/package.json                    |   70 +-
 packages/dev-utils/src/blockchain_lifecycle.ts     |   38 +-
 packages/dev-utils/src/rpc.ts                      |  110 +-
 packages/dev-utils/tsconfig.json                   |   18 +-
 packages/dev-utils/tslint.json                     |    2 +-
 packages/json-schemas/package.json                 |   86 +-
 .../json-schemas/schemas/basic_type_schemas.ts     |   12 +-
 .../json-schemas/schemas/block_range_schema.ts     |   30 +-
 .../json-schemas/schemas/ec_signature_schema.ts    |   30 +-
 .../schemas/index_filter_values_schema.ts          |   10 +-
 .../json-schemas/schemas/order_cancel_schema.ts    |   20 +-
 .../schemas/order_fill_or_kill_requests_schema.ts  |   20 +-
 .../schemas/order_fill_requests_schema.ts          |   20 +-
 packages/json-schemas/schemas/order_hash_schema.ts |    6 +-
 packages/json-schemas/schemas/order_schemas.ts     |   76 +-
 .../schemas/relayer_api_error_response_schema.ts   |   38 +-
 .../schemas/relayer_api_fees_payload_schema.ts     |   44 +-
 .../schemas/relayer_api_fees_response_schema.ts    |   16 +-
 ...layer_api_orberbook_channel_subscribe_schema.ts |   36 +-
 ...elayer_api_orderbook_channel_snapshot_schema.ts |   32 +-
 ...api_orderbook_channel_update_response_schema.ts |   18 +-
 .../relayer_api_orderbook_response_schema.ts       |   14 +-
 .../relayer_api_token_pairs_response_schema.ts     |   38 +-
 .../json-schemas/schemas/signed_orders_schema.ts   |    6 +-
 packages/json-schemas/schemas/token_schema.ts      |   18 +-
 packages/json-schemas/schemas/tx_data_schema.ts    |   56 +-
 packages/json-schemas/src/schema_validator.ts      |   44 +-
 packages/json-schemas/src/schemas.ts               |   68 +-
 packages/json-schemas/test/schema_test.ts          | 1798 +++++++-------
 packages/json-schemas/tsconfig.json                |   10 +-
 packages/json-schemas/tslint.json                  |    2 +-
 packages/monorepo-scripts/package.json             |   64 +-
 packages/monorepo-scripts/src/deps_versions.ts     |   54 +-
 packages/monorepo-scripts/tsconfig.json            |   10 +-
 packages/monorepo-scripts/tslint.json              |    2 +-
 packages/subproviders/package.json                 |  106 +-
 packages/subproviders/src/globals.d.ts             |  150 +-
 packages/subproviders/src/index.ts                 |   18 +-
 .../subproviders/src/subproviders/injected_web3.ts |   68 +-
 packages/subproviders/src/subproviders/ledger.ts   |  544 ++---
 .../subproviders/src/subproviders/redundant_rpc.ts |   84 +-
 .../subproviders/src/subproviders/subprovider.ts   |   58 +-
 packages/subproviders/src/types.ts                 |  102 +-
 packages/subproviders/test/chai_setup.ts           |   10 +-
 .../test/integration/ledger_subprovider_test.ts    |  322 +--
 .../test/unit/ledger_subprovider_test.ts           |  452 ++--
 .../test/unit/redundant_rpc_subprovider_test.ts    |   78 +-
 .../test/utils/report_callback_errors.ts           |   20 +-
 packages/subproviders/tsconfig.json                |   26 +-
 packages/subproviders/tslint.json                  |    2 +-
 packages/testnet-faucets/README.md                 |   40 +-
 packages/testnet-faucets/package.json              |   82 +-
 packages/testnet-faucets/src/ts/configs.ts         |   10 +-
 packages/testnet-faucets/src/ts/error_reporter.ts  |   58 +-
 .../testnet-faucets/src/ts/ether_request_queue.ts  |   30 +-
 packages/testnet-faucets/src/ts/global.d.ts        |   28 +-
 packages/testnet-faucets/src/ts/handler.ts         |  166 +-
 packages/testnet-faucets/src/ts/id_management.ts   |   26 +-
 packages/testnet-faucets/src/ts/request_queue.ts   |   80 +-
 packages/testnet-faucets/src/ts/rpc_urls.ts        |    8 +-
 packages/testnet-faucets/src/ts/server.ts          |    8 +-
 packages/testnet-faucets/src/ts/utils.ts           |   10 +-
 .../testnet-faucets/src/ts/zrx_request_queue.ts    |   52 +-
 packages/testnet-faucets/tsconfig.json             |   10 +-
 packages/testnet-faucets/tslint.json               |    2 +-
 packages/tslint-config/README.md                   |    2 +-
 packages/tslint-config/package.json                |   70 +-
 packages/tslint-config/rules/asyncSuffixRule.ts    |    6 +-
 .../tslint-config/rules/underscorePrivatesRule.ts  |   72 +-
 .../tslint-config/rules/walkers/async_suffix.ts    |   40 +-
 packages/tslint-config/tsconfig.json               |   10 +-
 packages/tslint-config/tslint.json                 |  198 +-
 packages/types/package.json                        |   58 +-
 packages/types/src/index.ts                        |   32 +-
 packages/types/tsconfig.json                       |   10 +-
 packages/types/tslint.json                         |    2 +-
 packages/utils/package.json                        |   64 +-
 packages/utils/src/address_utils.ts                |   56 +-
 packages/utils/src/class_utils.ts                  |   28 +-
 packages/utils/src/configured_bignumber.ts         |    2 +-
 packages/utils/src/interval_utils.ts               |   66 +-
 packages/utils/src/promisify.ts                    |   18 +-
 packages/utils/tsconfig.json                       |   10 +-
 packages/utils/tslint.json                         |    2 +-
 packages/web3-typescript-typings/index.d.ts        |  840 +++----
 packages/web3-typescript-typings/package.json      |   56 +-
 packages/web3-typescript-typings/tslint.json       |    2 +-
 packages/web3-wrapper/package.json                 |   68 +-
 packages/web3-wrapper/src/index.ts                 |  326 +--
 packages/web3-wrapper/tsconfig.json                |   10 +-
 packages/web3-wrapper/tslint.json                  |    2 +-
 packages/website/contracts/Mintable.json           |  376 +--
 packages/website/md/docs/0xjs/async.md             |   14 +-
 packages/website/package.json                      |  214 +-
 packages/website/ts/blockchain.ts                  | 1504 ++++++------
 .../components/dialogs/blockchain_err_dialog.tsx   |  282 +--
 .../dialogs/eth_weth_conversion_dialog.tsx         |  290 +--
 .../ts/components/dialogs/ledger_config_dialog.tsx |  460 ++--
 .../dialogs/portal_disclaimer_dialog.tsx           |   52 +-
 .../website/ts/components/dialogs/send_dialog.tsx  |  200 +-
 .../dialogs/track_token_confirmation_dialog.tsx    |  160 +-
 .../dialogs/u2f_not_supported_dialog.tsx           |   70 +-
 .../dialogs/wrapped_eth_section_notice_dialog.tsx  |   46 +-
 .../ts/components/eth_weth_conversion_button.tsx   |  208 +-
 packages/website/ts/components/eth_wrappers.tsx    |  674 +++---
 packages/website/ts/components/fill_order.tsx      | 1270 +++++-----
 packages/website/ts/components/fill_order_json.tsx |  124 +-
 .../website/ts/components/fill_warning_dialog.tsx  |   70 +-
 .../flash_messages/token_send_completed.tsx        |   38 +-
 .../flash_messages/transaction_submitted.tsx       |   30 +-
 packages/website/ts/components/footer.tsx          |  362 +--
 .../ts/components/generate_order/asset_picker.tsx  |  498 ++--
 .../generate_order/generate_order_form.tsx         |  620 ++---
 .../components/generate_order/new_token_form.tsx   |  418 ++--
 .../website/ts/components/inputs/address_input.tsx |  112 +-
 .../ts/components/inputs/allowance_toggle.tsx      |  142 +-
 .../ts/components/inputs/balance_bounded_input.tsx |  264 +--
 .../ts/components/inputs/eth_amount_input.tsx      |   68 +-
 .../ts/components/inputs/expiration_input.tsx      |  168 +-
 .../website/ts/components/inputs/hash_input.tsx    |   86 +-
 .../components/inputs/identicon_address_input.tsx  |   76 +-
 .../ts/components/inputs/token_amount_input.tsx    |  108 +-
 .../website/ts/components/inputs/token_input.tsx   |  164 +-
 packages/website/ts/components/order_json.tsx      |  322 +--
 packages/website/ts/components/portal.tsx          |  630 ++---
 packages/website/ts/components/portal_menu.tsx     |  122 +-
 packages/website/ts/components/send_button.tsx     |  136 +-
 packages/website/ts/components/token_balances.tsx  | 1066 ++++-----
 packages/website/ts/components/top_bar.tsx         |  634 ++---
 .../website/ts/components/top_bar_menu_item.tsx    |   74 +-
 .../ts/components/track_token_confirmation.tsx     |   94 +-
 .../ts/components/trade_history/trade_history.tsx  |  190 +-
 .../trade_history/trade_history_item.tsx           |  282 +--
 packages/website/ts/components/ui/alert.tsx        |   30 +-
 packages/website/ts/components/ui/badge.tsx        |   84 +-
 packages/website/ts/components/ui/copy_icon.tsx    |  126 +-
 .../ts/components/ui/drop_down_menu_item.tsx       |  170 +-
 .../website/ts/components/ui/ethereum_address.tsx  |   38 +-
 .../website/ts/components/ui/etherscan_icon.tsx    |   52 +-
 .../website/ts/components/ui/fake_text_field.tsx   |   44 +-
 .../website/ts/components/ui/flash_message.tsx     |   52 +-
 packages/website/ts/components/ui/help_tooltip.tsx |   28 +-
 packages/website/ts/components/ui/identicon.tsx    |   72 +-
 packages/website/ts/components/ui/input_label.tsx  |   28 +-
 .../ts/components/ui/lifecycle_raised_button.tsx   |  166 +-
 packages/website/ts/components/ui/loading.tsx      |   52 +-
 packages/website/ts/components/ui/menu_item.tsx    |   78 +-
 packages/website/ts/components/ui/party.tsx        |  240 +-
 .../website/ts/components/ui/required_label.tsx    |   14 +-
 .../website/ts/components/ui/simple_loading.tsx    |   18 +-
 packages/website/ts/components/ui/swap_icon.tsx    |   60 +-
 packages/website/ts/components/ui/token_icon.tsx   |   30 +-
 packages/website/ts/components/visual_order.tsx    |  120 +-
 .../ts/containers/connect_documentation.tsx        |  116 +-
 .../website/ts/containers/generate_order_form.tsx  |   64 +-
 packages/website/ts/containers/portal.tsx          |  112 +-
 .../containers/smart_contracts_documentation.tsx   |   58 +-
 .../ts/containers/zero_ex_js_documentation.tsx     |  258 +-
 packages/website/ts/globals.d.ts                   |  170 +-
 packages/website/ts/index.tsx                      |   60 +-
 packages/website/ts/lazy_component.tsx             |   82 +-
 packages/website/ts/local_storage/local_storage.ts |   62 +-
 .../ts/local_storage/tracked_token_storage.ts      |  114 +-
 .../ts/local_storage/trade_history_storage.tsx     |  160 +-
 packages/website/ts/pages/about/about.tsx          |  416 ++--
 packages/website/ts/pages/about/profile.tsx        |  116 +-
 .../website/ts/pages/documentation/comment.tsx     |   16 +-
 .../website/ts/pages/documentation/custom_enum.tsx |   34 +-
 .../website/ts/pages/documentation/docs_info.ts    |  198 +-
 .../ts/pages/documentation/documentation.tsx       |  648 +++---
 packages/website/ts/pages/documentation/enum.tsx   |   26 +-
 .../ts/pages/documentation/event_definition.tsx    |  132 +-
 .../website/ts/pages/documentation/interface.tsx   |   98 +-
 .../ts/pages/documentation/method_block.tsx        |  238 +-
 .../ts/pages/documentation/method_signature.tsx    |  148 +-
 .../website/ts/pages/documentation/source_link.tsx |   38 +-
 packages/website/ts/pages/documentation/type.tsx   |  354 +--
 .../ts/pages/documentation/type_definition.tsx     |  194 +-
 packages/website/ts/pages/faq/faq.tsx              |  846 +++----
 packages/website/ts/pages/faq/question.tsx         |   76 +-
 packages/website/ts/pages/landing/landing.tsx      | 1420 +++++------
 packages/website/ts/pages/not_found.tsx            |   52 +-
 packages/website/ts/pages/shared/anchor_title.tsx  |  142 +-
 .../ts/pages/shared/markdown_code_block.tsx        |   28 +-
 .../website/ts/pages/shared/markdown_section.tsx   |  112 +-
 .../ts/pages/shared/nested_sidebar_menu.tsx        |  268 +--
 .../website/ts/pages/shared/section_header.tsx     |   72 +-
 .../website/ts/pages/shared/version_drop_down.tsx  |   50 +-
 packages/website/ts/pages/wiki/wiki.tsx            |  344 +--
 packages/website/ts/redux/dispatcher.ts            |  452 ++--
 packages/website/ts/redux/reducer.ts               |  738 +++---
 packages/website/ts/schemas/order_schema.ts        |   26 +-
 packages/website/ts/schemas/order_taker_schema.ts  |   18 +-
 .../website/ts/schemas/signature_data_schema.ts    |   18 +-
 packages/website/ts/schemas/token_schema.ts        |   18 +-
 packages/website/ts/schemas/validator.ts           |   22 +-
 packages/website/ts/types.ts                       |  782 +++----
 packages/website/ts/utils/colors.ts                |   78 +-
 packages/website/ts/utils/configs.ts               |  230 +-
 packages/website/ts/utils/constants.ts             |  164 +-
 packages/website/ts/utils/doc_utils.ts             |   84 +-
 packages/website/ts/utils/doxity_utils.ts          |  316 +--
 packages/website/ts/utils/error_reporter.ts        |   74 +-
 packages/website/ts/utils/mui_theme.ts             |   60 +-
 packages/website/ts/utils/typedoc_utils.ts         |  678 +++---
 packages/website/ts/utils/utils.ts                 |  522 ++---
 packages/website/ts/web3_wrapper.ts                |  288 +--
 packages/website/tsconfig.json                     |   30 +-
 packages/website/tslint.json                       |   14 +-
 tsconfig.json                                      |   22 +-
 379 files changed, 34296 insertions(+), 34296 deletions(-)

diff --git a/lerna.json b/lerna.json
index 8ca0b0883..be294216a 100644
--- a/lerna.json
+++ b/lerna.json
@@ -1,7 +1,7 @@
 {
-	"lerna": "2.5.1",
-	"packages": ["packages/*"],
-	"version": "independent",
-	"npmClient": "yarn",
-	"useWorkspaces": true
+    "lerna": "2.5.1",
+    "packages": ["packages/*"],
+    "version": "independent",
+    "npmClient": "yarn",
+    "useWorkspaces": true
 }
diff --git a/package.json b/package.json
index 77dc32828..435920d2c 100644
--- a/package.json
+++ b/package.json
@@ -1,26 +1,26 @@
 {
-	"private": true,
-	"name": "0x.js",
-	"workspaces": ["packages/*"],
-	"scripts": {
-		"testrpc": "testrpc -p 8545 --networkId 50 -m \"${npm_package_config_mnemonic}\"",
-		"prettier": "prettier --write '**/*.{ts,tsx,json,md}'",
-		"prettier:ci": "prettier --list-different '**/*.{ts,tsx,json,md}'",
-		"lerna:run": "lerna run",
-		"lerna:rebuild": "lerna run clean; lerna run build;",
-		"lerna:publish":
-			"yarn install; lerna run clean; lerna run build; lerna publish --registry=https://registry.npmjs.org/"
-	},
-	"config": {
-		"mnemonic": "concert load couple harbor equip island argue ramp clarify fence smart topic"
-	},
-	"devDependencies": {
-		"@0xproject/utils": "^0.2.0",
-		"async-child-process": "^1.1.1",
-		"ethereumjs-testrpc": "^6.0.3",
-		"lerna": "^2.5.1",
-		"prettier": "1.9.2",
-		"publish-release": "0xproject/publish-release",
-		"semver-sort": "^0.0.4"
-	}
+    "private": true,
+    "name": "0x.js",
+    "workspaces": ["packages/*"],
+    "scripts": {
+        "testrpc": "testrpc -p 8545 --networkId 50 -m \"${npm_package_config_mnemonic}\"",
+        "prettier": "prettier --write '**/*.{ts,tsx,json,md}' --config .prettierrc",
+        "prettier:ci": "prettier --list-different '**/*.{ts,tsx,json,md}' --config .prettierrc",
+        "lerna:run": "lerna run",
+        "lerna:rebuild": "lerna run clean; lerna run build;",
+        "lerna:publish":
+            "yarn install; lerna run clean; lerna run build; lerna publish --registry=https://registry.npmjs.org/"
+    },
+    "config": {
+        "mnemonic": "concert load couple harbor equip island argue ramp clarify fence smart topic"
+    },
+    "devDependencies": {
+        "@0xproject/utils": "^0.2.0",
+        "async-child-process": "^1.1.1",
+        "ethereumjs-testrpc": "^6.0.3",
+        "lerna": "^2.5.1",
+        "prettier": "1.9.2",
+        "publish-release": "0xproject/publish-release",
+        "semver-sort": "^0.0.4"
+    }
 }
diff --git a/packages/0x.js/package.json b/packages/0x.js/package.json
index 67d6452b5..465a2a753 100644
--- a/packages/0x.js/package.json
+++ b/packages/0x.js/package.json
@@ -1,94 +1,94 @@
 {
-	"name": "0x.js",
-	"version": "0.30.2",
-	"description": "A javascript library for interacting with the 0x protocol",
-	"keywords": ["0x.js", "0xproject", "ethereum", "tokens", "exchange"],
-	"main": "lib/src/index.js",
-	"types": "lib/src/index.d.ts",
-	"scripts": {
-		"prebuild": "run-s clean generate_contract_wrappers",
-		"build": "run-p build:umd:prod build:commonjs; exit 0;",
-		"docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --json $JSON_FILE_PATH $PROJECT_DIR",
-		"upload_docs_json":
-			"aws s3 cp generated_docs/index.json $S3_URL --profile 0xproject --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --content-type application/json",
-		"generate_contract_wrappers":
-			"node ../abi-gen/lib/index.js --abiGlob 'src/artifacts/@(Exchange|Token|TokenTransferProxy|EtherToken|TokenRegistry|DummyToken).json' --templates contract_templates --output src/contract_wrappers/generated",
-		"lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'",
-		"test:circleci": "run-s test:coverage report_test_coverage",
-		"test": "run-s clean test:commonjs",
-		"test:coverage": "nyc npm run test --all",
-		"report_test_coverage": "nyc report --reporter=text-lcov | coveralls",
-		"update_contracts":
-			"for i in ${npm_package_config_artifacts}; do copyfiles -u 4 ../contracts/build/contracts/$i.json ../0x.js/src/artifacts; done;",
-		"clean": "shx rm -rf _bundles lib test_temp",
-		"build:umd:prod": "NODE_ENV=production webpack",
-		"build:commonjs": "tsc && copyfiles -u 2 './src/artifacts/**/*.json' ./lib/src/artifacts;",
-		"test:commonjs": "run-s build:commonjs run_mocha",
-		"run_mocha": "mocha lib/test/**/*_test.js --timeout 10000 --bail --exit"
-	},
-	"config": {
-		"artifacts": "TokenTransferProxy Exchange TokenRegistry Token EtherToken"
-	},
-	"repository": {
-		"type": "git",
-		"url": "https://github.com/0xProject/0x.js"
-	},
-	"license": "Apache-2.0",
-	"engines": {
-		"node": ">=6.0.0"
-	},
-	"devDependencies": {
-		"@0xproject/abi-gen": "^0.1.4",
-		"@0xproject/dev-utils": "^0.0.7",
-		"@0xproject/tslint-config": "^0.4.4",
-		"@types/bintrees": "^1.0.2",
-		"@types/jsonschema": "^1.1.1",
-		"@types/lodash": "^4.14.86",
-		"@types/mocha": "^2.2.42",
-		"@types/node": "^8.0.53",
-		"@types/sinon": "^2.2.2",
-		"@types/uuid": "^3.4.2",
-		"awesome-typescript-loader": "^3.1.3",
-		"chai": "^4.0.1",
-		"chai-as-promised": "^7.1.0",
-		"chai-as-promised-typescript-typings": "^0.0.6",
-		"chai-bignumber": "^2.0.1",
-		"chai-typescript-typings": "^0.0.2",
-		"copyfiles": "^1.2.0",
-		"coveralls": "^3.0.0",
-		"dirty-chai": "^2.0.1",
-		"json-loader": "^0.5.4",
-		"mocha": "^4.0.1",
-		"npm-run-all": "^4.1.2",
-		"nyc": "^11.0.1",
-		"opn-cli": "^3.1.0",
-		"request": "^2.81.0",
-		"request-promise-native": "^1.0.4",
-		"shx": "^0.2.2",
-		"sinon": "^4.0.0",
-		"source-map-support": "^0.5.0",
-		"truffle-hdwallet-provider": "^0.0.3",
-		"tslint": "5.8.0",
-		"typedoc": "~0.8.0",
-		"typescript": "~2.6.1",
-		"web3-provider-engine": "^13.0.1",
-		"web3-typescript-typings": "^0.9.6",
-		"webpack": "^3.1.0"
-	},
-	"dependencies": {
-		"@0xproject/assert": "^0.0.13",
-		"@0xproject/json-schemas": "^0.7.5",
-		"@0xproject/types": "^0.1.6",
-		"@0xproject/utils": "^0.2.2",
-		"@0xproject/web3-wrapper": "^0.1.7",
-		"bintrees": "^1.0.2",
-		"bn.js": "^4.11.8",
-		"ethereumjs-abi": "^0.6.4",
-		"ethereumjs-blockstream": "^2.0.6",
-		"ethereumjs-util": "^5.1.1",
-		"js-sha3": "^0.6.1",
-		"lodash": "^4.17.4",
-		"uuid": "^3.1.0",
-		"web3": "^0.20.0"
-	}
+    "name": "0x.js",
+    "version": "0.30.2",
+    "description": "A javascript library for interacting with the 0x protocol",
+    "keywords": ["0x.js", "0xproject", "ethereum", "tokens", "exchange"],
+    "main": "lib/src/index.js",
+    "types": "lib/src/index.d.ts",
+    "scripts": {
+        "prebuild": "run-s clean generate_contract_wrappers",
+        "build": "run-p build:umd:prod build:commonjs; exit 0;",
+        "docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --json $JSON_FILE_PATH $PROJECT_DIR",
+        "upload_docs_json":
+            "aws s3 cp generated_docs/index.json $S3_URL --profile 0xproject --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --content-type application/json",
+        "generate_contract_wrappers":
+            "node ../abi-gen/lib/index.js --abiGlob 'src/artifacts/@(Exchange|Token|TokenTransferProxy|EtherToken|TokenRegistry|DummyToken).json' --templates contract_templates --output src/contract_wrappers/generated",
+        "lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'",
+        "test:circleci": "run-s test:coverage report_test_coverage",
+        "test": "run-s clean test:commonjs",
+        "test:coverage": "nyc npm run test --all",
+        "report_test_coverage": "nyc report --reporter=text-lcov | coveralls",
+        "update_contracts":
+            "for i in ${npm_package_config_artifacts}; do copyfiles -u 4 ../contracts/build/contracts/$i.json ../0x.js/src/artifacts; done;",
+        "clean": "shx rm -rf _bundles lib test_temp",
+        "build:umd:prod": "NODE_ENV=production webpack",
+        "build:commonjs": "tsc && copyfiles -u 2 './src/artifacts/**/*.json' ./lib/src/artifacts;",
+        "test:commonjs": "run-s build:commonjs run_mocha",
+        "run_mocha": "mocha lib/test/**/*_test.js --timeout 10000 --bail --exit"
+    },
+    "config": {
+        "artifacts": "TokenTransferProxy Exchange TokenRegistry Token EtherToken"
+    },
+    "repository": {
+        "type": "git",
+        "url": "https://github.com/0xProject/0x.js"
+    },
+    "license": "Apache-2.0",
+    "engines": {
+        "node": ">=6.0.0"
+    },
+    "devDependencies": {
+        "@0xproject/abi-gen": "^0.1.4",
+        "@0xproject/dev-utils": "^0.0.7",
+        "@0xproject/tslint-config": "^0.4.4",
+        "@types/bintrees": "^1.0.2",
+        "@types/jsonschema": "^1.1.1",
+        "@types/lodash": "^4.14.86",
+        "@types/mocha": "^2.2.42",
+        "@types/node": "^8.0.53",
+        "@types/sinon": "^2.2.2",
+        "@types/uuid": "^3.4.2",
+        "awesome-typescript-loader": "^3.1.3",
+        "chai": "^4.0.1",
+        "chai-as-promised": "^7.1.0",
+        "chai-as-promised-typescript-typings": "^0.0.6",
+        "chai-bignumber": "^2.0.1",
+        "chai-typescript-typings": "^0.0.2",
+        "copyfiles": "^1.2.0",
+        "coveralls": "^3.0.0",
+        "dirty-chai": "^2.0.1",
+        "json-loader": "^0.5.4",
+        "mocha": "^4.0.1",
+        "npm-run-all": "^4.1.2",
+        "nyc": "^11.0.1",
+        "opn-cli": "^3.1.0",
+        "request": "^2.81.0",
+        "request-promise-native": "^1.0.4",
+        "shx": "^0.2.2",
+        "sinon": "^4.0.0",
+        "source-map-support": "^0.5.0",
+        "truffle-hdwallet-provider": "^0.0.3",
+        "tslint": "5.8.0",
+        "typedoc": "~0.8.0",
+        "typescript": "~2.6.1",
+        "web3-provider-engine": "^13.0.1",
+        "web3-typescript-typings": "^0.9.6",
+        "webpack": "^3.1.0"
+    },
+    "dependencies": {
+        "@0xproject/assert": "^0.0.13",
+        "@0xproject/json-schemas": "^0.7.5",
+        "@0xproject/types": "^0.1.6",
+        "@0xproject/utils": "^0.2.2",
+        "@0xproject/web3-wrapper": "^0.1.7",
+        "bintrees": "^1.0.2",
+        "bn.js": "^4.11.8",
+        "ethereumjs-abi": "^0.6.4",
+        "ethereumjs-blockstream": "^2.0.6",
+        "ethereumjs-util": "^5.1.1",
+        "js-sha3": "^0.6.1",
+        "lodash": "^4.17.4",
+        "uuid": "^3.1.0",
+        "web3": "^0.20.0"
+    }
 }
diff --git a/packages/0x.js/src/0x.ts b/packages/0x.js/src/0x.ts
index dec26e3eb..f8a484c5d 100644
--- a/packages/0x.js/src/0x.ts
+++ b/packages/0x.js/src/0x.ts
@@ -13,13 +13,13 @@ import { TokenWrapper } from './contract_wrappers/token_wrapper';
 import { OrderStateWatcher } from './order_watcher/order_state_watcher';
 import { zeroExConfigSchema } from './schemas/zero_ex_config_schema';
 import {
-	ECSignature,
-	Order,
-	SignedOrder,
-	TransactionReceiptWithDecodedLogs,
-	Web3Provider,
-	ZeroExConfig,
-	ZeroExError,
+    ECSignature,
+    Order,
+    SignedOrder,
+    TransactionReceiptWithDecodedLogs,
+    Web3Provider,
+    ZeroExConfig,
+    ZeroExError,
 } from './types';
 import { AbiDecoder } from './utils/abi_decoder';
 import { assert } from './utils/assert';
@@ -33,318 +33,318 @@ import { utils } from './utils/utils';
  * 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;
+    /**
+     * 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);
+    /**
+     * 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.isValidBaseUnitAmount('amount', amount);
-		assert.isNumber('decimals', decimals);
+        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.isValidBaseUnitAmount('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 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);
-		const hasDecimals = baseUnitAmount.decimalPlaces() !== 0;
-		if (hasDecimals) {
-			throw new Error(`Invalid unit amount: ${amount.toString()} - Too many decimal places`);
-		}
-		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.
-	 */
-	@decorators.syncZeroExErrorHandler
-	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);
-		assert.doesConformToSchema('config', config, zeroExConfigSchema);
-		const artifactJSONs = _.values(artifacts);
-		const abiArrays = _.map(artifactJSONs, artifact => artifact.abi);
-		this._abiDecoder = new AbiDecoder(abiArrays);
-		const defaults = {
-			gasPrice: config.gasPrice,
-		};
-		this._web3Wrapper = new Web3Wrapper(provider, defaults);
-		this.proxy = new TokenTransferProxyWrapper(
-			this._web3Wrapper,
-			config.networkId,
-			config.tokenTransferProxyContractAddress,
-		);
-		this.token = new TokenWrapper(this._web3Wrapper, config.networkId, this._abiDecoder, this.proxy);
-		this.exchange = new ExchangeWrapper(
-			this._web3Wrapper,
-			config.networkId,
-			this._abiDecoder,
-			this.token,
-			config.exchangeContractAddress,
-			config.zrxContractAddress,
-		);
-		this.tokenRegistry = new TokenRegistryWrapper(
-			this._web3Wrapper,
-			config.networkId,
-			config.tokenRegistryContractAddress,
-		);
-		this.etherToken = new EtherTokenWrapper(this._web3Wrapper, config.networkId, this._abiDecoder, this.token);
-		this.orderStateWatcher = new OrderStateWatcher(
-			this._web3Wrapper,
-			this._abiDecoder,
-			this.token,
-			this.exchange,
-			config.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.
-	 * @param   networkId   The id of the network your provider is connected to
-	 */
-	public setProvider(provider: Web3Provider, networkId: number): void {
-		this._web3Wrapper.setProvider(provider);
-		(this.exchange as any)._invalidateContractInstances();
-		(this.exchange as any)._setNetworkId(networkId);
-		(this.tokenRegistry as any)._invalidateContractInstance();
-		(this.tokenRegistry as any)._setNetworkId(networkId);
-		(this.token as any)._invalidateContractInstances();
-		(this.token as any)._setNetworkId(networkId);
-		(this.proxy as any)._invalidateContractInstance();
-		(this.proxy as any)._setNetworkId(networkId);
-		(this.etherToken as any)._invalidateContractInstance();
-		(this.etherToken as any)._setNetworkId(networkId);
-	}
-	/**
-	 * 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<string[]> {
-		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.
-	 * @param   shouldAddPersonalMessagePrefix  Some signers add the personal message prefix `\x19Ethereum Signed Message`
-	 *          themselves (e.g Parity Signer, Ledger, TestRPC) and others expect it to already be done by the client
-	 *          (e.g Metamask). Depending on which signer this request is going to, decide on whether to add the prefix
-	 *          before sending the request.
-	 * @return  An object containing the Elliptic curve signature parameters generated by signing the orderHash.
-	 */
-	public async signOrderHashAsync(
-		orderHash: string,
-		signerAddress: string,
-		shouldAddPersonalMessagePrefix: boolean,
-	): Promise<ECSignature> {
-		assert.isHexString('orderHash', orderHash);
-		await assert.isSenderAddressAsync('signerAddress', signerAddress, this._web3Wrapper);
+        const unit = new BigNumber(10).pow(decimals);
+        const baseUnitAmount = amount.times(unit);
+        const hasDecimals = baseUnitAmount.decimalPlaces() !== 0;
+        if (hasDecimals) {
+            throw new Error(`Invalid unit amount: ${amount.toString()} - Too many decimal places`);
+        }
+        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.
+     */
+    @decorators.syncZeroExErrorHandler
+    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);
+        assert.doesConformToSchema('config', config, zeroExConfigSchema);
+        const artifactJSONs = _.values(artifacts);
+        const abiArrays = _.map(artifactJSONs, artifact => artifact.abi);
+        this._abiDecoder = new AbiDecoder(abiArrays);
+        const defaults = {
+            gasPrice: config.gasPrice,
+        };
+        this._web3Wrapper = new Web3Wrapper(provider, defaults);
+        this.proxy = new TokenTransferProxyWrapper(
+            this._web3Wrapper,
+            config.networkId,
+            config.tokenTransferProxyContractAddress,
+        );
+        this.token = new TokenWrapper(this._web3Wrapper, config.networkId, this._abiDecoder, this.proxy);
+        this.exchange = new ExchangeWrapper(
+            this._web3Wrapper,
+            config.networkId,
+            this._abiDecoder,
+            this.token,
+            config.exchangeContractAddress,
+            config.zrxContractAddress,
+        );
+        this.tokenRegistry = new TokenRegistryWrapper(
+            this._web3Wrapper,
+            config.networkId,
+            config.tokenRegistryContractAddress,
+        );
+        this.etherToken = new EtherTokenWrapper(this._web3Wrapper, config.networkId, this._abiDecoder, this.token);
+        this.orderStateWatcher = new OrderStateWatcher(
+            this._web3Wrapper,
+            this._abiDecoder,
+            this.token,
+            this.exchange,
+            config.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.
+     * @param   networkId   The id of the network your provider is connected to
+     */
+    public setProvider(provider: Web3Provider, networkId: number): void {
+        this._web3Wrapper.setProvider(provider);
+        (this.exchange as any)._invalidateContractInstances();
+        (this.exchange as any)._setNetworkId(networkId);
+        (this.tokenRegistry as any)._invalidateContractInstance();
+        (this.tokenRegistry as any)._setNetworkId(networkId);
+        (this.token as any)._invalidateContractInstances();
+        (this.token as any)._setNetworkId(networkId);
+        (this.proxy as any)._invalidateContractInstance();
+        (this.proxy as any)._setNetworkId(networkId);
+        (this.etherToken as any)._invalidateContractInstance();
+        (this.etherToken as any)._setNetworkId(networkId);
+    }
+    /**
+     * 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<string[]> {
+        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.
+     * @param   shouldAddPersonalMessagePrefix  Some signers add the personal message prefix `\x19Ethereum Signed Message`
+     *          themselves (e.g Parity Signer, Ledger, TestRPC) and others expect it to already be done by the client
+     *          (e.g Metamask). Depending on which signer this request is going to, decide on whether to add the prefix
+     *          before sending the request.
+     * @return  An object containing the Elliptic curve signature parameters generated by signing the orderHash.
+     */
+    public async signOrderHashAsync(
+        orderHash: string,
+        signerAddress: string,
+        shouldAddPersonalMessagePrefix: boolean,
+    ): Promise<ECSignature> {
+        assert.isHexString('orderHash', orderHash);
+        await assert.isSenderAddressAsync('signerAddress', signerAddress, this._web3Wrapper);
 
-		let msgHashHex = orderHash;
-		if (shouldAddPersonalMessagePrefix) {
-			const orderHashBuff = ethUtil.toBuffer(orderHash);
-			const msgHashBuff = ethUtil.hashPersonalMessage(orderHashBuff);
-			msgHashHex = ethUtil.bufferToHex(msgHashBuff);
-		}
+        let msgHashHex = orderHash;
+        if (shouldAddPersonalMessagePrefix) {
+            const orderHashBuff = ethUtil.toBuffer(orderHash);
+            const msgHashBuff = ethUtil.hashPersonalMessage(orderHashBuff);
+            msgHashHex = ethUtil.bufferToHex(msgHashBuff);
+        }
 
-		const signature = await this._web3Wrapper.signTransactionAsync(signerAddress, msgHashHex);
+        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;
-			}
-		}
+        // 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;
-			}
-		}
+        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<TransactionReceiptWithDecodedLogs> {
-		let timeoutExceeded = false;
-		if (timeoutMs) {
-			setTimeout(() => (timeoutExceeded = true), timeoutMs);
-		}
+        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<TransactionReceiptWithDecodedLogs> {
+        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 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,
-					(err: Error) => {
-						intervalUtils.clearAsyncExcludingInterval(intervalId);
-						reject(err);
-					},
-				);
-			},
-		);
+                        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,
+                    (err: Error) => {
+                        intervalUtils.clearAsyncExcludingInterval(intervalId);
+                        reject(err);
+                    },
+                );
+            },
+        );
 
-		return txReceiptPromise;
-	}
-	/*
+        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<string> {
-		const tokenTransferProxyAddress = await (this.exchange as any)._getTokenTransferProxyAddressAsync();
-		return tokenTransferProxyAddress;
-	}
+    private async _getTokenTransferProxyAddressAsync(): Promise<string> {
+        const tokenTransferProxyAddress = await (this.exchange as any)._getTokenTransferProxyAddressAsync();
+        return tokenTransferProxyAddress;
+    }
 }
diff --git a/packages/0x.js/src/artifacts.ts b/packages/0x.js/src/artifacts.ts
index 7d4bd6757..cbacd7d56 100644
--- a/packages/0x.js/src/artifacts.ts
+++ b/packages/0x.js/src/artifacts.ts
@@ -8,11 +8,11 @@ import * as ZRXArtifact from './artifacts/ZRX.json';
 import { Artifact } from './types';
 
 export const artifacts = {
-	ZRXArtifact: (ZRXArtifact as any) as Artifact,
-	DummyTokenArtifact: (DummyTokenArtifact as any) as Artifact,
-	TokenArtifact: (TokenArtifact as any) as Artifact,
-	ExchangeArtifact: (ExchangeArtifact as any) as Artifact,
-	EtherTokenArtifact: (EtherTokenArtifact as any) as Artifact,
-	TokenRegistryArtifact: (TokenRegistryArtifact as any) as Artifact,
-	TokenTransferProxyArtifact: (TokenTransferProxyArtifact as any) as Artifact,
+    ZRXArtifact: (ZRXArtifact as any) as Artifact,
+    DummyTokenArtifact: (DummyTokenArtifact as any) as Artifact,
+    TokenArtifact: (TokenArtifact as any) as Artifact,
+    ExchangeArtifact: (ExchangeArtifact as any) as Artifact,
+    EtherTokenArtifact: (EtherTokenArtifact as any) as Artifact,
+    TokenRegistryArtifact: (TokenRegistryArtifact as any) as Artifact,
+    TokenTransferProxyArtifact: (TokenTransferProxyArtifact as any) as Artifact,
 };
diff --git a/packages/0x.js/src/artifacts/DummyToken.json b/packages/0x.js/src/artifacts/DummyToken.json
index f96d63c21..f64a8cd3d 100644
--- a/packages/0x.js/src/artifacts/DummyToken.json
+++ b/packages/0x.js/src/artifacts/DummyToken.json
@@ -1,22 +1,22 @@
 {
-	"contract_name": "DummyToken",
-	"abi": [
-		{
-			"constant": false,
-			"inputs": [
-				{
-					"name": "_target",
-					"type": "address"
-				},
-				{
-					"name": "_value",
-					"type": "uint256"
-				}
-			],
-			"name": "setBalance",
-			"outputs": [],
-			"payable": false,
-			"type": "function"
-		}
-	]
+    "contract_name": "DummyToken",
+    "abi": [
+        {
+            "constant": false,
+            "inputs": [
+                {
+                    "name": "_target",
+                    "type": "address"
+                },
+                {
+                    "name": "_value",
+                    "type": "uint256"
+                }
+            ],
+            "name": "setBalance",
+            "outputs": [],
+            "payable": false,
+            "type": "function"
+        }
+    ]
 }
diff --git a/packages/0x.js/src/artifacts/EtherToken.json b/packages/0x.js/src/artifacts/EtherToken.json
index ca5f9c035..26cca57cd 100644
--- a/packages/0x.js/src/artifacts/EtherToken.json
+++ b/packages/0x.js/src/artifacts/EtherToken.json
@@ -1,287 +1,287 @@
 {
-	"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"
-		},
-		{
-			"anonymous": false,
-			"inputs": [
-				{
-					"indexed": true,
-					"name": "_owner",
-					"type": "address"
-				},
-				{
-					"indexed": false,
-					"name": "_value",
-					"type": "uint256"
-				}
-			],
-			"name": "Deposit",
-			"type": "event"
-		},
-		{
-			"anonymous": false,
-			"inputs": [
-				{
-					"indexed": true,
-					"name": "_owner",
-					"type": "address"
-				},
-				{
-					"indexed": false,
-					"name": "_value",
-					"type": "uint256"
-				}
-			],
-			"name": "Withdrawal",
-			"type": "event"
-		}
-	],
-	"networks": {
-		"1": {
-			"address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
-		},
-		"3": {
-			"address": "0xc00fd9820cd2898cc4c054b7bf142de637ad129a"
-		},
-		"4": {
-			"address": "0xc778417e063141139fce010982780140aa0cd5ab"
-		},
-		"42": {
-			"address": "0x653e49e301e508a13237c0ddc98ae7d4cd2667a1"
-		},
-		"50": {
-			"address": "0x871dd7c2b4b25e1aa18728e9d5f2af4c4e431f5c"
-		}
-	}
+    "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"
+        },
+        {
+            "anonymous": false,
+            "inputs": [
+                {
+                    "indexed": true,
+                    "name": "_owner",
+                    "type": "address"
+                },
+                {
+                    "indexed": false,
+                    "name": "_value",
+                    "type": "uint256"
+                }
+            ],
+            "name": "Deposit",
+            "type": "event"
+        },
+        {
+            "anonymous": false,
+            "inputs": [
+                {
+                    "indexed": true,
+                    "name": "_owner",
+                    "type": "address"
+                },
+                {
+                    "indexed": false,
+                    "name": "_value",
+                    "type": "uint256"
+                }
+            ],
+            "name": "Withdrawal",
+            "type": "event"
+        }
+    ],
+    "networks": {
+        "1": {
+            "address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
+        },
+        "3": {
+            "address": "0xc00fd9820cd2898cc4c054b7bf142de637ad129a"
+        },
+        "4": {
+            "address": "0xc778417e063141139fce010982780140aa0cd5ab"
+        },
+        "42": {
+            "address": "0x653e49e301e508a13237c0ddc98ae7d4cd2667a1"
+        },
+        "50": {
+            "address": "0x871dd7c2b4b25e1aa18728e9d5f2af4c4e431f5c"
+        }
+    }
 }
diff --git a/packages/0x.js/src/artifacts/Exchange.json b/packages/0x.js/src/artifacts/Exchange.json
index 44bb41d4d..af8db7360 100644
--- a/packages/0x.js/src/artifacts/Exchange.json
+++ b/packages/0x.js/src/artifacts/Exchange.json
@@ -1,610 +1,610 @@
 {
-	"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"
-		}
-	],
-	"networks": {
-		"1": {
-			"address": "0x12459c951127e0c374ff9105dda097662a027093"
-		},
-		"3": {
-			"address": "0x479cc461fecd078f766ecc58533d6f69580cf3ac"
-		},
-		"4": {
-			"address": "0x1d16ef40fac01cec8adac2ac49427b9384192c05"
-		},
-		"42": {
-			"address": "0x90fe2af704b34e0224bf2299c838e04d4dcf1364"
-		},
-		"50": {
-			"address": "0x48bacb9266a570d521063ef5dd96e61686dbe788"
-		}
-	}
+    "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"
+        }
+    ],
+    "networks": {
+        "1": {
+            "address": "0x12459c951127e0c374ff9105dda097662a027093"
+        },
+        "3": {
+            "address": "0x479cc461fecd078f766ecc58533d6f69580cf3ac"
+        },
+        "4": {
+            "address": "0x1d16ef40fac01cec8adac2ac49427b9384192c05"
+        },
+        "42": {
+            "address": "0x90fe2af704b34e0224bf2299c838e04d4dcf1364"
+        },
+        "50": {
+            "address": "0x48bacb9266a570d521063ef5dd96e61686dbe788"
+        }
+    }
 }
diff --git a/packages/0x.js/src/artifacts/Token.json b/packages/0x.js/src/artifacts/Token.json
index bd4208275..3b5a86ae0 100644
--- a/packages/0x.js/src/artifacts/Token.json
+++ b/packages/0x.js/src/artifacts/Token.json
@@ -1,172 +1,172 @@
 {
-	"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"
-		}
-	]
+    "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"
+        }
+    ]
 }
diff --git a/packages/0x.js/src/artifacts/TokenRegistry.json b/packages/0x.js/src/artifacts/TokenRegistry.json
index 490ea0c34..0f583628c 100644
--- a/packages/0x.js/src/artifacts/TokenRegistry.json
+++ b/packages/0x.js/src/artifacts/TokenRegistry.json
@@ -1,547 +1,547 @@
 {
-	"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"
-		}
-	],
-	"networks": {
-		"1": {
-			"address": "0x926a74c5c36adf004c87399e65f75628b0f98d2c"
-		},
-		"3": {
-			"address": "0x6b1a50f0bb5a7995444bd3877b22dc89c62843ed"
-		},
-		"4": {
-			"address": "0x4e9aad8184de8833365fea970cd9149372fdf1e6"
-		},
-		"42": {
-			"address": "0xf18e504561f4347bea557f3d4558f559dddbae7f"
-		},
-		"50": {
-			"address": "0x0b1ba0af832d7c05fd64161e0db78e85978e8082"
-		}
-	}
+    "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"
+        }
+    ],
+    "networks": {
+        "1": {
+            "address": "0x926a74c5c36adf004c87399e65f75628b0f98d2c"
+        },
+        "3": {
+            "address": "0x6b1a50f0bb5a7995444bd3877b22dc89c62843ed"
+        },
+        "4": {
+            "address": "0x4e9aad8184de8833365fea970cd9149372fdf1e6"
+        },
+        "42": {
+            "address": "0xf18e504561f4347bea557f3d4558f559dddbae7f"
+        },
+        "50": {
+            "address": "0x0b1ba0af832d7c05fd64161e0db78e85978e8082"
+        }
+    }
 }
diff --git a/packages/0x.js/src/artifacts/TokenTransferProxy.json b/packages/0x.js/src/artifacts/TokenTransferProxy.json
index 5e45e4903..8cf551ddb 100644
--- a/packages/0x.js/src/artifacts/TokenTransferProxy.json
+++ b/packages/0x.js/src/artifacts/TokenTransferProxy.json
@@ -1,187 +1,187 @@
 {
-	"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"
-		}
-	],
-	"networks": {
-		"1": {
-			"address": "0x8da0d80f5007ef1e431dd2127178d224e32c2ef4"
-		},
-		"3": {
-			"address": "0x4e9aad8184de8833365fea970cd9149372fdf1e6"
-		},
-		"4": {
-			"address": "0xa8e9fa8f91e5ae138c74648c9c304f1c75003a8d"
-		},
-		"42": {
-			"address": "0x087eed4bc1ee3de49befbd66c662b434b15d49d4"
-		},
-		"50": {
-			"address": "0x1dc4c1cefef38a777b15aa20260a54e584b16c48"
-		}
-	}
+    "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"
+        }
+    ],
+    "networks": {
+        "1": {
+            "address": "0x8da0d80f5007ef1e431dd2127178d224e32c2ef4"
+        },
+        "3": {
+            "address": "0x4e9aad8184de8833365fea970cd9149372fdf1e6"
+        },
+        "4": {
+            "address": "0xa8e9fa8f91e5ae138c74648c9c304f1c75003a8d"
+        },
+        "42": {
+            "address": "0x087eed4bc1ee3de49befbd66c662b434b15d49d4"
+        },
+        "50": {
+            "address": "0x1dc4c1cefef38a777b15aa20260a54e584b16c48"
+        }
+    }
 }
diff --git a/packages/0x.js/src/artifacts/ZRX.json b/packages/0x.js/src/artifacts/ZRX.json
index 44f478ab4..e40b8f268 100644
--- a/packages/0x.js/src/artifacts/ZRX.json
+++ b/packages/0x.js/src/artifacts/ZRX.json
@@ -1,20 +1,20 @@
 {
-	"contract_name": "ZRX",
-	"networks": {
-		"1": {
-			"address": "0xe41d2489571d322189246dafa5ebde1f4699f498"
-		},
-		"3": {
-			"address": "0xa8e9fa8f91e5ae138c74648c9c304f1c75003a8d"
-		},
-		"4": {
-			"address": "0x00f58d6d585f84b2d7267940cede30ce2fe6eae8"
-		},
-		"42": {
-			"address": "0x6ff6c0ff1d68b964901f986d4c9fa3ac68346570"
-		},
-		"50": {
-			"address": "0x1d7022f5b17d2f8b695918fb48fa1089c9f85401"
-		}
-	}
+    "contract_name": "ZRX",
+    "networks": {
+        "1": {
+            "address": "0xe41d2489571d322189246dafa5ebde1f4699f498"
+        },
+        "3": {
+            "address": "0xa8e9fa8f91e5ae138c74648c9c304f1c75003a8d"
+        },
+        "4": {
+            "address": "0x00f58d6d585f84b2d7267940cede30ce2fe6eae8"
+        },
+        "42": {
+            "address": "0x6ff6c0ff1d68b964901f986d4c9fa3ac68346570"
+        },
+        "50": {
+            "address": "0x1d7022f5b17d2f8b695918fb48fa1089c9f85401"
+        }
+    }
 }
diff --git a/packages/0x.js/src/contract_wrappers/contract_wrapper.ts b/packages/0x.js/src/contract_wrappers/contract_wrapper.ts
index d1b753f45..27551c01d 100644
--- a/packages/0x.js/src/contract_wrappers/contract_wrapper.ts
+++ b/packages/0x.js/src/contract_wrappers/contract_wrapper.ts
@@ -5,203 +5,203 @@ import * as _ from 'lodash';
 import * as Web3 from 'web3';
 
 import {
-	Artifact,
-	BlockParamLiteral,
-	BlockRange,
-	ContractEventArgs,
-	ContractEvents,
-	EventCallback,
-	IndexedFilterValues,
-	InternalZeroExError,
-	LogWithDecodedArgs,
-	RawLog,
-	ZeroExError,
+    Artifact,
+    BlockParamLiteral,
+    BlockRange,
+    ContractEventArgs,
+    ContractEvents,
+    EventCallback,
+    IndexedFilterValues,
+    InternalZeroExError,
+    LogWithDecodedArgs,
+    RawLog,
+    ZeroExError,
 } from '../types';
 import { AbiDecoder } from '../utils/abi_decoder';
 import { constants } from '../utils/constants';
 import { filterUtils } from '../utils/filter_utils';
 
 const CONTRACT_NAME_TO_NOT_FOUND_ERROR: {
-	[contractName: string]: ZeroExError;
+    [contractName: string]: ZeroExError;
 } = {
-	ZRX: ZeroExError.ZRXContractDoesNotExist,
-	EtherToken: ZeroExError.EtherTokenContractDoesNotExist,
-	Token: ZeroExError.TokenContractDoesNotExist,
-	TokenRegistry: ZeroExError.TokenRegistryContractDoesNotExist,
-	TokenTransferProxy: ZeroExError.TokenTransferProxyContractDoesNotExist,
-	Exchange: ZeroExError.ExchangeContractDoesNotExist,
+    ZRX: ZeroExError.ZRXContractDoesNotExist,
+    EtherToken: ZeroExError.EtherTokenContractDoesNotExist,
+    Token: ZeroExError.TokenContractDoesNotExist,
+    TokenRegistry: ZeroExError.TokenRegistryContractDoesNotExist,
+    TokenTransferProxy: ZeroExError.TokenTransferProxyContractDoesNotExist,
+    Exchange: ZeroExError.ExchangeContractDoesNotExist,
 };
 
 export class ContractWrapper {
-	protected _web3Wrapper: Web3Wrapper;
-	private _networkId: number;
-	private _abiDecoder?: AbiDecoder;
-	private _blockAndLogStreamerIfExists: BlockAndLogStreamer | undefined;
-	private _blockAndLogStreamInterval: NodeJS.Timer;
-	private _filters: { [filterToken: string]: Web3.FilterObject };
-	private _filterCallbacks: {
-		[filterToken: string]: EventCallback<ContractEventArgs>;
-	};
-	private _onLogAddedSubscriptionToken: string | undefined;
-	private _onLogRemovedSubscriptionToken: string | undefined;
-	constructor(web3Wrapper: Web3Wrapper, networkId: number, abiDecoder?: AbiDecoder) {
-		this._web3Wrapper = web3Wrapper;
-		this._networkId = networkId;
-		this._abiDecoder = abiDecoder;
-		this._filters = {};
-		this._filterCallbacks = {};
-		this._blockAndLogStreamerIfExists = undefined;
-		this._onLogAddedSubscriptionToken = undefined;
-		this._onLogRemovedSubscriptionToken = undefined;
-	}
-	protected 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<ArgsType extends ContractEventArgs>(
-		address: string,
-		eventName: ContractEvents,
-		indexFilterValues: IndexedFilterValues,
-		abi: Web3.ContractAbi,
-		callback: EventCallback<ArgsType>,
-	): string {
-		const filter = filterUtils.getFilter(address, eventName, indexFilterValues, abi);
-		if (_.isUndefined(this._blockAndLogStreamerIfExists)) {
-			this._startBlockAndLogStream();
-		}
-		const filterToken = filterUtils.generateUUID();
-		this._filters[filterToken] = filter;
-		this._filterCallbacks[filterToken] = callback as EventCallback<ContractEventArgs>;
-		return filterToken;
-	}
-	protected async _getLogsAsync<ArgsType extends ContractEventArgs>(
-		address: string,
-		eventName: ContractEvents,
-		blockRange: BlockRange,
-		indexFilterValues: IndexedFilterValues,
-		abi: Web3.ContractAbi,
-	): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
-		const filter = filterUtils.getFilter(address, eventName, indexFilterValues, abi, blockRange);
-		const logs = await this._web3Wrapper.getLogsAsync(filter);
-		const logsWithDecodedArguments = _.map(logs, this._tryToDecodeLogOrNoop.bind(this));
-		return logsWithDecodedArguments;
-	}
-	protected _tryToDecodeLogOrNoop<ArgsType extends ContractEventArgs>(
-		log: Web3.LogEntry,
-	): LogWithDecodedArgs<ArgsType> | 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<Web3.ContractInstance> {
-		let contractAddress: string;
-		if (_.isUndefined(addressIfExists)) {
-			if (_.isUndefined(artifact.networks[this._networkId])) {
-				throw new Error(ZeroExError.ContractNotDeployedOnNetwork);
-			}
-			contractAddress = artifact.networks[this._networkId].address.toLowerCase();
-		} else {
-			contractAddress = addressIfExists;
-		}
-		const doesContractExist = await this._web3Wrapper.doesContractExistAtAddressAsync(contractAddress);
-		if (!doesContractExist) {
-			throw new Error(CONTRACT_NAME_TO_NOT_FOUND_ERROR[artifact.contract_name]);
-		}
-		const contractInstance = this._web3Wrapper.getContractInstance(artifact.abi, contractAddress);
-		return contractInstance;
-	}
-	protected _getContractAddress(artifact: Artifact, addressIfExists?: string): string {
-		if (_.isUndefined(addressIfExists)) {
-			const contractAddress = artifact.networks[this._networkId].address;
-			if (_.isUndefined(contractAddress)) {
-				throw new Error(ZeroExError.ExchangeContractDoesNotExist);
-			}
-			return contractAddress;
-		} else {
-			return addressIfExists;
-		}
-	}
-	private _onLogStateChanged<ArgsType extends ContractEventArgs>(isRemoved: 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<ArgsType>;
-				const logEvent = {
-					log: decodedLog,
-					isRemoved,
-				};
-				this._filterCallbacks[filterToken](null, logEvent);
-			}
-		});
-	}
-	private _startBlockAndLogStream(): void {
-		if (!_.isUndefined(this._blockAndLogStreamerIfExists)) {
-			throw new Error(ZeroExError.SubscriptionAlreadyPresent);
-		}
-		this._blockAndLogStreamerIfExists = new BlockAndLogStreamer(
-			this._web3Wrapper.getBlockAsync.bind(this._web3Wrapper),
-			this._web3Wrapper.getLogsAsync.bind(this._web3Wrapper),
-		);
-		const catchAllLogFilter = {};
-		this._blockAndLogStreamerIfExists.addLogFilter(catchAllLogFilter);
-		this._blockAndLogStreamInterval = intervalUtils.setAsyncExcludingInterval(
-			this._reconcileBlockAsync.bind(this),
-			constants.DEFAULT_BLOCK_POLLING_INTERVAL,
-			this._onReconcileBlockError.bind(this),
-		);
-		let isRemoved = false;
-		this._onLogAddedSubscriptionToken = this._blockAndLogStreamerIfExists.subscribeToOnLogAdded(
-			this._onLogStateChanged.bind(this, isRemoved),
-		);
-		isRemoved = true;
-		this._onLogRemovedSubscriptionToken = this._blockAndLogStreamerIfExists.subscribeToOnLogRemoved(
-			this._onLogStateChanged.bind(this, isRemoved),
-		);
-	}
-	private _onReconcileBlockError(err: Error): void {
-		const filterTokens = _.keys(this._filterCallbacks);
-		_.each(filterTokens, filterToken => {
-			this._unsubscribe(filterToken, err);
-		});
-	}
-	private _setNetworkId(networkId: number): void {
-		this._networkId = networkId;
-	}
-	private _stopBlockAndLogStream(): void {
-		if (_.isUndefined(this._blockAndLogStreamerIfExists)) {
-			throw new Error(ZeroExError.SubscriptionNotFound);
-		}
-		this._blockAndLogStreamerIfExists.unsubscribeFromOnLogAdded(this._onLogAddedSubscriptionToken as string);
-		this._blockAndLogStreamerIfExists.unsubscribeFromOnLogRemoved(this._onLogRemovedSubscriptionToken as string);
-		intervalUtils.clearAsyncExcludingInterval(this._blockAndLogStreamInterval);
-		delete this._blockAndLogStreamerIfExists;
-	}
-	private async _reconcileBlockAsync(): Promise<void> {
-		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._blockAndLogStreamerIfExists)) {
-			// If we clear the interval while fetching the block - this._blockAndLogStreamer will be undefined
-			await this._blockAndLogStreamerIfExists.reconcileNewBlock((latestBlock as any) as Block);
-		}
-	}
+    protected _web3Wrapper: Web3Wrapper;
+    private _networkId: number;
+    private _abiDecoder?: AbiDecoder;
+    private _blockAndLogStreamerIfExists: BlockAndLogStreamer | undefined;
+    private _blockAndLogStreamInterval: NodeJS.Timer;
+    private _filters: { [filterToken: string]: Web3.FilterObject };
+    private _filterCallbacks: {
+        [filterToken: string]: EventCallback<ContractEventArgs>;
+    };
+    private _onLogAddedSubscriptionToken: string | undefined;
+    private _onLogRemovedSubscriptionToken: string | undefined;
+    constructor(web3Wrapper: Web3Wrapper, networkId: number, abiDecoder?: AbiDecoder) {
+        this._web3Wrapper = web3Wrapper;
+        this._networkId = networkId;
+        this._abiDecoder = abiDecoder;
+        this._filters = {};
+        this._filterCallbacks = {};
+        this._blockAndLogStreamerIfExists = undefined;
+        this._onLogAddedSubscriptionToken = undefined;
+        this._onLogRemovedSubscriptionToken = undefined;
+    }
+    protected 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<ArgsType extends ContractEventArgs>(
+        address: string,
+        eventName: ContractEvents,
+        indexFilterValues: IndexedFilterValues,
+        abi: Web3.ContractAbi,
+        callback: EventCallback<ArgsType>,
+    ): string {
+        const filter = filterUtils.getFilter(address, eventName, indexFilterValues, abi);
+        if (_.isUndefined(this._blockAndLogStreamerIfExists)) {
+            this._startBlockAndLogStream();
+        }
+        const filterToken = filterUtils.generateUUID();
+        this._filters[filterToken] = filter;
+        this._filterCallbacks[filterToken] = callback as EventCallback<ContractEventArgs>;
+        return filterToken;
+    }
+    protected async _getLogsAsync<ArgsType extends ContractEventArgs>(
+        address: string,
+        eventName: ContractEvents,
+        blockRange: BlockRange,
+        indexFilterValues: IndexedFilterValues,
+        abi: Web3.ContractAbi,
+    ): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
+        const filter = filterUtils.getFilter(address, eventName, indexFilterValues, abi, blockRange);
+        const logs = await this._web3Wrapper.getLogsAsync(filter);
+        const logsWithDecodedArguments = _.map(logs, this._tryToDecodeLogOrNoop.bind(this));
+        return logsWithDecodedArguments;
+    }
+    protected _tryToDecodeLogOrNoop<ArgsType extends ContractEventArgs>(
+        log: Web3.LogEntry,
+    ): LogWithDecodedArgs<ArgsType> | 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<Web3.ContractInstance> {
+        let contractAddress: string;
+        if (_.isUndefined(addressIfExists)) {
+            if (_.isUndefined(artifact.networks[this._networkId])) {
+                throw new Error(ZeroExError.ContractNotDeployedOnNetwork);
+            }
+            contractAddress = artifact.networks[this._networkId].address.toLowerCase();
+        } else {
+            contractAddress = addressIfExists;
+        }
+        const doesContractExist = await this._web3Wrapper.doesContractExistAtAddressAsync(contractAddress);
+        if (!doesContractExist) {
+            throw new Error(CONTRACT_NAME_TO_NOT_FOUND_ERROR[artifact.contract_name]);
+        }
+        const contractInstance = this._web3Wrapper.getContractInstance(artifact.abi, contractAddress);
+        return contractInstance;
+    }
+    protected _getContractAddress(artifact: Artifact, addressIfExists?: string): string {
+        if (_.isUndefined(addressIfExists)) {
+            const contractAddress = artifact.networks[this._networkId].address;
+            if (_.isUndefined(contractAddress)) {
+                throw new Error(ZeroExError.ExchangeContractDoesNotExist);
+            }
+            return contractAddress;
+        } else {
+            return addressIfExists;
+        }
+    }
+    private _onLogStateChanged<ArgsType extends ContractEventArgs>(isRemoved: 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<ArgsType>;
+                const logEvent = {
+                    log: decodedLog,
+                    isRemoved,
+                };
+                this._filterCallbacks[filterToken](null, logEvent);
+            }
+        });
+    }
+    private _startBlockAndLogStream(): void {
+        if (!_.isUndefined(this._blockAndLogStreamerIfExists)) {
+            throw new Error(ZeroExError.SubscriptionAlreadyPresent);
+        }
+        this._blockAndLogStreamerIfExists = new BlockAndLogStreamer(
+            this._web3Wrapper.getBlockAsync.bind(this._web3Wrapper),
+            this._web3Wrapper.getLogsAsync.bind(this._web3Wrapper),
+        );
+        const catchAllLogFilter = {};
+        this._blockAndLogStreamerIfExists.addLogFilter(catchAllLogFilter);
+        this._blockAndLogStreamInterval = intervalUtils.setAsyncExcludingInterval(
+            this._reconcileBlockAsync.bind(this),
+            constants.DEFAULT_BLOCK_POLLING_INTERVAL,
+            this._onReconcileBlockError.bind(this),
+        );
+        let isRemoved = false;
+        this._onLogAddedSubscriptionToken = this._blockAndLogStreamerIfExists.subscribeToOnLogAdded(
+            this._onLogStateChanged.bind(this, isRemoved),
+        );
+        isRemoved = true;
+        this._onLogRemovedSubscriptionToken = this._blockAndLogStreamerIfExists.subscribeToOnLogRemoved(
+            this._onLogStateChanged.bind(this, isRemoved),
+        );
+    }
+    private _onReconcileBlockError(err: Error): void {
+        const filterTokens = _.keys(this._filterCallbacks);
+        _.each(filterTokens, filterToken => {
+            this._unsubscribe(filterToken, err);
+        });
+    }
+    private _setNetworkId(networkId: number): void {
+        this._networkId = networkId;
+    }
+    private _stopBlockAndLogStream(): void {
+        if (_.isUndefined(this._blockAndLogStreamerIfExists)) {
+            throw new Error(ZeroExError.SubscriptionNotFound);
+        }
+        this._blockAndLogStreamerIfExists.unsubscribeFromOnLogAdded(this._onLogAddedSubscriptionToken as string);
+        this._blockAndLogStreamerIfExists.unsubscribeFromOnLogRemoved(this._onLogRemovedSubscriptionToken as string);
+        intervalUtils.clearAsyncExcludingInterval(this._blockAndLogStreamInterval);
+        delete this._blockAndLogStreamerIfExists;
+    }
+    private async _reconcileBlockAsync(): Promise<void> {
+        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._blockAndLogStreamerIfExists)) {
+            // If we clear the interval while fetching the block - this._blockAndLogStreamer will be undefined
+            await this._blockAndLogStreamerIfExists.reconcileNewBlock((latestBlock as any) as Block);
+        }
+    }
 }
diff --git a/packages/0x.js/src/contract_wrappers/ether_token_wrapper.ts b/packages/0x.js/src/contract_wrappers/ether_token_wrapper.ts
index d412971be..b03571636 100644
--- a/packages/0x.js/src/contract_wrappers/ether_token_wrapper.ts
+++ b/packages/0x.js/src/contract_wrappers/ether_token_wrapper.ts
@@ -5,14 +5,14 @@ import * as _ from 'lodash';
 
 import { artifacts } from '../artifacts';
 import {
-	BlockRange,
-	EtherTokenContractEventArgs,
-	EtherTokenEvents,
-	EventCallback,
-	IndexedFilterValues,
-	LogWithDecodedArgs,
-	TransactionOpts,
-	ZeroExError,
+    BlockRange,
+    EtherTokenContractEventArgs,
+    EtherTokenEvents,
+    EventCallback,
+    IndexedFilterValues,
+    LogWithDecodedArgs,
+    TransactionOpts,
+    ZeroExError,
 } from '../types';
 import { AbiDecoder } from '../utils/abi_decoder';
 import { assert } from '../utils/assert';
@@ -26,159 +26,159 @@ import { TokenWrapper } from './token_wrapper';
  * The caller can convert ETH into the equivalent number of wrapped ETH ERC20 tokens and back.
  */
 export class EtherTokenWrapper extends ContractWrapper {
-	private _etherTokenContractsByAddress: {
-		[address: string]: EtherTokenContract;
-	} = {};
-	private _tokenWrapper: TokenWrapper;
-	constructor(web3Wrapper: Web3Wrapper, networkId: number, abiDecoder: AbiDecoder, tokenWrapper: TokenWrapper) {
-		super(web3Wrapper, networkId, abiDecoder);
-		this._tokenWrapper = tokenWrapper;
-	}
-	/**
-	 * 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   etherTokenAddress   EtherToken address you wish to deposit into.
-	 * @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.
-	 * @param   txOpts              Transaction parameters.
-	 * @return Transaction hash.
-	 */
-	public async depositAsync(
-		etherTokenAddress: string,
-		amountInWei: BigNumber,
-		depositor: string,
-		txOpts: TransactionOpts = {},
-	): Promise<string> {
-		assert.isValidBaseUnitAmount('amountInWei', amountInWei);
-		await assert.isSenderAddressAsync('depositor', depositor, this._web3Wrapper);
+    private _etherTokenContractsByAddress: {
+        [address: string]: EtherTokenContract;
+    } = {};
+    private _tokenWrapper: TokenWrapper;
+    constructor(web3Wrapper: Web3Wrapper, networkId: number, abiDecoder: AbiDecoder, tokenWrapper: TokenWrapper) {
+        super(web3Wrapper, networkId, abiDecoder);
+        this._tokenWrapper = tokenWrapper;
+    }
+    /**
+     * 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   etherTokenAddress   EtherToken address you wish to deposit into.
+     * @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.
+     * @param   txOpts              Transaction parameters.
+     * @return Transaction hash.
+     */
+    public async depositAsync(
+        etherTokenAddress: string,
+        amountInWei: BigNumber,
+        depositor: string,
+        txOpts: TransactionOpts = {},
+    ): Promise<string> {
+        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 ethBalanceInWei = await this._web3Wrapper.getBalanceInWeiAsync(depositor);
+        assert.assert(ethBalanceInWei.gte(amountInWei), ZeroExError.InsufficientEthBalanceForDeposit);
 
-		const wethContract = await this._getEtherTokenContractAsync(etherTokenAddress);
-		const txHash = await wethContract.deposit.sendTransactionAsync({
-			from: depositor,
-			value: amountInWei,
-			gas: txOpts.gasLimit,
-			gasPrice: txOpts.gasPrice,
-		});
-		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   etherTokenAddress   EtherToken address you wish to withdraw from.
-	 * @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.
-	 * @param   txOpts       Transaction parameters.
-	 * @return Transaction hash.
-	 */
-	public async withdrawAsync(
-		etherTokenAddress: string,
-		amountInWei: BigNumber,
-		withdrawer: string,
-		txOpts: TransactionOpts = {},
-	): Promise<string> {
-		assert.isValidBaseUnitAmount('amountInWei', amountInWei);
-		await assert.isSenderAddressAsync('withdrawer', withdrawer, this._web3Wrapper);
+        const wethContract = await this._getEtherTokenContractAsync(etherTokenAddress);
+        const txHash = await wethContract.deposit.sendTransactionAsync({
+            from: depositor,
+            value: amountInWei,
+            gas: txOpts.gasLimit,
+            gasPrice: txOpts.gasPrice,
+        });
+        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   etherTokenAddress   EtherToken address you wish to withdraw from.
+     * @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.
+     * @param   txOpts       Transaction parameters.
+     * @return Transaction hash.
+     */
+    public async withdrawAsync(
+        etherTokenAddress: string,
+        amountInWei: BigNumber,
+        withdrawer: string,
+        txOpts: TransactionOpts = {},
+    ): Promise<string> {
+        assert.isValidBaseUnitAmount('amountInWei', amountInWei);
+        await assert.isSenderAddressAsync('withdrawer', withdrawer, this._web3Wrapper);
 
-		const WETHBalanceInBaseUnits = await this._tokenWrapper.getBalanceAsync(etherTokenAddress, withdrawer);
-		assert.assert(WETHBalanceInBaseUnits.gte(amountInWei), ZeroExError.InsufficientWEthBalanceForWithdrawal);
+        const WETHBalanceInBaseUnits = await this._tokenWrapper.getBalanceAsync(etherTokenAddress, withdrawer);
+        assert.assert(WETHBalanceInBaseUnits.gte(amountInWei), ZeroExError.InsufficientWEthBalanceForWithdrawal);
 
-		const wethContract = await this._getEtherTokenContractAsync(etherTokenAddress);
-		const txHash = await wethContract.withdraw.sendTransactionAsync(amountInWei, {
-			from: withdrawer,
-			gas: txOpts.gasLimit,
-			gasPrice: txOpts.gasPrice,
-		});
-		return txHash;
-	}
-	/**
-	 * Gets historical logs without creating a subscription
-	 * @param   etherTokenAddress   An address of the ether token that emmited the logs.
-	 * @param   eventName           The ether token contract event you would like to subscribe to.
-	 * @param   blockRange          Block range to get logs from.
-	 * @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 `{_owner: aUserAddressHex}`
-	 * @return  Array of logs that match the parameters
-	 */
-	public async getLogsAsync<ArgsType extends EtherTokenContractEventArgs>(
-		etherTokenAddress: string,
-		eventName: EtherTokenEvents,
-		blockRange: BlockRange,
-		indexFilterValues: IndexedFilterValues,
-	): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
-		assert.isETHAddressHex('etherTokenAddress', etherTokenAddress);
-		assert.doesBelongToStringEnum('eventName', eventName, EtherTokenEvents);
-		assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema);
-		assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
-		const logs = await this._getLogsAsync<ArgsType>(
-			etherTokenAddress,
-			eventName,
-			blockRange,
-			indexFilterValues,
-			artifacts.EtherTokenArtifact.abi,
-		);
-		return logs;
-	}
-	/**
-	 * Subscribe to an event type emitted by the Token contract.
-	 * @param   etherTokenAddress   The hex encoded address where the ether token is deployed.
-	 * @param   eventName           The ether 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 `{_owner: aUserAddressHex}`
-	 * @param   callback            Callback that gets called when a log is added/removed
-	 * @return Subscription token used later to unsubscribe
-	 */
-	public subscribe<ArgsType extends EtherTokenContractEventArgs>(
-		etherTokenAddress: string,
-		eventName: EtherTokenEvents,
-		indexFilterValues: IndexedFilterValues,
-		callback: EventCallback<ArgsType>,
-	): string {
-		assert.isETHAddressHex('etherTokenAddress', etherTokenAddress);
-		assert.doesBelongToStringEnum('eventName', eventName, EtherTokenEvents);
-		assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
-		assert.isFunction('callback', callback);
-		const subscriptionToken = this._subscribe<ArgsType>(
-			etherTokenAddress,
-			eventName,
-			indexFilterValues,
-			artifacts.EtherTokenArtifact.abi,
-			callback,
-		);
-		return subscriptionToken;
-	}
-	/**
-	 * Cancel a subscription
-	 * @param   subscriptionToken Subscription token returned by `subscribe()`
-	 */
-	public unsubscribe(subscriptionToken: string): void {
-		this._unsubscribe(subscriptionToken);
-	}
-	/**
-	 * Cancels all existing subscriptions
-	 */
-	public unsubscribeAll(): void {
-		super.unsubscribeAll();
-	}
-	private _invalidateContractInstance(): void {
-		this.unsubscribeAll();
-		this._etherTokenContractsByAddress = {};
-	}
-	private async _getEtherTokenContractAsync(etherTokenAddress: string): Promise<EtherTokenContract> {
-		let etherTokenContract = this._etherTokenContractsByAddress[etherTokenAddress];
-		if (!_.isUndefined(etherTokenContract)) {
-			return etherTokenContract;
-		}
-		const web3ContractInstance = await this._instantiateContractIfExistsAsync(
-			artifacts.EtherTokenArtifact,
-			etherTokenAddress,
-		);
-		const contractInstance = new EtherTokenContract(web3ContractInstance, this._web3Wrapper.getContractDefaults());
-		etherTokenContract = contractInstance;
-		this._etherTokenContractsByAddress[etherTokenAddress] = etherTokenContract;
-		return etherTokenContract;
-	}
+        const wethContract = await this._getEtherTokenContractAsync(etherTokenAddress);
+        const txHash = await wethContract.withdraw.sendTransactionAsync(amountInWei, {
+            from: withdrawer,
+            gas: txOpts.gasLimit,
+            gasPrice: txOpts.gasPrice,
+        });
+        return txHash;
+    }
+    /**
+     * Gets historical logs without creating a subscription
+     * @param   etherTokenAddress   An address of the ether token that emmited the logs.
+     * @param   eventName           The ether token contract event you would like to subscribe to.
+     * @param   blockRange          Block range to get logs from.
+     * @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 `{_owner: aUserAddressHex}`
+     * @return  Array of logs that match the parameters
+     */
+    public async getLogsAsync<ArgsType extends EtherTokenContractEventArgs>(
+        etherTokenAddress: string,
+        eventName: EtherTokenEvents,
+        blockRange: BlockRange,
+        indexFilterValues: IndexedFilterValues,
+    ): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
+        assert.isETHAddressHex('etherTokenAddress', etherTokenAddress);
+        assert.doesBelongToStringEnum('eventName', eventName, EtherTokenEvents);
+        assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema);
+        assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
+        const logs = await this._getLogsAsync<ArgsType>(
+            etherTokenAddress,
+            eventName,
+            blockRange,
+            indexFilterValues,
+            artifacts.EtherTokenArtifact.abi,
+        );
+        return logs;
+    }
+    /**
+     * Subscribe to an event type emitted by the Token contract.
+     * @param   etherTokenAddress   The hex encoded address where the ether token is deployed.
+     * @param   eventName           The ether 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 `{_owner: aUserAddressHex}`
+     * @param   callback            Callback that gets called when a log is added/removed
+     * @return Subscription token used later to unsubscribe
+     */
+    public subscribe<ArgsType extends EtherTokenContractEventArgs>(
+        etherTokenAddress: string,
+        eventName: EtherTokenEvents,
+        indexFilterValues: IndexedFilterValues,
+        callback: EventCallback<ArgsType>,
+    ): string {
+        assert.isETHAddressHex('etherTokenAddress', etherTokenAddress);
+        assert.doesBelongToStringEnum('eventName', eventName, EtherTokenEvents);
+        assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
+        assert.isFunction('callback', callback);
+        const subscriptionToken = this._subscribe<ArgsType>(
+            etherTokenAddress,
+            eventName,
+            indexFilterValues,
+            artifacts.EtherTokenArtifact.abi,
+            callback,
+        );
+        return subscriptionToken;
+    }
+    /**
+     * Cancel a subscription
+     * @param   subscriptionToken Subscription token returned by `subscribe()`
+     */
+    public unsubscribe(subscriptionToken: string): void {
+        this._unsubscribe(subscriptionToken);
+    }
+    /**
+     * Cancels all existing subscriptions
+     */
+    public unsubscribeAll(): void {
+        super.unsubscribeAll();
+    }
+    private _invalidateContractInstance(): void {
+        this.unsubscribeAll();
+        this._etherTokenContractsByAddress = {};
+    }
+    private async _getEtherTokenContractAsync(etherTokenAddress: string): Promise<EtherTokenContract> {
+        let etherTokenContract = this._etherTokenContractsByAddress[etherTokenAddress];
+        if (!_.isUndefined(etherTokenContract)) {
+            return etherTokenContract;
+        }
+        const web3ContractInstance = await this._instantiateContractIfExistsAsync(
+            artifacts.EtherTokenArtifact,
+            etherTokenAddress,
+        );
+        const contractInstance = new EtherTokenContract(web3ContractInstance, this._web3Wrapper.getContractDefaults());
+        etherTokenContract = contractInstance;
+        this._etherTokenContractsByAddress[etherTokenAddress] = etherTokenContract;
+        return etherTokenContract;
+    }
 }
diff --git a/packages/0x.js/src/contract_wrappers/exchange_wrapper.ts b/packages/0x.js/src/contract_wrappers/exchange_wrapper.ts
index 668893d45..2b6117729 100644
--- a/packages/0x.js/src/contract_wrappers/exchange_wrapper.ts
+++ b/packages/0x.js/src/contract_wrappers/exchange_wrapper.ts
@@ -6,27 +6,27 @@ import * as Web3 from 'web3';
 
 import { artifacts } from '../artifacts';
 import {
-	BlockParamLiteral,
-	BlockRange,
-	DecodedLogArgs,
-	ECSignature,
-	EventCallback,
-	ExchangeContractErrCodes,
-	ExchangeContractErrs,
-	ExchangeContractEventArgs,
-	ExchangeEvents,
-	IndexedFilterValues,
-	LogErrorContractEventArgs,
-	LogWithDecodedArgs,
-	MethodOpts,
-	Order,
-	OrderAddresses,
-	OrderCancellationRequest,
-	OrderFillRequest,
-	OrderTransactionOpts,
-	OrderValues,
-	SignedOrder,
-	ValidateOrderFillableOpts,
+    BlockParamLiteral,
+    BlockRange,
+    DecodedLogArgs,
+    ECSignature,
+    EventCallback,
+    ExchangeContractErrCodes,
+    ExchangeContractErrs,
+    ExchangeContractEventArgs,
+    ExchangeEvents,
+    IndexedFilterValues,
+    LogErrorContractEventArgs,
+    LogWithDecodedArgs,
+    MethodOpts,
+    Order,
+    OrderAddresses,
+    OrderCancellationRequest,
+    OrderFillRequest,
+    OrderTransactionOpts,
+    OrderValues,
+    SignedOrder,
+    ValidateOrderFillableOpts,
 } from '../types';
 import { AbiDecoder } from '../utils/abi_decoder';
 import { assert } from '../utils/assert';
@@ -42,7 +42,7 @@ import { TokenWrapper } from './token_wrapper';
 const SHOULD_VALIDATE_BY_DEFAULT = true;
 
 interface ExchangeContractErrCodesToMsgs {
-	[exchangeContractErrCodes: number]: string;
+    [exchangeContractErrCodes: number]: string;
 }
 
 /**
@@ -50,864 +50,864 @@ interface ExchangeContractErrCodesToMsgs {
  * events of the 0x Exchange smart contract.
  */
 export class ExchangeWrapper extends ContractWrapper {
-	private _exchangeContractIfExists?: ExchangeContract;
-	private _orderValidationUtils: OrderValidationUtils;
-	private _tokenWrapper: TokenWrapper;
-	private _exchangeContractErrCodesToMsg: ExchangeContractErrCodesToMsgs = {
-		[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 _zrxContractAddressIfExists?: 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,
-		networkId: number,
-		abiDecoder: AbiDecoder,
-		tokenWrapper: TokenWrapper,
-		contractAddressIfExists?: string,
-		zrxContractAddressIfExists?: string,
-	) {
-		super(web3Wrapper, networkId, abiDecoder);
-		this._tokenWrapper = tokenWrapper;
-		this._orderValidationUtils = new OrderValidationUtils(this);
-		this._contractAddressIfExists = contractAddressIfExists;
-		this._zrxContractAddressIfExists = zrxContractAddressIfExists;
-	}
-	/**
-	 * 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 cancelled.
-	 */
-	public async getUnavailableTakerAmountAsync(orderHash: string, methodOpts?: MethodOpts): Promise<BigNumber> {
-		assert.doesConformToSchema('orderHash', orderHash, schemas.orderHashSchema);
+    private _exchangeContractIfExists?: ExchangeContract;
+    private _orderValidationUtils: OrderValidationUtils;
+    private _tokenWrapper: TokenWrapper;
+    private _exchangeContractErrCodesToMsg: ExchangeContractErrCodesToMsgs = {
+        [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 _zrxContractAddressIfExists?: 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,
+        networkId: number,
+        abiDecoder: AbiDecoder,
+        tokenWrapper: TokenWrapper,
+        contractAddressIfExists?: string,
+        zrxContractAddressIfExists?: string,
+    ) {
+        super(web3Wrapper, networkId, abiDecoder);
+        this._tokenWrapper = tokenWrapper;
+        this._orderValidationUtils = new OrderValidationUtils(this);
+        this._contractAddressIfExists = contractAddressIfExists;
+        this._zrxContractAddressIfExists = zrxContractAddressIfExists;
+    }
+    /**
+     * 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 cancelled.
+     */
+    public async getUnavailableTakerAmountAsync(orderHash: string, methodOpts?: MethodOpts): Promise<BigNumber> {
+        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<BigNumber> {
-		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<BigNumber> {
+        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 getCancelledTakerAmountAsync(orderHash: string, methodOpts?: MethodOpts): Promise<BigNumber> {
-		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 getCancelledTakerAmountAsync(orderHash: string, methodOpts?: MethodOpts): Promise<BigNumber> {
+        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.asyncZeroExErrorHandler
-	public async fillOrderAsync(
-		signedOrder: SignedOrder,
-		fillTakerTokenAmount: BigNumber,
-		shouldThrowOnInsufficientBalanceOrAllowance: boolean,
-		takerAddress: string,
-		orderTransactionOpts: OrderTransactionOpts = {},
-	): Promise<string> {
-		assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
-		assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
-		assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance);
-		await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
+        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.asyncZeroExErrorHandler
+    public async fillOrderAsync(
+        signedOrder: SignedOrder,
+        fillTakerTokenAmount: BigNumber,
+        shouldThrowOnInsufficientBalanceOrAllowance: boolean,
+        takerAddress: string,
+        orderTransactionOpts: OrderTransactionOpts = {},
+    ): Promise<string> {
+        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.shouldValidate)
-			? SHOULD_VALIDATE_BY_DEFAULT
-			: orderTransactionOpts.shouldValidate;
-		if (shouldValidate) {
-			const zrxTokenAddress = this.getZRXTokenAddress();
-			const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
-			await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync(
-				exchangeTradeEmulator,
-				signedOrder,
-				fillTakerTokenAmount,
-				takerAddress,
-				zrxTokenAddress,
-			);
-		}
+        const exchangeInstance = await this._getExchangeContractAsync();
+        const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
+            ? SHOULD_VALIDATE_BY_DEFAULT
+            : orderTransactionOpts.shouldValidate;
+        if (shouldValidate) {
+            const zrxTokenAddress = this.getZRXTokenAddress();
+            const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
+            await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync(
+                exchangeTradeEmulator,
+                signedOrder,
+                fillTakerTokenAmount,
+                takerAddress,
+                zrxTokenAddress,
+            );
+        }
 
-		const [orderAddresses, orderValues] = ExchangeWrapper._getOrderAddressesAndValues(signedOrder);
+        const [orderAddresses, orderValues] = ExchangeWrapper._getOrderAddressesAndValues(signedOrder);
 
-		const txHash: string = await exchangeInstance.fillOrder.sendTransactionAsync(
-			orderAddresses,
-			orderValues,
-			fillTakerTokenAmount,
-			shouldThrowOnInsufficientBalanceOrAllowance,
-			signedOrder.ecSignature.v,
-			signedOrder.ecSignature.r,
-			signedOrder.ecSignature.s,
-			{
-				from: takerAddress,
-				gas: orderTransactionOpts.gasLimit,
-				gasPrice: orderTransactionOpts.gasPrice,
-			},
-		);
-		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.asyncZeroExErrorHandler
-	public async fillOrdersUpToAsync(
-		signedOrders: SignedOrder[],
-		fillTakerTokenAmount: BigNumber,
-		shouldThrowOnInsufficientBalanceOrAllowance: boolean,
-		takerAddress: string,
-		orderTransactionOpts: OrderTransactionOpts = {},
-	): Promise<string> {
-		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 txHash: string = await exchangeInstance.fillOrder.sendTransactionAsync(
+            orderAddresses,
+            orderValues,
+            fillTakerTokenAmount,
+            shouldThrowOnInsufficientBalanceOrAllowance,
+            signedOrder.ecSignature.v,
+            signedOrder.ecSignature.r,
+            signedOrder.ecSignature.s,
+            {
+                from: takerAddress,
+                gas: orderTransactionOpts.gasLimit,
+                gasPrice: orderTransactionOpts.gasPrice,
+            },
+        );
+        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.asyncZeroExErrorHandler
+    public async fillOrdersUpToAsync(
+        signedOrders: SignedOrder[],
+        fillTakerTokenAmount: BigNumber,
+        shouldThrowOnInsufficientBalanceOrAllowance: boolean,
+        takerAddress: string,
+        orderTransactionOpts: OrderTransactionOpts = {},
+    ): Promise<string> {
+        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.shouldValidate)
-			? SHOULD_VALIDATE_BY_DEFAULT
-			: orderTransactionOpts.shouldValidate;
-		if (shouldValidate) {
-			let filledTakerTokenAmount = new BigNumber(0);
-			const zrxTokenAddress = this.getZRXTokenAddress();
-			const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
-			for (const signedOrder of signedOrders) {
-				const singleFilledTakerTokenAmount = await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync(
-					exchangeTradeEmulator,
-					signedOrder,
-					fillTakerTokenAmount.minus(filledTakerTokenAmount),
-					takerAddress,
-					zrxTokenAddress,
-				);
-				filledTakerTokenAmount = filledTakerTokenAmount.plus(singleFilledTakerTokenAmount);
-			}
-		}
+        const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
+            ? SHOULD_VALIDATE_BY_DEFAULT
+            : orderTransactionOpts.shouldValidate;
+        if (shouldValidate) {
+            let filledTakerTokenAmount = new BigNumber(0);
+            const zrxTokenAddress = this.getZRXTokenAddress();
+            const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
+            for (const signedOrder of signedOrders) {
+                const singleFilledTakerTokenAmount = await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync(
+                    exchangeTradeEmulator,
+                    signedOrder,
+                    fillTakerTokenAmount.minus(filledTakerTokenAmount),
+                    takerAddress,
+                    zrxTokenAddress,
+                );
+                filledTakerTokenAmount = filledTakerTokenAmount.plus(singleFilledTakerTokenAmount);
+            }
+        }
 
-		if (_.isEmpty(signedOrders)) {
-			throw new Error(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem);
-		}
+        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<any> because _.unzip doesn't type check if values have different types :'(
-		const [orderAddressesArray, orderValuesArray, vArray, rArray, sArray] = _.unzip<any>(
-			orderAddressesValuesAndSignatureArray,
-		);
+        const orderAddressesValuesAndSignatureArray = _.map(signedOrders, signedOrder => {
+            return [
+                ...ExchangeWrapper._getOrderAddressesAndValues(signedOrder),
+                signedOrder.ecSignature.v,
+                signedOrder.ecSignature.r,
+                signedOrder.ecSignature.s,
+            ];
+        });
+        // We use _.unzip<any> because _.unzip doesn't type check if values have different types :'(
+        const [orderAddressesArray, orderValuesArray, vArray, rArray, sArray] = _.unzip<any>(
+            orderAddressesValuesAndSignatureArray,
+        );
 
-		const exchangeInstance = await this._getExchangeContractAsync();
-		const txHash = await exchangeInstance.fillOrdersUpTo.sendTransactionAsync(
-			orderAddressesArray,
-			orderValuesArray,
-			fillTakerTokenAmount,
-			shouldThrowOnInsufficientBalanceOrAllowance,
-			vArray,
-			rArray,
-			sArray,
-			{
-				from: takerAddress,
-				gas: orderTransactionOpts.gasLimit,
-				gasPrice: orderTransactionOpts.gasPrice,
-			},
-		);
-		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.asyncZeroExErrorHandler
-	public async batchFillOrdersAsync(
-		orderFillRequests: OrderFillRequest[],
-		shouldThrowOnInsufficientBalanceOrAllowance: boolean,
-		takerAddress: string,
-		orderTransactionOpts: OrderTransactionOpts = {},
-	): Promise<string> {
-		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.shouldValidate)
-			? SHOULD_VALIDATE_BY_DEFAULT
-			: orderTransactionOpts.shouldValidate;
-		if (shouldValidate) {
-			const zrxTokenAddress = this.getZRXTokenAddress();
-			const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
-			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 exchangeInstance = await this._getExchangeContractAsync();
+        const txHash = await exchangeInstance.fillOrdersUpTo.sendTransactionAsync(
+            orderAddressesArray,
+            orderValuesArray,
+            fillTakerTokenAmount,
+            shouldThrowOnInsufficientBalanceOrAllowance,
+            vArray,
+            rArray,
+            sArray,
+            {
+                from: takerAddress,
+                gas: orderTransactionOpts.gasLimit,
+                gasPrice: orderTransactionOpts.gasPrice,
+            },
+        );
+        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.asyncZeroExErrorHandler
+    public async batchFillOrdersAsync(
+        orderFillRequests: OrderFillRequest[],
+        shouldThrowOnInsufficientBalanceOrAllowance: boolean,
+        takerAddress: string,
+        orderTransactionOpts: OrderTransactionOpts = {},
+    ): Promise<string> {
+        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.shouldValidate)
+            ? SHOULD_VALIDATE_BY_DEFAULT
+            : orderTransactionOpts.shouldValidate;
+        if (shouldValidate) {
+            const zrxTokenAddress = this.getZRXTokenAddress();
+            const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
+            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<any> because _.unzip doesn't type check if values have different types :'(
-		const [orderAddressesArray, orderValuesArray, fillTakerTokenAmounts, vArray, rArray, sArray] = _.unzip<any>(
-			orderAddressesValuesAmountsAndSignatureArray,
-		);
+        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<any> because _.unzip doesn't type check if values have different types :'(
+        const [orderAddressesArray, orderValuesArray, fillTakerTokenAmounts, vArray, rArray, sArray] = _.unzip<any>(
+            orderAddressesValuesAmountsAndSignatureArray,
+        );
 
-		const exchangeInstance = await this._getExchangeContractAsync();
-		const txHash = await exchangeInstance.batchFillOrders.sendTransactionAsync(
-			orderAddressesArray,
-			orderValuesArray,
-			fillTakerTokenAmounts,
-			shouldThrowOnInsufficientBalanceOrAllowance,
-			vArray,
-			rArray,
-			sArray,
-			{
-				from: takerAddress,
-				gas: orderTransactionOpts.gasLimit,
-				gasPrice: orderTransactionOpts.gasPrice,
-			},
-		);
-		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.asyncZeroExErrorHandler
-	public async fillOrKillOrderAsync(
-		signedOrder: SignedOrder,
-		fillTakerTokenAmount: BigNumber,
-		takerAddress: string,
-		orderTransactionOpts: OrderTransactionOpts = {},
-	): Promise<string> {
-		assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
-		assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
-		await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
+        const exchangeInstance = await this._getExchangeContractAsync();
+        const txHash = await exchangeInstance.batchFillOrders.sendTransactionAsync(
+            orderAddressesArray,
+            orderValuesArray,
+            fillTakerTokenAmounts,
+            shouldThrowOnInsufficientBalanceOrAllowance,
+            vArray,
+            rArray,
+            sArray,
+            {
+                from: takerAddress,
+                gas: orderTransactionOpts.gasLimit,
+                gasPrice: orderTransactionOpts.gasPrice,
+            },
+        );
+        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.asyncZeroExErrorHandler
+    public async fillOrKillOrderAsync(
+        signedOrder: SignedOrder,
+        fillTakerTokenAmount: BigNumber,
+        takerAddress: string,
+        orderTransactionOpts: OrderTransactionOpts = {},
+    ): Promise<string> {
+        assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
+        assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
+        await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
 
-		const exchangeInstance = await this._getExchangeContractAsync();
+        const exchangeInstance = await this._getExchangeContractAsync();
 
-		const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
-			? SHOULD_VALIDATE_BY_DEFAULT
-			: orderTransactionOpts.shouldValidate;
-		if (shouldValidate) {
-			const zrxTokenAddress = this.getZRXTokenAddress();
-			const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
-			await this._orderValidationUtils.validateFillOrKillOrderThrowIfInvalidAsync(
-				exchangeTradeEmulator,
-				signedOrder,
-				fillTakerTokenAmount,
-				takerAddress,
-				zrxTokenAddress,
-			);
-		}
+        const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
+            ? SHOULD_VALIDATE_BY_DEFAULT
+            : orderTransactionOpts.shouldValidate;
+        if (shouldValidate) {
+            const zrxTokenAddress = this.getZRXTokenAddress();
+            const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
+            await this._orderValidationUtils.validateFillOrKillOrderThrowIfInvalidAsync(
+                exchangeTradeEmulator,
+                signedOrder,
+                fillTakerTokenAmount,
+                takerAddress,
+                zrxTokenAddress,
+            );
+        }
 
-		const [orderAddresses, orderValues] = ExchangeWrapper._getOrderAddressesAndValues(signedOrder);
-		const txHash = await exchangeInstance.fillOrKillOrder.sendTransactionAsync(
-			orderAddresses,
-			orderValues,
-			fillTakerTokenAmount,
-			signedOrder.ecSignature.v,
-			signedOrder.ecSignature.r,
-			signedOrder.ecSignature.s,
-			{
-				from: takerAddress,
-				gas: orderTransactionOpts.gasLimit,
-				gasPrice: orderTransactionOpts.gasPrice,
-			},
-		);
-		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.asyncZeroExErrorHandler
-	public async batchFillOrKillAsync(
-		orderFillRequests: OrderFillRequest[],
-		takerAddress: string,
-		orderTransactionOpts: OrderTransactionOpts = {},
-	): Promise<string> {
-		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 [orderAddresses, orderValues] = ExchangeWrapper._getOrderAddressesAndValues(signedOrder);
+        const txHash = await exchangeInstance.fillOrKillOrder.sendTransactionAsync(
+            orderAddresses,
+            orderValues,
+            fillTakerTokenAmount,
+            signedOrder.ecSignature.v,
+            signedOrder.ecSignature.r,
+            signedOrder.ecSignature.s,
+            {
+                from: takerAddress,
+                gas: orderTransactionOpts.gasLimit,
+                gasPrice: orderTransactionOpts.gasPrice,
+            },
+        );
+        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.asyncZeroExErrorHandler
+    public async batchFillOrKillAsync(
+        orderFillRequests: OrderFillRequest[],
+        takerAddress: string,
+        orderTransactionOpts: OrderTransactionOpts = {},
+    ): Promise<string> {
+        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.shouldValidate)
-			? SHOULD_VALIDATE_BY_DEFAULT
-			: orderTransactionOpts.shouldValidate;
-		if (shouldValidate) {
-			const zrxTokenAddress = this.getZRXTokenAddress();
-			const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
-			for (const orderFillRequest of orderFillRequests) {
-				await this._orderValidationUtils.validateFillOrKillOrderThrowIfInvalidAsync(
-					exchangeTradeEmulator,
-					orderFillRequest.signedOrder,
-					orderFillRequest.takerTokenFillAmount,
-					takerAddress,
-					zrxTokenAddress,
-				);
-			}
-		}
+        const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
+            ? SHOULD_VALIDATE_BY_DEFAULT
+            : orderTransactionOpts.shouldValidate;
+        if (shouldValidate) {
+            const zrxTokenAddress = this.getZRXTokenAddress();
+            const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
+            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,
-			];
-		});
+        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<any> because _.unzip doesn't type check if values have different types :'(
-		const [orderAddresses, orderValues, fillTakerTokenAmounts, vParams, rParams, sParams] = _.unzip<any>(
-			orderAddressesValuesAndTakerTokenFillAmounts,
-		);
-		const txHash = await exchangeInstance.batchFillOrKillOrders.sendTransactionAsync(
-			orderAddresses,
-			orderValues,
-			fillTakerTokenAmounts,
-			vParams,
-			rParams,
-			sParams,
-			{
-				from: takerAddress,
-				gas: orderTransactionOpts.gasLimit,
-				gasPrice: orderTransactionOpts.gasPrice,
-			},
-		);
-		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.asyncZeroExErrorHandler
-	public async cancelOrderAsync(
-		order: Order | SignedOrder,
-		cancelTakerTokenAmount: BigNumber,
-		orderTransactionOpts: OrderTransactionOpts = {},
-	): Promise<string> {
-		assert.doesConformToSchema('order', order, schemas.orderSchema);
-		assert.isValidBaseUnitAmount('takerTokenCancelAmount', cancelTakerTokenAmount);
-		await assert.isSenderAddressAsync('order.maker', order.maker, this._web3Wrapper);
+        // We use _.unzip<any> because _.unzip doesn't type check if values have different types :'(
+        const [orderAddresses, orderValues, fillTakerTokenAmounts, vParams, rParams, sParams] = _.unzip<any>(
+            orderAddressesValuesAndTakerTokenFillAmounts,
+        );
+        const txHash = await exchangeInstance.batchFillOrKillOrders.sendTransactionAsync(
+            orderAddresses,
+            orderValues,
+            fillTakerTokenAmounts,
+            vParams,
+            rParams,
+            sParams,
+            {
+                from: takerAddress,
+                gas: orderTransactionOpts.gasLimit,
+                gasPrice: orderTransactionOpts.gasPrice,
+            },
+        );
+        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.asyncZeroExErrorHandler
+    public async cancelOrderAsync(
+        order: Order | SignedOrder,
+        cancelTakerTokenAmount: BigNumber,
+        orderTransactionOpts: OrderTransactionOpts = {},
+    ): Promise<string> {
+        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 exchangeInstance = await this._getExchangeContractAsync();
 
-		const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
-			? SHOULD_VALIDATE_BY_DEFAULT
-			: orderTransactionOpts.shouldValidate;
-		if (shouldValidate) {
-			const orderHash = utils.getOrderHashHex(order);
-			const unavailableTakerTokenAmount = await this.getUnavailableTakerAmountAsync(orderHash);
-			OrderValidationUtils.validateCancelOrderThrowIfInvalid(
-				order,
-				cancelTakerTokenAmount,
-				unavailableTakerTokenAmount,
-			);
-		}
+        const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
+            ? SHOULD_VALIDATE_BY_DEFAULT
+            : orderTransactionOpts.shouldValidate;
+        if (shouldValidate) {
+            const orderHash = utils.getOrderHashHex(order);
+            const unavailableTakerTokenAmount = await this.getUnavailableTakerAmountAsync(orderHash);
+            OrderValidationUtils.validateCancelOrderThrowIfInvalid(
+                order,
+                cancelTakerTokenAmount,
+                unavailableTakerTokenAmount,
+            );
+        }
 
-		const [orderAddresses, orderValues] = ExchangeWrapper._getOrderAddressesAndValues(order);
-		const txHash = await exchangeInstance.cancelOrder.sendTransactionAsync(
-			orderAddresses,
-			orderValues,
-			cancelTakerTokenAmount,
-			{
-				from: order.maker,
-				gas: orderTransactionOpts.gasLimit,
-				gasPrice: orderTransactionOpts.gasPrice,
-			},
-		);
-		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.asyncZeroExErrorHandler
-	public async batchCancelOrdersAsync(
-		orderCancellationRequests: OrderCancellationRequest[],
-		orderTransactionOpts: OrderTransactionOpts = {},
-	): Promise<string> {
-		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.shouldValidate)
-			? 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);
-				OrderValidationUtils.validateCancelOrderThrowIfInvalid(
-					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<any> because _.unzip doesn't type check if values have different types :'(
-		const [orderAddresses, orderValues, cancelTakerTokenAmounts] = _.unzip<any>(
-			orderAddressesValuesAndTakerTokenCancelAmounts,
-		);
-		const txHash = await exchangeInstance.batchCancelOrders.sendTransactionAsync(
-			orderAddresses,
-			orderValues,
-			cancelTakerTokenAmounts,
-			{
-				from: maker,
-				gas: orderTransactionOpts.gasLimit,
-				gasPrice: orderTransactionOpts.gasPrice,
-			},
-		);
-		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 subscribe<ArgsType extends ExchangeContractEventArgs>(
-		eventName: ExchangeEvents,
-		indexFilterValues: IndexedFilterValues,
-		callback: EventCallback<ArgsType>,
-	): string {
-		assert.doesBelongToStringEnum('eventName', eventName, ExchangeEvents);
-		assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
-		assert.isFunction('callback', callback);
-		const exchangeContractAddress = this.getContractAddress();
-		const subscriptionToken = this._subscribe<ArgsType>(
-			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);
-	}
-	/**
-	 * Cancels all existing subscriptions
-	 */
-	public unsubscribeAll(): void {
-		super.unsubscribeAll();
-	}
-	/**
-	 * Gets historical logs without creating a subscription
-	 * @param   eventName           The exchange contract event you would like to subscribe to.
-	 * @param   blockRange          Block range to get logs from.
-	 * @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<ArgsType extends ExchangeContractEventArgs>(
-		eventName: ExchangeEvents,
-		blockRange: BlockRange,
-		indexFilterValues: IndexedFilterValues,
-	): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
-		assert.doesBelongToStringEnum('eventName', eventName, ExchangeEvents);
-		assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema);
-		assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
-		const exchangeContractAddress = this.getContractAddress();
-		const logs = await this._getLogsAsync<ArgsType>(
-			exchangeContractAddress,
-			eventName,
-			blockRange,
-			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 getContractAddress(): string {
-		const contractAddress = this._getContractAddress(artifacts.ExchangeArtifact, this._contractAddressIfExists);
-		return contractAddress;
-	}
-	/**
-	 * 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<void> {
-		assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
-		const zrxTokenAddress = this.getZRXTokenAddress();
-		const expectedFillTakerTokenAmount = !_.isUndefined(opts) ? opts.expectedFillTakerTokenAmount : undefined;
-		const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
-		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<void> {
-		assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
-		assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
-		await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
-		const zrxTokenAddress = this.getZRXTokenAddress();
-		const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
-		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<void> {
-		assert.doesConformToSchema('order', order, schemas.orderSchema);
-		assert.isValidBaseUnitAmount('cancelTakerTokenAmount', cancelTakerTokenAmount);
-		const orderHash = utils.getOrderHashHex(order);
-		const unavailableTakerTokenAmount = await this.getUnavailableTakerAmountAsync(orderHash);
-		OrderValidationUtils.validateCancelOrderThrowIfInvalid(
-			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<void> {
-		assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
-		assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
-		await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
-		const zrxTokenAddress = this.getZRXTokenAddress();
-		const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
-		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<boolean> {
-		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<LogWithDecodedArgs<DecodedLogArgs> | Web3.LogEntry>): void {
-		const errLog = _.find(logs, {
-			event: ExchangeEvents.LogError,
-		}) as LogWithDecodedArgs<LogErrorContractEventArgs> | 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 getZRXTokenAddress(): string {
-		const contractAddress = this._getContractAddress(artifacts.ZRXArtifact, this._zrxContractAddressIfExists);
-		return contractAddress;
-	}
-	private _invalidateContractInstances(): void {
-		this.unsubscribeAll();
-		delete this._exchangeContractIfExists;
-	}
-	private async _isValidSignatureUsingContractCallAsync(
-		dataHex: string,
-		ecSignature: ECSignature,
-		signerAddressHex: string,
-	): Promise<boolean> {
-		assert.isHexString('dataHex', dataHex);
-		assert.doesConformToSchema('ecSignature', ecSignature, schemas.ecSignatureSchema);
-		assert.isETHAddressHex('signerAddressHex', signerAddressHex);
+        const [orderAddresses, orderValues] = ExchangeWrapper._getOrderAddressesAndValues(order);
+        const txHash = await exchangeInstance.cancelOrder.sendTransactionAsync(
+            orderAddresses,
+            orderValues,
+            cancelTakerTokenAmount,
+            {
+                from: order.maker,
+                gas: orderTransactionOpts.gasLimit,
+                gasPrice: orderTransactionOpts.gasPrice,
+            },
+        );
+        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.asyncZeroExErrorHandler
+    public async batchCancelOrdersAsync(
+        orderCancellationRequests: OrderCancellationRequest[],
+        orderTransactionOpts: OrderTransactionOpts = {},
+    ): Promise<string> {
+        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.shouldValidate)
+            ? 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);
+                OrderValidationUtils.validateCancelOrderThrowIfInvalid(
+                    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<any> because _.unzip doesn't type check if values have different types :'(
+        const [orderAddresses, orderValues, cancelTakerTokenAmounts] = _.unzip<any>(
+            orderAddressesValuesAndTakerTokenCancelAmounts,
+        );
+        const txHash = await exchangeInstance.batchCancelOrders.sendTransactionAsync(
+            orderAddresses,
+            orderValues,
+            cancelTakerTokenAmounts,
+            {
+                from: maker,
+                gas: orderTransactionOpts.gasLimit,
+                gasPrice: orderTransactionOpts.gasPrice,
+            },
+        );
+        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 subscribe<ArgsType extends ExchangeContractEventArgs>(
+        eventName: ExchangeEvents,
+        indexFilterValues: IndexedFilterValues,
+        callback: EventCallback<ArgsType>,
+    ): string {
+        assert.doesBelongToStringEnum('eventName', eventName, ExchangeEvents);
+        assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
+        assert.isFunction('callback', callback);
+        const exchangeContractAddress = this.getContractAddress();
+        const subscriptionToken = this._subscribe<ArgsType>(
+            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);
+    }
+    /**
+     * Cancels all existing subscriptions
+     */
+    public unsubscribeAll(): void {
+        super.unsubscribeAll();
+    }
+    /**
+     * Gets historical logs without creating a subscription
+     * @param   eventName           The exchange contract event you would like to subscribe to.
+     * @param   blockRange          Block range to get logs from.
+     * @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<ArgsType extends ExchangeContractEventArgs>(
+        eventName: ExchangeEvents,
+        blockRange: BlockRange,
+        indexFilterValues: IndexedFilterValues,
+    ): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
+        assert.doesBelongToStringEnum('eventName', eventName, ExchangeEvents);
+        assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema);
+        assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
+        const exchangeContractAddress = this.getContractAddress();
+        const logs = await this._getLogsAsync<ArgsType>(
+            exchangeContractAddress,
+            eventName,
+            blockRange,
+            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 getContractAddress(): string {
+        const contractAddress = this._getContractAddress(artifacts.ExchangeArtifact, this._contractAddressIfExists);
+        return contractAddress;
+    }
+    /**
+     * 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<void> {
+        assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
+        const zrxTokenAddress = this.getZRXTokenAddress();
+        const expectedFillTakerTokenAmount = !_.isUndefined(opts) ? opts.expectedFillTakerTokenAmount : undefined;
+        const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
+        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<void> {
+        assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
+        assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
+        await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
+        const zrxTokenAddress = this.getZRXTokenAddress();
+        const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
+        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<void> {
+        assert.doesConformToSchema('order', order, schemas.orderSchema);
+        assert.isValidBaseUnitAmount('cancelTakerTokenAmount', cancelTakerTokenAmount);
+        const orderHash = utils.getOrderHashHex(order);
+        const unavailableTakerTokenAmount = await this.getUnavailableTakerAmountAsync(orderHash);
+        OrderValidationUtils.validateCancelOrderThrowIfInvalid(
+            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<void> {
+        assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
+        assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
+        await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
+        const zrxTokenAddress = this.getZRXTokenAddress();
+        const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
+        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<boolean> {
+        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<LogWithDecodedArgs<DecodedLogArgs> | Web3.LogEntry>): void {
+        const errLog = _.find(logs, {
+            event: ExchangeEvents.LogError,
+        }) as LogWithDecodedArgs<LogErrorContractEventArgs> | 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 getZRXTokenAddress(): string {
+        const contractAddress = this._getContractAddress(artifacts.ZRXArtifact, this._zrxContractAddressIfExists);
+        return contractAddress;
+    }
+    private _invalidateContractInstances(): void {
+        this.unsubscribeAll();
+        delete this._exchangeContractIfExists;
+    }
+    private async _isValidSignatureUsingContractCallAsync(
+        dataHex: string,
+        ecSignature: ECSignature,
+        signerAddressHex: string,
+    ): Promise<boolean> {
+        assert.isHexString('dataHex', dataHex);
+        assert.doesConformToSchema('ecSignature', ecSignature, schemas.ecSignatureSchema);
+        assert.isETHAddressHex('signerAddressHex', signerAddressHex);
 
-		const exchangeInstance = await this._getExchangeContractAsync();
+        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<string> {
-		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<ExchangeContract> {
-		if (!_.isUndefined(this._exchangeContractIfExists)) {
-			return this._exchangeContractIfExists;
-		}
-		const web3ContractInstance = await this._instantiateContractIfExistsAsync(
-			artifacts.ExchangeArtifact,
-			this._contractAddressIfExists,
-		);
-		const contractInstance = new ExchangeContract(web3ContractInstance, this._web3Wrapper.getContractDefaults());
-		this._exchangeContractIfExists = contractInstance;
-		return this._exchangeContractIfExists;
-	}
-	private async _getTokenTransferProxyAddressAsync(): Promise<string> {
-		const exchangeInstance = await this._getExchangeContractAsync();
-		const tokenTransferProxyAddress = await exchangeInstance.TOKEN_TRANSFER_PROXY_CONTRACT.callAsync();
-		const tokenTransferProxyAddressLowerCase = tokenTransferProxyAddress.toLowerCase();
-		return tokenTransferProxyAddressLowerCase;
-	}
+        const isValidSignature = await exchangeInstance.isValidSignature.callAsync(
+            signerAddressHex,
+            dataHex,
+            ecSignature.v,
+            ecSignature.r,
+            ecSignature.s,
+        );
+        return isValidSignature;
+    }
+    private async _getOrderHashHexUsingContractCallAsync(order: Order | SignedOrder): Promise<string> {
+        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<ExchangeContract> {
+        if (!_.isUndefined(this._exchangeContractIfExists)) {
+            return this._exchangeContractIfExists;
+        }
+        const web3ContractInstance = await this._instantiateContractIfExistsAsync(
+            artifacts.ExchangeArtifact,
+            this._contractAddressIfExists,
+        );
+        const contractInstance = new ExchangeContract(web3ContractInstance, this._web3Wrapper.getContractDefaults());
+        this._exchangeContractIfExists = contractInstance;
+        return this._exchangeContractIfExists;
+    }
+    private async _getTokenTransferProxyAddressAsync(): Promise<string> {
+        const exchangeInstance = await this._getExchangeContractAsync();
+        const tokenTransferProxyAddress = await exchangeInstance.TOKEN_TRANSFER_PROXY_CONTRACT.callAsync();
+        const tokenTransferProxyAddressLowerCase = tokenTransferProxyAddress.toLowerCase();
+        return tokenTransferProxyAddressLowerCase;
+    }
 } // tslint:disable:max-file-line-count
diff --git a/packages/0x.js/src/contract_wrappers/token_registry_wrapper.ts b/packages/0x.js/src/contract_wrappers/token_registry_wrapper.ts
index bce48a590..f54aaf0f8 100644
--- a/packages/0x.js/src/contract_wrappers/token_registry_wrapper.ts
+++ b/packages/0x.js/src/contract_wrappers/token_registry_wrapper.ts
@@ -13,117 +13,117 @@ import { TokenRegistryContract } from './generated/token_registry';
  * 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;
-	private static _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;
-	}
-	constructor(web3Wrapper: Web3Wrapper, networkId: number, contractAddressIfExists?: string) {
-		super(web3Wrapper, networkId);
-		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<Token[]> {
-		const addresses = await this.getTokenAddressesAsync();
-		const tokenPromises: Array<Promise<Token | undefined>> = _.map(addresses, async (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<string[]> {
-		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<Token | undefined> {
-		assert.isETHAddressHex('address', address);
+    private _tokenRegistryContractIfExists?: TokenRegistryContract;
+    private _contractAddressIfExists?: string;
+    private static _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;
+    }
+    constructor(web3Wrapper: Web3Wrapper, networkId: number, contractAddressIfExists?: string) {
+        super(web3Wrapper, networkId);
+        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<Token[]> {
+        const addresses = await this.getTokenAddressesAsync();
+        const tokenPromises: Array<Promise<Token | undefined>> = _.map(addresses, async (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<string[]> {
+        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<Token | undefined> {
+        assert.isETHAddressHex('address', address);
 
-		const tokenRegistryContract = await this._getTokenRegistryContractAsync();
-		const metadata = await tokenRegistryContract.getTokenMetaData.callAsync(address);
-		const token = TokenRegistryWrapper._createTokenFromMetadata(metadata);
-		return token;
-	}
-	public async getTokenAddressBySymbolIfExistsAsync(symbol: string): Promise<string | undefined> {
-		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<string | undefined> {
-		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<Token | undefined> {
-		assert.isString('symbol', symbol);
-		const tokenRegistryContract = await this._getTokenRegistryContractAsync();
-		const metadata = await tokenRegistryContract.getTokenBySymbol.callAsync(symbol);
-		const token = TokenRegistryWrapper._createTokenFromMetadata(metadata);
-		return token;
-	}
-	public async getTokenByNameIfExistsAsync(name: string): Promise<Token | undefined> {
-		assert.isString('name', name);
-		const tokenRegistryContract = await this._getTokenRegistryContractAsync();
-		const metadata = await tokenRegistryContract.getTokenByName.callAsync(name);
-		const token = TokenRegistryWrapper._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 getContractAddress(): string {
-		const contractAddress = this._getContractAddress(
-			artifacts.TokenRegistryArtifact,
-			this._contractAddressIfExists,
-		);
-		return contractAddress;
-	}
-	private _invalidateContractInstance(): void {
-		delete this._tokenRegistryContractIfExists;
-	}
-	private async _getTokenRegistryContractAsync(): Promise<TokenRegistryContract> {
-		if (!_.isUndefined(this._tokenRegistryContractIfExists)) {
-			return this._tokenRegistryContractIfExists;
-		}
-		const web3ContractInstance = await this._instantiateContractIfExistsAsync(
-			artifacts.TokenRegistryArtifact,
-			this._contractAddressIfExists,
-		);
-		const contractInstance = new TokenRegistryContract(
-			web3ContractInstance,
-			this._web3Wrapper.getContractDefaults(),
-		);
-		this._tokenRegistryContractIfExists = contractInstance;
-		return this._tokenRegistryContractIfExists;
-	}
+        const tokenRegistryContract = await this._getTokenRegistryContractAsync();
+        const metadata = await tokenRegistryContract.getTokenMetaData.callAsync(address);
+        const token = TokenRegistryWrapper._createTokenFromMetadata(metadata);
+        return token;
+    }
+    public async getTokenAddressBySymbolIfExistsAsync(symbol: string): Promise<string | undefined> {
+        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<string | undefined> {
+        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<Token | undefined> {
+        assert.isString('symbol', symbol);
+        const tokenRegistryContract = await this._getTokenRegistryContractAsync();
+        const metadata = await tokenRegistryContract.getTokenBySymbol.callAsync(symbol);
+        const token = TokenRegistryWrapper._createTokenFromMetadata(metadata);
+        return token;
+    }
+    public async getTokenByNameIfExistsAsync(name: string): Promise<Token | undefined> {
+        assert.isString('name', name);
+        const tokenRegistryContract = await this._getTokenRegistryContractAsync();
+        const metadata = await tokenRegistryContract.getTokenByName.callAsync(name);
+        const token = TokenRegistryWrapper._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 getContractAddress(): string {
+        const contractAddress = this._getContractAddress(
+            artifacts.TokenRegistryArtifact,
+            this._contractAddressIfExists,
+        );
+        return contractAddress;
+    }
+    private _invalidateContractInstance(): void {
+        delete this._tokenRegistryContractIfExists;
+    }
+    private async _getTokenRegistryContractAsync(): Promise<TokenRegistryContract> {
+        if (!_.isUndefined(this._tokenRegistryContractIfExists)) {
+            return this._tokenRegistryContractIfExists;
+        }
+        const web3ContractInstance = await this._instantiateContractIfExistsAsync(
+            artifacts.TokenRegistryArtifact,
+            this._contractAddressIfExists,
+        );
+        const contractInstance = new TokenRegistryContract(
+            web3ContractInstance,
+            this._web3Wrapper.getContractDefaults(),
+        );
+        this._tokenRegistryContractIfExists = contractInstance;
+        return this._tokenRegistryContractIfExists;
+    }
 }
diff --git a/packages/0x.js/src/contract_wrappers/token_transfer_proxy_wrapper.ts b/packages/0x.js/src/contract_wrappers/token_transfer_proxy_wrapper.ts
index 635588fed..f5d9d108a 100644
--- a/packages/0x.js/src/contract_wrappers/token_transfer_proxy_wrapper.ts
+++ b/packages/0x.js/src/contract_wrappers/token_transfer_proxy_wrapper.ts
@@ -10,59 +10,59 @@ import { TokenTransferProxyContract } from './generated/token_transfer_proxy';
  * This class includes the functionality related to interacting with the TokenTransferProxy contract.
  */
 export class TokenTransferProxyWrapper extends ContractWrapper {
-	private _tokenTransferProxyContractIfExists?: TokenTransferProxyContract;
-	private _contractAddressIfExists?: string;
-	constructor(web3Wrapper: Web3Wrapper, networkId: number, contractAddressIfExists?: string) {
-		super(web3Wrapper, networkId);
-		this._contractAddressIfExists = contractAddressIfExists;
-	}
-	/**
-	 * 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<boolean> {
-		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<string[]> {
-		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 getContractAddress(): string {
-		const contractAddress = this._getContractAddress(
-			artifacts.TokenTransferProxyArtifact,
-			this._contractAddressIfExists,
-		);
-		return contractAddress;
-	}
-	private _invalidateContractInstance(): void {
-		delete this._tokenTransferProxyContractIfExists;
-	}
-	private async _getTokenTransferProxyContractAsync(): Promise<TokenTransferProxyContract> {
-		if (!_.isUndefined(this._tokenTransferProxyContractIfExists)) {
-			return this._tokenTransferProxyContractIfExists;
-		}
-		const web3ContractInstance = await this._instantiateContractIfExistsAsync(
-			artifacts.TokenTransferProxyArtifact,
-			this._contractAddressIfExists,
-		);
-		const contractInstance = new TokenTransferProxyContract(
-			web3ContractInstance,
-			this._web3Wrapper.getContractDefaults(),
-		);
-		this._tokenTransferProxyContractIfExists = contractInstance;
-		return this._tokenTransferProxyContractIfExists;
-	}
+    private _tokenTransferProxyContractIfExists?: TokenTransferProxyContract;
+    private _contractAddressIfExists?: string;
+    constructor(web3Wrapper: Web3Wrapper, networkId: number, contractAddressIfExists?: string) {
+        super(web3Wrapper, networkId);
+        this._contractAddressIfExists = contractAddressIfExists;
+    }
+    /**
+     * 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<boolean> {
+        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<string[]> {
+        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 getContractAddress(): string {
+        const contractAddress = this._getContractAddress(
+            artifacts.TokenTransferProxyArtifact,
+            this._contractAddressIfExists,
+        );
+        return contractAddress;
+    }
+    private _invalidateContractInstance(): void {
+        delete this._tokenTransferProxyContractIfExists;
+    }
+    private async _getTokenTransferProxyContractAsync(): Promise<TokenTransferProxyContract> {
+        if (!_.isUndefined(this._tokenTransferProxyContractIfExists)) {
+            return this._tokenTransferProxyContractIfExists;
+        }
+        const web3ContractInstance = await this._instantiateContractIfExistsAsync(
+            artifacts.TokenTransferProxyArtifact,
+            this._contractAddressIfExists,
+        );
+        const contractInstance = new TokenTransferProxyContract(
+            web3ContractInstance,
+            this._web3Wrapper.getContractDefaults(),
+        );
+        this._tokenTransferProxyContractIfExists = contractInstance;
+        return this._tokenTransferProxyContractIfExists;
+    }
 }
diff --git a/packages/0x.js/src/contract_wrappers/token_wrapper.ts b/packages/0x.js/src/contract_wrappers/token_wrapper.ts
index 366cabd9e..7943f4a60 100644
--- a/packages/0x.js/src/contract_wrappers/token_wrapper.ts
+++ b/packages/0x.js/src/contract_wrappers/token_wrapper.ts
@@ -5,15 +5,15 @@ import * as _ from 'lodash';
 
 import { artifacts } from '../artifacts';
 import {
-	BlockRange,
-	EventCallback,
-	IndexedFilterValues,
-	LogWithDecodedArgs,
-	MethodOpts,
-	TokenContractEventArgs,
-	TokenEvents,
-	TransactionOpts,
-	ZeroExError,
+    BlockRange,
+    EventCallback,
+    IndexedFilterValues,
+    LogWithDecodedArgs,
+    MethodOpts,
+    TokenContractEventArgs,
+    TokenEvents,
+    TransactionOpts,
+    ZeroExError,
 } from '../types';
 import { AbiDecoder } from '../utils/abi_decoder';
 import { assert } from '../utils/assert';
@@ -29,367 +29,367 @@ import { TokenTransferProxyWrapper } from './token_transfer_proxy_wrapper';
  * 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 _tokenTransferProxyWrapper: TokenTransferProxyWrapper;
-	constructor(
-		web3Wrapper: Web3Wrapper,
-		networkId: number,
-		abiDecoder: AbiDecoder,
-		tokenTransferProxyWrapper: TokenTransferProxyWrapper,
-	) {
-		super(web3Wrapper, networkId, abiDecoder);
-		this._tokenContractsByAddress = {};
-		this._tokenTransferProxyWrapper = tokenTransferProxyWrapper;
-	}
-	/**
-	 * 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<BigNumber> {
-		assert.isETHAddressHex('ownerAddress', ownerAddress);
-		assert.isETHAddressHex('tokenAddress', tokenAddress);
+    public UNLIMITED_ALLOWANCE_IN_BASE_UNITS = constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS;
+    private _tokenContractsByAddress: { [address: string]: TokenContract };
+    private _tokenTransferProxyWrapper: TokenTransferProxyWrapper;
+    constructor(
+        web3Wrapper: Web3Wrapper,
+        networkId: number,
+        abiDecoder: AbiDecoder,
+        tokenTransferProxyWrapper: TokenTransferProxyWrapper,
+    ) {
+        super(web3Wrapper, networkId, abiDecoder);
+        this._tokenContractsByAddress = {};
+        this._tokenTransferProxyWrapper = tokenTransferProxyWrapper;
+    }
+    /**
+     * 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<BigNumber> {
+        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.
-	 * @param   txOpts              Transaction parameters.
-	 * @return Transaction hash.
-	 */
-	public async setAllowanceAsync(
-		tokenAddress: string,
-		ownerAddress: string,
-		spenderAddress: string,
-		amountInBaseUnits: BigNumber,
-		txOpts: TransactionOpts = {},
-	): Promise<string> {
-		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);
+        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.
+     * @param   txOpts              Transaction parameters.
+     * @return Transaction hash.
+     */
+    public async setAllowanceAsync(
+        tokenAddress: string,
+        ownerAddress: string,
+        spenderAddress: string,
+        amountInBaseUnits: BigNumber,
+        txOpts: TransactionOpts = {},
+    ): Promise<string> {
+        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);
-		const txHash = await tokenContract.approve.sendTransactionAsync(spenderAddress, amountInBaseUnits, {
-			from: ownerAddress,
-			gas: txOpts.gasLimit,
-			gasPrice: txOpts.gasPrice,
-		});
-		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.
-	 * @param   txOpts              Transaction parameters.
-	 * @return Transaction hash.
-	 */
-	public async setUnlimitedAllowanceAsync(
-		tokenAddress: string,
-		ownerAddress: string,
-		spenderAddress: string,
-		txOpts: TransactionOpts = {},
-	): Promise<string> {
-		const txHash = await this.setAllowanceAsync(
-			tokenAddress,
-			ownerAddress,
-			spenderAddress,
-			this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS,
-			txOpts,
-		);
-		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<BigNumber> {
-		assert.isETHAddressHex('ownerAddress', ownerAddress);
-		assert.isETHAddressHex('tokenAddress', tokenAddress);
+        const tokenContract = await this._getTokenContractAsync(tokenAddress);
+        const txHash = await tokenContract.approve.sendTransactionAsync(spenderAddress, amountInBaseUnits, {
+            from: ownerAddress,
+            gas: txOpts.gasLimit,
+            gasPrice: txOpts.gasPrice,
+        });
+        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.
+     * @param   txOpts              Transaction parameters.
+     * @return Transaction hash.
+     */
+    public async setUnlimitedAllowanceAsync(
+        tokenAddress: string,
+        ownerAddress: string,
+        spenderAddress: string,
+        txOpts: TransactionOpts = {},
+    ): Promise<string> {
+        const txHash = await this.setAllowanceAsync(
+            tokenAddress,
+            ownerAddress,
+            spenderAddress,
+            this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS,
+            txOpts,
+        );
+        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<BigNumber> {
+        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<BigNumber> {
-		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<BigNumber> {
+        assert.isETHAddressHex('ownerAddress', ownerAddress);
+        assert.isETHAddressHex('tokenAddress', tokenAddress);
 
-		const proxyAddress = this._tokenTransferProxyWrapper.getContractAddress();
-		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.
-	 * @param   txOpts              Transaction parameters.
-	 * @return Transaction hash.
-	 */
-	public async setProxyAllowanceAsync(
-		tokenAddress: string,
-		ownerAddress: string,
-		amountInBaseUnits: BigNumber,
-		txOpts: TransactionOpts = {},
-	): Promise<string> {
-		assert.isETHAddressHex('ownerAddress', ownerAddress);
-		assert.isETHAddressHex('tokenAddress', tokenAddress);
-		assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits);
+        const proxyAddress = this._tokenTransferProxyWrapper.getContractAddress();
+        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.
+     * @param   txOpts              Transaction parameters.
+     * @return Transaction hash.
+     */
+    public async setProxyAllowanceAsync(
+        tokenAddress: string,
+        ownerAddress: string,
+        amountInBaseUnits: BigNumber,
+        txOpts: TransactionOpts = {},
+    ): Promise<string> {
+        assert.isETHAddressHex('ownerAddress', ownerAddress);
+        assert.isETHAddressHex('tokenAddress', tokenAddress);
+        assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits);
 
-		const proxyAddress = this._tokenTransferProxyWrapper.getContractAddress();
-		const txHash = await this.setAllowanceAsync(
-			tokenAddress,
-			ownerAddress,
-			proxyAddress,
-			amountInBaseUnits,
-			txOpts,
-		);
-		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.
-	 * @param   txOpts              Transaction parameters.
-	 * @return Transaction hash.
-	 */
-	public async setUnlimitedProxyAllowanceAsync(
-		tokenAddress: string,
-		ownerAddress: string,
-		txOpts: TransactionOpts = {},
-	): Promise<string> {
-		const txHash = await this.setProxyAllowanceAsync(
-			tokenAddress,
-			ownerAddress,
-			this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS,
-			txOpts,
-		);
-		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.
-	 * @param   txOpts              Transaction parameters.
-	 * @return Transaction hash.
-	 */
-	public async transferAsync(
-		tokenAddress: string,
-		fromAddress: string,
-		toAddress: string,
-		amountInBaseUnits: BigNumber,
-		txOpts: TransactionOpts = {},
-	): Promise<string> {
-		assert.isETHAddressHex('tokenAddress', tokenAddress);
-		await assert.isSenderAddressAsync('fromAddress', fromAddress, this._web3Wrapper);
-		assert.isETHAddressHex('toAddress', toAddress);
-		assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits);
+        const proxyAddress = this._tokenTransferProxyWrapper.getContractAddress();
+        const txHash = await this.setAllowanceAsync(
+            tokenAddress,
+            ownerAddress,
+            proxyAddress,
+            amountInBaseUnits,
+            txOpts,
+        );
+        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.
+     * @param   txOpts              Transaction parameters.
+     * @return Transaction hash.
+     */
+    public async setUnlimitedProxyAllowanceAsync(
+        tokenAddress: string,
+        ownerAddress: string,
+        txOpts: TransactionOpts = {},
+    ): Promise<string> {
+        const txHash = await this.setProxyAllowanceAsync(
+            tokenAddress,
+            ownerAddress,
+            this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS,
+            txOpts,
+        );
+        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.
+     * @param   txOpts              Transaction parameters.
+     * @return Transaction hash.
+     */
+    public async transferAsync(
+        tokenAddress: string,
+        fromAddress: string,
+        toAddress: string,
+        amountInBaseUnits: BigNumber,
+        txOpts: TransactionOpts = {},
+    ): Promise<string> {
+        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 tokenContract = await this._getTokenContractAsync(tokenAddress);
 
-		const fromAddressBalance = await this.getBalanceAsync(tokenAddress, fromAddress);
-		if (fromAddressBalance.lessThan(amountInBaseUnits)) {
-			throw new Error(ZeroExError.InsufficientBalanceForTransfer);
-		}
+        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,
-			gas: txOpts.gasLimit,
-			gasPrice: txOpts.gasPrice,
-		});
-		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.
-	 * @param   txOpts              Transaction parameters.
-	 * @return Transaction hash.
-	 */
-	public async transferFromAsync(
-		tokenAddress: string,
-		fromAddress: string,
-		toAddress: string,
-		senderAddress: string,
-		amountInBaseUnits: BigNumber,
-		txOpts: TransactionOpts = {},
-	): Promise<string> {
-		assert.isETHAddressHex('tokenAddress', tokenAddress);
-		assert.isETHAddressHex('fromAddress', fromAddress);
-		assert.isETHAddressHex('toAddress', toAddress);
-		await assert.isSenderAddressAsync('senderAddress', senderAddress, this._web3Wrapper);
-		assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits);
+        const txHash = await tokenContract.transfer.sendTransactionAsync(toAddress, amountInBaseUnits, {
+            from: fromAddress,
+            gas: txOpts.gasLimit,
+            gasPrice: txOpts.gasPrice,
+        });
+        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.
+     * @param   txOpts              Transaction parameters.
+     * @return Transaction hash.
+     */
+    public async transferFromAsync(
+        tokenAddress: string,
+        fromAddress: string,
+        toAddress: string,
+        senderAddress: string,
+        amountInBaseUnits: BigNumber,
+        txOpts: TransactionOpts = {},
+    ): Promise<string> {
+        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 tokenContract = await this._getTokenContractAsync(tokenAddress);
 
-		const fromAddressAllowance = await this.getAllowanceAsync(tokenAddress, fromAddress, senderAddress);
-		if (fromAddressAllowance.lessThan(amountInBaseUnits)) {
-			throw new Error(ZeroExError.InsufficientAllowanceForTransfer);
-		}
+        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 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,
-				gas: txOpts.gasLimit,
-				gasPrice: txOpts.gasPrice,
-			},
-		);
-		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<ArgsType extends TokenContractEventArgs>(
-		tokenAddress: string,
-		eventName: TokenEvents,
-		indexFilterValues: IndexedFilterValues,
-		callback: EventCallback<ArgsType>,
-	): string {
-		assert.isETHAddressHex('tokenAddress', tokenAddress);
-		assert.doesBelongToStringEnum('eventName', eventName, TokenEvents);
-		assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
-		assert.isFunction('callback', callback);
-		const subscriptionToken = this._subscribe<ArgsType>(
-			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);
-	}
-	/**
-	 * Cancels all existing subscriptions
-	 */
-	public unsubscribeAll(): void {
-		super.unsubscribeAll();
-	}
-	/**
-	 * 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   blockRange          Block range to get logs from.
-	 * @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<ArgsType extends TokenContractEventArgs>(
-		tokenAddress: string,
-		eventName: TokenEvents,
-		blockRange: BlockRange,
-		indexFilterValues: IndexedFilterValues,
-	): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
-		assert.isETHAddressHex('tokenAddress', tokenAddress);
-		assert.doesBelongToStringEnum('eventName', eventName, TokenEvents);
-		assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema);
-		assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
-		const logs = await this._getLogsAsync<ArgsType>(
-			tokenAddress,
-			eventName,
-			blockRange,
-			indexFilterValues,
-			artifacts.TokenArtifact.abi,
-		);
-		return logs;
-	}
-	private _invalidateContractInstances(): void {
-		this.unsubscribeAll();
-		this._tokenContractsByAddress = {};
-	}
-	private async _getTokenContractAsync(tokenAddress: string): Promise<TokenContract> {
-		let tokenContract = this._tokenContractsByAddress[tokenAddress];
-		if (!_.isUndefined(tokenContract)) {
-			return tokenContract;
-		}
-		const web3ContractInstance = await this._instantiateContractIfExistsAsync(
-			artifacts.TokenArtifact,
-			tokenAddress,
-		);
-		const contractInstance = new TokenContract(web3ContractInstance, this._web3Wrapper.getContractDefaults());
-		tokenContract = contractInstance;
-		this._tokenContractsByAddress[tokenAddress] = tokenContract;
-		return tokenContract;
-	}
+        const txHash = await tokenContract.transferFrom.sendTransactionAsync(
+            fromAddress,
+            toAddress,
+            amountInBaseUnits,
+            {
+                from: senderAddress,
+                gas: txOpts.gasLimit,
+                gasPrice: txOpts.gasPrice,
+            },
+        );
+        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<ArgsType extends TokenContractEventArgs>(
+        tokenAddress: string,
+        eventName: TokenEvents,
+        indexFilterValues: IndexedFilterValues,
+        callback: EventCallback<ArgsType>,
+    ): string {
+        assert.isETHAddressHex('tokenAddress', tokenAddress);
+        assert.doesBelongToStringEnum('eventName', eventName, TokenEvents);
+        assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
+        assert.isFunction('callback', callback);
+        const subscriptionToken = this._subscribe<ArgsType>(
+            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);
+    }
+    /**
+     * Cancels all existing subscriptions
+     */
+    public unsubscribeAll(): void {
+        super.unsubscribeAll();
+    }
+    /**
+     * 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   blockRange          Block range to get logs from.
+     * @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<ArgsType extends TokenContractEventArgs>(
+        tokenAddress: string,
+        eventName: TokenEvents,
+        blockRange: BlockRange,
+        indexFilterValues: IndexedFilterValues,
+    ): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
+        assert.isETHAddressHex('tokenAddress', tokenAddress);
+        assert.doesBelongToStringEnum('eventName', eventName, TokenEvents);
+        assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema);
+        assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
+        const logs = await this._getLogsAsync<ArgsType>(
+            tokenAddress,
+            eventName,
+            blockRange,
+            indexFilterValues,
+            artifacts.TokenArtifact.abi,
+        );
+        return logs;
+    }
+    private _invalidateContractInstances(): void {
+        this.unsubscribeAll();
+        this._tokenContractsByAddress = {};
+    }
+    private async _getTokenContractAsync(tokenAddress: string): Promise<TokenContract> {
+        let tokenContract = this._tokenContractsByAddress[tokenAddress];
+        if (!_.isUndefined(tokenContract)) {
+            return tokenContract;
+        }
+        const web3ContractInstance = await this._instantiateContractIfExistsAsync(
+            artifacts.TokenArtifact,
+            tokenAddress,
+        );
+        const contractInstance = new TokenContract(web3ContractInstance, this._web3Wrapper.getContractDefaults());
+        tokenContract = contractInstance;
+        this._tokenContractsByAddress[tokenAddress] = tokenContract;
+        return tokenContract;
+    }
 }
diff --git a/packages/0x.js/src/globals.d.ts b/packages/0x.js/src/globals.d.ts
index 9a53949b4..4f4932b6e 100644
--- a/packages/0x.js/src/globals.d.ts
+++ b/packages/0x.js/src/globals.d.ts
@@ -10,50 +10,50 @@ declare module 'web3-provider-engine/subproviders/rpc';
 // 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;
-	}
+    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 */
+    const json: any;
+    /* tslint:disable */
+    export default json;
+    /* tslint:enable */
 }
 
 declare module 'ethereumjs-abi' {
-	const soliditySHA3: (argTypes: string[], args: any[]) => Buffer;
+    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;
+    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[];
+    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[];
+    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[];
+    const decodeParams: (types: string[], data: string) => any[];
 }
diff --git a/packages/0x.js/src/globalsAugment.d.ts b/packages/0x.js/src/globalsAugment.d.ts
index c2f200ab8..3e2f2216b 100644
--- a/packages/0x.js/src/globalsAugment.d.ts
+++ b/packages/0x.js/src/globalsAugment.d.ts
@@ -3,21 +3,21 @@ import { BigNumber } from '@0xproject/utils';
 // 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;
-	}
+    // 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/packages/0x.js/src/index.ts b/packages/0x.js/src/index.ts
index ad5ef8534..599c3a2b0 100644
--- a/packages/0x.js/src/index.ts
+++ b/packages/0x.js/src/index.ts
@@ -1,50 +1,50 @@
 export { ZeroEx } from './0x';
 
 export {
-	Order,
-	BlockParamLiteral,
-	SignedOrder,
-	ECSignature,
-	ZeroExError,
-	EventCallback,
-	ExchangeContractErrs,
-	ContractEvent,
-	Token,
-	ExchangeEvents,
-	TokenEvents,
-	IndexedFilterValues,
-	BlockRange,
-	BlockParam,
-	OrderCancellationRequest,
-	OrderFillRequest,
-	LogErrorContractEventArgs,
-	LogCancelContractEventArgs,
-	LogFillContractEventArgs,
-	ExchangeContractEventArgs,
-	TransferContractEventArgs,
-	ApprovalContractEventArgs,
-	TokenContractEventArgs,
-	EtherTokenContractEventArgs,
-	WithdrawalContractEventArgs,
-	DepositContractEventArgs,
-	ContractEventArgs,
-	ContractEventArg,
-	Web3Provider,
-	ZeroExConfig,
-	EtherTokenEvents,
-	TransactionReceiptWithDecodedLogs,
-	LogWithDecodedArgs,
-	MethodOpts,
-	OrderTransactionOpts,
-	TransactionOpts,
-	FilterObject,
-	LogEvent,
-	DecodedLogEvent,
-	EventWatcherCallback,
-	OnOrderStateChangeCallback,
-	OrderStateValid,
-	OrderStateInvalid,
-	OrderState,
+    Order,
+    BlockParamLiteral,
+    SignedOrder,
+    ECSignature,
+    ZeroExError,
+    EventCallback,
+    ExchangeContractErrs,
+    ContractEvent,
+    Token,
+    ExchangeEvents,
+    TokenEvents,
+    IndexedFilterValues,
+    BlockRange,
+    BlockParam,
+    OrderCancellationRequest,
+    OrderFillRequest,
+    LogErrorContractEventArgs,
+    LogCancelContractEventArgs,
+    LogFillContractEventArgs,
+    ExchangeContractEventArgs,
+    TransferContractEventArgs,
+    ApprovalContractEventArgs,
+    TokenContractEventArgs,
+    EtherTokenContractEventArgs,
+    WithdrawalContractEventArgs,
+    DepositContractEventArgs,
+    ContractEventArgs,
+    ContractEventArg,
+    Web3Provider,
+    ZeroExConfig,
+    EtherTokenEvents,
+    TransactionReceiptWithDecodedLogs,
+    LogWithDecodedArgs,
+    MethodOpts,
+    OrderTransactionOpts,
+    TransactionOpts,
+    FilterObject,
+    LogEvent,
+    DecodedLogEvent,
+    EventWatcherCallback,
+    OnOrderStateChangeCallback,
+    OrderStateValid,
+    OrderStateInvalid,
+    OrderState,
 } from './types';
 
 export { TransactionReceipt } from '@0xproject/types';
diff --git a/packages/0x.js/src/order_watcher/event_watcher.ts b/packages/0x.js/src/order_watcher/event_watcher.ts
index 3e3cd978d..5d05bfb60 100644
--- a/packages/0x.js/src/order_watcher/event_watcher.ts
+++ b/packages/0x.js/src/order_watcher/event_watcher.ts
@@ -9,8 +9,8 @@ import { assert } from '../utils/assert';
 const DEFAULT_EVENT_POLLING_INTERVAL_MS = 200;
 
 enum LogEventState {
-	Removed,
-	Added,
+    Removed,
+    Added,
 }
 
 /*
@@ -18,76 +18,76 @@ enum LogEventState {
  * depth.
  */
 export class EventWatcher {
-	private _web3Wrapper: Web3Wrapper;
-	private _pollingIntervalMs: number;
-	private _intervalIdIfExists?: NodeJS.Timer;
-	private _lastEvents: Web3.LogEntry[] = [];
-	constructor(web3Wrapper: Web3Wrapper, pollingIntervalIfExistsMs: undefined | number) {
-		this._web3Wrapper = web3Wrapper;
-		this._pollingIntervalMs = _.isUndefined(pollingIntervalIfExistsMs)
-			? DEFAULT_EVENT_POLLING_INTERVAL_MS
-			: pollingIntervalIfExistsMs;
-	}
-	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,
-			(err: Error) => {
-				this.unsubscribe();
-				callback(err);
-			},
-		);
-	}
-	public unsubscribe(): void {
-		this._lastEvents = [];
-		if (!_.isUndefined(this._intervalIdIfExists)) {
-			intervalUtils.clearAsyncExcludingInterval(this._intervalIdIfExists);
-			delete this._intervalIdIfExists;
-		}
-	}
-	private async _pollForBlockchainEventsAsync(callback: EventWatcherCallback): Promise<void> {
-		const pendingEvents = await this._getEventsAsync();
-		if (_.isUndefined(pendingEvents)) {
-			// HACK: This should never happen, but happens frequently on CI due to a ganache bug
-			return;
-		}
-		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<Web3.LogEntry[]> {
-		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<void> {
-		for (const log of logs) {
-			const logEvent = {
-				removed: logEventState === LogEventState.Removed,
-				...log,
-			};
-			if (!_.isUndefined(this._intervalIdIfExists)) {
-				callback(null, logEvent);
-			}
-		}
-	}
+    private _web3Wrapper: Web3Wrapper;
+    private _pollingIntervalMs: number;
+    private _intervalIdIfExists?: NodeJS.Timer;
+    private _lastEvents: Web3.LogEntry[] = [];
+    constructor(web3Wrapper: Web3Wrapper, pollingIntervalIfExistsMs: undefined | number) {
+        this._web3Wrapper = web3Wrapper;
+        this._pollingIntervalMs = _.isUndefined(pollingIntervalIfExistsMs)
+            ? DEFAULT_EVENT_POLLING_INTERVAL_MS
+            : pollingIntervalIfExistsMs;
+    }
+    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,
+            (err: Error) => {
+                this.unsubscribe();
+                callback(err);
+            },
+        );
+    }
+    public unsubscribe(): void {
+        this._lastEvents = [];
+        if (!_.isUndefined(this._intervalIdIfExists)) {
+            intervalUtils.clearAsyncExcludingInterval(this._intervalIdIfExists);
+            delete this._intervalIdIfExists;
+        }
+    }
+    private async _pollForBlockchainEventsAsync(callback: EventWatcherCallback): Promise<void> {
+        const pendingEvents = await this._getEventsAsync();
+        if (_.isUndefined(pendingEvents)) {
+            // HACK: This should never happen, but happens frequently on CI due to a ganache bug
+            return;
+        }
+        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<Web3.LogEntry[]> {
+        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<void> {
+        for (const log of logs) {
+            const logEvent = {
+                removed: logEventState === LogEventState.Removed,
+                ...log,
+            };
+            if (!_.isUndefined(this._intervalIdIfExists)) {
+                callback(null, logEvent);
+            }
+        }
+    }
 }
diff --git a/packages/0x.js/src/order_watcher/expiration_watcher.ts b/packages/0x.js/src/order_watcher/expiration_watcher.ts
index a08de94c0..00b62162d 100644
--- a/packages/0x.js/src/order_watcher/expiration_watcher.ts
+++ b/packages/0x.js/src/order_watcher/expiration_watcher.ts
@@ -13,63 +13,63 @@ const DEFAULT_ORDER_EXPIRATION_CHECKING_INTERVAL_MS = 50;
  * It stores them in a min heap by expiration time and checks for expired ones every `orderExpirationCheckingIntervalMs`
  */
 export class ExpirationWatcher {
-	private _orderHashByExpirationRBTree: RBTree<string>;
-	private _expiration: { [orderHash: string]: BigNumber } = {};
-	private _orderExpirationCheckingIntervalMs: number;
-	private _expirationMarginMs: number;
-	private _orderExpirationCheckingIntervalIdIfExists?: NodeJS.Timer;
-	constructor(expirationMarginIfExistsMs?: number, orderExpirationCheckingIntervalIfExistsMs?: number) {
-		this._expirationMarginMs = expirationMarginIfExistsMs || DEFAULT_EXPIRATION_MARGIN_MS;
-		this._orderExpirationCheckingIntervalMs =
-			expirationMarginIfExistsMs || DEFAULT_ORDER_EXPIRATION_CHECKING_INTERVAL_MS;
-		const scoreFunction = (orderHash: string) => this._expiration[orderHash].toNumber();
-		const comparator = (lhs: string, rhs: string) => scoreFunction(lhs) - scoreFunction(rhs);
-		this._orderHashByExpirationRBTree = new RBTree(comparator);
-	}
-	public subscribe(callback: (orderHash: string) => void): void {
-		if (!_.isUndefined(this._orderExpirationCheckingIntervalIdIfExists)) {
-			throw new Error(ZeroExError.SubscriptionAlreadyPresent);
-		}
-		this._orderExpirationCheckingIntervalIdIfExists = intervalUtils.setInterval(
-			this._pruneExpiredOrders.bind(this, callback),
-			this._orderExpirationCheckingIntervalMs,
-			_.noop, // _pruneExpiredOrders never throws
-		);
-	}
-	public unsubscribe(): void {
-		if (_.isUndefined(this._orderExpirationCheckingIntervalIdIfExists)) {
-			throw new Error(ZeroExError.SubscriptionNotFound);
-		}
-		intervalUtils.clearInterval(this._orderExpirationCheckingIntervalIdIfExists);
-		delete this._orderExpirationCheckingIntervalIdIfExists;
-	}
-	public addOrder(orderHash: string, expirationUnixTimestampMs: BigNumber): void {
-		this._expiration[orderHash] = expirationUnixTimestampMs;
-		this._orderHashByExpirationRBTree.insert(orderHash);
-	}
-	public removeOrder(orderHash: string): void {
-		this._orderHashByExpirationRBTree.remove(orderHash);
-		delete this._expiration[orderHash];
-	}
-	private _pruneExpiredOrders(callback: (orderHash: string) => void): void {
-		const currentUnixTimestampMs = utils.getCurrentUnixTimestampMs();
-		while (true) {
-			const hasTrakedOrders = this._orderHashByExpirationRBTree.size === 0;
-			if (hasTrakedOrders) {
-				break;
-			}
-			const nextOrderHashToExpire = this._orderHashByExpirationRBTree.min();
-			const hasNoExpiredOrders = this._expiration[nextOrderHashToExpire].greaterThan(
-				currentUnixTimestampMs.plus(this._expirationMarginMs),
-			);
-			const isSubscriptionActive = _.isUndefined(this._orderExpirationCheckingIntervalIdIfExists);
-			if (hasNoExpiredOrders || isSubscriptionActive) {
-				break;
-			}
-			const orderHash = this._orderHashByExpirationRBTree.min();
-			this._orderHashByExpirationRBTree.remove(orderHash);
-			delete this._expiration[orderHash];
-			callback(orderHash);
-		}
-	}
+    private _orderHashByExpirationRBTree: RBTree<string>;
+    private _expiration: { [orderHash: string]: BigNumber } = {};
+    private _orderExpirationCheckingIntervalMs: number;
+    private _expirationMarginMs: number;
+    private _orderExpirationCheckingIntervalIdIfExists?: NodeJS.Timer;
+    constructor(expirationMarginIfExistsMs?: number, orderExpirationCheckingIntervalIfExistsMs?: number) {
+        this._expirationMarginMs = expirationMarginIfExistsMs || DEFAULT_EXPIRATION_MARGIN_MS;
+        this._orderExpirationCheckingIntervalMs =
+            expirationMarginIfExistsMs || DEFAULT_ORDER_EXPIRATION_CHECKING_INTERVAL_MS;
+        const scoreFunction = (orderHash: string) => this._expiration[orderHash].toNumber();
+        const comparator = (lhs: string, rhs: string) => scoreFunction(lhs) - scoreFunction(rhs);
+        this._orderHashByExpirationRBTree = new RBTree(comparator);
+    }
+    public subscribe(callback: (orderHash: string) => void): void {
+        if (!_.isUndefined(this._orderExpirationCheckingIntervalIdIfExists)) {
+            throw new Error(ZeroExError.SubscriptionAlreadyPresent);
+        }
+        this._orderExpirationCheckingIntervalIdIfExists = intervalUtils.setInterval(
+            this._pruneExpiredOrders.bind(this, callback),
+            this._orderExpirationCheckingIntervalMs,
+            _.noop, // _pruneExpiredOrders never throws
+        );
+    }
+    public unsubscribe(): void {
+        if (_.isUndefined(this._orderExpirationCheckingIntervalIdIfExists)) {
+            throw new Error(ZeroExError.SubscriptionNotFound);
+        }
+        intervalUtils.clearInterval(this._orderExpirationCheckingIntervalIdIfExists);
+        delete this._orderExpirationCheckingIntervalIdIfExists;
+    }
+    public addOrder(orderHash: string, expirationUnixTimestampMs: BigNumber): void {
+        this._expiration[orderHash] = expirationUnixTimestampMs;
+        this._orderHashByExpirationRBTree.insert(orderHash);
+    }
+    public removeOrder(orderHash: string): void {
+        this._orderHashByExpirationRBTree.remove(orderHash);
+        delete this._expiration[orderHash];
+    }
+    private _pruneExpiredOrders(callback: (orderHash: string) => void): void {
+        const currentUnixTimestampMs = utils.getCurrentUnixTimestampMs();
+        while (true) {
+            const hasTrakedOrders = this._orderHashByExpirationRBTree.size === 0;
+            if (hasTrakedOrders) {
+                break;
+            }
+            const nextOrderHashToExpire = this._orderHashByExpirationRBTree.min();
+            const hasNoExpiredOrders = this._expiration[nextOrderHashToExpire].greaterThan(
+                currentUnixTimestampMs.plus(this._expirationMarginMs),
+            );
+            const isSubscriptionActive = _.isUndefined(this._orderExpirationCheckingIntervalIdIfExists);
+            if (hasNoExpiredOrders || isSubscriptionActive) {
+                break;
+            }
+            const orderHash = this._orderHashByExpirationRBTree.min();
+            this._orderHashByExpirationRBTree.remove(orderHash);
+            delete this._expiration[orderHash];
+            callback(orderHash);
+        }
+    }
 }
diff --git a/packages/0x.js/src/order_watcher/order_state_watcher.ts b/packages/0x.js/src/order_watcher/order_state_watcher.ts
index 2c5da6b57..12ac60960 100644
--- a/packages/0x.js/src/order_watcher/order_state_watcher.ts
+++ b/packages/0x.js/src/order_watcher/order_state_watcher.ts
@@ -9,25 +9,25 @@ import { TokenWrapper } from '../contract_wrappers/token_wrapper';
 import { BalanceAndProxyAllowanceLazyStore } from '../stores/balance_proxy_allowance_lazy_store';
 import { OrderFilledCancelledLazyStore } from '../stores/order_filled_cancelled_lazy_store';
 import {
-	ApprovalContractEventArgs,
-	BlockParamLiteral,
-	ContractEventArgs,
-	DepositContractEventArgs,
-	EtherTokenEvents,
-	ExchangeContractErrs,
-	ExchangeEvents,
-	LogCancelContractEventArgs,
-	LogEvent,
-	LogFillContractEventArgs,
-	LogWithDecodedArgs,
-	OnOrderStateChangeCallback,
-	OrderState,
-	OrderStateWatcherConfig,
-	SignedOrder,
-	TokenEvents,
-	TransferContractEventArgs,
-	WithdrawalContractEventArgs,
-	ZeroExError,
+    ApprovalContractEventArgs,
+    BlockParamLiteral,
+    ContractEventArgs,
+    DepositContractEventArgs,
+    EtherTokenEvents,
+    ExchangeContractErrs,
+    ExchangeEvents,
+    LogCancelContractEventArgs,
+    LogEvent,
+    LogFillContractEventArgs,
+    LogWithDecodedArgs,
+    OnOrderStateChangeCallback,
+    OrderState,
+    OrderStateWatcherConfig,
+    SignedOrder,
+    TokenEvents,
+    TransferContractEventArgs,
+    WithdrawalContractEventArgs,
+    ZeroExError,
 } from '../types';
 import { AbiDecoder } from '../utils/abi_decoder';
 import { assert } from '../utils/assert';
@@ -38,17 +38,17 @@ import { EventWatcher } from './event_watcher';
 import { ExpirationWatcher } from './expiration_watcher';
 
 interface DependentOrderHashes {
-	[makerAddress: string]: {
-		[makerToken: string]: Set<string>;
-	};
+    [makerAddress: string]: {
+        [makerToken: string]: Set<string>;
+    };
 }
 
 interface OrderByOrderHash {
-	[orderHash: string]: SignedOrder;
+    [orderHash: string]: SignedOrder;
 }
 
 interface OrderStateByOrderHash {
-	[orderHash: string]: OrderState;
+    [orderHash: string]: OrderState;
 }
 
 const DEFAULT_CLEANUP_JOB_INTERVAL_MS = 1000 * 60 * 60; // 1h
@@ -60,319 +60,319 @@ const DEFAULT_CLEANUP_JOB_INTERVAL_MS = 1000 * 60 * 60; // 1h
  * the order should be deemed invalid.
  */
 export class OrderStateWatcher {
-	private _orderStateByOrderHashCache: OrderStateByOrderHash = {};
-	private _orderByOrderHash: OrderByOrderHash = {};
-	private _dependentOrderHashes: DependentOrderHashes = {};
-	private _callbackIfExists?: OnOrderStateChangeCallback;
-	private _eventWatcher: EventWatcher;
-	private _web3Wrapper: Web3Wrapper;
-	private _abiDecoder: AbiDecoder;
-	private _expirationWatcher: ExpirationWatcher;
-	private _orderStateUtils: OrderStateUtils;
-	private _orderFilledCancelledLazyStore: OrderFilledCancelledLazyStore;
-	private _balanceAndProxyAllowanceLazyStore: BalanceAndProxyAllowanceLazyStore;
-	private _cleanupJobInterval: number;
-	private _cleanupJobIntervalIdIfExists?: NodeJS.Timer;
-	constructor(
-		web3Wrapper: Web3Wrapper,
-		abiDecoder: AbiDecoder,
-		token: TokenWrapper,
-		exchange: ExchangeWrapper,
-		config?: OrderStateWatcherConfig,
-	) {
-		this._abiDecoder = abiDecoder;
-		this._web3Wrapper = web3Wrapper;
-		const pollingIntervalIfExistsMs = _.isUndefined(config) ? undefined : config.eventPollingIntervalMs;
-		this._eventWatcher = new EventWatcher(web3Wrapper, pollingIntervalIfExistsMs);
-		this._balanceAndProxyAllowanceLazyStore = new BalanceAndProxyAllowanceLazyStore(
-			token,
-			BlockParamLiteral.Pending,
-		);
-		this._orderFilledCancelledLazyStore = new OrderFilledCancelledLazyStore(exchange);
-		this._orderStateUtils = new OrderStateUtils(
-			this._balanceAndProxyAllowanceLazyStore,
-			this._orderFilledCancelledLazyStore,
-		);
-		const orderExpirationCheckingIntervalMsIfExists = _.isUndefined(config)
-			? undefined
-			: config.orderExpirationCheckingIntervalMs;
-		const expirationMarginIfExistsMs = _.isUndefined(config) ? undefined : config.expirationMarginMs;
-		this._expirationWatcher = new ExpirationWatcher(
-			expirationMarginIfExistsMs,
-			orderExpirationCheckingIntervalMsIfExists,
-		);
-		this._cleanupJobInterval =
-			_.isUndefined(config) || _.isUndefined(config.cleanupJobIntervalMs)
-				? DEFAULT_CLEANUP_JOB_INTERVAL_MS
-				: config.cleanupJobIntervalMs;
-	}
-	/**
-	 * 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);
-		const expirationUnixTimestampMs = signedOrder.expirationUnixTimestampSec.times(1000);
-		this._expirationWatcher.addOrder(orderHash, expirationUnixTimestampMs);
-	}
-	/**
-	 * 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];
-		delete this._orderStateByOrderHashCache[orderHash];
-		const exchange = (this._orderFilledCancelledLazyStore as any)._exchange as ExchangeWrapper;
-		const zrxTokenAddress = exchange.getZRXTokenAddress();
-		this._removeFromDependentOrderHashes(signedOrder.maker, zrxTokenAddress, orderHash);
-		this._removeFromDependentOrderHashes(signedOrder.maker, signedOrder.makerTokenAddress, orderHash);
-		this._expirationWatcher.removeOrder(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._callbackIfExists)) {
-			throw new Error(ZeroExError.SubscriptionAlreadyPresent);
-		}
-		this._callbackIfExists = callback;
-		this._eventWatcher.subscribe(this._onEventWatcherCallbackAsync.bind(this));
-		this._expirationWatcher.subscribe(this._onOrderExpired.bind(this));
-		this._cleanupJobIntervalIdIfExists = intervalUtils.setAsyncExcludingInterval(
-			this._cleanupAsync.bind(this),
-			this._cleanupJobInterval,
-			(err: Error) => {
-				this.unsubscribe();
-				callback(err);
-			},
-		);
-	}
-	/**
-	 * Ends an orderStateWatcher subscription.
-	 */
-	public unsubscribe(): void {
-		if (_.isUndefined(this._callbackIfExists) || _.isUndefined(this._cleanupJobIntervalIdIfExists)) {
-			throw new Error(ZeroExError.SubscriptionNotFound);
-		}
-		this._balanceAndProxyAllowanceLazyStore.deleteAll();
-		this._orderFilledCancelledLazyStore.deleteAll();
-		delete this._callbackIfExists;
-		this._eventWatcher.unsubscribe();
-		this._expirationWatcher.unsubscribe();
-		intervalUtils.clearAsyncExcludingInterval(this._cleanupJobIntervalIdIfExists);
-	}
-	private async _cleanupAsync(): Promise<void> {
-		for (const orderHash of _.keys(this._orderByOrderHash)) {
-			this._cleanupOrderRelatedState(orderHash);
-			await this._emitRevalidateOrdersAsync([orderHash]);
-		}
-	}
-	private _cleanupOrderRelatedState(orderHash: string): void {
-		const signedOrder = this._orderByOrderHash[orderHash];
+    private _orderStateByOrderHashCache: OrderStateByOrderHash = {};
+    private _orderByOrderHash: OrderByOrderHash = {};
+    private _dependentOrderHashes: DependentOrderHashes = {};
+    private _callbackIfExists?: OnOrderStateChangeCallback;
+    private _eventWatcher: EventWatcher;
+    private _web3Wrapper: Web3Wrapper;
+    private _abiDecoder: AbiDecoder;
+    private _expirationWatcher: ExpirationWatcher;
+    private _orderStateUtils: OrderStateUtils;
+    private _orderFilledCancelledLazyStore: OrderFilledCancelledLazyStore;
+    private _balanceAndProxyAllowanceLazyStore: BalanceAndProxyAllowanceLazyStore;
+    private _cleanupJobInterval: number;
+    private _cleanupJobIntervalIdIfExists?: NodeJS.Timer;
+    constructor(
+        web3Wrapper: Web3Wrapper,
+        abiDecoder: AbiDecoder,
+        token: TokenWrapper,
+        exchange: ExchangeWrapper,
+        config?: OrderStateWatcherConfig,
+    ) {
+        this._abiDecoder = abiDecoder;
+        this._web3Wrapper = web3Wrapper;
+        const pollingIntervalIfExistsMs = _.isUndefined(config) ? undefined : config.eventPollingIntervalMs;
+        this._eventWatcher = new EventWatcher(web3Wrapper, pollingIntervalIfExistsMs);
+        this._balanceAndProxyAllowanceLazyStore = new BalanceAndProxyAllowanceLazyStore(
+            token,
+            BlockParamLiteral.Pending,
+        );
+        this._orderFilledCancelledLazyStore = new OrderFilledCancelledLazyStore(exchange);
+        this._orderStateUtils = new OrderStateUtils(
+            this._balanceAndProxyAllowanceLazyStore,
+            this._orderFilledCancelledLazyStore,
+        );
+        const orderExpirationCheckingIntervalMsIfExists = _.isUndefined(config)
+            ? undefined
+            : config.orderExpirationCheckingIntervalMs;
+        const expirationMarginIfExistsMs = _.isUndefined(config) ? undefined : config.expirationMarginMs;
+        this._expirationWatcher = new ExpirationWatcher(
+            expirationMarginIfExistsMs,
+            orderExpirationCheckingIntervalMsIfExists,
+        );
+        this._cleanupJobInterval =
+            _.isUndefined(config) || _.isUndefined(config.cleanupJobIntervalMs)
+                ? DEFAULT_CLEANUP_JOB_INTERVAL_MS
+                : config.cleanupJobIntervalMs;
+    }
+    /**
+     * 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);
+        const expirationUnixTimestampMs = signedOrder.expirationUnixTimestampSec.times(1000);
+        this._expirationWatcher.addOrder(orderHash, expirationUnixTimestampMs);
+    }
+    /**
+     * 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];
+        delete this._orderStateByOrderHashCache[orderHash];
+        const exchange = (this._orderFilledCancelledLazyStore as any)._exchange as ExchangeWrapper;
+        const zrxTokenAddress = exchange.getZRXTokenAddress();
+        this._removeFromDependentOrderHashes(signedOrder.maker, zrxTokenAddress, orderHash);
+        this._removeFromDependentOrderHashes(signedOrder.maker, signedOrder.makerTokenAddress, orderHash);
+        this._expirationWatcher.removeOrder(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._callbackIfExists)) {
+            throw new Error(ZeroExError.SubscriptionAlreadyPresent);
+        }
+        this._callbackIfExists = callback;
+        this._eventWatcher.subscribe(this._onEventWatcherCallbackAsync.bind(this));
+        this._expirationWatcher.subscribe(this._onOrderExpired.bind(this));
+        this._cleanupJobIntervalIdIfExists = intervalUtils.setAsyncExcludingInterval(
+            this._cleanupAsync.bind(this),
+            this._cleanupJobInterval,
+            (err: Error) => {
+                this.unsubscribe();
+                callback(err);
+            },
+        );
+    }
+    /**
+     * Ends an orderStateWatcher subscription.
+     */
+    public unsubscribe(): void {
+        if (_.isUndefined(this._callbackIfExists) || _.isUndefined(this._cleanupJobIntervalIdIfExists)) {
+            throw new Error(ZeroExError.SubscriptionNotFound);
+        }
+        this._balanceAndProxyAllowanceLazyStore.deleteAll();
+        this._orderFilledCancelledLazyStore.deleteAll();
+        delete this._callbackIfExists;
+        this._eventWatcher.unsubscribe();
+        this._expirationWatcher.unsubscribe();
+        intervalUtils.clearAsyncExcludingInterval(this._cleanupJobIntervalIdIfExists);
+    }
+    private async _cleanupAsync(): Promise<void> {
+        for (const orderHash of _.keys(this._orderByOrderHash)) {
+            this._cleanupOrderRelatedState(orderHash);
+            await this._emitRevalidateOrdersAsync([orderHash]);
+        }
+    }
+    private _cleanupOrderRelatedState(orderHash: string): void {
+        const signedOrder = this._orderByOrderHash[orderHash];
 
-		this._orderFilledCancelledLazyStore.deleteFilledTakerAmount(orderHash);
-		this._orderFilledCancelledLazyStore.deleteCancelledTakerAmount(orderHash);
+        this._orderFilledCancelledLazyStore.deleteFilledTakerAmount(orderHash);
+        this._orderFilledCancelledLazyStore.deleteCancelledTakerAmount(orderHash);
 
-		this._balanceAndProxyAllowanceLazyStore.deleteBalance(signedOrder.makerTokenAddress, signedOrder.maker);
-		this._balanceAndProxyAllowanceLazyStore.deleteProxyAllowance(signedOrder.makerTokenAddress, signedOrder.maker);
-		this._balanceAndProxyAllowanceLazyStore.deleteBalance(signedOrder.takerTokenAddress, signedOrder.taker);
-		this._balanceAndProxyAllowanceLazyStore.deleteProxyAllowance(signedOrder.takerTokenAddress, signedOrder.taker);
+        this._balanceAndProxyAllowanceLazyStore.deleteBalance(signedOrder.makerTokenAddress, signedOrder.maker);
+        this._balanceAndProxyAllowanceLazyStore.deleteProxyAllowance(signedOrder.makerTokenAddress, signedOrder.maker);
+        this._balanceAndProxyAllowanceLazyStore.deleteBalance(signedOrder.takerTokenAddress, signedOrder.taker);
+        this._balanceAndProxyAllowanceLazyStore.deleteProxyAllowance(signedOrder.takerTokenAddress, signedOrder.taker);
 
-		const zrxTokenAddress = this._getZRXTokenAddress();
-		if (!signedOrder.makerFee.isZero()) {
-			this._balanceAndProxyAllowanceLazyStore.deleteBalance(zrxTokenAddress, signedOrder.maker);
-			this._balanceAndProxyAllowanceLazyStore.deleteProxyAllowance(zrxTokenAddress, signedOrder.maker);
-		}
-		if (!signedOrder.takerFee.isZero()) {
-			this._balanceAndProxyAllowanceLazyStore.deleteBalance(zrxTokenAddress, signedOrder.taker);
-			this._balanceAndProxyAllowanceLazyStore.deleteProxyAllowance(zrxTokenAddress, signedOrder.taker);
-		}
-	}
-	private _onOrderExpired(orderHash: string): void {
-		const orderState: OrderState = {
-			isValid: false,
-			orderHash,
-			error: ExchangeContractErrs.OrderFillExpired,
-		};
-		if (!_.isUndefined(this._orderByOrderHash[orderHash])) {
-			this.removeOrder(orderHash);
-			if (!_.isUndefined(this._callbackIfExists)) {
-				this._callbackIfExists(null, orderState);
-			}
-		}
-	}
-	private async _onEventWatcherCallbackAsync(err: Error | null, logIfExists?: LogEvent): Promise<void> {
-		if (!_.isNull(err)) {
-			if (!_.isUndefined(this._callbackIfExists)) {
-				this._callbackIfExists(err);
-				this.unsubscribe();
-			}
-			return;
-		}
-		const log = logIfExists as LogEvent; // At this moment we are sure that no error occured and log is defined.
-		const maybeDecodedLog = this._abiDecoder.tryToDecodeLogOrNoop(log);
-		const isLogDecoded = !_.isUndefined((maybeDecodedLog as LogWithDecodedArgs<any>).event);
-		if (!isLogDecoded) {
-			return; // noop
-		}
-		const decodedLog = maybeDecodedLog as LogWithDecodedArgs<ContractEventArgs>;
-		let makerToken: string;
-		let makerAddress: string;
-		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;
-				if (
-					!_.isUndefined(this._dependentOrderHashes[makerAddress]) &&
-					!_.isUndefined(this._dependentOrderHashes[makerAddress][makerToken])
-				) {
-					const orderHashes = Array.from(this._dependentOrderHashes[makerAddress][makerToken]);
-					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;
-				if (
-					!_.isUndefined(this._dependentOrderHashes[makerAddress]) &&
-					!_.isUndefined(this._dependentOrderHashes[makerAddress][makerToken])
-				) {
-					const orderHashes = Array.from(this._dependentOrderHashes[makerAddress][makerToken]);
-					await this._emitRevalidateOrdersAsync(orderHashes);
-				}
-				break;
-			}
-			case EtherTokenEvents.Deposit: {
-				// Invalidate cache
-				const args = decodedLog.args as DepositContractEventArgs;
-				this._balanceAndProxyAllowanceLazyStore.deleteBalance(decodedLog.address, args._owner);
-				// Revalidate orders
-				makerToken = decodedLog.address;
-				makerAddress = args._owner;
-				if (
-					!_.isUndefined(this._dependentOrderHashes[makerAddress]) &&
-					!_.isUndefined(this._dependentOrderHashes[makerAddress][makerToken])
-				) {
-					const orderHashes = Array.from(this._dependentOrderHashes[makerAddress][makerToken]);
-					await this._emitRevalidateOrdersAsync(orderHashes);
-				}
-				break;
-			}
-			case EtherTokenEvents.Withdrawal: {
-				// Invalidate cache
-				const args = decodedLog.args as WithdrawalContractEventArgs;
-				this._balanceAndProxyAllowanceLazyStore.deleteBalance(decodedLog.address, args._owner);
-				// Revalidate orders
-				makerToken = decodedLog.address;
-				makerAddress = args._owner;
-				if (
-					!_.isUndefined(this._dependentOrderHashes[makerAddress]) &&
-					!_.isUndefined(this._dependentOrderHashes[makerAddress][makerToken])
-				) {
-					const orderHashes = Array.from(this._dependentOrderHashes[makerAddress][makerToken]);
-					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
+        const zrxTokenAddress = this._getZRXTokenAddress();
+        if (!signedOrder.makerFee.isZero()) {
+            this._balanceAndProxyAllowanceLazyStore.deleteBalance(zrxTokenAddress, signedOrder.maker);
+            this._balanceAndProxyAllowanceLazyStore.deleteProxyAllowance(zrxTokenAddress, signedOrder.maker);
+        }
+        if (!signedOrder.takerFee.isZero()) {
+            this._balanceAndProxyAllowanceLazyStore.deleteBalance(zrxTokenAddress, signedOrder.taker);
+            this._balanceAndProxyAllowanceLazyStore.deleteProxyAllowance(zrxTokenAddress, signedOrder.taker);
+        }
+    }
+    private _onOrderExpired(orderHash: string): void {
+        const orderState: OrderState = {
+            isValid: false,
+            orderHash,
+            error: ExchangeContractErrs.OrderFillExpired,
+        };
+        if (!_.isUndefined(this._orderByOrderHash[orderHash])) {
+            this.removeOrder(orderHash);
+            if (!_.isUndefined(this._callbackIfExists)) {
+                this._callbackIfExists(null, orderState);
+            }
+        }
+    }
+    private async _onEventWatcherCallbackAsync(err: Error | null, logIfExists?: LogEvent): Promise<void> {
+        if (!_.isNull(err)) {
+            if (!_.isUndefined(this._callbackIfExists)) {
+                this._callbackIfExists(err);
+                this.unsubscribe();
+            }
+            return;
+        }
+        const log = logIfExists as LogEvent; // At this moment we are sure that no error occured and log is defined.
+        const maybeDecodedLog = this._abiDecoder.tryToDecodeLogOrNoop(log);
+        const isLogDecoded = !_.isUndefined((maybeDecodedLog as LogWithDecodedArgs<any>).event);
+        if (!isLogDecoded) {
+            return; // noop
+        }
+        const decodedLog = maybeDecodedLog as LogWithDecodedArgs<ContractEventArgs>;
+        let makerToken: string;
+        let makerAddress: string;
+        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;
+                if (
+                    !_.isUndefined(this._dependentOrderHashes[makerAddress]) &&
+                    !_.isUndefined(this._dependentOrderHashes[makerAddress][makerToken])
+                ) {
+                    const orderHashes = Array.from(this._dependentOrderHashes[makerAddress][makerToken]);
+                    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;
+                if (
+                    !_.isUndefined(this._dependentOrderHashes[makerAddress]) &&
+                    !_.isUndefined(this._dependentOrderHashes[makerAddress][makerToken])
+                ) {
+                    const orderHashes = Array.from(this._dependentOrderHashes[makerAddress][makerToken]);
+                    await this._emitRevalidateOrdersAsync(orderHashes);
+                }
+                break;
+            }
+            case EtherTokenEvents.Deposit: {
+                // Invalidate cache
+                const args = decodedLog.args as DepositContractEventArgs;
+                this._balanceAndProxyAllowanceLazyStore.deleteBalance(decodedLog.address, args._owner);
+                // Revalidate orders
+                makerToken = decodedLog.address;
+                makerAddress = args._owner;
+                if (
+                    !_.isUndefined(this._dependentOrderHashes[makerAddress]) &&
+                    !_.isUndefined(this._dependentOrderHashes[makerAddress][makerToken])
+                ) {
+                    const orderHashes = Array.from(this._dependentOrderHashes[makerAddress][makerToken]);
+                    await this._emitRevalidateOrdersAsync(orderHashes);
+                }
+                break;
+            }
+            case EtherTokenEvents.Withdrawal: {
+                // Invalidate cache
+                const args = decodedLog.args as WithdrawalContractEventArgs;
+                this._balanceAndProxyAllowanceLazyStore.deleteBalance(decodedLog.address, args._owner);
+                // Revalidate orders
+                makerToken = decodedLog.address;
+                makerAddress = args._owner;
+                if (
+                    !_.isUndefined(this._dependentOrderHashes[makerAddress]) &&
+                    !_.isUndefined(this._dependentOrderHashes[makerAddress][makerToken])
+                ) {
+                    const orderHashes = Array.from(this._dependentOrderHashes[makerAddress][makerToken]);
+                    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<void> {
-		for (const orderHash of orderHashes) {
-			const signedOrder = this._orderByOrderHash[orderHash];
-			// 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._callbackIfExists)) {
-				break; // Unsubscribe was called
-			}
-			if (_.isEqual(orderState, this._orderStateByOrderHashCache[orderHash])) {
-				// Actual order state didn't change
-				continue;
-			} else {
-				this._orderStateByOrderHashCache[orderHash] = orderState;
-			}
-			this._callbackIfExists(null, orderState);
-		}
-	}
-	private _addToDependentOrderHashes(signedOrder: SignedOrder, orderHash: string): void {
-		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);
-		const zrxTokenAddress = this._getZRXTokenAddress();
-		if (_.isUndefined(this._dependentOrderHashes[signedOrder.maker][zrxTokenAddress])) {
-			this._dependentOrderHashes[signedOrder.maker][zrxTokenAddress] = new Set();
-		}
-		this._dependentOrderHashes[signedOrder.maker][zrxTokenAddress].add(orderHash);
-	}
-	private _removeFromDependentOrderHashes(makerAddress: string, tokenAddress: string, orderHash: string) {
-		this._dependentOrderHashes[makerAddress][tokenAddress].delete(orderHash);
-		if (this._dependentOrderHashes[makerAddress][tokenAddress].size === 0) {
-			delete this._dependentOrderHashes[makerAddress][tokenAddress];
-		}
-		if (_.isEmpty(this._dependentOrderHashes[makerAddress])) {
-			delete this._dependentOrderHashes[makerAddress];
-		}
-	}
-	private _getZRXTokenAddress(): string {
-		const exchange = (this._orderFilledCancelledLazyStore as any)._exchange as ExchangeWrapper;
-		const zrxTokenAddress = exchange.getZRXTokenAddress();
-		return zrxTokenAddress;
-	}
+            default:
+                throw utils.spawnSwitchErr('decodedLog.event', decodedLog.event);
+        }
+    }
+    private async _emitRevalidateOrdersAsync(orderHashes: string[]): Promise<void> {
+        for (const orderHash of orderHashes) {
+            const signedOrder = this._orderByOrderHash[orderHash];
+            // 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._callbackIfExists)) {
+                break; // Unsubscribe was called
+            }
+            if (_.isEqual(orderState, this._orderStateByOrderHashCache[orderHash])) {
+                // Actual order state didn't change
+                continue;
+            } else {
+                this._orderStateByOrderHashCache[orderHash] = orderState;
+            }
+            this._callbackIfExists(null, orderState);
+        }
+    }
+    private _addToDependentOrderHashes(signedOrder: SignedOrder, orderHash: string): void {
+        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);
+        const zrxTokenAddress = this._getZRXTokenAddress();
+        if (_.isUndefined(this._dependentOrderHashes[signedOrder.maker][zrxTokenAddress])) {
+            this._dependentOrderHashes[signedOrder.maker][zrxTokenAddress] = new Set();
+        }
+        this._dependentOrderHashes[signedOrder.maker][zrxTokenAddress].add(orderHash);
+    }
+    private _removeFromDependentOrderHashes(makerAddress: string, tokenAddress: string, orderHash: string) {
+        this._dependentOrderHashes[makerAddress][tokenAddress].delete(orderHash);
+        if (this._dependentOrderHashes[makerAddress][tokenAddress].size === 0) {
+            delete this._dependentOrderHashes[makerAddress][tokenAddress];
+        }
+        if (_.isEmpty(this._dependentOrderHashes[makerAddress])) {
+            delete this._dependentOrderHashes[makerAddress];
+        }
+    }
+    private _getZRXTokenAddress(): string {
+        const exchange = (this._orderFilledCancelledLazyStore as any)._exchange as ExchangeWrapper;
+        const zrxTokenAddress = exchange.getZRXTokenAddress();
+        return zrxTokenAddress;
+    }
 }
diff --git a/packages/0x.js/src/order_watcher/remaining_fillable_calculator.ts b/packages/0x.js/src/order_watcher/remaining_fillable_calculator.ts
index e010092af..20b09d606 100644
--- a/packages/0x.js/src/order_watcher/remaining_fillable_calculator.ts
+++ b/packages/0x.js/src/order_watcher/remaining_fillable_calculator.ts
@@ -3,94 +3,94 @@ import { BigNumber } from '@0xproject/utils';
 import { SignedOrder } from '../types';
 
 export class RemainingFillableCalculator {
-	private _signedOrder: SignedOrder;
-	private _isMakerTokenZRX: boolean;
-	// Transferrable Amount is the minimum of Approval and Balance
-	private _transferrableMakerTokenAmount: BigNumber;
-	private _transferrableMakerFeeTokenAmount: BigNumber;
-	private _remainingMakerTokenAmount: BigNumber;
-	private _remainingMakerFeeAmount: BigNumber;
-	constructor(
-		signedOrder: SignedOrder,
-		isMakerTokenZRX: boolean,
-		transferrableMakerTokenAmount: BigNumber,
-		transferrableMakerFeeTokenAmount: BigNumber,
-		remainingMakerTokenAmount: BigNumber,
-	) {
-		this._signedOrder = signedOrder;
-		this._isMakerTokenZRX = isMakerTokenZRX;
-		this._transferrableMakerTokenAmount = transferrableMakerTokenAmount;
-		this._transferrableMakerFeeTokenAmount = transferrableMakerFeeTokenAmount;
-		this._remainingMakerTokenAmount = remainingMakerTokenAmount;
-		this._remainingMakerFeeAmount = remainingMakerTokenAmount
-			.times(signedOrder.makerFee)
-			.dividedToIntegerBy(signedOrder.makerTokenAmount);
-	}
-	public computeRemainingMakerFillable(): BigNumber {
-		if (this._hasSufficientFundsForFeeAndTransferAmount()) {
-			return this._remainingMakerTokenAmount;
-		}
-		if (this._signedOrder.makerFee.isZero()) {
-			return BigNumber.min(this._remainingMakerTokenAmount, this._transferrableMakerTokenAmount);
-		}
-		return this._calculatePartiallyFillableMakerTokenAmount();
-	}
-	public computeRemainingTakerFillable(): BigNumber {
-		return this.computeRemainingMakerFillable()
-			.times(this._signedOrder.takerTokenAmount)
-			.dividedToIntegerBy(this._signedOrder.makerTokenAmount);
-	}
-	private _hasSufficientFundsForFeeAndTransferAmount(): boolean {
-		if (this._isMakerTokenZRX) {
-			const totalZRXTransferAmountRequired = this._remainingMakerTokenAmount.plus(this._remainingMakerFeeAmount);
-			const hasSufficientFunds = this._transferrableMakerTokenAmount.greaterThanOrEqualTo(
-				totalZRXTransferAmountRequired,
-			);
-			return hasSufficientFunds;
-		} else {
-			const hasSufficientFundsForTransferAmount = this._transferrableMakerTokenAmount.greaterThanOrEqualTo(
-				this._remainingMakerTokenAmount,
-			);
-			const hasSufficientFundsForFeeAmount = this._transferrableMakerFeeTokenAmount.greaterThanOrEqualTo(
-				this._remainingMakerFeeAmount,
-			);
-			const hasSufficientFunds = hasSufficientFundsForTransferAmount && hasSufficientFundsForFeeAmount;
-			return hasSufficientFunds;
-		}
-	}
-	private _calculatePartiallyFillableMakerTokenAmount(): BigNumber {
-		// Given an order for 200 wei for 2 ZRXwei fee, find 100 wei for 1 ZRXwei. Order ratio is then 100:1
-		const orderToFeeRatio = this._signedOrder.makerTokenAmount.dividedBy(this._signedOrder.makerFee);
-		// The number of times the maker can fill the order, if each fill only required the transfer of a single
-		// baseUnit of fee tokens.
-		// Given 2 ZRXwei, the maximum amount of times Maker can fill this order, in terms of fees, is 2
-		const fillableTimesInFeeTokenBaseUnits = BigNumber.min(
-			this._transferrableMakerFeeTokenAmount,
-			this._remainingMakerFeeAmount,
-		);
-		// The number of times the Maker can fill the order, given the Maker Token Balance
-		// Assuming a balance of 150 wei, and an orderToFeeRatio of 100:1, maker can fill this order 1 time.
-		let fillableTimesInMakerTokenUnits = this._transferrableMakerTokenAmount.dividedBy(orderToFeeRatio);
-		if (this._isMakerTokenZRX) {
-			// If ZRX is the maker token, the Fee and the Maker amount need to be removed from the same pool;
-			// 200 ZRXwei for 2ZRXwei fee can only be filled once (need 202 ZRXwei)
-			const totalZRXTokenPooled = this._transferrableMakerTokenAmount;
-			// The purchasing power here is less as the tokens are taken from the same Pool
-			// For every one number of fills, we have to take an extra ZRX out of the pool
-			fillableTimesInMakerTokenUnits = totalZRXTokenPooled.dividedBy(orderToFeeRatio.plus(new BigNumber(1)));
-		}
-		// When Ratio is not fully divisible there can be remainders which cannot be represented, so they are floored.
-		// This can result in a RoundingError being thrown by the Exchange Contract.
-		const partiallyFillableMakerTokenAmount = fillableTimesInMakerTokenUnits
-			.times(this._signedOrder.makerTokenAmount)
-			.dividedToIntegerBy(this._signedOrder.makerFee);
-		const partiallyFillableFeeTokenAmount = fillableTimesInFeeTokenBaseUnits
-			.times(this._signedOrder.makerTokenAmount)
-			.dividedToIntegerBy(this._signedOrder.makerFee);
-		const partiallyFillableAmount = BigNumber.min(
-			partiallyFillableMakerTokenAmount,
-			partiallyFillableFeeTokenAmount,
-		);
-		return partiallyFillableAmount;
-	}
+    private _signedOrder: SignedOrder;
+    private _isMakerTokenZRX: boolean;
+    // Transferrable Amount is the minimum of Approval and Balance
+    private _transferrableMakerTokenAmount: BigNumber;
+    private _transferrableMakerFeeTokenAmount: BigNumber;
+    private _remainingMakerTokenAmount: BigNumber;
+    private _remainingMakerFeeAmount: BigNumber;
+    constructor(
+        signedOrder: SignedOrder,
+        isMakerTokenZRX: boolean,
+        transferrableMakerTokenAmount: BigNumber,
+        transferrableMakerFeeTokenAmount: BigNumber,
+        remainingMakerTokenAmount: BigNumber,
+    ) {
+        this._signedOrder = signedOrder;
+        this._isMakerTokenZRX = isMakerTokenZRX;
+        this._transferrableMakerTokenAmount = transferrableMakerTokenAmount;
+        this._transferrableMakerFeeTokenAmount = transferrableMakerFeeTokenAmount;
+        this._remainingMakerTokenAmount = remainingMakerTokenAmount;
+        this._remainingMakerFeeAmount = remainingMakerTokenAmount
+            .times(signedOrder.makerFee)
+            .dividedToIntegerBy(signedOrder.makerTokenAmount);
+    }
+    public computeRemainingMakerFillable(): BigNumber {
+        if (this._hasSufficientFundsForFeeAndTransferAmount()) {
+            return this._remainingMakerTokenAmount;
+        }
+        if (this._signedOrder.makerFee.isZero()) {
+            return BigNumber.min(this._remainingMakerTokenAmount, this._transferrableMakerTokenAmount);
+        }
+        return this._calculatePartiallyFillableMakerTokenAmount();
+    }
+    public computeRemainingTakerFillable(): BigNumber {
+        return this.computeRemainingMakerFillable()
+            .times(this._signedOrder.takerTokenAmount)
+            .dividedToIntegerBy(this._signedOrder.makerTokenAmount);
+    }
+    private _hasSufficientFundsForFeeAndTransferAmount(): boolean {
+        if (this._isMakerTokenZRX) {
+            const totalZRXTransferAmountRequired = this._remainingMakerTokenAmount.plus(this._remainingMakerFeeAmount);
+            const hasSufficientFunds = this._transferrableMakerTokenAmount.greaterThanOrEqualTo(
+                totalZRXTransferAmountRequired,
+            );
+            return hasSufficientFunds;
+        } else {
+            const hasSufficientFundsForTransferAmount = this._transferrableMakerTokenAmount.greaterThanOrEqualTo(
+                this._remainingMakerTokenAmount,
+            );
+            const hasSufficientFundsForFeeAmount = this._transferrableMakerFeeTokenAmount.greaterThanOrEqualTo(
+                this._remainingMakerFeeAmount,
+            );
+            const hasSufficientFunds = hasSufficientFundsForTransferAmount && hasSufficientFundsForFeeAmount;
+            return hasSufficientFunds;
+        }
+    }
+    private _calculatePartiallyFillableMakerTokenAmount(): BigNumber {
+        // Given an order for 200 wei for 2 ZRXwei fee, find 100 wei for 1 ZRXwei. Order ratio is then 100:1
+        const orderToFeeRatio = this._signedOrder.makerTokenAmount.dividedBy(this._signedOrder.makerFee);
+        // The number of times the maker can fill the order, if each fill only required the transfer of a single
+        // baseUnit of fee tokens.
+        // Given 2 ZRXwei, the maximum amount of times Maker can fill this order, in terms of fees, is 2
+        const fillableTimesInFeeTokenBaseUnits = BigNumber.min(
+            this._transferrableMakerFeeTokenAmount,
+            this._remainingMakerFeeAmount,
+        );
+        // The number of times the Maker can fill the order, given the Maker Token Balance
+        // Assuming a balance of 150 wei, and an orderToFeeRatio of 100:1, maker can fill this order 1 time.
+        let fillableTimesInMakerTokenUnits = this._transferrableMakerTokenAmount.dividedBy(orderToFeeRatio);
+        if (this._isMakerTokenZRX) {
+            // If ZRX is the maker token, the Fee and the Maker amount need to be removed from the same pool;
+            // 200 ZRXwei for 2ZRXwei fee can only be filled once (need 202 ZRXwei)
+            const totalZRXTokenPooled = this._transferrableMakerTokenAmount;
+            // The purchasing power here is less as the tokens are taken from the same Pool
+            // For every one number of fills, we have to take an extra ZRX out of the pool
+            fillableTimesInMakerTokenUnits = totalZRXTokenPooled.dividedBy(orderToFeeRatio.plus(new BigNumber(1)));
+        }
+        // When Ratio is not fully divisible there can be remainders which cannot be represented, so they are floored.
+        // This can result in a RoundingError being thrown by the Exchange Contract.
+        const partiallyFillableMakerTokenAmount = fillableTimesInMakerTokenUnits
+            .times(this._signedOrder.makerTokenAmount)
+            .dividedToIntegerBy(this._signedOrder.makerFee);
+        const partiallyFillableFeeTokenAmount = fillableTimesInFeeTokenBaseUnits
+            .times(this._signedOrder.makerTokenAmount)
+            .dividedToIntegerBy(this._signedOrder.makerFee);
+        const partiallyFillableAmount = BigNumber.min(
+            partiallyFillableMakerTokenAmount,
+            partiallyFillableFeeTokenAmount,
+        );
+        return partiallyFillableAmount;
+    }
 }
diff --git a/packages/0x.js/src/schemas/zero_ex_config_schema.ts b/packages/0x.js/src/schemas/zero_ex_config_schema.ts
index 657b24c58..546b1c2d0 100644
--- a/packages/0x.js/src/schemas/zero_ex_config_schema.ts
+++ b/packages/0x.js/src/schemas/zero_ex_config_schema.ts
@@ -1,27 +1,27 @@
 export const zeroExConfigSchema = {
-	id: '/ZeroExConfig',
-	properties: {
-		networkId: {
-			type: 'number',
-			minimum: 0,
-		},
-		gasPrice: { $ref: '/Number' },
-		exchangeContractAddress: { $ref: '/Address' },
-		tokenRegistryContractAddress: { $ref: '/Address' },
-		orderWatcherConfig: {
-			type: 'object',
-			properties: {
-				pollingIntervalMs: {
-					type: 'number',
-					minimum: 0,
-				},
-				numConfirmations: {
-					type: 'number',
-					minimum: 0,
-				},
-			},
-		},
-	},
-	type: 'object',
-	required: ['networkId'],
+    id: '/ZeroExConfig',
+    properties: {
+        networkId: {
+            type: 'number',
+            minimum: 0,
+        },
+        gasPrice: { $ref: '/Number' },
+        exchangeContractAddress: { $ref: '/Address' },
+        tokenRegistryContractAddress: { $ref: '/Address' },
+        orderWatcherConfig: {
+            type: 'object',
+            properties: {
+                pollingIntervalMs: {
+                    type: 'number',
+                    minimum: 0,
+                },
+                numConfirmations: {
+                    type: 'number',
+                    minimum: 0,
+                },
+            },
+        },
+    },
+    type: 'object',
+    required: ['networkId'],
 };
diff --git a/packages/0x.js/src/stores/balance_proxy_allowance_lazy_store.ts b/packages/0x.js/src/stores/balance_proxy_allowance_lazy_store.ts
index 379afa4bc..33feea105 100644
--- a/packages/0x.js/src/stores/balance_proxy_allowance_lazy_store.ts
+++ b/packages/0x.js/src/stores/balance_proxy_allowance_lazy_store.ts
@@ -8,79 +8,79 @@ import { BlockParamLiteral } from '../types';
  * Copy on read store for balances/proxyAllowances of tokens/accounts
  */
 export class BalanceAndProxyAllowanceLazyStore {
-	private _token: TokenWrapper;
-	private _defaultBlock: BlockParamLiteral;
-	private _balance: {
-		[tokenAddress: string]: {
-			[userAddress: string]: BigNumber;
-		};
-	};
-	private _proxyAllowance: {
-		[tokenAddress: string]: {
-			[userAddress: string]: BigNumber;
-		};
-	};
-	constructor(token: TokenWrapper, defaultBlock: BlockParamLiteral) {
-		this._token = token;
-		this._defaultBlock = defaultBlock;
-		this._balance = {};
-		this._proxyAllowance = {};
-	}
-	public async getBalanceAsync(tokenAddress: string, userAddress: string): Promise<BigNumber> {
-		if (_.isUndefined(this._balance[tokenAddress]) || _.isUndefined(this._balance[tokenAddress][userAddress])) {
-			const methodOpts = {
-				defaultBlock: this._defaultBlock,
-			};
-			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<BigNumber> {
-		if (
-			_.isUndefined(this._proxyAllowance[tokenAddress]) ||
-			_.isUndefined(this._proxyAllowance[tokenAddress][userAddress])
-		) {
-			const methodOpts = {
-				defaultBlock: this._defaultBlock,
-			};
-			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 = {};
-	}
+    private _token: TokenWrapper;
+    private _defaultBlock: BlockParamLiteral;
+    private _balance: {
+        [tokenAddress: string]: {
+            [userAddress: string]: BigNumber;
+        };
+    };
+    private _proxyAllowance: {
+        [tokenAddress: string]: {
+            [userAddress: string]: BigNumber;
+        };
+    };
+    constructor(token: TokenWrapper, defaultBlock: BlockParamLiteral) {
+        this._token = token;
+        this._defaultBlock = defaultBlock;
+        this._balance = {};
+        this._proxyAllowance = {};
+    }
+    public async getBalanceAsync(tokenAddress: string, userAddress: string): Promise<BigNumber> {
+        if (_.isUndefined(this._balance[tokenAddress]) || _.isUndefined(this._balance[tokenAddress][userAddress])) {
+            const methodOpts = {
+                defaultBlock: this._defaultBlock,
+            };
+            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<BigNumber> {
+        if (
+            _.isUndefined(this._proxyAllowance[tokenAddress]) ||
+            _.isUndefined(this._proxyAllowance[tokenAddress][userAddress])
+        ) {
+            const methodOpts = {
+                defaultBlock: this._defaultBlock,
+            };
+            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/packages/0x.js/src/stores/order_filled_cancelled_lazy_store.ts b/packages/0x.js/src/stores/order_filled_cancelled_lazy_store.ts
index a99db0702..e22364c09 100644
--- a/packages/0x.js/src/stores/order_filled_cancelled_lazy_store.ts
+++ b/packages/0x.js/src/stores/order_filled_cancelled_lazy_store.ts
@@ -8,54 +8,54 @@ 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<BigNumber> {
-		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<BigNumber> {
-		if (_.isUndefined(this._cancelledTakerAmount[orderHash])) {
-			const methodOpts = {
-				defaultBlock: BlockParamLiteral.Pending,
-			};
-			const cancelledTakerAmount = await this._exchange.getCancelledTakerAmountAsync(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 = {};
-	}
+    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<BigNumber> {
+        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<BigNumber> {
+        if (_.isUndefined(this._cancelledTakerAmount[orderHash])) {
+            const methodOpts = {
+                defaultBlock: BlockParamLiteral.Pending,
+            };
+            const cancelledTakerAmount = await this._exchange.getCancelledTakerAmountAsync(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/packages/0x.js/src/types.ts b/packages/0x.js/src/types.ts
index 7eda4bea6..3c93910e9 100644
--- a/packages/0x.js/src/types.ts
+++ b/packages/0x.js/src/types.ts
@@ -3,41 +3,41 @@ import { BigNumber } from '@0xproject/utils';
 import * as Web3 from 'web3';
 
 export enum ZeroExError {
-	ExchangeContractDoesNotExist = 'EXCHANGE_CONTRACT_DOES_NOT_EXIST',
-	ZRXContractDoesNotExist = 'ZRX_CONTRACT_DOES_NOT_EXIST',
-	EtherTokenContractDoesNotExist = 'ETHER_TOKEN_CONTRACT_DOES_NOT_EXIST',
-	TokenTransferProxyContractDoesNotExist = 'TOKEN_TRANSFER_PROXY_CONTRACT_DOES_NOT_EXIST',
-	TokenRegistryContractDoesNotExist = 'TOKEN_REGISTRY_CONTRACT_DOES_NOT_EXIST',
-	TokenContractDoesNotExist = 'TOKEN_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',
+    ExchangeContractDoesNotExist = 'EXCHANGE_CONTRACT_DOES_NOT_EXIST',
+    ZRXContractDoesNotExist = 'ZRX_CONTRACT_DOES_NOT_EXIST',
+    EtherTokenContractDoesNotExist = 'ETHER_TOKEN_CONTRACT_DOES_NOT_EXIST',
+    TokenTransferProxyContractDoesNotExist = 'TOKEN_TRANSFER_PROXY_CONTRACT_DOES_NOT_EXIST',
+    TokenRegistryContractDoesNotExist = 'TOKEN_REGISTRY_CONTRACT_DOES_NOT_EXIST',
+    TokenContractDoesNotExist = 'TOKEN_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',
-	WethNotInTokenRegistry = 'WETH_NOT_IN_TOKEN_REGISTRY',
+    NoAbiDecoder = 'NO_ABI_DECODER',
+    ZrxNotInTokenRegistry = 'ZRX_NOT_IN_TOKEN_REGISTRY',
+    WethNotInTokenRegistry = 'WETH_NOT_IN_TOKEN_REGISTRY',
 }
 
 /**
  * Elliptic Curve signature
  */
 export interface ECSignature {
-	v: number;
-	r: string;
-	s: string;
+    v: number;
+    r: string;
+    s: string;
 }
 
 export type OrderAddresses = [string, string, string, string, string];
@@ -46,214 +46,214 @@ export type OrderValues = [BigNumber, BigNumber, BigNumber, BigNumber, BigNumber
 
 export type LogEvent = Web3.LogEntryEvent;
 export interface DecodedLogEvent<ArgsType> {
-	isRemoved: boolean;
-	log: LogWithDecodedArgs<ArgsType>;
+    isRemoved: boolean;
+    log: LogWithDecodedArgs<ArgsType>;
 }
 
 export type EventCallback<ArgsType> = (err: null | Error, log?: DecodedLogEvent<ArgsType>) => void;
 export type EventWatcherCallback = (err: null | Error, log?: LogEvent) => void;
 
 export enum SolidityTypes {
-	Address = 'address',
-	Uint256 = 'uint256',
-	Uint8 = 'uint8',
-	Uint = 'uint',
+    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
+    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',
+    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;
+    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;
+    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;
+    maker: string;
+    feeRecipient: string;
+    makerToken: string;
+    takerToken: string;
+    cancelledMakerTokenAmount: BigNumber;
+    cancelledTakerTokenAmount: BigNumber;
+    tokens: string;
+    orderHash: string;
 }
 export interface LogErrorContractEventArgs {
-	errorId: BigNumber;
-	orderHash: string;
+    errorId: BigNumber;
+    orderHash: string;
 }
 export type ExchangeContractEventArgs =
-	| LogFillContractEventArgs
-	| LogCancelContractEventArgs
-	| LogErrorContractEventArgs;
+    | LogFillContractEventArgs
+    | LogCancelContractEventArgs
+    | LogErrorContractEventArgs;
 export interface TransferContractEventArgs {
-	_from: string;
-	_to: string;
-	_value: BigNumber;
+    _from: string;
+    _to: string;
+    _value: BigNumber;
 }
 export interface ApprovalContractEventArgs {
-	_owner: string;
-	_spender: string;
-	_value: BigNumber;
+    _owner: string;
+    _spender: string;
+    _value: BigNumber;
 }
 export interface DepositContractEventArgs {
-	_owner: string;
-	_value: BigNumber;
+    _owner: string;
+    _value: BigNumber;
 }
 export interface WithdrawalContractEventArgs {
-	_owner: string;
-	_value: BigNumber;
+    _owner: string;
+    _value: BigNumber;
 }
 export type TokenContractEventArgs = TransferContractEventArgs | ApprovalContractEventArgs;
 export type EtherTokenContractEventArgs =
-	| TokenContractEventArgs
-	| DepositContractEventArgs
-	| WithdrawalContractEventArgs;
+    | TokenContractEventArgs
+    | DepositContractEventArgs
+    | WithdrawalContractEventArgs;
 export type ContractEventArgs = ExchangeContractEventArgs | TokenContractEventArgs | EtherTokenContractEventArgs;
 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;
+    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;
+    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;
+    name: string;
+    address: string;
+    symbol: string;
+    decimals: number;
 }
 
 export interface TxOpts {
-	from: string;
-	gas?: number;
-	value?: BigNumber;
-	gasPrice?: BigNumber;
+    from: string;
+    gas?: number;
+    value?: BigNumber;
+    gasPrice?: BigNumber;
 }
 
 export interface TokenAddressBySymbol {
-	[symbol: string]: string;
+    [symbol: string]: string;
 }
 
 export enum ExchangeEvents {
-	LogFill = 'LogFill',
-	LogCancel = 'LogCancel',
-	LogError = 'LogError',
+    LogFill = 'LogFill',
+    LogCancel = 'LogCancel',
+    LogError = 'LogError',
 }
 
 export enum TokenEvents {
-	Transfer = 'Transfer',
-	Approval = 'Approval',
+    Transfer = 'Transfer',
+    Approval = 'Approval',
 }
 
 export enum EtherTokenEvents {
-	Transfer = 'Transfer',
-	Approval = 'Approval',
-	Deposit = 'Deposit',
-	Withdrawal = 'Withdrawal',
+    Transfer = 'Transfer',
+    Approval = 'Approval',
+    Deposit = 'Deposit',
+    Withdrawal = 'Withdrawal',
 }
 
 export type ContractEvents = TokenEvents | ExchangeEvents | EtherTokenEvents;
 
 export interface IndexedFilterValues {
-	[index: string]: ContractEventArg;
+    [index: string]: ContractEventArg;
 }
 
 // Earliest is omitted by design. It is simply an alias for the `0` constant and
 // is thus not very helpful. Moreover, this type is used in places that only accept
 // `latest` or `pending`.
 export enum BlockParamLiteral {
-	Latest = 'latest',
-	Pending = 'pending',
+    Latest = 'latest',
+    Pending = 'pending',
 }
 
 export type BlockParam = BlockParamLiteral | number;
 
 export interface BlockRange {
-	fromBlock: BlockParam;
-	toBlock: BlockParam;
+    fromBlock: BlockParam;
+    toBlock: BlockParam;
 }
 
 export type DoneCallback = (err?: Error) => void;
 
 export interface OrderCancellationRequest {
-	order: Order | SignedOrder;
-	takerTokenCancelAmount: BigNumber;
+    order: Order | SignedOrder;
+    takerTokenCancelAmount: BigNumber;
 }
 
 export interface OrderFillRequest {
-	signedOrder: SignedOrder;
-	takerTokenFillAmount: BigNumber;
+    signedOrder: SignedOrder;
+    takerTokenFillAmount: BigNumber;
 }
 
 export type AsyncMethod = (...args: any[]) => Promise<any>;
@@ -268,8 +268,8 @@ export type SyncMethod = (...args: any[]) => any;
 export type Web3Provider = Web3.Provider;
 
 export interface JSONRPCPayload {
-	params: any[];
-	method: string;
+    params: any[];
+    method: string;
 }
 
 /*
@@ -280,10 +280,10 @@ export interface JSONRPCPayload {
  * cleanupJobIntervalMs: How often to run a cleanup job which revalidates all the orders. Defaults: 1h
  */
 export interface OrderStateWatcherConfig {
-	orderExpirationCheckingIntervalMs?: number;
-	eventPollingIntervalMs?: number;
-	expirationMarginMs?: number;
-	cleanupJobIntervalMs?: number;
+    orderExpirationCheckingIntervalMs?: number;
+    eventPollingIntervalMs?: number;
+    expirationMarginMs?: number;
+    cleanupJobIntervalMs?: number;
 }
 
 /*
@@ -296,42 +296,42 @@ export interface OrderStateWatcherConfig {
  * orderWatcherConfig: All the configs related to the orderWatcher
  */
 export interface ZeroExConfig {
-	networkId: number;
-	gasPrice?: BigNumber;
-	exchangeContractAddress?: string;
-	zrxContractAddress?: string;
-	tokenRegistryContractAddress?: string;
-	tokenTransferProxyContractAddress?: string;
-	orderWatcherConfig?: OrderStateWatcherConfig;
+    networkId: number;
+    gasPrice?: BigNumber;
+    exchangeContractAddress?: string;
+    zrxContractAddress?: string;
+    tokenRegistryContractAddress?: string;
+    tokenTransferProxyContractAddress?: string;
+    orderWatcherConfig?: OrderStateWatcherConfig;
 }
 
 export enum AbiType {
-	Function = 'function',
-	Constructor = 'constructor',
-	Event = 'event',
-	Fallback = 'fallback',
+    Function = 'function',
+    Constructor = 'constructor',
+    Event = 'event',
+    Fallback = 'fallback',
 }
 
 export interface DecodedLogArgs {
-	[argName: string]: ContractEventArg;
+    [argName: string]: ContractEventArg;
 }
 
 export interface LogWithDecodedArgs<ArgsType> extends Web3.DecodedLogEntry<ArgsType> {}
 
 export interface TransactionReceiptWithDecodedLogs extends TransactionReceipt {
-	logs: Array<LogWithDecodedArgs<DecodedLogArgs> | Web3.LogEntry>;
+    logs: Array<LogWithDecodedArgs<DecodedLogArgs> | Web3.LogEntry>;
 }
 
 export type ArtifactContractName = 'ZRX' | 'TokenTransferProxy' | 'TokenRegistry' | 'Token' | 'Exchange' | 'EtherToken';
 
 export interface Artifact {
-	contract_name: ArtifactContractName;
-	abi: Web3.ContractAbi;
-	networks: {
-		[networkId: number]: {
-			address: string;
-		};
-	};
+    contract_name: ArtifactContractName;
+    abi: Web3.ContractAbi;
+    networks: {
+        [networkId: number]: {
+            address: string;
+        };
+    };
 }
 
 /*
@@ -341,7 +341,7 @@ export interface Artifact {
  * allowance/balance to fill the entire remaining order amount.
  */
 export interface ValidateOrderFillableOpts {
-	expectedFillTakerTokenAmount?: BigNumber;
+    expectedFillTakerTokenAmount?: BigNumber;
 }
 
 /*
@@ -351,7 +351,7 @@ export interface ValidateOrderFillableOpts {
  * flag when  running Parity).
  */
 export interface MethodOpts {
-	defaultBlock?: Web3.BlockParam;
+    defaultBlock?: Web3.BlockParam;
 }
 
 /*
@@ -359,8 +359,8 @@ export interface MethodOpts {
  * gasLimit: The amount of gas to send with a transaction
  */
 export interface TransactionOpts {
-	gasPrice?: BigNumber;
-	gasLimit?: number;
+    gasPrice?: BigNumber;
+    gasLimit?: number;
 }
 
 /*
@@ -368,42 +368,42 @@ export interface TransactionOpts {
  * broadcasting it. For example, order has a valid signature, maker has sufficient funds, etc. Default: true
  */
 export interface OrderTransactionOpts extends TransactionOpts {
-	shouldValidate?: boolean;
+    shouldValidate?: boolean;
 }
 
 export type FilterObject = Web3.FilterObject;
 
 export enum TradeSide {
-	Maker = 'maker',
-	Taker = 'taker',
+    Maker = 'maker',
+    Taker = 'taker',
 }
 
 export enum TransferType {
-	Trade = 'trade',
-	Fee = 'fee',
+    Trade = 'trade',
+    Fee = 'fee',
 }
 
 export interface OrderRelevantState {
-	makerBalance: BigNumber;
-	makerProxyAllowance: BigNumber;
-	makerFeeBalance: BigNumber;
-	makerFeeProxyAllowance: BigNumber;
-	filledTakerTokenAmount: BigNumber;
-	cancelledTakerTokenAmount: BigNumber;
-	remainingFillableMakerTokenAmount: BigNumber;
-	remainingFillableTakerTokenAmount: BigNumber;
+    makerBalance: BigNumber;
+    makerProxyAllowance: BigNumber;
+    makerFeeBalance: BigNumber;
+    makerFeeProxyAllowance: BigNumber;
+    filledTakerTokenAmount: BigNumber;
+    cancelledTakerTokenAmount: BigNumber;
+    remainingFillableMakerTokenAmount: BigNumber;
+    remainingFillableTakerTokenAmount: BigNumber;
 }
 
 export interface OrderStateValid {
-	isValid: true;
-	orderHash: string;
-	orderRelevantState: OrderRelevantState;
+    isValid: true;
+    orderHash: string;
+    orderRelevantState: OrderRelevantState;
 }
 
 export interface OrderStateInvalid {
-	isValid: false;
-	orderHash: string;
-	error: ExchangeContractErrs;
+    isValid: false;
+    orderHash: string;
+    error: ExchangeContractErrs;
 }
 
 export type OrderState = OrderStateValid | OrderStateInvalid;
diff --git a/packages/0x.js/src/utils/abi_decoder.ts b/packages/0x.js/src/utils/abi_decoder.ts
index ace6dd165..bbd2a0b1d 100644
--- a/packages/0x.js/src/utils/abi_decoder.ts
+++ b/packages/0x.js/src/utils/abi_decoder.ts
@@ -6,67 +6,67 @@ import * as SolidityCoder from 'web3/lib/solidity/coder';
 import { AbiType, ContractEventArgs, DecodedLogArgs, LogWithDecodedArgs, RawLog, SolidityTypes } from '../types';
 
 export class AbiDecoder {
-	private _savedABIs: Web3.AbiDefinition[] = [];
-	private _methodIds: { [signatureHash: string]: Web3.EventAbi } = {};
-	private static _padZeros(address: string) {
-		let formatted = address;
-		if (_.startsWith(formatted, '0x')) {
-			formatted = formatted.slice(2);
-		}
+    private _savedABIs: Web3.AbiDefinition[] = [];
+    private _methodIds: { [signatureHash: string]: Web3.EventAbi } = {};
+    private static _padZeros(address: string) {
+        let formatted = address;
+        if (_.startsWith(formatted, '0x')) {
+            formatted = formatted.slice(2);
+        }
 
-		formatted = _.padStart(formatted, 40, '0');
-		return `0x${formatted}`;
-	}
-	constructor(abiArrays: Web3.AbiDefinition[][]) {
-		_.map(abiArrays, this._addABI.bind(this));
-	}
-	// This method can only decode logs from the 0x & ERC20 smart contracts
-	public tryToDecodeLogOrNoop<ArgsType extends ContractEventArgs>(
-		log: Web3.LogEntry,
-	): LogWithDecodedArgs<ArgsType> | RawLog {
-		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;
+        formatted = _.padStart(formatted, 40, '0');
+        return `0x${formatted}`;
+    }
+    constructor(abiArrays: Web3.AbiDefinition[][]) {
+        _.map(abiArrays, this._addABI.bind(this));
+    }
+    // This method can only decode logs from the 0x & ERC20 smart contracts
+    public tryToDecodeLogOrNoop<ArgsType extends ContractEventArgs>(
+        log: Web3.LogEntry,
+    ): LogWithDecodedArgs<ArgsType> | RawLog {
+        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));
+        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 = AbiDecoder._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;
-		});
+        _.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 = AbiDecoder._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);
-	}
+        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);
+    }
 }
diff --git a/packages/0x.js/src/utils/assert.ts b/packages/0x.js/src/utils/assert.ts
index 776ee7b79..c21f2dbca 100644
--- a/packages/0x.js/src/utils/assert.ts
+++ b/packages/0x.js/src/utils/assert.ts
@@ -11,25 +11,25 @@ import { ECSignature } from '../types';
 import { signatureUtils } from '../utils/signature_utils';
 
 export const assert = {
-	...sharedAssert,
-	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`);
-	},
-	async isSenderAddressAsync(
-		variableName: string,
-		senderAddressHex: string,
-		web3Wrapper: Web3Wrapper,
-	): Promise<void> {
-		sharedAssert.isETHAddressHex(variableName, senderAddressHex);
-		const isSenderAddressAvailable = await web3Wrapper.isSenderAddressAvailableAsync(senderAddressHex);
-		sharedAssert.assert(
-			isSenderAddressAvailable,
-			`Specified ${variableName} ${senderAddressHex} isn't available through the supplied web3 provider`,
-		);
-	},
-	async isUserAddressAvailableAsync(web3Wrapper: Web3Wrapper): Promise<void> {
-		const availableAddresses = await web3Wrapper.getAvailableAddressesAsync();
-		this.assert(!_.isEmpty(availableAddresses), 'No addresses were available on the provided web3 provider');
-	},
+    ...sharedAssert,
+    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`);
+    },
+    async isSenderAddressAsync(
+        variableName: string,
+        senderAddressHex: string,
+        web3Wrapper: Web3Wrapper,
+    ): Promise<void> {
+        sharedAssert.isETHAddressHex(variableName, senderAddressHex);
+        const isSenderAddressAvailable = await web3Wrapper.isSenderAddressAvailableAsync(senderAddressHex);
+        sharedAssert.assert(
+            isSenderAddressAvailable,
+            `Specified ${variableName} ${senderAddressHex} isn't available through the supplied web3 provider`,
+        );
+    },
+    async isUserAddressAvailableAsync(web3Wrapper: Web3Wrapper): Promise<void> {
+        const availableAddresses = await web3Wrapper.getAvailableAddressesAsync();
+        this.assert(!_.isEmpty(availableAddresses), 'No addresses were available on the provided web3 provider');
+    },
 };
diff --git a/packages/0x.js/src/utils/constants.ts b/packages/0x.js/src/utils/constants.ts
index f32847ec2..06beec8e2 100644
--- a/packages/0x.js/src/utils/constants.ts
+++ b/packages/0x.js/src/utils/constants.ts
@@ -1,12 +1,12 @@
 import { BigNumber } from '@0xproject/utils';
 
 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',
-	INVALID_TAKER_FORMAT: 'instance.taker is not of a type(s) string',
-	UNLIMITED_ALLOWANCE_IN_BASE_UNITS: new BigNumber(2).pow(256).minus(1),
-	DEFAULT_BLOCK_POLLING_INTERVAL: 1000,
+    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',
+    INVALID_TAKER_FORMAT: 'instance.taker is not of a type(s) string',
+    UNLIMITED_ALLOWANCE_IN_BASE_UNITS: new BigNumber(2).pow(256).minus(1),
+    DEFAULT_BLOCK_POLLING_INTERVAL: 1000,
 };
diff --git a/packages/0x.js/src/utils/decorators.ts b/packages/0x.js/src/utils/decorators.ts
index c1a022a81..f774d734e 100644
--- a/packages/0x.js/src/utils/decorators.ts
+++ b/packages/0x.js/src/utils/decorators.ts
@@ -7,85 +7,85 @@ import { constants } from './constants';
 type ErrorTransformer = (err: Error) => Error;
 
 const contractCallErrorTransformer = (error: Error) => {
-	if (_.includes(error.message, constants.INVALID_JUMP_PATTERN)) {
-		return new Error(ZeroExError.InvalidJump);
-	}
-	if (_.includes(error.message, constants.OUT_OF_GAS_PATTERN)) {
-		return new Error(ZeroExError.OutOfGas);
-	}
-	return error;
+    if (_.includes(error.message, constants.INVALID_JUMP_PATTERN)) {
+        return new Error(ZeroExError.InvalidJump);
+    }
+    if (_.includes(error.message, constants.OUT_OF_GAS_PATTERN)) {
+        return new Error(ZeroExError.OutOfGas);
+    }
+    return error;
 };
 
 const schemaErrorTransformer = (error: Error) => {
-	if (_.includes(error.message, constants.INVALID_TAKER_FORMAT)) {
-		const errMsg =
-			'Order taker must be of type string. If you want anyone to be able to fill an order - pass ZeroEx.NULL_ADDRESS';
-		return new Error(errMsg);
-	}
-	return error;
+    if (_.includes(error.message, constants.INVALID_TAKER_FORMAT)) {
+        const errMsg =
+            'Order taker must be of type string. If you want anyone to be able to fill an order - pass ZeroEx.NULL_ADDRESS';
+        return new Error(errMsg);
+    }
+    return error;
 };
 
 /**
  * Source: https://stackoverflow.com/a/29837695/3546986
  */
 const asyncErrorHandlerFactory = (errorTransformer: ErrorTransformer) => {
-	const asyncErrorHandlingDecorator = (
-		target: object,
-		key: string | symbol,
-		descriptor: TypedPropertyDescriptor<AsyncMethod>,
-	) => {
-		const originalMethod = descriptor.value as AsyncMethod;
+    const asyncErrorHandlingDecorator = (
+        target: object,
+        key: string | symbol,
+        descriptor: TypedPropertyDescriptor<AsyncMethod>,
+    ) => {
+        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) {
-				const transformedError = errorTransformer(error);
-				throw transformedError;
-			}
-		};
+        // 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) {
+                const transformedError = errorTransformer(error);
+                throw transformedError;
+            }
+        };
 
-		return descriptor;
-	};
+        return descriptor;
+    };
 
-	return asyncErrorHandlingDecorator;
+    return asyncErrorHandlingDecorator;
 };
 
 const syncErrorHandlerFactory = (errorTransformer: ErrorTransformer) => {
-	const syncErrorHandlingDecorator = (
-		target: object,
-		key: string | symbol,
-		descriptor: TypedPropertyDescriptor<SyncMethod>,
-	) => {
-		const originalMethod = descriptor.value as SyncMethod;
+    const syncErrorHandlingDecorator = (
+        target: object,
+        key: string | symbol,
+        descriptor: TypedPropertyDescriptor<SyncMethod>,
+    ) => {
+        const originalMethod = descriptor.value as SyncMethod;
 
-		// 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 = function(...args: any[]) {
-			try {
-				const result = originalMethod.apply(this, args);
-				return result;
-			} catch (error) {
-				const transformedError = errorTransformer(error);
-				throw transformedError;
-			}
-		};
+        // 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 = function(...args: any[]) {
+            try {
+                const result = originalMethod.apply(this, args);
+                return result;
+            } catch (error) {
+                const transformedError = errorTransformer(error);
+                throw transformedError;
+            }
+        };
 
-		return descriptor;
-	};
+        return descriptor;
+    };
 
-	return syncErrorHandlingDecorator;
+    return syncErrorHandlingDecorator;
 };
 
 // _.flow(f, g) = f ∘ g
 const zeroExErrorTransformer = _.flow(schemaErrorTransformer, contractCallErrorTransformer);
 
 export const decorators = {
-	asyncZeroExErrorHandler: asyncErrorHandlerFactory(zeroExErrorTransformer),
-	syncZeroExErrorHandler: syncErrorHandlerFactory(zeroExErrorTransformer),
+    asyncZeroExErrorHandler: asyncErrorHandlerFactory(zeroExErrorTransformer),
+    syncZeroExErrorHandler: syncErrorHandlerFactory(zeroExErrorTransformer),
 };
diff --git a/packages/0x.js/src/utils/exchange_transfer_simulator.ts b/packages/0x.js/src/utils/exchange_transfer_simulator.ts
index c9a2f87ce..662cd210c 100644
--- a/packages/0x.js/src/utils/exchange_transfer_simulator.ts
+++ b/packages/0x.js/src/utils/exchange_transfer_simulator.ts
@@ -6,101 +6,101 @@ import { BalanceAndProxyAllowanceLazyStore } from '../stores/balance_proxy_allow
 import { BlockParamLiteral, ExchangeContractErrs, TradeSide, TransferType } from '../types';
 
 enum FailureReason {
-	Balance = 'balance',
-	ProxyAllowance = 'proxyAllowance',
+    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,
-		},
-	},
+    [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;
-	private static _throwValidationError(
-		failureReason: FailureReason,
-		tradeSide: TradeSide,
-		transferType: TransferType,
-	): never {
-		const errMsg = ERR_MSG_MAPPING[failureReason][tradeSide][transferType];
-		throw new Error(errMsg);
-	}
-	constructor(token: TokenWrapper, defaultBlock: BlockParamLiteral) {
-		this._store = new BalanceAndProxyAllowanceLazyStore(token, defaultBlock);
-		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<void> {
-		const balance = await this._store.getBalanceAsync(tokenAddress, from);
-		const proxyAllowance = await this._store.getProxyAllowanceAsync(tokenAddress, from);
-		if (proxyAllowance.lessThan(amountInBaseUnits)) {
-			ExchangeTransferSimulator._throwValidationError(FailureReason.ProxyAllowance, tradeSide, transferType);
-		}
-		if (balance.lessThan(amountInBaseUnits)) {
-			ExchangeTransferSimulator._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<void> {
-		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<void> {
-		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<void> {
-		const balance = await this._store.getBalanceAsync(tokenAddress, userAddress);
-		this._store.setBalance(tokenAddress, userAddress, balance.minus(amountInBaseUnits));
-	}
+    private _store: BalanceAndProxyAllowanceLazyStore;
+    private _UNLIMITED_ALLOWANCE_IN_BASE_UNITS: BigNumber;
+    private static _throwValidationError(
+        failureReason: FailureReason,
+        tradeSide: TradeSide,
+        transferType: TransferType,
+    ): never {
+        const errMsg = ERR_MSG_MAPPING[failureReason][tradeSide][transferType];
+        throw new Error(errMsg);
+    }
+    constructor(token: TokenWrapper, defaultBlock: BlockParamLiteral) {
+        this._store = new BalanceAndProxyAllowanceLazyStore(token, defaultBlock);
+        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<void> {
+        const balance = await this._store.getBalanceAsync(tokenAddress, from);
+        const proxyAllowance = await this._store.getProxyAllowanceAsync(tokenAddress, from);
+        if (proxyAllowance.lessThan(amountInBaseUnits)) {
+            ExchangeTransferSimulator._throwValidationError(FailureReason.ProxyAllowance, tradeSide, transferType);
+        }
+        if (balance.lessThan(amountInBaseUnits)) {
+            ExchangeTransferSimulator._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<void> {
+        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<void> {
+        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<void> {
+        const balance = await this._store.getBalanceAsync(tokenAddress, userAddress);
+        this._store.setBalance(tokenAddress, userAddress, balance.minus(amountInBaseUnits));
+    }
 }
diff --git a/packages/0x.js/src/utils/filter_utils.ts b/packages/0x.js/src/utils/filter_utils.ts
index c34ae8893..97205ace3 100644
--- a/packages/0x.js/src/utils/filter_utils.ts
+++ b/packages/0x.js/src/utils/filter_utils.ts
@@ -9,79 +9,79 @@ import { BlockRange, ContractEvents, IndexedFilterValues } from '../types';
 const TOPIC_LENGTH = 32;
 
 export const filterUtils = {
-	generateUUID(): string {
-		return uuid();
-	},
-	getFilter(
-		address: string,
-		eventName: ContractEvents,
-		indexFilterValues: IndexedFilterValues,
-		abi: Web3.ContractAbi,
-		blockRange?: BlockRange,
-	): 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(blockRange)) {
-			filter = {
-				...blockRange,
-				...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<string | null> {
-		const topics: Array<string | null> = [];
-		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<string[] | string | null>): 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;
-	},
+    generateUUID(): string {
+        return uuid();
+    },
+    getFilter(
+        address: string,
+        eventName: ContractEvents,
+        indexFilterValues: IndexedFilterValues,
+        abi: Web3.ContractAbi,
+        blockRange?: BlockRange,
+    ): 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(blockRange)) {
+            filter = {
+                ...blockRange,
+                ...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<string | null> {
+        const topics: Array<string | null> = [];
+        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<string[] | string | null>): 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/packages/0x.js/src/utils/order_state_utils.ts b/packages/0x.js/src/utils/order_state_utils.ts
index 04d3b641e..b7a55ff42 100644
--- a/packages/0x.js/src/utils/order_state_utils.ts
+++ b/packages/0x.js/src/utils/order_state_utils.ts
@@ -7,138 +7,138 @@ import { RemainingFillableCalculator } from '../order_watcher/remaining_fillable
 import { BalanceAndProxyAllowanceLazyStore } from '../stores/balance_proxy_allowance_lazy_store';
 import { OrderFilledCancelledLazyStore } from '../stores/order_filled_cancelled_lazy_store';
 import {
-	ExchangeContractErrs,
-	OrderRelevantState,
-	OrderState,
-	OrderStateInvalid,
-	OrderStateValid,
-	SignedOrder,
+    ExchangeContractErrs,
+    OrderRelevantState,
+    OrderState,
+    OrderStateInvalid,
+    OrderStateValid,
+    SignedOrder,
 } from '../types';
 
 const ACCEPTABLE_RELATIVE_ROUNDING_ERROR = 0.0001;
 
 export class OrderStateUtils {
-	private _balanceAndProxyAllowanceLazyStore: BalanceAndProxyAllowanceLazyStore;
-	private _orderFilledCancelledLazyStore: OrderFilledCancelledLazyStore;
-	private static _validateIfOrderIsValid(signedOrder: SignedOrder, orderRelevantState: OrderRelevantState): void {
-		const unavailableTakerTokenAmount = orderRelevantState.cancelledTakerTokenAmount.add(
-			orderRelevantState.filledTakerTokenAmount,
-		);
-		const availableTakerTokenAmount = signedOrder.takerTokenAmount.minus(unavailableTakerTokenAmount);
-		if (availableTakerTokenAmount.eq(0)) {
-			throw new Error(ExchangeContractErrs.OrderRemainingFillAmountZero);
-		}
+    private _balanceAndProxyAllowanceLazyStore: BalanceAndProxyAllowanceLazyStore;
+    private _orderFilledCancelledLazyStore: OrderFilledCancelledLazyStore;
+    private static _validateIfOrderIsValid(signedOrder: SignedOrder, orderRelevantState: OrderRelevantState): void {
+        const unavailableTakerTokenAmount = orderRelevantState.cancelledTakerTokenAmount.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);
-			}
-		}
-		const minFillableTakerTokenAmountWithinNoRoundingErrorRange = signedOrder.takerTokenAmount
-			.dividedBy(ACCEPTABLE_RELATIVE_ROUNDING_ERROR)
-			.dividedBy(signedOrder.makerTokenAmount);
-		if (
-			orderRelevantState.remainingFillableTakerTokenAmount.lessThan(
-				minFillableTakerTokenAmountWithinNoRoundingErrorRange,
-			)
-		) {
-			throw new Error(ExchangeContractErrs.OrderFillRoundingError);
-		}
-	}
-	constructor(
-		balanceAndProxyAllowanceLazyStore: BalanceAndProxyAllowanceLazyStore,
-		orderFilledCancelledLazyStore: OrderFilledCancelledLazyStore,
-	) {
-		this._balanceAndProxyAllowanceLazyStore = balanceAndProxyAllowanceLazyStore;
-		this._orderFilledCancelledLazyStore = orderFilledCancelledLazyStore;
-	}
-	public async getOrderStateAsync(signedOrder: SignedOrder): Promise<OrderState> {
-		const orderRelevantState = await this.getOrderRelevantStateAsync(signedOrder);
-		const orderHash = ZeroEx.getOrderHashHex(signedOrder);
-		try {
-			OrderStateUtils._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<OrderRelevantState> {
-		// 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 = exchange.getZRXTokenAddress();
-		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 cancelledTakerTokenAmount = 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 transferrableMakerTokenAmount = BigNumber.min([makerProxyAllowance, makerBalance]);
-		const transferrableFeeTokenAmount = BigNumber.min([makerFeeProxyAllowance, makerFeeBalance]);
+        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);
+            }
+        }
+        const minFillableTakerTokenAmountWithinNoRoundingErrorRange = signedOrder.takerTokenAmount
+            .dividedBy(ACCEPTABLE_RELATIVE_ROUNDING_ERROR)
+            .dividedBy(signedOrder.makerTokenAmount);
+        if (
+            orderRelevantState.remainingFillableTakerTokenAmount.lessThan(
+                minFillableTakerTokenAmountWithinNoRoundingErrorRange,
+            )
+        ) {
+            throw new Error(ExchangeContractErrs.OrderFillRoundingError);
+        }
+    }
+    constructor(
+        balanceAndProxyAllowanceLazyStore: BalanceAndProxyAllowanceLazyStore,
+        orderFilledCancelledLazyStore: OrderFilledCancelledLazyStore,
+    ) {
+        this._balanceAndProxyAllowanceLazyStore = balanceAndProxyAllowanceLazyStore;
+        this._orderFilledCancelledLazyStore = orderFilledCancelledLazyStore;
+    }
+    public async getOrderStateAsync(signedOrder: SignedOrder): Promise<OrderState> {
+        const orderRelevantState = await this.getOrderRelevantStateAsync(signedOrder);
+        const orderHash = ZeroEx.getOrderHashHex(signedOrder);
+        try {
+            OrderStateUtils._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<OrderRelevantState> {
+        // 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 = exchange.getZRXTokenAddress();
+        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 cancelledTakerTokenAmount = 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 transferrableMakerTokenAmount = BigNumber.min([makerProxyAllowance, makerBalance]);
+        const transferrableFeeTokenAmount = BigNumber.min([makerFeeProxyAllowance, makerFeeBalance]);
 
-		const isMakerTokenZRX = signedOrder.makerTokenAddress === zrxTokenAddress;
-		const remainingFillableCalculator = new RemainingFillableCalculator(
-			signedOrder,
-			isMakerTokenZRX,
-			transferrableMakerTokenAmount,
-			transferrableFeeTokenAmount,
-			remainingMakerTokenAmount,
-		);
-		const remainingFillableMakerTokenAmount = remainingFillableCalculator.computeRemainingMakerFillable();
-		const remainingFillableTakerTokenAmount = remainingFillableCalculator.computeRemainingTakerFillable();
-		const orderRelevantState = {
-			makerBalance,
-			makerProxyAllowance,
-			makerFeeBalance,
-			makerFeeProxyAllowance,
-			filledTakerTokenAmount,
-			cancelledTakerTokenAmount,
-			remainingFillableMakerTokenAmount,
-			remainingFillableTakerTokenAmount,
-		};
-		return orderRelevantState;
-	}
+        const isMakerTokenZRX = signedOrder.makerTokenAddress === zrxTokenAddress;
+        const remainingFillableCalculator = new RemainingFillableCalculator(
+            signedOrder,
+            isMakerTokenZRX,
+            transferrableMakerTokenAmount,
+            transferrableFeeTokenAmount,
+            remainingMakerTokenAmount,
+        );
+        const remainingFillableMakerTokenAmount = remainingFillableCalculator.computeRemainingMakerFillable();
+        const remainingFillableTakerTokenAmount = remainingFillableCalculator.computeRemainingTakerFillable();
+        const orderRelevantState = {
+            makerBalance,
+            makerProxyAllowance,
+            makerFeeBalance,
+            makerFeeProxyAllowance,
+            filledTakerTokenAmount,
+            cancelledTakerTokenAmount,
+            remainingFillableMakerTokenAmount,
+            remainingFillableTakerTokenAmount,
+        };
+        return orderRelevantState;
+    }
 }
diff --git a/packages/0x.js/src/utils/order_validation_utils.ts b/packages/0x.js/src/utils/order_validation_utils.ts
index 8ff22266f..917d414c8 100644
--- a/packages/0x.js/src/utils/order_validation_utils.ts
+++ b/packages/0x.js/src/utils/order_validation_utils.ts
@@ -10,207 +10,207 @@ import { utils } from '../utils/utils';
 import { ExchangeTransferSimulator } from './exchange_transfer_simulator';
 
 export class OrderValidationUtils {
-	private _exchangeWrapper: ExchangeWrapper;
-	public static validateCancelOrderThrowIfInvalid(
-		order: Order,
-		cancelTakerTokenAmount: BigNumber,
-		unavailableTakerTokenAmount: BigNumber,
-	): void {
-		if (cancelTakerTokenAmount.eq(0)) {
-			throw new Error(ExchangeContractErrs.OrderCancelAmountZero);
-		}
-		if (order.takerTokenAmount.eq(unavailableTakerTokenAmount)) {
-			throw new Error(ExchangeContractErrs.OrderAlreadyCancelledOrFilled);
-		}
-		const currentUnixTimestampSec = utils.getCurrentUnixTimestampSec();
-		if (order.expirationUnixTimestampSec.lessThan(currentUnixTimestampSec)) {
-			throw new Error(ExchangeContractErrs.OrderCancelExpired);
-		}
-	}
-	public static async validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
-		exchangeTradeEmulator: ExchangeTransferSimulator,
-		signedOrder: SignedOrder,
-		fillTakerTokenAmount: BigNumber,
-		senderAddress: string,
-		zrxTokenAddress: string,
-	): Promise<void> {
-		const fillMakerTokenAmount = OrderValidationUtils._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 = OrderValidationUtils._getPartialAmount(
-			fillTakerTokenAmount,
-			signedOrder.takerTokenAmount,
-			signedOrder.makerFee,
-		);
-		await exchangeTradeEmulator.transferFromAsync(
-			zrxTokenAddress,
-			signedOrder.maker,
-			signedOrder.feeRecipient,
-			makerFeeAmount,
-			TradeSide.Maker,
-			TransferType.Fee,
-		);
-		const takerFeeAmount = OrderValidationUtils._getPartialAmount(
-			fillTakerTokenAmount,
-			signedOrder.takerTokenAmount,
-			signedOrder.takerFee,
-		);
-		await exchangeTradeEmulator.transferFromAsync(
-			zrxTokenAddress,
-			senderAddress,
-			signedOrder.feeRecipient,
-			takerFeeAmount,
-			TradeSide.Taker,
-			TransferType.Fee,
-		);
-	}
-	private static _validateRemainingFillAmountNotZeroOrThrow(
-		takerTokenAmount: BigNumber,
-		unavailableTakerTokenAmount: BigNumber,
-	) {
-		if (takerTokenAmount.eq(unavailableTakerTokenAmount)) {
-			throw new Error(ExchangeContractErrs.OrderRemainingFillAmountZero);
-		}
-	}
-	private static _validateOrderNotExpiredOrThrow(expirationUnixTimestampSec: BigNumber) {
-		const currentUnixTimestampSec = utils.getCurrentUnixTimestampSec();
-		if (expirationUnixTimestampSec.lessThan(currentUnixTimestampSec)) {
-			throw new Error(ExchangeContractErrs.OrderFillExpired);
-		}
-	}
-	private static _getPartialAmount(numerator: BigNumber, denominator: BigNumber, target: BigNumber): BigNumber {
-		const fillMakerTokenAmount = numerator
-			.mul(target)
-			.div(denominator)
-			.round(0);
-		return fillMakerTokenAmount;
-	}
-	constructor(exchangeWrapper: ExchangeWrapper) {
-		this._exchangeWrapper = exchangeWrapper;
-	}
-	public async validateOrderFillableOrThrowAsync(
-		exchangeTradeEmulator: ExchangeTransferSimulator,
-		signedOrder: SignedOrder,
-		zrxTokenAddress: string,
-		expectedFillTakerTokenAmount?: BigNumber,
-	): Promise<void> {
-		const orderHash = utils.getOrderHashHex(signedOrder);
-		const unavailableTakerTokenAmount = await this._exchangeWrapper.getUnavailableTakerAmountAsync(orderHash);
-		OrderValidationUtils._validateRemainingFillAmountNotZeroOrThrow(
-			signedOrder.takerTokenAmount,
-			unavailableTakerTokenAmount,
-		);
-		OrderValidationUtils._validateOrderNotExpiredOrThrow(signedOrder.expirationUnixTimestampSec);
-		let fillTakerTokenAmount = signedOrder.takerTokenAmount.minus(unavailableTakerTokenAmount);
-		if (!_.isUndefined(expectedFillTakerTokenAmount)) {
-			fillTakerTokenAmount = expectedFillTakerTokenAmount;
-		}
-		const fillMakerTokenAmount = OrderValidationUtils._getPartialAmount(
-			fillTakerTokenAmount,
-			signedOrder.takerTokenAmount,
-			signedOrder.makerTokenAmount,
-		);
-		await exchangeTradeEmulator.transferFromAsync(
-			signedOrder.makerTokenAddress,
-			signedOrder.maker,
-			signedOrder.taker,
-			fillMakerTokenAmount,
-			TradeSide.Maker,
-			TransferType.Trade,
-		);
-		const makerFeeAmount = OrderValidationUtils._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<BigNumber> {
-		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);
-		OrderValidationUtils._validateRemainingFillAmountNotZeroOrThrow(
-			signedOrder.takerTokenAmount,
-			unavailableTakerTokenAmount,
-		);
-		if (signedOrder.taker !== constants.NULL_ADDRESS && signedOrder.taker !== takerAddress) {
-			throw new Error(ExchangeContractErrs.TransactionSenderIsNotFillOrderTaker);
-		}
-		OrderValidationUtils._validateOrderNotExpiredOrThrow(signedOrder.expirationUnixTimestampSec);
-		const remainingTakerTokenAmount = signedOrder.takerTokenAmount.minus(unavailableTakerTokenAmount);
-		const filledTakerTokenAmount = remainingTakerTokenAmount.lessThan(fillTakerTokenAmount)
-			? remainingTakerTokenAmount
-			: fillTakerTokenAmount;
-		await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
-			exchangeTradeEmulator,
-			signedOrder,
-			filledTakerTokenAmount,
-			takerAddress,
-			zrxTokenAddress,
-		);
+    private _exchangeWrapper: ExchangeWrapper;
+    public static validateCancelOrderThrowIfInvalid(
+        order: Order,
+        cancelTakerTokenAmount: BigNumber,
+        unavailableTakerTokenAmount: BigNumber,
+    ): void {
+        if (cancelTakerTokenAmount.eq(0)) {
+            throw new Error(ExchangeContractErrs.OrderCancelAmountZero);
+        }
+        if (order.takerTokenAmount.eq(unavailableTakerTokenAmount)) {
+            throw new Error(ExchangeContractErrs.OrderAlreadyCancelledOrFilled);
+        }
+        const currentUnixTimestampSec = utils.getCurrentUnixTimestampSec();
+        if (order.expirationUnixTimestampSec.lessThan(currentUnixTimestampSec)) {
+            throw new Error(ExchangeContractErrs.OrderCancelExpired);
+        }
+    }
+    public static async validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
+        exchangeTradeEmulator: ExchangeTransferSimulator,
+        signedOrder: SignedOrder,
+        fillTakerTokenAmount: BigNumber,
+        senderAddress: string,
+        zrxTokenAddress: string,
+    ): Promise<void> {
+        const fillMakerTokenAmount = OrderValidationUtils._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 = OrderValidationUtils._getPartialAmount(
+            fillTakerTokenAmount,
+            signedOrder.takerTokenAmount,
+            signedOrder.makerFee,
+        );
+        await exchangeTradeEmulator.transferFromAsync(
+            zrxTokenAddress,
+            signedOrder.maker,
+            signedOrder.feeRecipient,
+            makerFeeAmount,
+            TradeSide.Maker,
+            TransferType.Fee,
+        );
+        const takerFeeAmount = OrderValidationUtils._getPartialAmount(
+            fillTakerTokenAmount,
+            signedOrder.takerTokenAmount,
+            signedOrder.takerFee,
+        );
+        await exchangeTradeEmulator.transferFromAsync(
+            zrxTokenAddress,
+            senderAddress,
+            signedOrder.feeRecipient,
+            takerFeeAmount,
+            TradeSide.Taker,
+            TransferType.Fee,
+        );
+    }
+    private static _validateRemainingFillAmountNotZeroOrThrow(
+        takerTokenAmount: BigNumber,
+        unavailableTakerTokenAmount: BigNumber,
+    ) {
+        if (takerTokenAmount.eq(unavailableTakerTokenAmount)) {
+            throw new Error(ExchangeContractErrs.OrderRemainingFillAmountZero);
+        }
+    }
+    private static _validateOrderNotExpiredOrThrow(expirationUnixTimestampSec: BigNumber) {
+        const currentUnixTimestampSec = utils.getCurrentUnixTimestampSec();
+        if (expirationUnixTimestampSec.lessThan(currentUnixTimestampSec)) {
+            throw new Error(ExchangeContractErrs.OrderFillExpired);
+        }
+    }
+    private static _getPartialAmount(numerator: BigNumber, denominator: BigNumber, target: BigNumber): BigNumber {
+        const fillMakerTokenAmount = numerator
+            .mul(target)
+            .div(denominator)
+            .round(0);
+        return fillMakerTokenAmount;
+    }
+    constructor(exchangeWrapper: ExchangeWrapper) {
+        this._exchangeWrapper = exchangeWrapper;
+    }
+    public async validateOrderFillableOrThrowAsync(
+        exchangeTradeEmulator: ExchangeTransferSimulator,
+        signedOrder: SignedOrder,
+        zrxTokenAddress: string,
+        expectedFillTakerTokenAmount?: BigNumber,
+    ): Promise<void> {
+        const orderHash = utils.getOrderHashHex(signedOrder);
+        const unavailableTakerTokenAmount = await this._exchangeWrapper.getUnavailableTakerAmountAsync(orderHash);
+        OrderValidationUtils._validateRemainingFillAmountNotZeroOrThrow(
+            signedOrder.takerTokenAmount,
+            unavailableTakerTokenAmount,
+        );
+        OrderValidationUtils._validateOrderNotExpiredOrThrow(signedOrder.expirationUnixTimestampSec);
+        let fillTakerTokenAmount = signedOrder.takerTokenAmount.minus(unavailableTakerTokenAmount);
+        if (!_.isUndefined(expectedFillTakerTokenAmount)) {
+            fillTakerTokenAmount = expectedFillTakerTokenAmount;
+        }
+        const fillMakerTokenAmount = OrderValidationUtils._getPartialAmount(
+            fillTakerTokenAmount,
+            signedOrder.takerTokenAmount,
+            signedOrder.makerTokenAmount,
+        );
+        await exchangeTradeEmulator.transferFromAsync(
+            signedOrder.makerTokenAddress,
+            signedOrder.maker,
+            signedOrder.taker,
+            fillMakerTokenAmount,
+            TradeSide.Maker,
+            TransferType.Trade,
+        );
+        const makerFeeAmount = OrderValidationUtils._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<BigNumber> {
+        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);
+        OrderValidationUtils._validateRemainingFillAmountNotZeroOrThrow(
+            signedOrder.takerTokenAmount,
+            unavailableTakerTokenAmount,
+        );
+        if (signedOrder.taker !== constants.NULL_ADDRESS && signedOrder.taker !== takerAddress) {
+            throw new Error(ExchangeContractErrs.TransactionSenderIsNotFillOrderTaker);
+        }
+        OrderValidationUtils._validateOrderNotExpiredOrThrow(signedOrder.expirationUnixTimestampSec);
+        const remainingTakerTokenAmount = signedOrder.takerTokenAmount.minus(unavailableTakerTokenAmount);
+        const filledTakerTokenAmount = remainingTakerTokenAmount.lessThan(fillTakerTokenAmount)
+            ? remainingTakerTokenAmount
+            : fillTakerTokenAmount;
+        await OrderValidationUtils.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<void> {
-		const filledTakerTokenAmount = await this.validateFillOrderThrowIfInvalidAsync(
-			exchangeTradeEmulator,
-			signedOrder,
-			fillTakerTokenAmount,
-			takerAddress,
-			zrxTokenAddress,
-		);
-		if (filledTakerTokenAmount !== fillTakerTokenAmount) {
-			throw new Error(ExchangeContractErrs.InsufficientRemainingFillAmount);
-		}
-	}
+        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<void> {
+        const filledTakerTokenAmount = await this.validateFillOrderThrowIfInvalidAsync(
+            exchangeTradeEmulator,
+            signedOrder,
+            fillTakerTokenAmount,
+            takerAddress,
+            zrxTokenAddress,
+        );
+        if (filledTakerTokenAmount !== fillTakerTokenAmount) {
+            throw new Error(ExchangeContractErrs.InsufficientRemainingFillAmount);
+        }
+    }
 }
diff --git a/packages/0x.js/src/utils/signature_utils.ts b/packages/0x.js/src/utils/signature_utils.ts
index 19b5c76c7..b0f1d61ef 100644
--- a/packages/0x.js/src/utils/signature_utils.ts
+++ b/packages/0x.js/src/utils/signature_utils.ts
@@ -3,44 +3,44 @@ 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;
-	},
+    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/packages/0x.js/src/utils/utils.ts b/packages/0x.js/src/utils/utils.ts
index ae07941ef..42cf5d956 100644
--- a/packages/0x.js/src/utils/utils.ts
+++ b/packages/0x.js/src/utils/utils.ts
@@ -7,62 +7,62 @@ import * as _ from 'lodash';
 import { Order, SignedOrder, SolidityTypes } from '../types';
 
 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);
-	},
-	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;
-	},
-	getCurrentUnixTimestampSec(): BigNumber {
-		return new BigNumber(Date.now() / 1000).round();
-	},
-	getCurrentUnixTimestampMs(): BigNumber {
-		return new BigNumber(Date.now());
-	},
+    /**
+     * 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);
+    },
+    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;
+    },
+    getCurrentUnixTimestampSec(): BigNumber {
+        return new BigNumber(Date.now() / 1000).round();
+    },
+    getCurrentUnixTimestampMs(): BigNumber {
+        return new BigNumber(Date.now());
+    },
 };
diff --git a/packages/0x.js/test/0x.js_test.ts b/packages/0x.js/test/0x.js_test.ts
index 5ece5192f..927fe20be 100644
--- a/packages/0x.js/test/0x.js_test.ts
+++ b/packages/0x.js/test/0x.js_test.ts
@@ -19,278 +19,278 @@ const expect = chai.expect;
 const SHOULD_ADD_PERSONAL_MESSAGE_PREFIX = false;
 
 describe('ZeroEx library', () => {
-	const web3 = web3Factory.create();
-	const config = {
-		networkId: constants.TESTRPC_NETWORK_ID,
-	};
-	const zeroEx = new ZeroEx(web3.currentProvider, config);
-	describe('#setProvider', () => {
-		it('overrides provider in nested web3s and invalidates contractInstances', async () => {
-			// Instantiate the contract instances with the current provider
-			await (zeroEx.exchange as any)._getExchangeContractAsync();
-			await (zeroEx.tokenRegistry as any)._getTokenRegistryContractAsync();
-			expect((zeroEx.exchange as any)._exchangeContractIfExists).to.not.be.undefined();
-			expect((zeroEx.tokenRegistry as any)._tokenRegistryContractIfExists).to.not.be.undefined();
+    const web3 = web3Factory.create();
+    const config = {
+        networkId: constants.TESTRPC_NETWORK_ID,
+    };
+    const zeroEx = new ZeroEx(web3.currentProvider, config);
+    describe('#setProvider', () => {
+        it('overrides provider in nested web3s and invalidates contractInstances', async () => {
+            // Instantiate the contract instances with the current provider
+            await (zeroEx.exchange as any)._getExchangeContractAsync();
+            await (zeroEx.tokenRegistry as any)._getTokenRegistryContractAsync();
+            expect((zeroEx.exchange as any)._exchangeContractIfExists).to.not.be.undefined();
+            expect((zeroEx.tokenRegistry as any)._tokenRegistryContractIfExists).to.not.be.undefined();
 
-			const newProvider = web3Factory.getRpcProvider();
-			// Add property to newProvider so that we can differentiate it from old provider
-			(newProvider as any).zeroExTestId = 1;
-			zeroEx.setProvider(newProvider, constants.TESTRPC_NETWORK_ID);
+            const newProvider = web3Factory.getRpcProvider();
+            // Add property to newProvider so that we can differentiate it from old provider
+            (newProvider as any).zeroExTestId = 1;
+            zeroEx.setProvider(newProvider, constants.TESTRPC_NETWORK_ID);
 
-			// Check that contractInstances with old provider are removed after provider update
-			expect((zeroEx.exchange as any)._exchangeContractIfExists).to.be.undefined();
-			expect((zeroEx.tokenRegistry as any)._tokenRegistryContractIfExists).to.be.undefined();
+            // Check that contractInstances with old provider are removed after provider update
+            expect((zeroEx.exchange as any)._exchangeContractIfExists).to.be.undefined();
+            expect((zeroEx.tokenRegistry as any)._tokenRegistryContractIfExists).to.be.undefined();
 
-			// Check that all nested web3 wrapper instances return the updated provider
-			const nestedWeb3WrapperProvider = (zeroEx as any)._web3Wrapper.getCurrentProvider();
-			expect(nestedWeb3WrapperProvider.zeroExTestId).to.be.a('number');
-			const exchangeWeb3WrapperProvider = (zeroEx.exchange as any)._web3Wrapper.getCurrentProvider();
-			expect(exchangeWeb3WrapperProvider.zeroExTestId).to.be.a('number');
-			const tokenRegistryWeb3WrapperProvider = (zeroEx.tokenRegistry as any)._web3Wrapper.getCurrentProvider();
-			expect(tokenRegistryWeb3WrapperProvider.zeroExTestId).to.be.a('number');
-		});
-	});
-	describe('#isValidSignature', () => {
-		// The Exchange smart contract `isValidSignature` method only validates orderHashes and assumes
-		// the length of the data is exactly 32 bytes. Thus for these tests, we use data of this size.
-		const dataHex = '0x6927e990021d23b1eb7b8789f6a6feaf98fe104bb0cf8259421b79f9a34222b0';
-		const signature = {
-			v: 27,
-			r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
-			s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
-		};
-		const address = '0x5409ed021d9299bf6814279a6a1411a7e866a631';
-		it("should return false if the data doesn't pertain to the signature & address", async () => {
-			expect(ZeroEx.isValidSignature('0x0', signature, address)).to.be.false();
-			return expect(
-				(zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync('0x0', signature, address),
-			).to.become(false);
-		});
-		it("should return false if the address doesn't pertain to the signature & data", async () => {
-			const validUnrelatedAddress = '0x8b0292b11a196601ed2ce54b665cafeca0347d42';
-			expect(ZeroEx.isValidSignature(dataHex, signature, validUnrelatedAddress)).to.be.false();
-			return expect(
-				(zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync(
-					dataHex,
-					signature,
-					validUnrelatedAddress,
-				),
-			).to.become(false);
-		});
-		it("should return false if the signature doesn't pertain to the dataHex & address", async () => {
-			const wrongSignature = _.assign({}, signature, { v: 28 });
-			expect(ZeroEx.isValidSignature(dataHex, wrongSignature, address)).to.be.false();
-			return expect(
-				(zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync(dataHex, wrongSignature, address),
-			).to.become(false);
-		});
-		it('should return true if the signature does pertain to the dataHex & address', async () => {
-			const isValidSignatureLocal = ZeroEx.isValidSignature(dataHex, signature, address);
-			expect(isValidSignatureLocal).to.be.true();
-			return expect(
-				(zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync(dataHex, signature, address),
-			).to.become(true);
-		});
-	});
-	describe('#generateSalt', () => {
-		it('generates different salts', () => {
-			const equal = ZeroEx.generatePseudoRandomSalt().eq(ZeroEx.generatePseudoRandomSalt());
-			expect(equal).to.be.false();
-		});
-		it('generates salt in range [0..2^256)', () => {
-			const salt = ZeroEx.generatePseudoRandomSalt();
-			expect(salt.greaterThanOrEqualTo(0)).to.be.true();
-			const twoPow256 = new BigNumber(2).pow(256);
-			expect(salt.lessThan(twoPow256)).to.be.true();
-		});
-	});
-	describe('#isValidOrderHash', () => {
-		it('returns false if the value is not a hex string', () => {
-			const isValid = ZeroEx.isValidOrderHash('not a hex');
-			expect(isValid).to.be.false();
-		});
-		it('returns false if the length is wrong', () => {
-			const isValid = ZeroEx.isValidOrderHash('0xdeadbeef');
-			expect(isValid).to.be.false();
-		});
-		it('returns true if order hash is correct', () => {
-			const isValid = ZeroEx.isValidOrderHash('0x' + Array(65).join('0'));
-			expect(isValid).to.be.true();
-		});
-	});
-	describe('#toUnitAmount', () => {
-		it('should throw if invalid baseUnit amount supplied as argument', () => {
-			const invalidBaseUnitAmount = new BigNumber(1000000000.4);
-			const decimals = 6;
-			expect(() => ZeroEx.toUnitAmount(invalidBaseUnitAmount, decimals)).to.throw(
-				'amount should be in baseUnits (no decimals), found value: 1000000000.4',
-			);
-		});
-		it('Should return the expected unit amount for the decimals passed in', () => {
-			const baseUnitAmount = new BigNumber(1000000000);
-			const decimals = 6;
-			const unitAmount = ZeroEx.toUnitAmount(baseUnitAmount, decimals);
-			const expectedUnitAmount = new BigNumber(1000);
-			expect(unitAmount).to.be.bignumber.equal(expectedUnitAmount);
-		});
-	});
-	describe('#toBaseUnitAmount', () => {
-		it('Should return the expected base unit amount for the decimals passed in', () => {
-			const unitAmount = new BigNumber(1000);
-			const decimals = 6;
-			const baseUnitAmount = ZeroEx.toBaseUnitAmount(unitAmount, decimals);
-			const expectedUnitAmount = new BigNumber(1000000000);
-			expect(baseUnitAmount).to.be.bignumber.equal(expectedUnitAmount);
-		});
-		it('should throw if unitAmount has more decimals then specified as the max decimal precision', () => {
-			const unitAmount = new BigNumber(0.823091);
-			const decimals = 5;
-			expect(() => ZeroEx.toBaseUnitAmount(unitAmount, decimals)).to.throw(
-				'Invalid unit amount: 0.823091 - Too many decimal places',
-			);
-		});
-	});
-	describe('#getOrderHashHex', () => {
-		const expectedOrderHash = '0x39da987067a3c9e5f1617694f1301326ba8c8b0498ebef5df4863bed394e3c83';
-		const fakeExchangeContractAddress = '0xb69e673309512a9d726f87304c6984054f87a93b';
-		const order: Order = {
-			maker: constants.NULL_ADDRESS,
-			taker: constants.NULL_ADDRESS,
-			feeRecipient: constants.NULL_ADDRESS,
-			makerTokenAddress: constants.NULL_ADDRESS,
-			takerTokenAddress: constants.NULL_ADDRESS,
-			exchangeContractAddress: fakeExchangeContractAddress,
-			salt: new BigNumber(0),
-			makerFee: new BigNumber(0),
-			takerFee: new BigNumber(0),
-			makerTokenAmount: new BigNumber(0),
-			takerTokenAmount: new BigNumber(0),
-			expirationUnixTimestampSec: new BigNumber(0),
-		};
-		it('calculates the order hash', async () => {
-			const orderHash = ZeroEx.getOrderHashHex(order);
-			expect(orderHash).to.be.equal(expectedOrderHash);
-		});
-		it('throws a readable error message if taker format is invalid', async () => {
-			const orderWithInvalidtakerFormat = {
-				...order,
-				taker: (null as any) as string,
-			};
-			const expectedErrorMessage =
-				'Order taker must be of type string. If you want anyone to be able to fill an order - pass ZeroEx.NULL_ADDRESS';
-			expect(() => ZeroEx.getOrderHashHex(orderWithInvalidtakerFormat)).to.throw(expectedErrorMessage);
-		});
-	});
-	describe('#signOrderHashAsync', () => {
-		let stubs: Sinon.SinonStub[] = [];
-		let makerAddress: string;
-		before(async () => {
-			const availableAddreses = await zeroEx.getAvailableAddressesAsync();
-			makerAddress = availableAddreses[0];
-		});
-		afterEach(() => {
-			// clean up any stubs after the test has completed
-			_.each(stubs, s => s.restore());
-			stubs = [];
-		});
-		it('Should return the correct ECSignature', async () => {
-			const orderHash = '0x6927e990021d23b1eb7b8789f6a6feaf98fe104bb0cf8259421b79f9a34222b0';
-			const expectedECSignature = {
-				v: 27,
-				r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
-				s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
-			};
-			const ecSignature = await zeroEx.signOrderHashAsync(
-				orderHash,
-				makerAddress,
-				SHOULD_ADD_PERSONAL_MESSAGE_PREFIX,
-			);
-			expect(ecSignature).to.deep.equal(expectedECSignature);
-		});
-		it('should return the correct ECSignature for signatureHex concatenated as R + S + V', async () => {
-			const orderHash = '0x34decbedc118904df65f379a175bb39ca18209d6ce41d5ed549d54e6e0a95004';
-			const signature =
-				'0x22109d11d79cb8bf96ed88625e1cd9558800c4073332a9a02857499883ee5ce3050aa3cc1f2c435e67e114cdce54b9527b4f50548342401bc5d2b77adbdacb021b';
-			const expectedECSignature = {
-				v: 27,
-				r: '0x22109d11d79cb8bf96ed88625e1cd9558800c4073332a9a02857499883ee5ce3',
-				s: '0x050aa3cc1f2c435e67e114cdce54b9527b4f50548342401bc5d2b77adbdacb02',
-			};
-			stubs = [
-				Sinon.stub((zeroEx as any)._web3Wrapper, 'signTransactionAsync').returns(Promise.resolve(signature)),
-				Sinon.stub(ZeroEx, 'isValidSignature').returns(true),
-			];
+            // Check that all nested web3 wrapper instances return the updated provider
+            const nestedWeb3WrapperProvider = (zeroEx as any)._web3Wrapper.getCurrentProvider();
+            expect(nestedWeb3WrapperProvider.zeroExTestId).to.be.a('number');
+            const exchangeWeb3WrapperProvider = (zeroEx.exchange as any)._web3Wrapper.getCurrentProvider();
+            expect(exchangeWeb3WrapperProvider.zeroExTestId).to.be.a('number');
+            const tokenRegistryWeb3WrapperProvider = (zeroEx.tokenRegistry as any)._web3Wrapper.getCurrentProvider();
+            expect(tokenRegistryWeb3WrapperProvider.zeroExTestId).to.be.a('number');
+        });
+    });
+    describe('#isValidSignature', () => {
+        // The Exchange smart contract `isValidSignature` method only validates orderHashes and assumes
+        // the length of the data is exactly 32 bytes. Thus for these tests, we use data of this size.
+        const dataHex = '0x6927e990021d23b1eb7b8789f6a6feaf98fe104bb0cf8259421b79f9a34222b0';
+        const signature = {
+            v: 27,
+            r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
+            s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
+        };
+        const address = '0x5409ed021d9299bf6814279a6a1411a7e866a631';
+        it("should return false if the data doesn't pertain to the signature & address", async () => {
+            expect(ZeroEx.isValidSignature('0x0', signature, address)).to.be.false();
+            return expect(
+                (zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync('0x0', signature, address),
+            ).to.become(false);
+        });
+        it("should return false if the address doesn't pertain to the signature & data", async () => {
+            const validUnrelatedAddress = '0x8b0292b11a196601ed2ce54b665cafeca0347d42';
+            expect(ZeroEx.isValidSignature(dataHex, signature, validUnrelatedAddress)).to.be.false();
+            return expect(
+                (zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync(
+                    dataHex,
+                    signature,
+                    validUnrelatedAddress,
+                ),
+            ).to.become(false);
+        });
+        it("should return false if the signature doesn't pertain to the dataHex & address", async () => {
+            const wrongSignature = _.assign({}, signature, { v: 28 });
+            expect(ZeroEx.isValidSignature(dataHex, wrongSignature, address)).to.be.false();
+            return expect(
+                (zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync(dataHex, wrongSignature, address),
+            ).to.become(false);
+        });
+        it('should return true if the signature does pertain to the dataHex & address', async () => {
+            const isValidSignatureLocal = ZeroEx.isValidSignature(dataHex, signature, address);
+            expect(isValidSignatureLocal).to.be.true();
+            return expect(
+                (zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync(dataHex, signature, address),
+            ).to.become(true);
+        });
+    });
+    describe('#generateSalt', () => {
+        it('generates different salts', () => {
+            const equal = ZeroEx.generatePseudoRandomSalt().eq(ZeroEx.generatePseudoRandomSalt());
+            expect(equal).to.be.false();
+        });
+        it('generates salt in range [0..2^256)', () => {
+            const salt = ZeroEx.generatePseudoRandomSalt();
+            expect(salt.greaterThanOrEqualTo(0)).to.be.true();
+            const twoPow256 = new BigNumber(2).pow(256);
+            expect(salt.lessThan(twoPow256)).to.be.true();
+        });
+    });
+    describe('#isValidOrderHash', () => {
+        it('returns false if the value is not a hex string', () => {
+            const isValid = ZeroEx.isValidOrderHash('not a hex');
+            expect(isValid).to.be.false();
+        });
+        it('returns false if the length is wrong', () => {
+            const isValid = ZeroEx.isValidOrderHash('0xdeadbeef');
+            expect(isValid).to.be.false();
+        });
+        it('returns true if order hash is correct', () => {
+            const isValid = ZeroEx.isValidOrderHash('0x' + Array(65).join('0'));
+            expect(isValid).to.be.true();
+        });
+    });
+    describe('#toUnitAmount', () => {
+        it('should throw if invalid baseUnit amount supplied as argument', () => {
+            const invalidBaseUnitAmount = new BigNumber(1000000000.4);
+            const decimals = 6;
+            expect(() => ZeroEx.toUnitAmount(invalidBaseUnitAmount, decimals)).to.throw(
+                'amount should be in baseUnits (no decimals), found value: 1000000000.4',
+            );
+        });
+        it('Should return the expected unit amount for the decimals passed in', () => {
+            const baseUnitAmount = new BigNumber(1000000000);
+            const decimals = 6;
+            const unitAmount = ZeroEx.toUnitAmount(baseUnitAmount, decimals);
+            const expectedUnitAmount = new BigNumber(1000);
+            expect(unitAmount).to.be.bignumber.equal(expectedUnitAmount);
+        });
+    });
+    describe('#toBaseUnitAmount', () => {
+        it('Should return the expected base unit amount for the decimals passed in', () => {
+            const unitAmount = new BigNumber(1000);
+            const decimals = 6;
+            const baseUnitAmount = ZeroEx.toBaseUnitAmount(unitAmount, decimals);
+            const expectedUnitAmount = new BigNumber(1000000000);
+            expect(baseUnitAmount).to.be.bignumber.equal(expectedUnitAmount);
+        });
+        it('should throw if unitAmount has more decimals then specified as the max decimal precision', () => {
+            const unitAmount = new BigNumber(0.823091);
+            const decimals = 5;
+            expect(() => ZeroEx.toBaseUnitAmount(unitAmount, decimals)).to.throw(
+                'Invalid unit amount: 0.823091 - Too many decimal places',
+            );
+        });
+    });
+    describe('#getOrderHashHex', () => {
+        const expectedOrderHash = '0x39da987067a3c9e5f1617694f1301326ba8c8b0498ebef5df4863bed394e3c83';
+        const fakeExchangeContractAddress = '0xb69e673309512a9d726f87304c6984054f87a93b';
+        const order: Order = {
+            maker: constants.NULL_ADDRESS,
+            taker: constants.NULL_ADDRESS,
+            feeRecipient: constants.NULL_ADDRESS,
+            makerTokenAddress: constants.NULL_ADDRESS,
+            takerTokenAddress: constants.NULL_ADDRESS,
+            exchangeContractAddress: fakeExchangeContractAddress,
+            salt: new BigNumber(0),
+            makerFee: new BigNumber(0),
+            takerFee: new BigNumber(0),
+            makerTokenAmount: new BigNumber(0),
+            takerTokenAmount: new BigNumber(0),
+            expirationUnixTimestampSec: new BigNumber(0),
+        };
+        it('calculates the order hash', async () => {
+            const orderHash = ZeroEx.getOrderHashHex(order);
+            expect(orderHash).to.be.equal(expectedOrderHash);
+        });
+        it('throws a readable error message if taker format is invalid', async () => {
+            const orderWithInvalidtakerFormat = {
+                ...order,
+                taker: (null as any) as string,
+            };
+            const expectedErrorMessage =
+                'Order taker must be of type string. If you want anyone to be able to fill an order - pass ZeroEx.NULL_ADDRESS';
+            expect(() => ZeroEx.getOrderHashHex(orderWithInvalidtakerFormat)).to.throw(expectedErrorMessage);
+        });
+    });
+    describe('#signOrderHashAsync', () => {
+        let stubs: Sinon.SinonStub[] = [];
+        let makerAddress: string;
+        before(async () => {
+            const availableAddreses = await zeroEx.getAvailableAddressesAsync();
+            makerAddress = availableAddreses[0];
+        });
+        afterEach(() => {
+            // clean up any stubs after the test has completed
+            _.each(stubs, s => s.restore());
+            stubs = [];
+        });
+        it('Should return the correct ECSignature', async () => {
+            const orderHash = '0x6927e990021d23b1eb7b8789f6a6feaf98fe104bb0cf8259421b79f9a34222b0';
+            const expectedECSignature = {
+                v: 27,
+                r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
+                s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
+            };
+            const ecSignature = await zeroEx.signOrderHashAsync(
+                orderHash,
+                makerAddress,
+                SHOULD_ADD_PERSONAL_MESSAGE_PREFIX,
+            );
+            expect(ecSignature).to.deep.equal(expectedECSignature);
+        });
+        it('should return the correct ECSignature for signatureHex concatenated as R + S + V', async () => {
+            const orderHash = '0x34decbedc118904df65f379a175bb39ca18209d6ce41d5ed549d54e6e0a95004';
+            const signature =
+                '0x22109d11d79cb8bf96ed88625e1cd9558800c4073332a9a02857499883ee5ce3050aa3cc1f2c435e67e114cdce54b9527b4f50548342401bc5d2b77adbdacb021b';
+            const expectedECSignature = {
+                v: 27,
+                r: '0x22109d11d79cb8bf96ed88625e1cd9558800c4073332a9a02857499883ee5ce3',
+                s: '0x050aa3cc1f2c435e67e114cdce54b9527b4f50548342401bc5d2b77adbdacb02',
+            };
+            stubs = [
+                Sinon.stub((zeroEx as any)._web3Wrapper, 'signTransactionAsync').returns(Promise.resolve(signature)),
+                Sinon.stub(ZeroEx, 'isValidSignature').returns(true),
+            ];
 
-			const ecSignature = await zeroEx.signOrderHashAsync(
-				orderHash,
-				makerAddress,
-				SHOULD_ADD_PERSONAL_MESSAGE_PREFIX,
-			);
-			expect(ecSignature).to.deep.equal(expectedECSignature);
-		});
-		it('should return the correct ECSignature for signatureHex concatenated as V + R + S', async () => {
-			const orderHash = '0xc793e33ffded933b76f2f48d9aa3339fc090399d5e7f5dec8d3660f5480793f7';
-			const signature =
-				'0x1bc80bedc6756722672753413efdd749b5adbd4fd552595f59c13427407ee9aee02dea66f25a608bbae457e020fb6decb763deb8b7192abab624997242da248960';
-			const expectedECSignature = {
-				v: 27,
-				r: '0xc80bedc6756722672753413efdd749b5adbd4fd552595f59c13427407ee9aee0',
-				s: '0x2dea66f25a608bbae457e020fb6decb763deb8b7192abab624997242da248960',
-			};
-			stubs = [
-				Sinon.stub((zeroEx as any)._web3Wrapper, 'signTransactionAsync').returns(Promise.resolve(signature)),
-				Sinon.stub(ZeroEx, 'isValidSignature').returns(true),
-			];
+            const ecSignature = await zeroEx.signOrderHashAsync(
+                orderHash,
+                makerAddress,
+                SHOULD_ADD_PERSONAL_MESSAGE_PREFIX,
+            );
+            expect(ecSignature).to.deep.equal(expectedECSignature);
+        });
+        it('should return the correct ECSignature for signatureHex concatenated as V + R + S', async () => {
+            const orderHash = '0xc793e33ffded933b76f2f48d9aa3339fc090399d5e7f5dec8d3660f5480793f7';
+            const signature =
+                '0x1bc80bedc6756722672753413efdd749b5adbd4fd552595f59c13427407ee9aee02dea66f25a608bbae457e020fb6decb763deb8b7192abab624997242da248960';
+            const expectedECSignature = {
+                v: 27,
+                r: '0xc80bedc6756722672753413efdd749b5adbd4fd552595f59c13427407ee9aee0',
+                s: '0x2dea66f25a608bbae457e020fb6decb763deb8b7192abab624997242da248960',
+            };
+            stubs = [
+                Sinon.stub((zeroEx as any)._web3Wrapper, 'signTransactionAsync').returns(Promise.resolve(signature)),
+                Sinon.stub(ZeroEx, 'isValidSignature').returns(true),
+            ];
 
-			const ecSignature = await zeroEx.signOrderHashAsync(
-				orderHash,
-				makerAddress,
-				SHOULD_ADD_PERSONAL_MESSAGE_PREFIX,
-			);
-			expect(ecSignature).to.deep.equal(expectedECSignature);
-		});
-	});
-	describe('#awaitTransactionMinedAsync', () => {
-		beforeEach(async () => {
-			await blockchainLifecycle.startAsync();
-		});
-		afterEach(async () => {
-			await blockchainLifecycle.revertAsync();
-		});
-		it('returns transaction receipt with decoded logs', async () => {
-			const availableAddresses = await zeroEx.getAvailableAddressesAsync();
-			const coinbase = availableAddresses[0];
-			const tokens = await zeroEx.tokenRegistry.getTokensAsync();
-			const tokenUtils = new TokenUtils(tokens);
-			const zrxTokenAddress = tokenUtils.getProtocolTokenOrThrow().address;
-			const proxyAddress = zeroEx.proxy.getContractAddress();
-			const txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(zrxTokenAddress, coinbase);
-			const txReceiptWithDecodedLogs = await zeroEx.awaitTransactionMinedAsync(txHash);
-			const log = txReceiptWithDecodedLogs.logs[0] as LogWithDecodedArgs<ApprovalContractEventArgs>;
-			expect(log.event).to.be.equal(TokenEvents.Approval);
-			expect(log.args._owner).to.be.equal(coinbase);
-			expect(log.args._spender).to.be.equal(proxyAddress);
-			expect(log.args._value).to.be.bignumber.equal(zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
-		});
-	});
-	describe('#config', () => {
-		it('allows to specify exchange contract address', async () => {
-			const zeroExConfig = {
-				exchangeContractAddress: ZeroEx.NULL_ADDRESS,
-				networkId: constants.TESTRPC_NETWORK_ID,
-			};
-			const zeroExWithWrongExchangeAddress = new ZeroEx(web3.currentProvider, zeroExConfig);
-			expect(zeroExWithWrongExchangeAddress.exchange.getContractAddress()).to.be.equal(ZeroEx.NULL_ADDRESS);
-		});
-		it('allows to specify token registry token contract address', async () => {
-			const zeroExConfig = {
-				tokenRegistryContractAddress: ZeroEx.NULL_ADDRESS,
-				networkId: constants.TESTRPC_NETWORK_ID,
-			};
-			const zeroExWithWrongTokenRegistryAddress = new ZeroEx(web3.currentProvider, zeroExConfig);
-			expect(zeroExWithWrongTokenRegistryAddress.tokenRegistry.getContractAddress()).to.be.equal(
-				ZeroEx.NULL_ADDRESS,
-			);
-		});
-	});
+            const ecSignature = await zeroEx.signOrderHashAsync(
+                orderHash,
+                makerAddress,
+                SHOULD_ADD_PERSONAL_MESSAGE_PREFIX,
+            );
+            expect(ecSignature).to.deep.equal(expectedECSignature);
+        });
+    });
+    describe('#awaitTransactionMinedAsync', () => {
+        beforeEach(async () => {
+            await blockchainLifecycle.startAsync();
+        });
+        afterEach(async () => {
+            await blockchainLifecycle.revertAsync();
+        });
+        it('returns transaction receipt with decoded logs', async () => {
+            const availableAddresses = await zeroEx.getAvailableAddressesAsync();
+            const coinbase = availableAddresses[0];
+            const tokens = await zeroEx.tokenRegistry.getTokensAsync();
+            const tokenUtils = new TokenUtils(tokens);
+            const zrxTokenAddress = tokenUtils.getProtocolTokenOrThrow().address;
+            const proxyAddress = zeroEx.proxy.getContractAddress();
+            const txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(zrxTokenAddress, coinbase);
+            const txReceiptWithDecodedLogs = await zeroEx.awaitTransactionMinedAsync(txHash);
+            const log = txReceiptWithDecodedLogs.logs[0] as LogWithDecodedArgs<ApprovalContractEventArgs>;
+            expect(log.event).to.be.equal(TokenEvents.Approval);
+            expect(log.args._owner).to.be.equal(coinbase);
+            expect(log.args._spender).to.be.equal(proxyAddress);
+            expect(log.args._value).to.be.bignumber.equal(zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
+        });
+    });
+    describe('#config', () => {
+        it('allows to specify exchange contract address', async () => {
+            const zeroExConfig = {
+                exchangeContractAddress: ZeroEx.NULL_ADDRESS,
+                networkId: constants.TESTRPC_NETWORK_ID,
+            };
+            const zeroExWithWrongExchangeAddress = new ZeroEx(web3.currentProvider, zeroExConfig);
+            expect(zeroExWithWrongExchangeAddress.exchange.getContractAddress()).to.be.equal(ZeroEx.NULL_ADDRESS);
+        });
+        it('allows to specify token registry token contract address', async () => {
+            const zeroExConfig = {
+                tokenRegistryContractAddress: ZeroEx.NULL_ADDRESS,
+                networkId: constants.TESTRPC_NETWORK_ID,
+            };
+            const zeroExWithWrongTokenRegistryAddress = new ZeroEx(web3.currentProvider, zeroExConfig);
+            expect(zeroExWithWrongTokenRegistryAddress.tokenRegistry.getContractAddress()).to.be.equal(
+                ZeroEx.NULL_ADDRESS,
+            );
+        });
+    });
 });
diff --git a/packages/0x.js/test/artifacts_test.ts b/packages/0x.js/test/artifacts_test.ts
index 3a791f436..e8ab9aa97 100644
--- a/packages/0x.js/test/artifacts_test.ts
+++ b/packages/0x.js/test/artifacts_test.ts
@@ -12,44 +12,44 @@ chaiSetup.configure();
 const TIMEOUT = 10000;
 
 describe('Artifacts', () => {
-	describe('contracts are deployed on kovan', () => {
-		const kovanRpcUrl = constants.KOVAN_RPC_URL;
-		const packageJSONContent = fs.readFileSync('package.json', 'utf-8');
-		const packageJSON = JSON.parse(packageJSONContent);
-		const mnemonic = packageJSON.config.mnemonic;
-		const web3Provider = new HDWalletProvider(mnemonic, kovanRpcUrl);
-		const config = {
-			networkId: constants.KOVAN_NETWORK_ID,
-		};
-		const zeroEx = new ZeroEx(web3Provider, config);
-		it('token registry contract is deployed', async () => {
-			await (zeroEx.tokenRegistry as any)._getTokenRegistryContractAsync();
-		}).timeout(TIMEOUT);
-		it('proxy contract is deployed', async () => {
-			await (zeroEx.proxy as any)._getTokenTransferProxyContractAsync();
-		}).timeout(TIMEOUT);
-		it('exchange contract is deployed', async () => {
-			await (zeroEx.exchange as any)._getExchangeContractAsync();
-		}).timeout(TIMEOUT);
-	});
-	describe('contracts are deployed on ropsten', () => {
-		const ropstenRpcUrl = constants.ROPSTEN_RPC_URL;
-		const packageJSONContent = fs.readFileSync('package.json', 'utf-8');
-		const packageJSON = JSON.parse(packageJSONContent);
-		const mnemonic = packageJSON.config.mnemonic;
-		const web3Provider = new HDWalletProvider(mnemonic, ropstenRpcUrl);
-		const config = {
-			networkId: constants.ROPSTEN_NETWORK_ID,
-		};
-		const zeroEx = new ZeroEx(web3Provider, config);
-		it('token registry contract is deployed', async () => {
-			await (zeroEx.tokenRegistry as any)._getTokenRegistryContractAsync();
-		}).timeout(TIMEOUT);
-		it('proxy contract is deployed', async () => {
-			await (zeroEx.proxy as any)._getTokenTransferProxyContractAsync();
-		}).timeout(TIMEOUT);
-		it('exchange contract is deployed', async () => {
-			await (zeroEx.exchange as any)._getExchangeContractAsync();
-		}).timeout(TIMEOUT);
-	});
+    describe('contracts are deployed on kovan', () => {
+        const kovanRpcUrl = constants.KOVAN_RPC_URL;
+        const packageJSONContent = fs.readFileSync('package.json', 'utf-8');
+        const packageJSON = JSON.parse(packageJSONContent);
+        const mnemonic = packageJSON.config.mnemonic;
+        const web3Provider = new HDWalletProvider(mnemonic, kovanRpcUrl);
+        const config = {
+            networkId: constants.KOVAN_NETWORK_ID,
+        };
+        const zeroEx = new ZeroEx(web3Provider, config);
+        it('token registry contract is deployed', async () => {
+            await (zeroEx.tokenRegistry as any)._getTokenRegistryContractAsync();
+        }).timeout(TIMEOUT);
+        it('proxy contract is deployed', async () => {
+            await (zeroEx.proxy as any)._getTokenTransferProxyContractAsync();
+        }).timeout(TIMEOUT);
+        it('exchange contract is deployed', async () => {
+            await (zeroEx.exchange as any)._getExchangeContractAsync();
+        }).timeout(TIMEOUT);
+    });
+    describe('contracts are deployed on ropsten', () => {
+        const ropstenRpcUrl = constants.ROPSTEN_RPC_URL;
+        const packageJSONContent = fs.readFileSync('package.json', 'utf-8');
+        const packageJSON = JSON.parse(packageJSONContent);
+        const mnemonic = packageJSON.config.mnemonic;
+        const web3Provider = new HDWalletProvider(mnemonic, ropstenRpcUrl);
+        const config = {
+            networkId: constants.ROPSTEN_NETWORK_ID,
+        };
+        const zeroEx = new ZeroEx(web3Provider, config);
+        it('token registry contract is deployed', async () => {
+            await (zeroEx.tokenRegistry as any)._getTokenRegistryContractAsync();
+        }).timeout(TIMEOUT);
+        it('proxy contract is deployed', async () => {
+            await (zeroEx.proxy as any)._getTokenTransferProxyContractAsync();
+        }).timeout(TIMEOUT);
+        it('exchange contract is deployed', async () => {
+            await (zeroEx.exchange as any)._getExchangeContractAsync();
+        }).timeout(TIMEOUT);
+    });
 });
diff --git a/packages/0x.js/test/assert_test.ts b/packages/0x.js/test/assert_test.ts
index 2c72a5e88..1f2820070 100644
--- a/packages/0x.js/test/assert_test.ts
+++ b/packages/0x.js/test/assert_test.ts
@@ -10,34 +10,34 @@ import { web3Factory } from './utils/web3_factory';
 const expect = chai.expect;
 
 describe('Assertion library', () => {
-	const web3 = web3Factory.create();
-	const config = {
-		networkId: constants.TESTRPC_NETWORK_ID,
-	};
-	const zeroEx = new ZeroEx(web3.currentProvider, config);
-	describe('#isSenderAddressHexAsync', () => {
-		it('throws when address is invalid', async () => {
-			const address = '0xdeadbeef';
-			const varName = 'address';
-			return expect(
-				assert.isSenderAddressAsync(varName, address, (zeroEx as any)._web3Wrapper),
-			).to.be.rejectedWith(`Expected ${varName} to be of type ETHAddressHex, encountered: ${address}`);
-		});
-		it('throws when address is unavailable', async () => {
-			const validUnrelatedAddress = '0x8b0292b11a196601eddce54b665cafeca0347d42';
-			const varName = 'address';
-			return expect(
-				assert.isSenderAddressAsync(varName, validUnrelatedAddress, (zeroEx as any)._web3Wrapper),
-			).to.be.rejectedWith(
-				`Specified ${varName} ${validUnrelatedAddress} isn't available through the supplied web3 provider`,
-			);
-		});
-		it("doesn't throw if address is available", async () => {
-			const availableAddress = (await zeroEx.getAvailableAddressesAsync())[0];
-			const varName = 'address';
-			return expect(
-				assert.isSenderAddressAsync(varName, availableAddress, (zeroEx as any)._web3Wrapper),
-			).to.become(undefined);
-		});
-	});
+    const web3 = web3Factory.create();
+    const config = {
+        networkId: constants.TESTRPC_NETWORK_ID,
+    };
+    const zeroEx = new ZeroEx(web3.currentProvider, config);
+    describe('#isSenderAddressHexAsync', () => {
+        it('throws when address is invalid', async () => {
+            const address = '0xdeadbeef';
+            const varName = 'address';
+            return expect(
+                assert.isSenderAddressAsync(varName, address, (zeroEx as any)._web3Wrapper),
+            ).to.be.rejectedWith(`Expected ${varName} to be of type ETHAddressHex, encountered: ${address}`);
+        });
+        it('throws when address is unavailable', async () => {
+            const validUnrelatedAddress = '0x8b0292b11a196601eddce54b665cafeca0347d42';
+            const varName = 'address';
+            return expect(
+                assert.isSenderAddressAsync(varName, validUnrelatedAddress, (zeroEx as any)._web3Wrapper),
+            ).to.be.rejectedWith(
+                `Specified ${varName} ${validUnrelatedAddress} isn't available through the supplied web3 provider`,
+            );
+        });
+        it("doesn't throw if address is available", async () => {
+            const availableAddress = (await zeroEx.getAvailableAddressesAsync())[0];
+            const varName = 'address';
+            return expect(
+                assert.isSenderAddressAsync(varName, availableAddress, (zeroEx as any)._web3Wrapper),
+            ).to.become(undefined);
+        });
+    });
 });
diff --git a/packages/0x.js/test/ether_token_wrapper_test.ts b/packages/0x.js/test/ether_token_wrapper_test.ts
index 67e62dc12..b810fc9f1 100644
--- a/packages/0x.js/test/ether_token_wrapper_test.ts
+++ b/packages/0x.js/test/ether_token_wrapper_test.ts
@@ -5,17 +5,17 @@ import 'mocha';
 import * as Web3 from 'web3';
 
 import {
-	ApprovalContractEventArgs,
-	BlockParamLiteral,
-	BlockRange,
-	DecodedLogEvent,
-	DepositContractEventArgs,
-	EtherTokenEvents,
-	Token,
-	TransferContractEventArgs,
-	WithdrawalContractEventArgs,
-	ZeroEx,
-	ZeroExError,
+    ApprovalContractEventArgs,
+    BlockParamLiteral,
+    BlockRange,
+    DecodedLogEvent,
+    DepositContractEventArgs,
+    EtherTokenEvents,
+    Token,
+    TransferContractEventArgs,
+    WithdrawalContractEventArgs,
+    ZeroEx,
+    ZeroExError,
 } from '../src';
 import { artifacts } from '../src/artifacts';
 import { DoneCallback } from '../src/types';
@@ -37,339 +37,339 @@ const blockchainLifecycle = new BlockchainLifecycle(constants.RPC_URL);
 const MAX_REASONABLE_GAS_COST_IN_WEI = 62517;
 
 describe('EtherTokenWrapper', () => {
-	let web3: Web3;
-	let zeroEx: ZeroEx;
-	let tokens: Token[];
-	let userAddresses: string[];
-	let addressWithETH: string;
-	let wethContractAddress: string;
-	let depositWeiAmount: BigNumber;
-	let decimalPlaces: number;
-	let addressWithoutFunds: string;
-	const gasPrice = new BigNumber(1);
-	const zeroExConfig = {
-		gasPrice,
-		networkId: constants.TESTRPC_NETWORK_ID,
-	};
-	const transferAmount = new BigNumber(42);
-	const allowanceAmount = new BigNumber(42);
-	const depositAmount = new BigNumber(42);
-	const withdrawalAmount = new BigNumber(42);
-	before(async () => {
-		web3 = web3Factory.create();
-		zeroEx = new ZeroEx(web3.currentProvider, zeroExConfig);
-		tokens = await zeroEx.tokenRegistry.getTokensAsync();
-		userAddresses = await zeroEx.getAvailableAddressesAsync();
-		addressWithETH = userAddresses[0];
-		wethContractAddress = (zeroEx.etherToken as any)._getContractAddress(artifacts.EtherTokenArtifact);
-		depositWeiAmount = (zeroEx as any)._web3Wrapper.toWei(new BigNumber(5));
-		decimalPlaces = 7;
-		addressWithoutFunds = userAddresses[1];
-	});
-	beforeEach(async () => {
-		await blockchainLifecycle.startAsync();
-	});
-	afterEach(async () => {
-		await blockchainLifecycle.revertAsync();
-	});
-	describe('#depositAsync', () => {
-		it('should successfully deposit ETH and issue Wrapped ETH tokens', async () => {
-			const preETHBalance = await (zeroEx as any)._web3Wrapper.getBalanceInWeiAsync(addressWithETH);
-			const preWETHBalance = await zeroEx.token.getBalanceAsync(wethContractAddress, addressWithETH);
-			expect(preETHBalance).to.be.bignumber.gt(0);
-			expect(preWETHBalance).to.be.bignumber.equal(0);
+    let web3: Web3;
+    let zeroEx: ZeroEx;
+    let tokens: Token[];
+    let userAddresses: string[];
+    let addressWithETH: string;
+    let wethContractAddress: string;
+    let depositWeiAmount: BigNumber;
+    let decimalPlaces: number;
+    let addressWithoutFunds: string;
+    const gasPrice = new BigNumber(1);
+    const zeroExConfig = {
+        gasPrice,
+        networkId: constants.TESTRPC_NETWORK_ID,
+    };
+    const transferAmount = new BigNumber(42);
+    const allowanceAmount = new BigNumber(42);
+    const depositAmount = new BigNumber(42);
+    const withdrawalAmount = new BigNumber(42);
+    before(async () => {
+        web3 = web3Factory.create();
+        zeroEx = new ZeroEx(web3.currentProvider, zeroExConfig);
+        tokens = await zeroEx.tokenRegistry.getTokensAsync();
+        userAddresses = await zeroEx.getAvailableAddressesAsync();
+        addressWithETH = userAddresses[0];
+        wethContractAddress = (zeroEx.etherToken as any)._getContractAddress(artifacts.EtherTokenArtifact);
+        depositWeiAmount = (zeroEx as any)._web3Wrapper.toWei(new BigNumber(5));
+        decimalPlaces = 7;
+        addressWithoutFunds = userAddresses[1];
+    });
+    beforeEach(async () => {
+        await blockchainLifecycle.startAsync();
+    });
+    afterEach(async () => {
+        await blockchainLifecycle.revertAsync();
+    });
+    describe('#depositAsync', () => {
+        it('should successfully deposit ETH and issue Wrapped ETH tokens', async () => {
+            const preETHBalance = await (zeroEx as any)._web3Wrapper.getBalanceInWeiAsync(addressWithETH);
+            const preWETHBalance = await zeroEx.token.getBalanceAsync(wethContractAddress, addressWithETH);
+            expect(preETHBalance).to.be.bignumber.gt(0);
+            expect(preWETHBalance).to.be.bignumber.equal(0);
 
-			const txHash = await zeroEx.etherToken.depositAsync(wethContractAddress, depositWeiAmount, addressWithETH);
-			await zeroEx.awaitTransactionMinedAsync(txHash);
+            const txHash = await zeroEx.etherToken.depositAsync(wethContractAddress, depositWeiAmount, addressWithETH);
+            await zeroEx.awaitTransactionMinedAsync(txHash);
 
-			const postETHBalanceInWei = await (zeroEx as any)._web3Wrapper.getBalanceInWeiAsync(addressWithETH);
-			const postWETHBalanceInBaseUnits = await zeroEx.token.getBalanceAsync(wethContractAddress, addressWithETH);
+            const postETHBalanceInWei = await (zeroEx as any)._web3Wrapper.getBalanceInWeiAsync(addressWithETH);
+            const postWETHBalanceInBaseUnits = await zeroEx.token.getBalanceAsync(wethContractAddress, addressWithETH);
 
-			expect(postWETHBalanceInBaseUnits).to.be.bignumber.equal(depositWeiAmount);
-			const remainingETHInWei = preETHBalance.minus(depositWeiAmount);
-			const gasCost = remainingETHInWei.minus(postETHBalanceInWei);
-			expect(gasCost).to.be.bignumber.lte(MAX_REASONABLE_GAS_COST_IN_WEI);
-		});
-		it('should throw if user has insufficient ETH balance for deposit', async () => {
-			const preETHBalance = await (zeroEx as any)._web3Wrapper.getBalanceInWeiAsync(addressWithETH);
+            expect(postWETHBalanceInBaseUnits).to.be.bignumber.equal(depositWeiAmount);
+            const remainingETHInWei = preETHBalance.minus(depositWeiAmount);
+            const gasCost = remainingETHInWei.minus(postETHBalanceInWei);
+            expect(gasCost).to.be.bignumber.lte(MAX_REASONABLE_GAS_COST_IN_WEI);
+        });
+        it('should throw if user has insufficient ETH balance for deposit', async () => {
+            const preETHBalance = await (zeroEx as any)._web3Wrapper.getBalanceInWeiAsync(addressWithETH);
 
-			const extraETHBalance = (zeroEx as any)._web3Wrapper.toWei(5, 'ether');
-			const overETHBalanceinWei = preETHBalance.add(extraETHBalance);
+            const extraETHBalance = (zeroEx as any)._web3Wrapper.toWei(5, 'ether');
+            const overETHBalanceinWei = preETHBalance.add(extraETHBalance);
 
-			return expect(
-				zeroEx.etherToken.depositAsync(wethContractAddress, overETHBalanceinWei, addressWithETH),
-			).to.be.rejectedWith(ZeroExError.InsufficientEthBalanceForDeposit);
-		});
-	});
-	describe('#withdrawAsync', () => {
-		it('should successfully withdraw ETH in return for Wrapped ETH tokens', async () => {
-			const ETHBalanceInWei = await (zeroEx as any)._web3Wrapper.getBalanceInWeiAsync(addressWithETH);
+            return expect(
+                zeroEx.etherToken.depositAsync(wethContractAddress, overETHBalanceinWei, addressWithETH),
+            ).to.be.rejectedWith(ZeroExError.InsufficientEthBalanceForDeposit);
+        });
+    });
+    describe('#withdrawAsync', () => {
+        it('should successfully withdraw ETH in return for Wrapped ETH tokens', async () => {
+            const ETHBalanceInWei = await (zeroEx as any)._web3Wrapper.getBalanceInWeiAsync(addressWithETH);
 
-			await zeroEx.etherToken.depositAsync(wethContractAddress, depositWeiAmount, addressWithETH);
+            await zeroEx.etherToken.depositAsync(wethContractAddress, depositWeiAmount, addressWithETH);
 
-			const expectedPreETHBalance = ETHBalanceInWei.minus(depositWeiAmount);
-			const preETHBalance = await (zeroEx as any)._web3Wrapper.getBalanceInWeiAsync(addressWithETH);
-			const preWETHBalance = await zeroEx.token.getBalanceAsync(wethContractAddress, addressWithETH);
-			let gasCost = expectedPreETHBalance.minus(preETHBalance);
-			expect(gasCost).to.be.bignumber.lte(MAX_REASONABLE_GAS_COST_IN_WEI);
-			expect(preWETHBalance).to.be.bignumber.equal(depositWeiAmount);
+            const expectedPreETHBalance = ETHBalanceInWei.minus(depositWeiAmount);
+            const preETHBalance = await (zeroEx as any)._web3Wrapper.getBalanceInWeiAsync(addressWithETH);
+            const preWETHBalance = await zeroEx.token.getBalanceAsync(wethContractAddress, addressWithETH);
+            let gasCost = expectedPreETHBalance.minus(preETHBalance);
+            expect(gasCost).to.be.bignumber.lte(MAX_REASONABLE_GAS_COST_IN_WEI);
+            expect(preWETHBalance).to.be.bignumber.equal(depositWeiAmount);
 
-			const txHash = await zeroEx.etherToken.withdrawAsync(wethContractAddress, depositWeiAmount, addressWithETH);
-			await zeroEx.awaitTransactionMinedAsync(txHash);
+            const txHash = await zeroEx.etherToken.withdrawAsync(wethContractAddress, depositWeiAmount, addressWithETH);
+            await zeroEx.awaitTransactionMinedAsync(txHash);
 
-			const postETHBalance = await (zeroEx as any)._web3Wrapper.getBalanceInWeiAsync(addressWithETH);
-			const postWETHBalanceInBaseUnits = await zeroEx.token.getBalanceAsync(wethContractAddress, addressWithETH);
+            const postETHBalance = await (zeroEx as any)._web3Wrapper.getBalanceInWeiAsync(addressWithETH);
+            const postWETHBalanceInBaseUnits = await zeroEx.token.getBalanceAsync(wethContractAddress, addressWithETH);
 
-			expect(postWETHBalanceInBaseUnits).to.be.bignumber.equal(0);
-			const expectedETHBalance = preETHBalance.add(depositWeiAmount).round(decimalPlaces);
-			gasCost = expectedETHBalance.minus(postETHBalance);
-			expect(gasCost).to.be.bignumber.lte(MAX_REASONABLE_GAS_COST_IN_WEI);
-		});
-		it('should throw if user has insufficient WETH balance for withdrawl', async () => {
-			const preWETHBalance = await zeroEx.token.getBalanceAsync(wethContractAddress, addressWithETH);
-			expect(preWETHBalance).to.be.bignumber.equal(0);
+            expect(postWETHBalanceInBaseUnits).to.be.bignumber.equal(0);
+            const expectedETHBalance = preETHBalance.add(depositWeiAmount).round(decimalPlaces);
+            gasCost = expectedETHBalance.minus(postETHBalance);
+            expect(gasCost).to.be.bignumber.lte(MAX_REASONABLE_GAS_COST_IN_WEI);
+        });
+        it('should throw if user has insufficient WETH balance for withdrawl', async () => {
+            const preWETHBalance = await zeroEx.token.getBalanceAsync(wethContractAddress, addressWithETH);
+            expect(preWETHBalance).to.be.bignumber.equal(0);
 
-			const overWETHBalance = preWETHBalance.add(999999999);
+            const overWETHBalance = preWETHBalance.add(999999999);
 
-			return expect(
-				zeroEx.etherToken.withdrawAsync(wethContractAddress, overWETHBalance, addressWithETH),
-			).to.be.rejectedWith(ZeroExError.InsufficientWEthBalanceForWithdrawal);
-		});
-	});
-	describe('#subscribe', () => {
-		const indexFilterValues = {};
-		let etherTokenAddress: string;
-		before(() => {
-			const tokenUtils = new TokenUtils(tokens);
-			const etherToken = tokenUtils.getWethTokenOrThrow();
-			etherTokenAddress = etherToken.address;
-		});
-		afterEach(() => {
-			zeroEx.etherToken.unsubscribeAll();
-		});
-		// Hack: Mocha does not allow a test to be both async and have a `done` callback
-		// Since we need to await the receipt of the event in the `subscribe` callback,
-		// we do need both. A hack is to make the top-level async fn w/ a done callback and then
-		// wrap the rest of the test in an async block
-		// Source: https://github.com/mochajs/mocha/issues/2407
-		it('Should receive the Transfer event when tokens are transfered', (done: DoneCallback) => {
-			(async () => {
-				const callback = reportNodeCallbackErrors(done)(
-					(logEvent: DecodedLogEvent<TransferContractEventArgs>) => {
-						expect(logEvent).to.not.be.undefined();
-						expect(logEvent.isRemoved).to.be.false();
-						expect(logEvent.log.logIndex).to.be.equal(0);
-						expect(logEvent.log.transactionIndex).to.be.equal(0);
-						expect(logEvent.log.blockNumber).to.be.a('number');
-						const args = logEvent.log.args;
-						expect(args._from).to.be.equal(addressWithETH);
-						expect(args._to).to.be.equal(addressWithoutFunds);
-						expect(args._value).to.be.bignumber.equal(transferAmount);
-					},
-				);
-				await zeroEx.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH);
-				zeroEx.etherToken.subscribe(etherTokenAddress, EtherTokenEvents.Transfer, indexFilterValues, callback);
-				await zeroEx.token.transferAsync(
-					etherTokenAddress,
-					addressWithETH,
-					addressWithoutFunds,
-					transferAmount,
-				);
-			})().catch(done);
-		});
-		it('Should receive the Approval event when allowance is being set', (done: DoneCallback) => {
-			(async () => {
-				const callback = reportNodeCallbackErrors(done)(
-					(logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
-						expect(logEvent).to.not.be.undefined();
-						expect(logEvent.isRemoved).to.be.false();
-						const args = logEvent.log.args;
-						expect(args._owner).to.be.equal(addressWithETH);
-						expect(args._spender).to.be.equal(addressWithoutFunds);
-						expect(args._value).to.be.bignumber.equal(allowanceAmount);
-					},
-				);
-				zeroEx.etherToken.subscribe(etherTokenAddress, EtherTokenEvents.Approval, indexFilterValues, callback);
-				await zeroEx.token.setAllowanceAsync(
-					etherTokenAddress,
-					addressWithETH,
-					addressWithoutFunds,
-					allowanceAmount,
-				);
-			})().catch(done);
-		});
-		it('Should receive the Deposit event when ether is being deposited', (done: DoneCallback) => {
-			(async () => {
-				const callback = reportNodeCallbackErrors(done)(
-					(logEvent: DecodedLogEvent<DepositContractEventArgs>) => {
-						expect(logEvent).to.not.be.undefined();
-						expect(logEvent.isRemoved).to.be.false();
-						const args = logEvent.log.args;
-						expect(args._owner).to.be.equal(addressWithETH);
-						expect(args._value).to.be.bignumber.equal(depositAmount);
-					},
-				);
-				zeroEx.etherToken.subscribe(etherTokenAddress, EtherTokenEvents.Deposit, indexFilterValues, callback);
-				await zeroEx.etherToken.depositAsync(etherTokenAddress, depositAmount, addressWithETH);
-			})().catch(done);
-		});
-		it('Should receive the Withdrawal event when ether is being withdrawn', (done: DoneCallback) => {
-			(async () => {
-				const callback = reportNodeCallbackErrors(done)(
-					(logEvent: DecodedLogEvent<WithdrawalContractEventArgs>) => {
-						expect(logEvent).to.not.be.undefined();
-						expect(logEvent.isRemoved).to.be.false();
-						const args = logEvent.log.args;
-						expect(args._owner).to.be.equal(addressWithETH);
-						expect(args._value).to.be.bignumber.equal(depositAmount);
-					},
-				);
-				await zeroEx.etherToken.depositAsync(etherTokenAddress, depositAmount, addressWithETH);
-				zeroEx.etherToken.subscribe(
-					etherTokenAddress,
-					EtherTokenEvents.Withdrawal,
-					indexFilterValues,
-					callback,
-				);
-				await zeroEx.etherToken.withdrawAsync(etherTokenAddress, withdrawalAmount, addressWithETH);
-			})().catch(done);
-		});
-		it('should cancel outstanding subscriptions when ZeroEx.setProvider is called', (done: DoneCallback) => {
-			(async () => {
-				const callbackNeverToBeCalled = reportNodeCallbackErrors(done)(
-					(logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
-						done(new Error('Expected this subscription to have been cancelled'));
-					},
-				);
-				zeroEx.etherToken.subscribe(
-					etherTokenAddress,
-					EtherTokenEvents.Transfer,
-					indexFilterValues,
-					callbackNeverToBeCalled,
-				);
-				const callbackToBeCalled = reportNodeCallbackErrors(done)();
-				const newProvider = web3Factory.getRpcProvider();
-				zeroEx.setProvider(newProvider, constants.TESTRPC_NETWORK_ID);
-				await zeroEx.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH);
-				zeroEx.etherToken.subscribe(
-					etherTokenAddress,
-					EtherTokenEvents.Transfer,
-					indexFilterValues,
-					callbackToBeCalled,
-				);
-				await zeroEx.token.transferAsync(
-					etherTokenAddress,
-					addressWithETH,
-					addressWithoutFunds,
-					transferAmount,
-				);
-			})().catch(done);
-		});
-		it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => {
-			(async () => {
-				const callbackNeverToBeCalled = reportNodeCallbackErrors(done)(
-					(logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
-						done(new Error('Expected this subscription to have been cancelled'));
-					},
-				);
-				await zeroEx.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH);
-				const subscriptionToken = zeroEx.etherToken.subscribe(
-					etherTokenAddress,
-					EtherTokenEvents.Transfer,
-					indexFilterValues,
-					callbackNeverToBeCalled,
-				);
-				zeroEx.etherToken.unsubscribe(subscriptionToken);
-				await zeroEx.token.transferAsync(
-					etherTokenAddress,
-					addressWithETH,
-					addressWithoutFunds,
-					transferAmount,
-				);
-				done();
-			})().catch(done);
-		});
-	});
-	describe('#getLogsAsync', () => {
-		let etherTokenAddress: string;
-		let tokenTransferProxyAddress: string;
-		const blockRange: BlockRange = {
-			fromBlock: 0,
-			toBlock: BlockParamLiteral.Latest,
-		};
-		let txHash: string;
-		before(() => {
-			addressWithETH = userAddresses[0];
-			const tokenUtils = new TokenUtils(tokens);
-			const etherToken = tokenUtils.getWethTokenOrThrow();
-			etherTokenAddress = etherToken.address;
-			tokenTransferProxyAddress = zeroEx.proxy.getContractAddress();
-		});
-		it('should get logs with decoded args emitted by Approval', async () => {
-			txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(etherTokenAddress, addressWithETH);
-			await zeroEx.awaitTransactionMinedAsync(txHash);
-			const eventName = EtherTokenEvents.Approval;
-			const indexFilterValues = {};
-			const logs = await zeroEx.etherToken.getLogsAsync<ApprovalContractEventArgs>(
-				etherTokenAddress,
-				eventName,
-				blockRange,
-				indexFilterValues,
-			);
-			expect(logs).to.have.length(1);
-			const args = logs[0].args;
-			expect(logs[0].event).to.be.equal(eventName);
-			expect(args._owner).to.be.equal(addressWithETH);
-			expect(args._spender).to.be.equal(tokenTransferProxyAddress);
-			expect(args._value).to.be.bignumber.equal(zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
-		});
-		it('should get logs with decoded args emitted by Deposit', async () => {
-			await zeroEx.etherToken.depositAsync(etherTokenAddress, depositAmount, addressWithETH);
-			const eventName = EtherTokenEvents.Deposit;
-			const indexFilterValues = {};
-			const logs = await zeroEx.etherToken.getLogsAsync<DepositContractEventArgs>(
-				etherTokenAddress,
-				eventName,
-				blockRange,
-				indexFilterValues,
-			);
-			expect(logs).to.have.length(1);
-			const args = logs[0].args;
-			expect(logs[0].event).to.be.equal(eventName);
-			expect(args._owner).to.be.equal(addressWithETH);
-			expect(args._value).to.be.bignumber.equal(depositAmount);
-		});
-		it('should only get the logs with the correct event name', async () => {
-			txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(etherTokenAddress, addressWithETH);
-			await zeroEx.awaitTransactionMinedAsync(txHash);
-			const differentEventName = EtherTokenEvents.Transfer;
-			const indexFilterValues = {};
-			const logs = await zeroEx.etherToken.getLogsAsync(
-				etherTokenAddress,
-				differentEventName,
-				blockRange,
-				indexFilterValues,
-			);
-			expect(logs).to.have.length(0);
-		});
-		it('should only get the logs with the correct indexed fields', async () => {
-			txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(etherTokenAddress, addressWithETH);
-			await zeroEx.awaitTransactionMinedAsync(txHash);
-			txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(etherTokenAddress, addressWithoutFunds);
-			await zeroEx.awaitTransactionMinedAsync(txHash);
-			const eventName = EtherTokenEvents.Approval;
-			const indexFilterValues = {
-				_owner: addressWithETH,
-			};
-			const logs = await zeroEx.etherToken.getLogsAsync<ApprovalContractEventArgs>(
-				etherTokenAddress,
-				eventName,
-				blockRange,
-				indexFilterValues,
-			);
-			expect(logs).to.have.length(1);
-			const args = logs[0].args;
-			expect(args._owner).to.be.equal(addressWithETH);
-		});
-	});
+            return expect(
+                zeroEx.etherToken.withdrawAsync(wethContractAddress, overWETHBalance, addressWithETH),
+            ).to.be.rejectedWith(ZeroExError.InsufficientWEthBalanceForWithdrawal);
+        });
+    });
+    describe('#subscribe', () => {
+        const indexFilterValues = {};
+        let etherTokenAddress: string;
+        before(() => {
+            const tokenUtils = new TokenUtils(tokens);
+            const etherToken = tokenUtils.getWethTokenOrThrow();
+            etherTokenAddress = etherToken.address;
+        });
+        afterEach(() => {
+            zeroEx.etherToken.unsubscribeAll();
+        });
+        // Hack: Mocha does not allow a test to be both async and have a `done` callback
+        // Since we need to await the receipt of the event in the `subscribe` callback,
+        // we do need both. A hack is to make the top-level async fn w/ a done callback and then
+        // wrap the rest of the test in an async block
+        // Source: https://github.com/mochajs/mocha/issues/2407
+        it('Should receive the Transfer event when tokens are transfered', (done: DoneCallback) => {
+            (async () => {
+                const callback = reportNodeCallbackErrors(done)(
+                    (logEvent: DecodedLogEvent<TransferContractEventArgs>) => {
+                        expect(logEvent).to.not.be.undefined();
+                        expect(logEvent.isRemoved).to.be.false();
+                        expect(logEvent.log.logIndex).to.be.equal(0);
+                        expect(logEvent.log.transactionIndex).to.be.equal(0);
+                        expect(logEvent.log.blockNumber).to.be.a('number');
+                        const args = logEvent.log.args;
+                        expect(args._from).to.be.equal(addressWithETH);
+                        expect(args._to).to.be.equal(addressWithoutFunds);
+                        expect(args._value).to.be.bignumber.equal(transferAmount);
+                    },
+                );
+                await zeroEx.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH);
+                zeroEx.etherToken.subscribe(etherTokenAddress, EtherTokenEvents.Transfer, indexFilterValues, callback);
+                await zeroEx.token.transferAsync(
+                    etherTokenAddress,
+                    addressWithETH,
+                    addressWithoutFunds,
+                    transferAmount,
+                );
+            })().catch(done);
+        });
+        it('Should receive the Approval event when allowance is being set', (done: DoneCallback) => {
+            (async () => {
+                const callback = reportNodeCallbackErrors(done)(
+                    (logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
+                        expect(logEvent).to.not.be.undefined();
+                        expect(logEvent.isRemoved).to.be.false();
+                        const args = logEvent.log.args;
+                        expect(args._owner).to.be.equal(addressWithETH);
+                        expect(args._spender).to.be.equal(addressWithoutFunds);
+                        expect(args._value).to.be.bignumber.equal(allowanceAmount);
+                    },
+                );
+                zeroEx.etherToken.subscribe(etherTokenAddress, EtherTokenEvents.Approval, indexFilterValues, callback);
+                await zeroEx.token.setAllowanceAsync(
+                    etherTokenAddress,
+                    addressWithETH,
+                    addressWithoutFunds,
+                    allowanceAmount,
+                );
+            })().catch(done);
+        });
+        it('Should receive the Deposit event when ether is being deposited', (done: DoneCallback) => {
+            (async () => {
+                const callback = reportNodeCallbackErrors(done)(
+                    (logEvent: DecodedLogEvent<DepositContractEventArgs>) => {
+                        expect(logEvent).to.not.be.undefined();
+                        expect(logEvent.isRemoved).to.be.false();
+                        const args = logEvent.log.args;
+                        expect(args._owner).to.be.equal(addressWithETH);
+                        expect(args._value).to.be.bignumber.equal(depositAmount);
+                    },
+                );
+                zeroEx.etherToken.subscribe(etherTokenAddress, EtherTokenEvents.Deposit, indexFilterValues, callback);
+                await zeroEx.etherToken.depositAsync(etherTokenAddress, depositAmount, addressWithETH);
+            })().catch(done);
+        });
+        it('Should receive the Withdrawal event when ether is being withdrawn', (done: DoneCallback) => {
+            (async () => {
+                const callback = reportNodeCallbackErrors(done)(
+                    (logEvent: DecodedLogEvent<WithdrawalContractEventArgs>) => {
+                        expect(logEvent).to.not.be.undefined();
+                        expect(logEvent.isRemoved).to.be.false();
+                        const args = logEvent.log.args;
+                        expect(args._owner).to.be.equal(addressWithETH);
+                        expect(args._value).to.be.bignumber.equal(depositAmount);
+                    },
+                );
+                await zeroEx.etherToken.depositAsync(etherTokenAddress, depositAmount, addressWithETH);
+                zeroEx.etherToken.subscribe(
+                    etherTokenAddress,
+                    EtherTokenEvents.Withdrawal,
+                    indexFilterValues,
+                    callback,
+                );
+                await zeroEx.etherToken.withdrawAsync(etherTokenAddress, withdrawalAmount, addressWithETH);
+            })().catch(done);
+        });
+        it('should cancel outstanding subscriptions when ZeroEx.setProvider is called', (done: DoneCallback) => {
+            (async () => {
+                const callbackNeverToBeCalled = reportNodeCallbackErrors(done)(
+                    (logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
+                        done(new Error('Expected this subscription to have been cancelled'));
+                    },
+                );
+                zeroEx.etherToken.subscribe(
+                    etherTokenAddress,
+                    EtherTokenEvents.Transfer,
+                    indexFilterValues,
+                    callbackNeverToBeCalled,
+                );
+                const callbackToBeCalled = reportNodeCallbackErrors(done)();
+                const newProvider = web3Factory.getRpcProvider();
+                zeroEx.setProvider(newProvider, constants.TESTRPC_NETWORK_ID);
+                await zeroEx.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH);
+                zeroEx.etherToken.subscribe(
+                    etherTokenAddress,
+                    EtherTokenEvents.Transfer,
+                    indexFilterValues,
+                    callbackToBeCalled,
+                );
+                await zeroEx.token.transferAsync(
+                    etherTokenAddress,
+                    addressWithETH,
+                    addressWithoutFunds,
+                    transferAmount,
+                );
+            })().catch(done);
+        });
+        it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => {
+            (async () => {
+                const callbackNeverToBeCalled = reportNodeCallbackErrors(done)(
+                    (logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
+                        done(new Error('Expected this subscription to have been cancelled'));
+                    },
+                );
+                await zeroEx.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH);
+                const subscriptionToken = zeroEx.etherToken.subscribe(
+                    etherTokenAddress,
+                    EtherTokenEvents.Transfer,
+                    indexFilterValues,
+                    callbackNeverToBeCalled,
+                );
+                zeroEx.etherToken.unsubscribe(subscriptionToken);
+                await zeroEx.token.transferAsync(
+                    etherTokenAddress,
+                    addressWithETH,
+                    addressWithoutFunds,
+                    transferAmount,
+                );
+                done();
+            })().catch(done);
+        });
+    });
+    describe('#getLogsAsync', () => {
+        let etherTokenAddress: string;
+        let tokenTransferProxyAddress: string;
+        const blockRange: BlockRange = {
+            fromBlock: 0,
+            toBlock: BlockParamLiteral.Latest,
+        };
+        let txHash: string;
+        before(() => {
+            addressWithETH = userAddresses[0];
+            const tokenUtils = new TokenUtils(tokens);
+            const etherToken = tokenUtils.getWethTokenOrThrow();
+            etherTokenAddress = etherToken.address;
+            tokenTransferProxyAddress = zeroEx.proxy.getContractAddress();
+        });
+        it('should get logs with decoded args emitted by Approval', async () => {
+            txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(etherTokenAddress, addressWithETH);
+            await zeroEx.awaitTransactionMinedAsync(txHash);
+            const eventName = EtherTokenEvents.Approval;
+            const indexFilterValues = {};
+            const logs = await zeroEx.etherToken.getLogsAsync<ApprovalContractEventArgs>(
+                etherTokenAddress,
+                eventName,
+                blockRange,
+                indexFilterValues,
+            );
+            expect(logs).to.have.length(1);
+            const args = logs[0].args;
+            expect(logs[0].event).to.be.equal(eventName);
+            expect(args._owner).to.be.equal(addressWithETH);
+            expect(args._spender).to.be.equal(tokenTransferProxyAddress);
+            expect(args._value).to.be.bignumber.equal(zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
+        });
+        it('should get logs with decoded args emitted by Deposit', async () => {
+            await zeroEx.etherToken.depositAsync(etherTokenAddress, depositAmount, addressWithETH);
+            const eventName = EtherTokenEvents.Deposit;
+            const indexFilterValues = {};
+            const logs = await zeroEx.etherToken.getLogsAsync<DepositContractEventArgs>(
+                etherTokenAddress,
+                eventName,
+                blockRange,
+                indexFilterValues,
+            );
+            expect(logs).to.have.length(1);
+            const args = logs[0].args;
+            expect(logs[0].event).to.be.equal(eventName);
+            expect(args._owner).to.be.equal(addressWithETH);
+            expect(args._value).to.be.bignumber.equal(depositAmount);
+        });
+        it('should only get the logs with the correct event name', async () => {
+            txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(etherTokenAddress, addressWithETH);
+            await zeroEx.awaitTransactionMinedAsync(txHash);
+            const differentEventName = EtherTokenEvents.Transfer;
+            const indexFilterValues = {};
+            const logs = await zeroEx.etherToken.getLogsAsync(
+                etherTokenAddress,
+                differentEventName,
+                blockRange,
+                indexFilterValues,
+            );
+            expect(logs).to.have.length(0);
+        });
+        it('should only get the logs with the correct indexed fields', async () => {
+            txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(etherTokenAddress, addressWithETH);
+            await zeroEx.awaitTransactionMinedAsync(txHash);
+            txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(etherTokenAddress, addressWithoutFunds);
+            await zeroEx.awaitTransactionMinedAsync(txHash);
+            const eventName = EtherTokenEvents.Approval;
+            const indexFilterValues = {
+                _owner: addressWithETH,
+            };
+            const logs = await zeroEx.etherToken.getLogsAsync<ApprovalContractEventArgs>(
+                etherTokenAddress,
+                eventName,
+                blockRange,
+                indexFilterValues,
+            );
+            expect(logs).to.have.length(1);
+            const args = logs[0].args;
+            expect(args._owner).to.be.equal(addressWithETH);
+        });
+    });
 });
diff --git a/packages/0x.js/test/event_watcher_test.ts b/packages/0x.js/test/event_watcher_test.ts
index f0c97eced..f92fb2b02 100644
--- a/packages/0x.js/test/event_watcher_test.ts
+++ b/packages/0x.js/test/event_watcher_test.ts
@@ -17,110 +17,110 @@ chaiSetup.configure();
 const expect = chai.expect;
 
 describe('EventWatcher', () => {
-	let web3: Web3;
-	let stubs: Sinon.SinonStub[] = [];
-	let eventWatcher: EventWatcher;
-	let web3Wrapper: Web3Wrapper;
-	const logA: Web3.LogEntry = {
-		address: '0x71d271f8b14adef568f8f28f1587ce7271ac4ca5',
-		blockHash: null,
-		blockNumber: null,
-		data: '',
-		logIndex: null,
-		topics: [],
-		transactionHash: '0x004881d38cd4a8f72f1a0d68c8b9b8124504706041ff37019c1d1ed6bfda8e17',
-		transactionIndex: 0,
-	};
-	const logB: Web3.LogEntry = {
-		address: '0x8d12a197cb00d4747a1fe03395095ce2a5cc6819',
-		blockHash: null,
-		blockNumber: null,
-		data: '',
-		logIndex: null,
-		topics: ['0xf341246adaac6f497bc2a656f546ab9e182111d630394f0c57c710a59a2cb567'],
-		transactionHash: '0x01ef3c048b18d9b09ea195b4ed94cf8dd5f3d857a1905ff886b152cfb1166f25',
-		transactionIndex: 0,
-	};
-	const logC: Web3.LogEntry = {
-		address: '0x1d271f8b174adef58f1587ce68f8f27271ac4ca5',
-		blockHash: null,
-		blockNumber: null,
-		data: '',
-		logIndex: null,
-		topics: ['0xf341246adaac6f497bc2a656f546ab9e182111d630394f0c57c710a59a2cb567'],
-		transactionHash: '0x01ef3c048b18d9b09ea195b4ed94cf8dd5f3d857a1905ff886b152cfb1166f25',
-		transactionIndex: 0,
-	};
-	before(async () => {
-		web3 = web3Factory.create();
-		const pollingIntervalMs = 10;
-		web3Wrapper = new Web3Wrapper(web3.currentProvider);
-		eventWatcher = new EventWatcher(web3Wrapper, pollingIntervalMs);
-	});
-	afterEach(() => {
-		// clean up any stubs after the test has completed
-		_.each(stubs, s => s.restore());
-		stubs = [];
-		eventWatcher.unsubscribe();
-	});
-	it('correctly emits initial log events', (done: DoneCallback) => {
-		const logs: Web3.LogEntry[] = [logA, logB];
-		const expectedLogEvents = [
-			{
-				removed: false,
-				...logA,
-			},
-			{
-				removed: false,
-				...logB,
-			},
-		];
-		const getLogsStub = Sinon.stub(web3Wrapper, 'getLogsAsync');
-		getLogsStub.onCall(0).returns(logs);
-		stubs.push(getLogsStub);
-		const expectedToBeCalledOnce = false;
-		const callback = reportNodeCallbackErrors(done, expectedToBeCalledOnce)((event: LogEvent) => {
-			const expectedLogEvent = expectedLogEvents.shift();
-			expect(event).to.be.deep.equal(expectedLogEvent);
-			if (_.isEmpty(expectedLogEvents)) {
-				done();
-			}
-		});
-		eventWatcher.subscribe(callback);
-	});
-	it('correctly computes the difference and emits only changes', (done: DoneCallback) => {
-		const initialLogs: Web3.LogEntry[] = [logA, logB];
-		const changedLogs: Web3.LogEntry[] = [logA, logC];
-		const expectedLogEvents = [
-			{
-				removed: false,
-				...logA,
-			},
-			{
-				removed: false,
-				...logB,
-			},
-			{
-				removed: true,
-				...logB,
-			},
-			{
-				removed: false,
-				...logC,
-			},
-		];
-		const getLogsStub = Sinon.stub(web3Wrapper, 'getLogsAsync');
-		getLogsStub.onCall(0).returns(initialLogs);
-		getLogsStub.onCall(1).returns(changedLogs);
-		stubs.push(getLogsStub);
-		const expectedToBeCalledOnce = false;
-		const callback = reportNodeCallbackErrors(done, expectedToBeCalledOnce)((event: LogEvent) => {
-			const expectedLogEvent = expectedLogEvents.shift();
-			expect(event).to.be.deep.equal(expectedLogEvent);
-			if (_.isEmpty(expectedLogEvents)) {
-				done();
-			}
-		});
-		eventWatcher.subscribe(callback);
-	});
+    let web3: Web3;
+    let stubs: Sinon.SinonStub[] = [];
+    let eventWatcher: EventWatcher;
+    let web3Wrapper: Web3Wrapper;
+    const logA: Web3.LogEntry = {
+        address: '0x71d271f8b14adef568f8f28f1587ce7271ac4ca5',
+        blockHash: null,
+        blockNumber: null,
+        data: '',
+        logIndex: null,
+        topics: [],
+        transactionHash: '0x004881d38cd4a8f72f1a0d68c8b9b8124504706041ff37019c1d1ed6bfda8e17',
+        transactionIndex: 0,
+    };
+    const logB: Web3.LogEntry = {
+        address: '0x8d12a197cb00d4747a1fe03395095ce2a5cc6819',
+        blockHash: null,
+        blockNumber: null,
+        data: '',
+        logIndex: null,
+        topics: ['0xf341246adaac6f497bc2a656f546ab9e182111d630394f0c57c710a59a2cb567'],
+        transactionHash: '0x01ef3c048b18d9b09ea195b4ed94cf8dd5f3d857a1905ff886b152cfb1166f25',
+        transactionIndex: 0,
+    };
+    const logC: Web3.LogEntry = {
+        address: '0x1d271f8b174adef58f1587ce68f8f27271ac4ca5',
+        blockHash: null,
+        blockNumber: null,
+        data: '',
+        logIndex: null,
+        topics: ['0xf341246adaac6f497bc2a656f546ab9e182111d630394f0c57c710a59a2cb567'],
+        transactionHash: '0x01ef3c048b18d9b09ea195b4ed94cf8dd5f3d857a1905ff886b152cfb1166f25',
+        transactionIndex: 0,
+    };
+    before(async () => {
+        web3 = web3Factory.create();
+        const pollingIntervalMs = 10;
+        web3Wrapper = new Web3Wrapper(web3.currentProvider);
+        eventWatcher = new EventWatcher(web3Wrapper, pollingIntervalMs);
+    });
+    afterEach(() => {
+        // clean up any stubs after the test has completed
+        _.each(stubs, s => s.restore());
+        stubs = [];
+        eventWatcher.unsubscribe();
+    });
+    it('correctly emits initial log events', (done: DoneCallback) => {
+        const logs: Web3.LogEntry[] = [logA, logB];
+        const expectedLogEvents = [
+            {
+                removed: false,
+                ...logA,
+            },
+            {
+                removed: false,
+                ...logB,
+            },
+        ];
+        const getLogsStub = Sinon.stub(web3Wrapper, 'getLogsAsync');
+        getLogsStub.onCall(0).returns(logs);
+        stubs.push(getLogsStub);
+        const expectedToBeCalledOnce = false;
+        const callback = reportNodeCallbackErrors(done, expectedToBeCalledOnce)((event: LogEvent) => {
+            const expectedLogEvent = expectedLogEvents.shift();
+            expect(event).to.be.deep.equal(expectedLogEvent);
+            if (_.isEmpty(expectedLogEvents)) {
+                done();
+            }
+        });
+        eventWatcher.subscribe(callback);
+    });
+    it('correctly computes the difference and emits only changes', (done: DoneCallback) => {
+        const initialLogs: Web3.LogEntry[] = [logA, logB];
+        const changedLogs: Web3.LogEntry[] = [logA, logC];
+        const expectedLogEvents = [
+            {
+                removed: false,
+                ...logA,
+            },
+            {
+                removed: false,
+                ...logB,
+            },
+            {
+                removed: true,
+                ...logB,
+            },
+            {
+                removed: false,
+                ...logC,
+            },
+        ];
+        const getLogsStub = Sinon.stub(web3Wrapper, 'getLogsAsync');
+        getLogsStub.onCall(0).returns(initialLogs);
+        getLogsStub.onCall(1).returns(changedLogs);
+        stubs.push(getLogsStub);
+        const expectedToBeCalledOnce = false;
+        const callback = reportNodeCallbackErrors(done, expectedToBeCalledOnce)((event: LogEvent) => {
+            const expectedLogEvent = expectedLogEvents.shift();
+            expect(event).to.be.deep.equal(expectedLogEvent);
+            if (_.isEmpty(expectedLogEvents)) {
+                done();
+            }
+        });
+        eventWatcher.subscribe(callback);
+    });
 });
diff --git a/packages/0x.js/test/exchange_transfer_simulator_test.ts b/packages/0x.js/test/exchange_transfer_simulator_test.ts
index 9f4d76933..20b4a05ca 100644
--- a/packages/0x.js/test/exchange_transfer_simulator_test.ts
+++ b/packages/0x.js/test/exchange_transfer_simulator_test.ts
@@ -15,103 +15,103 @@ const expect = chai.expect;
 const blockchainLifecycle = new BlockchainLifecycle(constants.RPC_URL);
 
 describe('ExchangeTransferSimulator', () => {
-	const web3 = web3Factory.create();
-	const config = {
-		networkId: constants.TESTRPC_NETWORK_ID,
-	};
-	const zeroEx = new ZeroEx(web3.currentProvider, config);
-	const transferAmount = new BigNumber(5);
-	let userAddresses: string[];
-	let tokens: Token[];
-	let coinbase: string;
-	let sender: string;
-	let recipient: string;
-	let exampleTokenAddress: string;
-	let exchangeTransferSimulator: ExchangeTransferSimulator;
-	let txHash: string;
-	before(async () => {
-		userAddresses = await zeroEx.getAvailableAddressesAsync();
-		[coinbase, sender, recipient] = userAddresses;
-		tokens = await zeroEx.tokenRegistry.getTokensAsync();
-		exampleTokenAddress = tokens[0].address;
-	});
-	beforeEach(async () => {
-		await blockchainLifecycle.startAsync();
-	});
-	afterEach(async () => {
-		await blockchainLifecycle.revertAsync();
-	});
-	describe('#transferFromAsync', () => {
-		beforeEach(() => {
-			exchangeTransferSimulator = new ExchangeTransferSimulator(zeroEx.token, BlockParamLiteral.Latest);
-		});
-		it("throws if the user doesn't have enough allowance", async () => {
-			return expect(
-				exchangeTransferSimulator.transferFromAsync(
-					exampleTokenAddress,
-					sender,
-					recipient,
-					transferAmount,
-					TradeSide.Taker,
-					TransferType.Trade,
-				),
-			).to.be.rejectedWith(ExchangeContractErrs.InsufficientTakerAllowance);
-		});
-		it("throws if the user doesn't have enough balance", async () => {
-			txHash = await zeroEx.token.setProxyAllowanceAsync(exampleTokenAddress, sender, transferAmount);
-			await zeroEx.awaitTransactionMinedAsync(txHash);
-			return expect(
-				exchangeTransferSimulator.transferFromAsync(
-					exampleTokenAddress,
-					sender,
-					recipient,
-					transferAmount,
-					TradeSide.Maker,
-					TransferType.Trade,
-				),
-			).to.be.rejectedWith(ExchangeContractErrs.InsufficientMakerBalance);
-		});
-		it('updates balances and proxyAllowance after transfer', async () => {
-			txHash = await zeroEx.token.transferAsync(exampleTokenAddress, coinbase, sender, transferAmount);
-			await zeroEx.awaitTransactionMinedAsync(txHash);
-			txHash = await zeroEx.token.setProxyAllowanceAsync(exampleTokenAddress, sender, transferAmount);
-			await zeroEx.awaitTransactionMinedAsync(txHash);
-			await exchangeTransferSimulator.transferFromAsync(
-				exampleTokenAddress,
-				sender,
-				recipient,
-				transferAmount,
-				TradeSide.Taker,
-				TransferType.Trade,
-			);
-			const store = (exchangeTransferSimulator as any)._store;
-			const senderBalance = await store.getBalanceAsync(exampleTokenAddress, sender);
-			const recipientBalance = await store.getBalanceAsync(exampleTokenAddress, recipient);
-			const senderProxyAllowance = await store.getProxyAllowanceAsync(exampleTokenAddress, sender);
-			expect(senderBalance).to.be.bignumber.equal(0);
-			expect(recipientBalance).to.be.bignumber.equal(transferAmount);
-			expect(senderProxyAllowance).to.be.bignumber.equal(0);
-		});
-		it("doesn't update proxyAllowance after transfer if unlimited", async () => {
-			txHash = await zeroEx.token.transferAsync(exampleTokenAddress, coinbase, sender, transferAmount);
-			await zeroEx.awaitTransactionMinedAsync(txHash);
-			txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(exampleTokenAddress, sender);
-			await zeroEx.awaitTransactionMinedAsync(txHash);
-			await exchangeTransferSimulator.transferFromAsync(
-				exampleTokenAddress,
-				sender,
-				recipient,
-				transferAmount,
-				TradeSide.Taker,
-				TransferType.Trade,
-			);
-			const store = (exchangeTransferSimulator as any)._store;
-			const senderBalance = await store.getBalanceAsync(exampleTokenAddress, sender);
-			const recipientBalance = await store.getBalanceAsync(exampleTokenAddress, recipient);
-			const senderProxyAllowance = await store.getProxyAllowanceAsync(exampleTokenAddress, sender);
-			expect(senderBalance).to.be.bignumber.equal(0);
-			expect(recipientBalance).to.be.bignumber.equal(transferAmount);
-			expect(senderProxyAllowance).to.be.bignumber.equal(zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
-		});
-	});
+    const web3 = web3Factory.create();
+    const config = {
+        networkId: constants.TESTRPC_NETWORK_ID,
+    };
+    const zeroEx = new ZeroEx(web3.currentProvider, config);
+    const transferAmount = new BigNumber(5);
+    let userAddresses: string[];
+    let tokens: Token[];
+    let coinbase: string;
+    let sender: string;
+    let recipient: string;
+    let exampleTokenAddress: string;
+    let exchangeTransferSimulator: ExchangeTransferSimulator;
+    let txHash: string;
+    before(async () => {
+        userAddresses = await zeroEx.getAvailableAddressesAsync();
+        [coinbase, sender, recipient] = userAddresses;
+        tokens = await zeroEx.tokenRegistry.getTokensAsync();
+        exampleTokenAddress = tokens[0].address;
+    });
+    beforeEach(async () => {
+        await blockchainLifecycle.startAsync();
+    });
+    afterEach(async () => {
+        await blockchainLifecycle.revertAsync();
+    });
+    describe('#transferFromAsync', () => {
+        beforeEach(() => {
+            exchangeTransferSimulator = new ExchangeTransferSimulator(zeroEx.token, BlockParamLiteral.Latest);
+        });
+        it("throws if the user doesn't have enough allowance", async () => {
+            return expect(
+                exchangeTransferSimulator.transferFromAsync(
+                    exampleTokenAddress,
+                    sender,
+                    recipient,
+                    transferAmount,
+                    TradeSide.Taker,
+                    TransferType.Trade,
+                ),
+            ).to.be.rejectedWith(ExchangeContractErrs.InsufficientTakerAllowance);
+        });
+        it("throws if the user doesn't have enough balance", async () => {
+            txHash = await zeroEx.token.setProxyAllowanceAsync(exampleTokenAddress, sender, transferAmount);
+            await zeroEx.awaitTransactionMinedAsync(txHash);
+            return expect(
+                exchangeTransferSimulator.transferFromAsync(
+                    exampleTokenAddress,
+                    sender,
+                    recipient,
+                    transferAmount,
+                    TradeSide.Maker,
+                    TransferType.Trade,
+                ),
+            ).to.be.rejectedWith(ExchangeContractErrs.InsufficientMakerBalance);
+        });
+        it('updates balances and proxyAllowance after transfer', async () => {
+            txHash = await zeroEx.token.transferAsync(exampleTokenAddress, coinbase, sender, transferAmount);
+            await zeroEx.awaitTransactionMinedAsync(txHash);
+            txHash = await zeroEx.token.setProxyAllowanceAsync(exampleTokenAddress, sender, transferAmount);
+            await zeroEx.awaitTransactionMinedAsync(txHash);
+            await exchangeTransferSimulator.transferFromAsync(
+                exampleTokenAddress,
+                sender,
+                recipient,
+                transferAmount,
+                TradeSide.Taker,
+                TransferType.Trade,
+            );
+            const store = (exchangeTransferSimulator as any)._store;
+            const senderBalance = await store.getBalanceAsync(exampleTokenAddress, sender);
+            const recipientBalance = await store.getBalanceAsync(exampleTokenAddress, recipient);
+            const senderProxyAllowance = await store.getProxyAllowanceAsync(exampleTokenAddress, sender);
+            expect(senderBalance).to.be.bignumber.equal(0);
+            expect(recipientBalance).to.be.bignumber.equal(transferAmount);
+            expect(senderProxyAllowance).to.be.bignumber.equal(0);
+        });
+        it("doesn't update proxyAllowance after transfer if unlimited", async () => {
+            txHash = await zeroEx.token.transferAsync(exampleTokenAddress, coinbase, sender, transferAmount);
+            await zeroEx.awaitTransactionMinedAsync(txHash);
+            txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(exampleTokenAddress, sender);
+            await zeroEx.awaitTransactionMinedAsync(txHash);
+            await exchangeTransferSimulator.transferFromAsync(
+                exampleTokenAddress,
+                sender,
+                recipient,
+                transferAmount,
+                TradeSide.Taker,
+                TransferType.Trade,
+            );
+            const store = (exchangeTransferSimulator as any)._store;
+            const senderBalance = await store.getBalanceAsync(exampleTokenAddress, sender);
+            const recipientBalance = await store.getBalanceAsync(exampleTokenAddress, recipient);
+            const senderProxyAllowance = await store.getProxyAllowanceAsync(exampleTokenAddress, sender);
+            expect(senderBalance).to.be.bignumber.equal(0);
+            expect(recipientBalance).to.be.bignumber.equal(transferAmount);
+            expect(senderProxyAllowance).to.be.bignumber.equal(zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
+        });
+    });
 });
diff --git a/packages/0x.js/test/exchange_wrapper_test.ts b/packages/0x.js/test/exchange_wrapper_test.ts
index f67e61a55..7e0ffd818 100644
--- a/packages/0x.js/test/exchange_wrapper_test.ts
+++ b/packages/0x.js/test/exchange_wrapper_test.ts
@@ -6,17 +6,17 @@ import 'mocha';
 import * as Web3 from 'web3';
 
 import {
-	BlockRange,
-	DecodedLogEvent,
-	ExchangeContractErrs,
-	ExchangeEvents,
-	LogCancelContractEventArgs,
-	LogFillContractEventArgs,
-	OrderCancellationRequest,
-	OrderFillRequest,
-	SignedOrder,
-	Token,
-	ZeroEx,
+    BlockRange,
+    DecodedLogEvent,
+    ExchangeContractErrs,
+    ExchangeEvents,
+    LogCancelContractEventArgs,
+    LogFillContractEventArgs,
+    OrderCancellationRequest,
+    OrderFillRequest,
+    SignedOrder,
+    Token,
+    ZeroEx,
 } from '../src';
 import { BlockParamLiteral, DoneCallback } from '../src/types';
 
@@ -34,1114 +34,1114 @@ const blockchainLifecycle = new BlockchainLifecycle(constants.RPC_URL);
 const NON_EXISTENT_ORDER_HASH = '0x79370342234e7acd6bbeac335bd3bb1d368383294b64b8160a00f4060e4d3777';
 
 describe('ExchangeWrapper', () => {
-	let web3: Web3;
-	let zeroEx: ZeroEx;
-	let tokenUtils: TokenUtils;
-	let tokens: Token[];
-	let userAddresses: string[];
-	let zrxTokenAddress: string;
-	let fillScenarios: FillScenarios;
-	let exchangeContractAddress: string;
-	const config = {
-		networkId: constants.TESTRPC_NETWORK_ID,
-	};
-	before(async () => {
-		web3 = web3Factory.create();
-		zeroEx = new ZeroEx(web3.currentProvider, config);
-		exchangeContractAddress = zeroEx.exchange.getContractAddress();
-		userAddresses = await zeroEx.getAvailableAddressesAsync();
-		tokens = await zeroEx.tokenRegistry.getTokensAsync();
-		tokenUtils = new TokenUtils(tokens);
-		zrxTokenAddress = tokenUtils.getProtocolTokenOrThrow().address;
-		fillScenarios = new FillScenarios(zeroEx, userAddresses, tokens, zrxTokenAddress, exchangeContractAddress);
-		await fillScenarios.initTokenBalancesAsync();
-	});
-	beforeEach(async () => {
-		await blockchainLifecycle.startAsync();
-	});
-	afterEach(async () => {
-		await blockchainLifecycle.revertAsync();
-	});
-	describe('fillOrKill order(s)', () => {
-		let makerTokenAddress: string;
-		let takerTokenAddress: string;
-		let coinbase: string;
-		let makerAddress: string;
-		let takerAddress: string;
-		let feeRecipient: string;
-		const takerTokenFillAmount = new BigNumber(5);
-		before(async () => {
-			[coinbase, makerAddress, takerAddress, feeRecipient] = userAddresses;
-			tokens = await zeroEx.tokenRegistry.getTokensAsync();
-			const [makerToken, takerToken] = tokenUtils.getDummyTokens();
-			makerTokenAddress = makerToken.address;
-			takerTokenAddress = takerToken.address;
-		});
-		describe('#batchFillOrKillAsync', () => {
-			it('successfully batch fillOrKill', async () => {
-				const fillableAmount = new BigNumber(5);
-				const partialFillTakerAmount = new BigNumber(2);
-				const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-					makerTokenAddress,
-					takerTokenAddress,
-					makerAddress,
-					takerAddress,
-					fillableAmount,
-				);
-				const anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
-					makerTokenAddress,
-					takerTokenAddress,
-					makerAddress,
-					takerAddress,
-					fillableAmount,
-				);
-				const orderFillRequests = [
-					{
-						signedOrder,
-						takerTokenFillAmount: partialFillTakerAmount,
-					},
-					{
-						signedOrder: anotherSignedOrder,
-						takerTokenFillAmount: partialFillTakerAmount,
-					},
-				];
-				await zeroEx.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress);
-			});
-			describe('order transaction options', () => {
-				let signedOrder: SignedOrder;
-				let orderFillRequests: OrderFillRequest[];
-				const fillableAmount = new BigNumber(5);
-				beforeEach(async () => {
-					signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-						makerTokenAddress,
-						takerTokenAddress,
-						makerAddress,
-						takerAddress,
-						fillableAmount,
-					);
-					orderFillRequests = [
-						{
-							signedOrder,
-							takerTokenFillAmount: new BigNumber(0),
-						},
-					];
-				});
-				it('should validate when orderTransactionOptions are not present', async () => {
-					return expect(
-						zeroEx.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress),
-					).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
-				});
-				it('should validate when orderTransactionOptions specify to validate', async () => {
-					return expect(
-						zeroEx.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress, {
-							shouldValidate: true,
-						}),
-					).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
-				});
-				it('should not validate when orderTransactionOptions specify not to validate', async () => {
-					return expect(
-						zeroEx.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress, {
-							shouldValidate: false,
-						}),
-					).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
-				});
-			});
-		});
-		describe('#fillOrKillOrderAsync', () => {
-			let signedOrder: SignedOrder;
-			const fillableAmount = new BigNumber(5);
-			beforeEach(async () => {
-				signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-					makerTokenAddress,
-					takerTokenAddress,
-					makerAddress,
-					takerAddress,
-					fillableAmount,
-				);
-			});
-			describe('successful fills', () => {
-				it('should fill a valid order', async () => {
-					expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress)).to.be.bignumber.equal(
-						fillableAmount,
-					);
-					expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress)).to.be.bignumber.equal(
-						0,
-					);
-					expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress)).to.be.bignumber.equal(
-						0,
-					);
-					expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress)).to.be.bignumber.equal(
-						fillableAmount,
-					);
-					await zeroEx.exchange.fillOrKillOrderAsync(signedOrder, takerTokenFillAmount, takerAddress);
-					expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress)).to.be.bignumber.equal(
-						fillableAmount.minus(takerTokenFillAmount),
-					);
-					expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress)).to.be.bignumber.equal(
-						takerTokenFillAmount,
-					);
-					expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress)).to.be.bignumber.equal(
-						takerTokenFillAmount,
-					);
-					expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress)).to.be.bignumber.equal(
-						fillableAmount.minus(takerTokenFillAmount),
-					);
-				});
-				it('should partially fill a valid order', async () => {
-					const partialFillAmount = new BigNumber(3);
-					await zeroEx.exchange.fillOrKillOrderAsync(signedOrder, partialFillAmount, takerAddress);
-					expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress)).to.be.bignumber.equal(
-						fillableAmount.minus(partialFillAmount),
-					);
-					expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress)).to.be.bignumber.equal(
-						partialFillAmount,
-					);
-					expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress)).to.be.bignumber.equal(
-						partialFillAmount,
-					);
-					expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress)).to.be.bignumber.equal(
-						fillableAmount.minus(partialFillAmount),
-					);
-				});
-			});
-			describe('order transaction options', () => {
-				const emptyFillableAmount = new BigNumber(0);
-				it('should validate when orderTransactionOptions are not present', async () => {
-					return expect(
-						zeroEx.exchange.fillOrKillOrderAsync(signedOrder, emptyFillableAmount, takerAddress),
-					).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
-				});
-				it('should validate when orderTransactionOptions specify to validate', async () => {
-					return expect(
-						zeroEx.exchange.fillOrKillOrderAsync(signedOrder, emptyFillableAmount, takerAddress, {
-							shouldValidate: true,
-						}),
-					).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
-				});
-				it('should not validate when orderTransactionOptions specify not to validate', async () => {
-					return expect(
-						zeroEx.exchange.fillOrKillOrderAsync(signedOrder, emptyFillableAmount, takerAddress, {
-							shouldValidate: false,
-						}),
-					).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
-				});
-			});
-		});
-	});
-	describe('fill order(s)', () => {
-		let makerTokenAddress: string;
-		let takerTokenAddress: string;
-		let coinbase: string;
-		let makerAddress: string;
-		let takerAddress: string;
-		let feeRecipient: string;
-		const fillableAmount = new BigNumber(5);
-		const takerTokenFillAmount = new BigNumber(5);
-		const shouldThrowOnInsufficientBalanceOrAllowance = true;
-		before(async () => {
-			[coinbase, makerAddress, takerAddress, feeRecipient] = userAddresses;
-			tokens = await zeroEx.tokenRegistry.getTokensAsync();
-			const [makerToken, takerToken] = tokenUtils.getDummyTokens();
-			makerTokenAddress = makerToken.address;
-			takerTokenAddress = takerToken.address;
-		});
-		describe('#fillOrderAsync', () => {
-			describe('successful fills', () => {
-				it('should fill a valid order', async () => {
-					const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-						makerTokenAddress,
-						takerTokenAddress,
-						makerAddress,
-						takerAddress,
-						fillableAmount,
-					);
-					expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress)).to.be.bignumber.equal(
-						fillableAmount,
-					);
-					expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress)).to.be.bignumber.equal(
-						0,
-					);
-					expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress)).to.be.bignumber.equal(
-						0,
-					);
-					expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress)).to.be.bignumber.equal(
-						fillableAmount,
-					);
-					const txHash = await zeroEx.exchange.fillOrderAsync(
-						signedOrder,
-						takerTokenFillAmount,
-						shouldThrowOnInsufficientBalanceOrAllowance,
-						takerAddress,
-					);
-					await zeroEx.awaitTransactionMinedAsync(txHash);
-					expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress)).to.be.bignumber.equal(
-						fillableAmount.minus(takerTokenFillAmount),
-					);
-					expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress)).to.be.bignumber.equal(
-						takerTokenFillAmount,
-					);
-					expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress)).to.be.bignumber.equal(
-						takerTokenFillAmount,
-					);
-					expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress)).to.be.bignumber.equal(
-						fillableAmount.minus(takerTokenFillAmount),
-					);
-				});
-				it('should partially fill the valid order', async () => {
-					const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-						makerTokenAddress,
-						takerTokenAddress,
-						makerAddress,
-						takerAddress,
-						fillableAmount,
-					);
-					const partialFillAmount = new BigNumber(3);
-					const txHash = await zeroEx.exchange.fillOrderAsync(
-						signedOrder,
-						partialFillAmount,
-						shouldThrowOnInsufficientBalanceOrAllowance,
-						takerAddress,
-					);
-					await zeroEx.awaitTransactionMinedAsync(txHash);
-					expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress)).to.be.bignumber.equal(
-						fillableAmount.minus(partialFillAmount),
-					);
-					expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress)).to.be.bignumber.equal(
-						partialFillAmount,
-					);
-					expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress)).to.be.bignumber.equal(
-						partialFillAmount,
-					);
-					expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress)).to.be.bignumber.equal(
-						fillableAmount.minus(partialFillAmount),
-					);
-				});
-				it('should fill the valid orders with fees', async () => {
-					const makerFee = new BigNumber(1);
-					const takerFee = new BigNumber(2);
-					const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
-						makerTokenAddress,
-						takerTokenAddress,
-						makerFee,
-						takerFee,
-						makerAddress,
-						takerAddress,
-						fillableAmount,
-						feeRecipient,
-					);
-					const txHash = await zeroEx.exchange.fillOrderAsync(
-						signedOrder,
-						takerTokenFillAmount,
-						shouldThrowOnInsufficientBalanceOrAllowance,
-						takerAddress,
-					);
-					await zeroEx.awaitTransactionMinedAsync(txHash);
-					expect(await zeroEx.token.getBalanceAsync(zrxTokenAddress, feeRecipient)).to.be.bignumber.equal(
-						makerFee.plus(takerFee),
-					);
-				});
-			});
-			describe('order transaction options', () => {
-				let signedOrder: SignedOrder;
-				const emptyFillTakerAmount = new BigNumber(0);
-				beforeEach(async () => {
-					signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-						makerTokenAddress,
-						takerTokenAddress,
-						makerAddress,
-						takerAddress,
-						fillableAmount,
-					);
-				});
-				it('should validate when orderTransactionOptions are not present', async () => {
-					return expect(
-						zeroEx.exchange.fillOrderAsync(
-							signedOrder,
-							emptyFillTakerAmount,
-							shouldThrowOnInsufficientBalanceOrAllowance,
-							takerAddress,
-						),
-					).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
-				});
-				it('should validate when orderTransactionOptions specify to validate', async () => {
-					return expect(
-						zeroEx.exchange.fillOrderAsync(
-							signedOrder,
-							emptyFillTakerAmount,
-							shouldThrowOnInsufficientBalanceOrAllowance,
-							takerAddress,
-							{
-								shouldValidate: true,
-							},
-						),
-					).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
-				});
-				it('should not validate when orderTransactionOptions specify not to validate', async () => {
-					return expect(
-						zeroEx.exchange.fillOrderAsync(
-							signedOrder,
-							emptyFillTakerAmount,
-							shouldThrowOnInsufficientBalanceOrAllowance,
-							takerAddress,
-							{
-								shouldValidate: false,
-							},
-						),
-					).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
-				});
-			});
-			describe('negative fill amount', async () => {
-				let signedOrder: SignedOrder;
-				const negativeFillTakerAmount = new BigNumber(-100);
-				beforeEach(async () => {
-					signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-						makerTokenAddress,
-						takerTokenAddress,
-						makerAddress,
-						takerAddress,
-						fillableAmount,
-					);
-				});
-				it('should not allow the exchange wrapper to fill if amount is negative', async () => {
-					return expect(
-						zeroEx.exchange.fillOrderAsync(
-							signedOrder,
-							negativeFillTakerAmount,
-							shouldThrowOnInsufficientBalanceOrAllowance,
-							takerAddress,
-						),
-					).to.be.rejected();
-				});
-			});
-		});
-		describe('#batchFillOrdersAsync', () => {
-			let signedOrder: SignedOrder;
-			let signedOrderHashHex: string;
-			let anotherSignedOrder: SignedOrder;
-			let anotherOrderHashHex: string;
-			let orderFillBatch: OrderFillRequest[];
-			beforeEach(async () => {
-				signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-					makerTokenAddress,
-					takerTokenAddress,
-					makerAddress,
-					takerAddress,
-					fillableAmount,
-				);
-				signedOrderHashHex = ZeroEx.getOrderHashHex(signedOrder);
-				anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
-					makerTokenAddress,
-					takerTokenAddress,
-					makerAddress,
-					takerAddress,
-					fillableAmount,
-				);
-				anotherOrderHashHex = ZeroEx.getOrderHashHex(anotherSignedOrder);
-			});
-			describe('successful batch fills', () => {
-				beforeEach(() => {
-					orderFillBatch = [
-						{
-							signedOrder,
-							takerTokenFillAmount,
-						},
-						{
-							signedOrder: anotherSignedOrder,
-							takerTokenFillAmount,
-						},
-					];
-				});
-				it('should throw if a batch is empty', async () => {
-					return expect(
-						zeroEx.exchange.batchFillOrdersAsync(
-							[],
-							shouldThrowOnInsufficientBalanceOrAllowance,
-							takerAddress,
-						),
-					).to.be.rejectedWith(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem);
-				});
-				it('should successfully fill multiple orders', async () => {
-					const txHash = await zeroEx.exchange.batchFillOrdersAsync(
-						orderFillBatch,
-						shouldThrowOnInsufficientBalanceOrAllowance,
-						takerAddress,
-					);
-					await zeroEx.awaitTransactionMinedAsync(txHash);
-					const filledAmount = await zeroEx.exchange.getFilledTakerAmountAsync(signedOrderHashHex);
-					const anotherFilledAmount = await zeroEx.exchange.getFilledTakerAmountAsync(anotherOrderHashHex);
-					expect(filledAmount).to.be.bignumber.equal(takerTokenFillAmount);
-					expect(anotherFilledAmount).to.be.bignumber.equal(takerTokenFillAmount);
-				});
-			});
-			describe('order transaction options', () => {
-				beforeEach(async () => {
-					const emptyFillTakerAmount = new BigNumber(0);
-					orderFillBatch = [
-						{
-							signedOrder,
-							takerTokenFillAmount: emptyFillTakerAmount,
-						},
-						{
-							signedOrder: anotherSignedOrder,
-							takerTokenFillAmount: emptyFillTakerAmount,
-						},
-					];
-				});
-				it('should validate when orderTransactionOptions are not present', async () => {
-					return expect(
-						zeroEx.exchange.batchFillOrdersAsync(
-							orderFillBatch,
-							shouldThrowOnInsufficientBalanceOrAllowance,
-							takerAddress,
-						),
-					).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
-				});
-				it('should validate when orderTransactionOptions specify to validate', async () => {
-					return expect(
-						zeroEx.exchange.batchFillOrdersAsync(
-							orderFillBatch,
-							shouldThrowOnInsufficientBalanceOrAllowance,
-							takerAddress,
-							{
-								shouldValidate: true,
-							},
-						),
-					).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
-				});
-				it('should not validate when orderTransactionOptions specify not to validate', async () => {
-					return expect(
-						zeroEx.exchange.batchFillOrdersAsync(
-							orderFillBatch,
-							shouldThrowOnInsufficientBalanceOrAllowance,
-							takerAddress,
-							{
-								shouldValidate: false,
-							},
-						),
-					).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
-				});
-			});
-			describe('negative batch fill amount', async () => {
-				beforeEach(async () => {
-					const negativeFillTakerAmount = new BigNumber(-100);
-					orderFillBatch = [
-						{
-							signedOrder,
-							takerTokenFillAmount,
-						},
-						{
-							signedOrder: anotherSignedOrder,
-							takerTokenFillAmount: negativeFillTakerAmount,
-						},
-					];
-				});
-				it('should not allow the exchange wrapper to batch fill if any amount is negative', async () => {
-					return expect(
-						zeroEx.exchange.batchFillOrdersAsync(
-							orderFillBatch,
-							shouldThrowOnInsufficientBalanceOrAllowance,
-							takerAddress,
-						),
-					).to.be.rejected();
-				});
-			});
-		});
-		describe('#fillOrdersUpTo', () => {
-			let signedOrder: SignedOrder;
-			let signedOrderHashHex: string;
-			let anotherSignedOrder: SignedOrder;
-			let anotherOrderHashHex: string;
-			let signedOrders: SignedOrder[];
-			const fillUpToAmount = fillableAmount.plus(fillableAmount).minus(1);
-			beforeEach(async () => {
-				signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-					makerTokenAddress,
-					takerTokenAddress,
-					makerAddress,
-					takerAddress,
-					fillableAmount,
-				);
-				signedOrderHashHex = ZeroEx.getOrderHashHex(signedOrder);
-				anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
-					makerTokenAddress,
-					takerTokenAddress,
-					makerAddress,
-					takerAddress,
-					fillableAmount,
-				);
-				anotherOrderHashHex = ZeroEx.getOrderHashHex(anotherSignedOrder);
-				signedOrders = [signedOrder, anotherSignedOrder];
-			});
-			describe('successful batch fills', () => {
-				it('should throw if a batch is empty', async () => {
-					return expect(
-						zeroEx.exchange.fillOrdersUpToAsync(
-							[],
-							fillUpToAmount,
-							shouldThrowOnInsufficientBalanceOrAllowance,
-							takerAddress,
-						),
-					).to.be.rejectedWith(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem);
-				});
-				it('should successfully fill up to specified amount when all orders are fully funded', async () => {
-					const txHash = await zeroEx.exchange.fillOrdersUpToAsync(
-						signedOrders,
-						fillUpToAmount,
-						shouldThrowOnInsufficientBalanceOrAllowance,
-						takerAddress,
-					);
-					await zeroEx.awaitTransactionMinedAsync(txHash);
-					const filledAmount = await zeroEx.exchange.getFilledTakerAmountAsync(signedOrderHashHex);
-					const anotherFilledAmount = await zeroEx.exchange.getFilledTakerAmountAsync(anotherOrderHashHex);
-					expect(filledAmount).to.be.bignumber.equal(fillableAmount);
-					const remainingFillAmount = fillableAmount.minus(1);
-					expect(anotherFilledAmount).to.be.bignumber.equal(remainingFillAmount);
-				});
-				it('should successfully fill up to specified amount even if filling all orders would fail', async () => {
-					const missingBalance = new BigNumber(1); // User will still have enough balance to fill up to 9,
-					// but won't have 10 to fully fill all orders in a batch.
-					await zeroEx.token.transferAsync(makerTokenAddress, makerAddress, coinbase, missingBalance);
-					const txHash = await zeroEx.exchange.fillOrdersUpToAsync(
-						signedOrders,
-						fillUpToAmount,
-						shouldThrowOnInsufficientBalanceOrAllowance,
-						takerAddress,
-					);
-					await zeroEx.awaitTransactionMinedAsync(txHash);
-					const filledAmount = await zeroEx.exchange.getFilledTakerAmountAsync(signedOrderHashHex);
-					const anotherFilledAmount = await zeroEx.exchange.getFilledTakerAmountAsync(anotherOrderHashHex);
-					expect(filledAmount).to.be.bignumber.equal(fillableAmount);
-					const remainingFillAmount = fillableAmount.minus(1);
-					expect(anotherFilledAmount).to.be.bignumber.equal(remainingFillAmount);
-				});
-			});
-			describe('failed batch fills', () => {
-				it("should fail validation if user doesn't have enough balance without fill up to", async () => {
-					const missingBalance = new BigNumber(2); // User will only have enough balance to fill up to 8
-					await zeroEx.token.transferAsync(makerTokenAddress, makerAddress, coinbase, missingBalance);
-					return expect(
-						zeroEx.exchange.fillOrdersUpToAsync(
-							signedOrders,
-							fillUpToAmount,
-							shouldThrowOnInsufficientBalanceOrAllowance,
-							takerAddress,
-						),
-					).to.be.rejectedWith(ExchangeContractErrs.InsufficientMakerBalance);
-				});
-			});
-			describe('order transaction options', () => {
-				const emptyFillUpToAmount = new BigNumber(0);
-				it('should validate when orderTransactionOptions are not present', async () => {
-					return expect(
-						zeroEx.exchange.fillOrdersUpToAsync(
-							signedOrders,
-							emptyFillUpToAmount,
-							shouldThrowOnInsufficientBalanceOrAllowance,
-							takerAddress,
-						),
-					).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
-				});
-				it('should validate when orderTransactionOptions specify to validate', async () => {
-					return expect(
-						zeroEx.exchange.fillOrdersUpToAsync(
-							signedOrders,
-							emptyFillUpToAmount,
-							shouldThrowOnInsufficientBalanceOrAllowance,
-							takerAddress,
-							{
-								shouldValidate: true,
-							},
-						),
-					).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
-				});
-				it('should not validate when orderTransactionOptions specify not to validate', async () => {
-					return expect(
-						zeroEx.exchange.fillOrdersUpToAsync(
-							signedOrders,
-							emptyFillUpToAmount,
-							shouldThrowOnInsufficientBalanceOrAllowance,
-							takerAddress,
-							{
-								shouldValidate: false,
-							},
-						),
-					).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
-				});
-			});
-		});
-	});
-	describe('cancel order(s)', () => {
-		let makerTokenAddress: string;
-		let takerTokenAddress: string;
-		let coinbase: string;
-		let makerAddress: string;
-		let takerAddress: string;
-		const fillableAmount = new BigNumber(5);
-		let signedOrder: SignedOrder;
-		let orderHashHex: string;
-		const cancelAmount = new BigNumber(3);
-		beforeEach(async () => {
-			[coinbase, makerAddress, takerAddress] = userAddresses;
-			const [makerToken, takerToken] = tokenUtils.getDummyTokens();
-			makerTokenAddress = makerToken.address;
-			takerTokenAddress = takerToken.address;
-			signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-				makerTokenAddress,
-				takerTokenAddress,
-				makerAddress,
-				takerAddress,
-				fillableAmount,
-			);
-			orderHashHex = ZeroEx.getOrderHashHex(signedOrder);
-		});
-		describe('#cancelOrderAsync', () => {
-			describe('successful cancels', () => {
-				it('should cancel an order', async () => {
-					const txHash = await zeroEx.exchange.cancelOrderAsync(signedOrder, cancelAmount);
-					await zeroEx.awaitTransactionMinedAsync(txHash);
-					const cancelledAmount = await zeroEx.exchange.getCancelledTakerAmountAsync(orderHashHex);
-					expect(cancelledAmount).to.be.bignumber.equal(cancelAmount);
-				});
-			});
-			describe('order transaction options', () => {
-				const emptyCancelTakerTokenAmount = new BigNumber(0);
-				it('should validate when orderTransactionOptions are not present', async () => {
-					return expect(
-						zeroEx.exchange.cancelOrderAsync(signedOrder, emptyCancelTakerTokenAmount),
-					).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
-				});
-				it('should validate when orderTransactionOptions specify to validate', async () => {
-					return expect(
-						zeroEx.exchange.cancelOrderAsync(signedOrder, emptyCancelTakerTokenAmount, {
-							shouldValidate: true,
-						}),
-					).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
-				});
-				it('should not validate when orderTransactionOptions specify not to validate', async () => {
-					return expect(
-						zeroEx.exchange.cancelOrderAsync(signedOrder, emptyCancelTakerTokenAmount, {
-							shouldValidate: false,
-						}),
-					).to.not.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
-				});
-			});
-		});
-		describe('#batchCancelOrdersAsync', () => {
-			let anotherSignedOrder: SignedOrder;
-			let anotherOrderHashHex: string;
-			let cancelBatch: OrderCancellationRequest[];
-			beforeEach(async () => {
-				anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
-					makerTokenAddress,
-					takerTokenAddress,
-					makerAddress,
-					takerAddress,
-					fillableAmount,
-				);
-				anotherOrderHashHex = ZeroEx.getOrderHashHex(anotherSignedOrder);
-				cancelBatch = [
-					{
-						order: signedOrder,
-						takerTokenCancelAmount: cancelAmount,
-					},
-					{
-						order: anotherSignedOrder,
-						takerTokenCancelAmount: cancelAmount,
-					},
-				];
-			});
-			describe('failed batch cancels', () => {
-				it('should throw when orders have different makers', async () => {
-					const signedOrderWithDifferentMaker = await fillScenarios.createFillableSignedOrderAsync(
-						makerTokenAddress,
-						takerTokenAddress,
-						takerAddress,
-						takerAddress,
-						fillableAmount,
-					);
-					return expect(
-						zeroEx.exchange.batchCancelOrdersAsync([
-							cancelBatch[0],
-							{
-								order: signedOrderWithDifferentMaker,
-								takerTokenCancelAmount: cancelAmount,
-							},
-						]),
-					).to.be.rejectedWith(ExchangeContractErrs.MultipleMakersInSingleCancelBatchDisallowed);
-				});
-			});
-			describe('successful batch cancels', () => {
-				it('should cancel a batch of orders', async () => {
-					await zeroEx.exchange.batchCancelOrdersAsync(cancelBatch);
-					const cancelledAmount = await zeroEx.exchange.getCancelledTakerAmountAsync(orderHashHex);
-					const anotherCancelledAmount = await zeroEx.exchange.getCancelledTakerAmountAsync(
-						anotherOrderHashHex,
-					);
-					expect(cancelledAmount).to.be.bignumber.equal(cancelAmount);
-					expect(anotherCancelledAmount).to.be.bignumber.equal(cancelAmount);
-				});
-			});
-			describe('order transaction options', () => {
-				beforeEach(async () => {
-					const emptyTakerTokenCancelAmount = new BigNumber(0);
-					cancelBatch = [
-						{
-							order: signedOrder,
-							takerTokenCancelAmount: emptyTakerTokenCancelAmount,
-						},
-						{
-							order: anotherSignedOrder,
-							takerTokenCancelAmount: emptyTakerTokenCancelAmount,
-						},
-					];
-				});
-				it('should validate when orderTransactionOptions are not present', async () => {
-					return expect(zeroEx.exchange.batchCancelOrdersAsync(cancelBatch)).to.be.rejectedWith(
-						ExchangeContractErrs.OrderCancelAmountZero,
-					);
-				});
-				it('should validate when orderTransactionOptions specify to validate', async () => {
-					return expect(
-						zeroEx.exchange.batchCancelOrdersAsync(cancelBatch, {
-							shouldValidate: true,
-						}),
-					).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
-				});
-				it('should not validate when orderTransactionOptions specify not to validate', async () => {
-					return expect(
-						zeroEx.exchange.batchCancelOrdersAsync(cancelBatch, {
-							shouldValidate: false,
-						}),
-					).to.not.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
-				});
-			});
-		});
-	});
-	describe('tests that require partially filled order', () => {
-		let makerTokenAddress: string;
-		let takerTokenAddress: string;
-		let takerAddress: string;
-		let fillableAmount: BigNumber;
-		let partialFillAmount: BigNumber;
-		let signedOrder: SignedOrder;
-		let orderHash: string;
-		before(() => {
-			takerAddress = userAddresses[1];
-			tokenUtils = new TokenUtils(tokens);
-			const [makerToken, takerToken] = tokenUtils.getDummyTokens();
-			makerTokenAddress = makerToken.address;
-			takerTokenAddress = takerToken.address;
-		});
-		beforeEach(async () => {
-			fillableAmount = new BigNumber(5);
-			partialFillAmount = new BigNumber(2);
-			signedOrder = await fillScenarios.createPartiallyFilledSignedOrderAsync(
-				makerTokenAddress,
-				takerTokenAddress,
-				takerAddress,
-				fillableAmount,
-				partialFillAmount,
-			);
-			orderHash = ZeroEx.getOrderHashHex(signedOrder);
-		});
-		describe('#getUnavailableTakerAmountAsync', () => {
-			it('should throw if passed an invalid orderHash', async () => {
-				const invalidOrderHashHex = '0x123';
-				return expect(zeroEx.exchange.getUnavailableTakerAmountAsync(invalidOrderHashHex)).to.be.rejected();
-			});
-			it('should return zero if passed a valid but non-existent orderHash', async () => {
-				const unavailableValueT = await zeroEx.exchange.getUnavailableTakerAmountAsync(NON_EXISTENT_ORDER_HASH);
-				expect(unavailableValueT).to.be.bignumber.equal(0);
-			});
-			it('should return the unavailableValueT for a valid and partially filled orderHash', async () => {
-				const unavailableValueT = await zeroEx.exchange.getUnavailableTakerAmountAsync(orderHash);
-				expect(unavailableValueT).to.be.bignumber.equal(partialFillAmount);
-			});
-		});
-		describe('#getFilledTakerAmountAsync', () => {
-			it('should throw if passed an invalid orderHash', async () => {
-				const invalidOrderHashHex = '0x123';
-				return expect(zeroEx.exchange.getFilledTakerAmountAsync(invalidOrderHashHex)).to.be.rejected();
-			});
-			it('should return zero if passed a valid but non-existent orderHash', async () => {
-				const filledValueT = await zeroEx.exchange.getFilledTakerAmountAsync(NON_EXISTENT_ORDER_HASH);
-				expect(filledValueT).to.be.bignumber.equal(0);
-			});
-			it('should return the filledValueT for a valid and partially filled orderHash', async () => {
-				const filledValueT = await zeroEx.exchange.getFilledTakerAmountAsync(orderHash);
-				expect(filledValueT).to.be.bignumber.equal(partialFillAmount);
-			});
-		});
-		describe('#getCancelledTakerAmountAsync', () => {
-			it('should throw if passed an invalid orderHash', async () => {
-				const invalidOrderHashHex = '0x123';
-				return expect(zeroEx.exchange.getCancelledTakerAmountAsync(invalidOrderHashHex)).to.be.rejected();
-			});
-			it('should return zero if passed a valid but non-existent orderHash', async () => {
-				const cancelledValueT = await zeroEx.exchange.getCancelledTakerAmountAsync(NON_EXISTENT_ORDER_HASH);
-				expect(cancelledValueT).to.be.bignumber.equal(0);
-			});
-			it('should return the cancelledValueT for a valid and partially filled orderHash', async () => {
-				const cancelledValueT = await zeroEx.exchange.getCancelledTakerAmountAsync(orderHash);
-				expect(cancelledValueT).to.be.bignumber.equal(0);
-			});
-			it('should return the cancelledValueT for a valid and cancelled orderHash', async () => {
-				const cancelAmount = fillableAmount.minus(partialFillAmount);
-				await zeroEx.exchange.cancelOrderAsync(signedOrder, cancelAmount);
-				const cancelledValueT = await zeroEx.exchange.getCancelledTakerAmountAsync(orderHash);
-				expect(cancelledValueT).to.be.bignumber.equal(cancelAmount);
-			});
-		});
-	});
-	describe('#subscribe', () => {
-		const indexFilterValues = {};
-		const shouldThrowOnInsufficientBalanceOrAllowance = true;
-		let makerTokenAddress: string;
-		let takerTokenAddress: string;
-		let coinbase: string;
-		let takerAddress: string;
-		let makerAddress: string;
-		let fillableAmount: BigNumber;
-		let signedOrder: SignedOrder;
-		const takerTokenFillAmountInBaseUnits = new BigNumber(1);
-		const cancelTakerAmountInBaseUnits = new BigNumber(1);
-		before(() => {
-			[coinbase, makerAddress, takerAddress] = userAddresses;
-			const [makerToken, takerToken] = tokenUtils.getDummyTokens();
-			makerTokenAddress = makerToken.address;
-			takerTokenAddress = takerToken.address;
-		});
-		beforeEach(async () => {
-			fillableAmount = new BigNumber(5);
-			signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-				makerTokenAddress,
-				takerTokenAddress,
-				makerAddress,
-				takerAddress,
-				fillableAmount,
-			);
-		});
-		afterEach(async () => {
-			zeroEx.exchange.unsubscribeAll();
-		});
-		// Hack: Mocha does not allow a test to be both async and have a `done` callback
-		// Since we need to await the receipt of the event in the `subscribe` callback,
-		// we do need both. A hack is to make the top-level a sync fn w/ a done callback and then
-		// wrap the rest of the test in an async block
-		// Source: https://github.com/mochajs/mocha/issues/2407
-		it('Should receive the LogFill event when an order is filled', (done: DoneCallback) => {
-			(async () => {
-				const callback = reportNodeCallbackErrors(done)(
-					(logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
-						expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogFill);
-					},
-				);
-				zeroEx.exchange.subscribe(ExchangeEvents.LogFill, indexFilterValues, callback);
-				await zeroEx.exchange.fillOrderAsync(
-					signedOrder,
-					takerTokenFillAmountInBaseUnits,
-					shouldThrowOnInsufficientBalanceOrAllowance,
-					takerAddress,
-				);
-			})().catch(done);
-		});
-		it('Should receive the LogCancel event when an order is cancelled', (done: DoneCallback) => {
-			(async () => {
-				const callback = reportNodeCallbackErrors(done)(
-					(logEvent: DecodedLogEvent<LogCancelContractEventArgs>) => {
-						expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogCancel);
-					},
-				);
-				zeroEx.exchange.subscribe(ExchangeEvents.LogCancel, indexFilterValues, callback);
-				await zeroEx.exchange.cancelOrderAsync(signedOrder, cancelTakerAmountInBaseUnits);
-			})().catch(done);
-		});
-		it('Outstanding subscriptions are cancelled when zeroEx.setProvider called', (done: DoneCallback) => {
-			(async () => {
-				const callbackNeverToBeCalled = reportNodeCallbackErrors(done)(
-					(logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
-						done(new Error('Expected this subscription to have been cancelled'));
-					},
-				);
-				zeroEx.exchange.subscribe(ExchangeEvents.LogFill, indexFilterValues, callbackNeverToBeCalled);
+    let web3: Web3;
+    let zeroEx: ZeroEx;
+    let tokenUtils: TokenUtils;
+    let tokens: Token[];
+    let userAddresses: string[];
+    let zrxTokenAddress: string;
+    let fillScenarios: FillScenarios;
+    let exchangeContractAddress: string;
+    const config = {
+        networkId: constants.TESTRPC_NETWORK_ID,
+    };
+    before(async () => {
+        web3 = web3Factory.create();
+        zeroEx = new ZeroEx(web3.currentProvider, config);
+        exchangeContractAddress = zeroEx.exchange.getContractAddress();
+        userAddresses = await zeroEx.getAvailableAddressesAsync();
+        tokens = await zeroEx.tokenRegistry.getTokensAsync();
+        tokenUtils = new TokenUtils(tokens);
+        zrxTokenAddress = tokenUtils.getProtocolTokenOrThrow().address;
+        fillScenarios = new FillScenarios(zeroEx, userAddresses, tokens, zrxTokenAddress, exchangeContractAddress);
+        await fillScenarios.initTokenBalancesAsync();
+    });
+    beforeEach(async () => {
+        await blockchainLifecycle.startAsync();
+    });
+    afterEach(async () => {
+        await blockchainLifecycle.revertAsync();
+    });
+    describe('fillOrKill order(s)', () => {
+        let makerTokenAddress: string;
+        let takerTokenAddress: string;
+        let coinbase: string;
+        let makerAddress: string;
+        let takerAddress: string;
+        let feeRecipient: string;
+        const takerTokenFillAmount = new BigNumber(5);
+        before(async () => {
+            [coinbase, makerAddress, takerAddress, feeRecipient] = userAddresses;
+            tokens = await zeroEx.tokenRegistry.getTokensAsync();
+            const [makerToken, takerToken] = tokenUtils.getDummyTokens();
+            makerTokenAddress = makerToken.address;
+            takerTokenAddress = takerToken.address;
+        });
+        describe('#batchFillOrKillAsync', () => {
+            it('successfully batch fillOrKill', async () => {
+                const fillableAmount = new BigNumber(5);
+                const partialFillTakerAmount = new BigNumber(2);
+                const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                    makerTokenAddress,
+                    takerTokenAddress,
+                    makerAddress,
+                    takerAddress,
+                    fillableAmount,
+                );
+                const anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                    makerTokenAddress,
+                    takerTokenAddress,
+                    makerAddress,
+                    takerAddress,
+                    fillableAmount,
+                );
+                const orderFillRequests = [
+                    {
+                        signedOrder,
+                        takerTokenFillAmount: partialFillTakerAmount,
+                    },
+                    {
+                        signedOrder: anotherSignedOrder,
+                        takerTokenFillAmount: partialFillTakerAmount,
+                    },
+                ];
+                await zeroEx.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress);
+            });
+            describe('order transaction options', () => {
+                let signedOrder: SignedOrder;
+                let orderFillRequests: OrderFillRequest[];
+                const fillableAmount = new BigNumber(5);
+                beforeEach(async () => {
+                    signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                        makerTokenAddress,
+                        takerTokenAddress,
+                        makerAddress,
+                        takerAddress,
+                        fillableAmount,
+                    );
+                    orderFillRequests = [
+                        {
+                            signedOrder,
+                            takerTokenFillAmount: new BigNumber(0),
+                        },
+                    ];
+                });
+                it('should validate when orderTransactionOptions are not present', async () => {
+                    return expect(
+                        zeroEx.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress),
+                    ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
+                });
+                it('should validate when orderTransactionOptions specify to validate', async () => {
+                    return expect(
+                        zeroEx.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress, {
+                            shouldValidate: true,
+                        }),
+                    ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
+                });
+                it('should not validate when orderTransactionOptions specify not to validate', async () => {
+                    return expect(
+                        zeroEx.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress, {
+                            shouldValidate: false,
+                        }),
+                    ).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
+                });
+            });
+        });
+        describe('#fillOrKillOrderAsync', () => {
+            let signedOrder: SignedOrder;
+            const fillableAmount = new BigNumber(5);
+            beforeEach(async () => {
+                signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                    makerTokenAddress,
+                    takerTokenAddress,
+                    makerAddress,
+                    takerAddress,
+                    fillableAmount,
+                );
+            });
+            describe('successful fills', () => {
+                it('should fill a valid order', async () => {
+                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress)).to.be.bignumber.equal(
+                        fillableAmount,
+                    );
+                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress)).to.be.bignumber.equal(
+                        0,
+                    );
+                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress)).to.be.bignumber.equal(
+                        0,
+                    );
+                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress)).to.be.bignumber.equal(
+                        fillableAmount,
+                    );
+                    await zeroEx.exchange.fillOrKillOrderAsync(signedOrder, takerTokenFillAmount, takerAddress);
+                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress)).to.be.bignumber.equal(
+                        fillableAmount.minus(takerTokenFillAmount),
+                    );
+                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress)).to.be.bignumber.equal(
+                        takerTokenFillAmount,
+                    );
+                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress)).to.be.bignumber.equal(
+                        takerTokenFillAmount,
+                    );
+                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress)).to.be.bignumber.equal(
+                        fillableAmount.minus(takerTokenFillAmount),
+                    );
+                });
+                it('should partially fill a valid order', async () => {
+                    const partialFillAmount = new BigNumber(3);
+                    await zeroEx.exchange.fillOrKillOrderAsync(signedOrder, partialFillAmount, takerAddress);
+                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress)).to.be.bignumber.equal(
+                        fillableAmount.minus(partialFillAmount),
+                    );
+                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress)).to.be.bignumber.equal(
+                        partialFillAmount,
+                    );
+                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress)).to.be.bignumber.equal(
+                        partialFillAmount,
+                    );
+                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress)).to.be.bignumber.equal(
+                        fillableAmount.minus(partialFillAmount),
+                    );
+                });
+            });
+            describe('order transaction options', () => {
+                const emptyFillableAmount = new BigNumber(0);
+                it('should validate when orderTransactionOptions are not present', async () => {
+                    return expect(
+                        zeroEx.exchange.fillOrKillOrderAsync(signedOrder, emptyFillableAmount, takerAddress),
+                    ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
+                });
+                it('should validate when orderTransactionOptions specify to validate', async () => {
+                    return expect(
+                        zeroEx.exchange.fillOrKillOrderAsync(signedOrder, emptyFillableAmount, takerAddress, {
+                            shouldValidate: true,
+                        }),
+                    ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
+                });
+                it('should not validate when orderTransactionOptions specify not to validate', async () => {
+                    return expect(
+                        zeroEx.exchange.fillOrKillOrderAsync(signedOrder, emptyFillableAmount, takerAddress, {
+                            shouldValidate: false,
+                        }),
+                    ).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
+                });
+            });
+        });
+    });
+    describe('fill order(s)', () => {
+        let makerTokenAddress: string;
+        let takerTokenAddress: string;
+        let coinbase: string;
+        let makerAddress: string;
+        let takerAddress: string;
+        let feeRecipient: string;
+        const fillableAmount = new BigNumber(5);
+        const takerTokenFillAmount = new BigNumber(5);
+        const shouldThrowOnInsufficientBalanceOrAllowance = true;
+        before(async () => {
+            [coinbase, makerAddress, takerAddress, feeRecipient] = userAddresses;
+            tokens = await zeroEx.tokenRegistry.getTokensAsync();
+            const [makerToken, takerToken] = tokenUtils.getDummyTokens();
+            makerTokenAddress = makerToken.address;
+            takerTokenAddress = takerToken.address;
+        });
+        describe('#fillOrderAsync', () => {
+            describe('successful fills', () => {
+                it('should fill a valid order', async () => {
+                    const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                        makerTokenAddress,
+                        takerTokenAddress,
+                        makerAddress,
+                        takerAddress,
+                        fillableAmount,
+                    );
+                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress)).to.be.bignumber.equal(
+                        fillableAmount,
+                    );
+                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress)).to.be.bignumber.equal(
+                        0,
+                    );
+                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress)).to.be.bignumber.equal(
+                        0,
+                    );
+                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress)).to.be.bignumber.equal(
+                        fillableAmount,
+                    );
+                    const txHash = await zeroEx.exchange.fillOrderAsync(
+                        signedOrder,
+                        takerTokenFillAmount,
+                        shouldThrowOnInsufficientBalanceOrAllowance,
+                        takerAddress,
+                    );
+                    await zeroEx.awaitTransactionMinedAsync(txHash);
+                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress)).to.be.bignumber.equal(
+                        fillableAmount.minus(takerTokenFillAmount),
+                    );
+                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress)).to.be.bignumber.equal(
+                        takerTokenFillAmount,
+                    );
+                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress)).to.be.bignumber.equal(
+                        takerTokenFillAmount,
+                    );
+                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress)).to.be.bignumber.equal(
+                        fillableAmount.minus(takerTokenFillAmount),
+                    );
+                });
+                it('should partially fill the valid order', async () => {
+                    const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                        makerTokenAddress,
+                        takerTokenAddress,
+                        makerAddress,
+                        takerAddress,
+                        fillableAmount,
+                    );
+                    const partialFillAmount = new BigNumber(3);
+                    const txHash = await zeroEx.exchange.fillOrderAsync(
+                        signedOrder,
+                        partialFillAmount,
+                        shouldThrowOnInsufficientBalanceOrAllowance,
+                        takerAddress,
+                    );
+                    await zeroEx.awaitTransactionMinedAsync(txHash);
+                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress)).to.be.bignumber.equal(
+                        fillableAmount.minus(partialFillAmount),
+                    );
+                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress)).to.be.bignumber.equal(
+                        partialFillAmount,
+                    );
+                    expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress)).to.be.bignumber.equal(
+                        partialFillAmount,
+                    );
+                    expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress)).to.be.bignumber.equal(
+                        fillableAmount.minus(partialFillAmount),
+                    );
+                });
+                it('should fill the valid orders with fees', async () => {
+                    const makerFee = new BigNumber(1);
+                    const takerFee = new BigNumber(2);
+                    const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
+                        makerTokenAddress,
+                        takerTokenAddress,
+                        makerFee,
+                        takerFee,
+                        makerAddress,
+                        takerAddress,
+                        fillableAmount,
+                        feeRecipient,
+                    );
+                    const txHash = await zeroEx.exchange.fillOrderAsync(
+                        signedOrder,
+                        takerTokenFillAmount,
+                        shouldThrowOnInsufficientBalanceOrAllowance,
+                        takerAddress,
+                    );
+                    await zeroEx.awaitTransactionMinedAsync(txHash);
+                    expect(await zeroEx.token.getBalanceAsync(zrxTokenAddress, feeRecipient)).to.be.bignumber.equal(
+                        makerFee.plus(takerFee),
+                    );
+                });
+            });
+            describe('order transaction options', () => {
+                let signedOrder: SignedOrder;
+                const emptyFillTakerAmount = new BigNumber(0);
+                beforeEach(async () => {
+                    signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                        makerTokenAddress,
+                        takerTokenAddress,
+                        makerAddress,
+                        takerAddress,
+                        fillableAmount,
+                    );
+                });
+                it('should validate when orderTransactionOptions are not present', async () => {
+                    return expect(
+                        zeroEx.exchange.fillOrderAsync(
+                            signedOrder,
+                            emptyFillTakerAmount,
+                            shouldThrowOnInsufficientBalanceOrAllowance,
+                            takerAddress,
+                        ),
+                    ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
+                });
+                it('should validate when orderTransactionOptions specify to validate', async () => {
+                    return expect(
+                        zeroEx.exchange.fillOrderAsync(
+                            signedOrder,
+                            emptyFillTakerAmount,
+                            shouldThrowOnInsufficientBalanceOrAllowance,
+                            takerAddress,
+                            {
+                                shouldValidate: true,
+                            },
+                        ),
+                    ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
+                });
+                it('should not validate when orderTransactionOptions specify not to validate', async () => {
+                    return expect(
+                        zeroEx.exchange.fillOrderAsync(
+                            signedOrder,
+                            emptyFillTakerAmount,
+                            shouldThrowOnInsufficientBalanceOrAllowance,
+                            takerAddress,
+                            {
+                                shouldValidate: false,
+                            },
+                        ),
+                    ).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
+                });
+            });
+            describe('negative fill amount', async () => {
+                let signedOrder: SignedOrder;
+                const negativeFillTakerAmount = new BigNumber(-100);
+                beforeEach(async () => {
+                    signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                        makerTokenAddress,
+                        takerTokenAddress,
+                        makerAddress,
+                        takerAddress,
+                        fillableAmount,
+                    );
+                });
+                it('should not allow the exchange wrapper to fill if amount is negative', async () => {
+                    return expect(
+                        zeroEx.exchange.fillOrderAsync(
+                            signedOrder,
+                            negativeFillTakerAmount,
+                            shouldThrowOnInsufficientBalanceOrAllowance,
+                            takerAddress,
+                        ),
+                    ).to.be.rejected();
+                });
+            });
+        });
+        describe('#batchFillOrdersAsync', () => {
+            let signedOrder: SignedOrder;
+            let signedOrderHashHex: string;
+            let anotherSignedOrder: SignedOrder;
+            let anotherOrderHashHex: string;
+            let orderFillBatch: OrderFillRequest[];
+            beforeEach(async () => {
+                signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                    makerTokenAddress,
+                    takerTokenAddress,
+                    makerAddress,
+                    takerAddress,
+                    fillableAmount,
+                );
+                signedOrderHashHex = ZeroEx.getOrderHashHex(signedOrder);
+                anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                    makerTokenAddress,
+                    takerTokenAddress,
+                    makerAddress,
+                    takerAddress,
+                    fillableAmount,
+                );
+                anotherOrderHashHex = ZeroEx.getOrderHashHex(anotherSignedOrder);
+            });
+            describe('successful batch fills', () => {
+                beforeEach(() => {
+                    orderFillBatch = [
+                        {
+                            signedOrder,
+                            takerTokenFillAmount,
+                        },
+                        {
+                            signedOrder: anotherSignedOrder,
+                            takerTokenFillAmount,
+                        },
+                    ];
+                });
+                it('should throw if a batch is empty', async () => {
+                    return expect(
+                        zeroEx.exchange.batchFillOrdersAsync(
+                            [],
+                            shouldThrowOnInsufficientBalanceOrAllowance,
+                            takerAddress,
+                        ),
+                    ).to.be.rejectedWith(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem);
+                });
+                it('should successfully fill multiple orders', async () => {
+                    const txHash = await zeroEx.exchange.batchFillOrdersAsync(
+                        orderFillBatch,
+                        shouldThrowOnInsufficientBalanceOrAllowance,
+                        takerAddress,
+                    );
+                    await zeroEx.awaitTransactionMinedAsync(txHash);
+                    const filledAmount = await zeroEx.exchange.getFilledTakerAmountAsync(signedOrderHashHex);
+                    const anotherFilledAmount = await zeroEx.exchange.getFilledTakerAmountAsync(anotherOrderHashHex);
+                    expect(filledAmount).to.be.bignumber.equal(takerTokenFillAmount);
+                    expect(anotherFilledAmount).to.be.bignumber.equal(takerTokenFillAmount);
+                });
+            });
+            describe('order transaction options', () => {
+                beforeEach(async () => {
+                    const emptyFillTakerAmount = new BigNumber(0);
+                    orderFillBatch = [
+                        {
+                            signedOrder,
+                            takerTokenFillAmount: emptyFillTakerAmount,
+                        },
+                        {
+                            signedOrder: anotherSignedOrder,
+                            takerTokenFillAmount: emptyFillTakerAmount,
+                        },
+                    ];
+                });
+                it('should validate when orderTransactionOptions are not present', async () => {
+                    return expect(
+                        zeroEx.exchange.batchFillOrdersAsync(
+                            orderFillBatch,
+                            shouldThrowOnInsufficientBalanceOrAllowance,
+                            takerAddress,
+                        ),
+                    ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
+                });
+                it('should validate when orderTransactionOptions specify to validate', async () => {
+                    return expect(
+                        zeroEx.exchange.batchFillOrdersAsync(
+                            orderFillBatch,
+                            shouldThrowOnInsufficientBalanceOrAllowance,
+                            takerAddress,
+                            {
+                                shouldValidate: true,
+                            },
+                        ),
+                    ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
+                });
+                it('should not validate when orderTransactionOptions specify not to validate', async () => {
+                    return expect(
+                        zeroEx.exchange.batchFillOrdersAsync(
+                            orderFillBatch,
+                            shouldThrowOnInsufficientBalanceOrAllowance,
+                            takerAddress,
+                            {
+                                shouldValidate: false,
+                            },
+                        ),
+                    ).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
+                });
+            });
+            describe('negative batch fill amount', async () => {
+                beforeEach(async () => {
+                    const negativeFillTakerAmount = new BigNumber(-100);
+                    orderFillBatch = [
+                        {
+                            signedOrder,
+                            takerTokenFillAmount,
+                        },
+                        {
+                            signedOrder: anotherSignedOrder,
+                            takerTokenFillAmount: negativeFillTakerAmount,
+                        },
+                    ];
+                });
+                it('should not allow the exchange wrapper to batch fill if any amount is negative', async () => {
+                    return expect(
+                        zeroEx.exchange.batchFillOrdersAsync(
+                            orderFillBatch,
+                            shouldThrowOnInsufficientBalanceOrAllowance,
+                            takerAddress,
+                        ),
+                    ).to.be.rejected();
+                });
+            });
+        });
+        describe('#fillOrdersUpTo', () => {
+            let signedOrder: SignedOrder;
+            let signedOrderHashHex: string;
+            let anotherSignedOrder: SignedOrder;
+            let anotherOrderHashHex: string;
+            let signedOrders: SignedOrder[];
+            const fillUpToAmount = fillableAmount.plus(fillableAmount).minus(1);
+            beforeEach(async () => {
+                signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                    makerTokenAddress,
+                    takerTokenAddress,
+                    makerAddress,
+                    takerAddress,
+                    fillableAmount,
+                );
+                signedOrderHashHex = ZeroEx.getOrderHashHex(signedOrder);
+                anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                    makerTokenAddress,
+                    takerTokenAddress,
+                    makerAddress,
+                    takerAddress,
+                    fillableAmount,
+                );
+                anotherOrderHashHex = ZeroEx.getOrderHashHex(anotherSignedOrder);
+                signedOrders = [signedOrder, anotherSignedOrder];
+            });
+            describe('successful batch fills', () => {
+                it('should throw if a batch is empty', async () => {
+                    return expect(
+                        zeroEx.exchange.fillOrdersUpToAsync(
+                            [],
+                            fillUpToAmount,
+                            shouldThrowOnInsufficientBalanceOrAllowance,
+                            takerAddress,
+                        ),
+                    ).to.be.rejectedWith(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem);
+                });
+                it('should successfully fill up to specified amount when all orders are fully funded', async () => {
+                    const txHash = await zeroEx.exchange.fillOrdersUpToAsync(
+                        signedOrders,
+                        fillUpToAmount,
+                        shouldThrowOnInsufficientBalanceOrAllowance,
+                        takerAddress,
+                    );
+                    await zeroEx.awaitTransactionMinedAsync(txHash);
+                    const filledAmount = await zeroEx.exchange.getFilledTakerAmountAsync(signedOrderHashHex);
+                    const anotherFilledAmount = await zeroEx.exchange.getFilledTakerAmountAsync(anotherOrderHashHex);
+                    expect(filledAmount).to.be.bignumber.equal(fillableAmount);
+                    const remainingFillAmount = fillableAmount.minus(1);
+                    expect(anotherFilledAmount).to.be.bignumber.equal(remainingFillAmount);
+                });
+                it('should successfully fill up to specified amount even if filling all orders would fail', async () => {
+                    const missingBalance = new BigNumber(1); // User will still have enough balance to fill up to 9,
+                    // but won't have 10 to fully fill all orders in a batch.
+                    await zeroEx.token.transferAsync(makerTokenAddress, makerAddress, coinbase, missingBalance);
+                    const txHash = await zeroEx.exchange.fillOrdersUpToAsync(
+                        signedOrders,
+                        fillUpToAmount,
+                        shouldThrowOnInsufficientBalanceOrAllowance,
+                        takerAddress,
+                    );
+                    await zeroEx.awaitTransactionMinedAsync(txHash);
+                    const filledAmount = await zeroEx.exchange.getFilledTakerAmountAsync(signedOrderHashHex);
+                    const anotherFilledAmount = await zeroEx.exchange.getFilledTakerAmountAsync(anotherOrderHashHex);
+                    expect(filledAmount).to.be.bignumber.equal(fillableAmount);
+                    const remainingFillAmount = fillableAmount.minus(1);
+                    expect(anotherFilledAmount).to.be.bignumber.equal(remainingFillAmount);
+                });
+            });
+            describe('failed batch fills', () => {
+                it("should fail validation if user doesn't have enough balance without fill up to", async () => {
+                    const missingBalance = new BigNumber(2); // User will only have enough balance to fill up to 8
+                    await zeroEx.token.transferAsync(makerTokenAddress, makerAddress, coinbase, missingBalance);
+                    return expect(
+                        zeroEx.exchange.fillOrdersUpToAsync(
+                            signedOrders,
+                            fillUpToAmount,
+                            shouldThrowOnInsufficientBalanceOrAllowance,
+                            takerAddress,
+                        ),
+                    ).to.be.rejectedWith(ExchangeContractErrs.InsufficientMakerBalance);
+                });
+            });
+            describe('order transaction options', () => {
+                const emptyFillUpToAmount = new BigNumber(0);
+                it('should validate when orderTransactionOptions are not present', async () => {
+                    return expect(
+                        zeroEx.exchange.fillOrdersUpToAsync(
+                            signedOrders,
+                            emptyFillUpToAmount,
+                            shouldThrowOnInsufficientBalanceOrAllowance,
+                            takerAddress,
+                        ),
+                    ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
+                });
+                it('should validate when orderTransactionOptions specify to validate', async () => {
+                    return expect(
+                        zeroEx.exchange.fillOrdersUpToAsync(
+                            signedOrders,
+                            emptyFillUpToAmount,
+                            shouldThrowOnInsufficientBalanceOrAllowance,
+                            takerAddress,
+                            {
+                                shouldValidate: true,
+                            },
+                        ),
+                    ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
+                });
+                it('should not validate when orderTransactionOptions specify not to validate', async () => {
+                    return expect(
+                        zeroEx.exchange.fillOrdersUpToAsync(
+                            signedOrders,
+                            emptyFillUpToAmount,
+                            shouldThrowOnInsufficientBalanceOrAllowance,
+                            takerAddress,
+                            {
+                                shouldValidate: false,
+                            },
+                        ),
+                    ).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
+                });
+            });
+        });
+    });
+    describe('cancel order(s)', () => {
+        let makerTokenAddress: string;
+        let takerTokenAddress: string;
+        let coinbase: string;
+        let makerAddress: string;
+        let takerAddress: string;
+        const fillableAmount = new BigNumber(5);
+        let signedOrder: SignedOrder;
+        let orderHashHex: string;
+        const cancelAmount = new BigNumber(3);
+        beforeEach(async () => {
+            [coinbase, makerAddress, takerAddress] = userAddresses;
+            const [makerToken, takerToken] = tokenUtils.getDummyTokens();
+            makerTokenAddress = makerToken.address;
+            takerTokenAddress = takerToken.address;
+            signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                makerTokenAddress,
+                takerTokenAddress,
+                makerAddress,
+                takerAddress,
+                fillableAmount,
+            );
+            orderHashHex = ZeroEx.getOrderHashHex(signedOrder);
+        });
+        describe('#cancelOrderAsync', () => {
+            describe('successful cancels', () => {
+                it('should cancel an order', async () => {
+                    const txHash = await zeroEx.exchange.cancelOrderAsync(signedOrder, cancelAmount);
+                    await zeroEx.awaitTransactionMinedAsync(txHash);
+                    const cancelledAmount = await zeroEx.exchange.getCancelledTakerAmountAsync(orderHashHex);
+                    expect(cancelledAmount).to.be.bignumber.equal(cancelAmount);
+                });
+            });
+            describe('order transaction options', () => {
+                const emptyCancelTakerTokenAmount = new BigNumber(0);
+                it('should validate when orderTransactionOptions are not present', async () => {
+                    return expect(
+                        zeroEx.exchange.cancelOrderAsync(signedOrder, emptyCancelTakerTokenAmount),
+                    ).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
+                });
+                it('should validate when orderTransactionOptions specify to validate', async () => {
+                    return expect(
+                        zeroEx.exchange.cancelOrderAsync(signedOrder, emptyCancelTakerTokenAmount, {
+                            shouldValidate: true,
+                        }),
+                    ).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
+                });
+                it('should not validate when orderTransactionOptions specify not to validate', async () => {
+                    return expect(
+                        zeroEx.exchange.cancelOrderAsync(signedOrder, emptyCancelTakerTokenAmount, {
+                            shouldValidate: false,
+                        }),
+                    ).to.not.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
+                });
+            });
+        });
+        describe('#batchCancelOrdersAsync', () => {
+            let anotherSignedOrder: SignedOrder;
+            let anotherOrderHashHex: string;
+            let cancelBatch: OrderCancellationRequest[];
+            beforeEach(async () => {
+                anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                    makerTokenAddress,
+                    takerTokenAddress,
+                    makerAddress,
+                    takerAddress,
+                    fillableAmount,
+                );
+                anotherOrderHashHex = ZeroEx.getOrderHashHex(anotherSignedOrder);
+                cancelBatch = [
+                    {
+                        order: signedOrder,
+                        takerTokenCancelAmount: cancelAmount,
+                    },
+                    {
+                        order: anotherSignedOrder,
+                        takerTokenCancelAmount: cancelAmount,
+                    },
+                ];
+            });
+            describe('failed batch cancels', () => {
+                it('should throw when orders have different makers', async () => {
+                    const signedOrderWithDifferentMaker = await fillScenarios.createFillableSignedOrderAsync(
+                        makerTokenAddress,
+                        takerTokenAddress,
+                        takerAddress,
+                        takerAddress,
+                        fillableAmount,
+                    );
+                    return expect(
+                        zeroEx.exchange.batchCancelOrdersAsync([
+                            cancelBatch[0],
+                            {
+                                order: signedOrderWithDifferentMaker,
+                                takerTokenCancelAmount: cancelAmount,
+                            },
+                        ]),
+                    ).to.be.rejectedWith(ExchangeContractErrs.MultipleMakersInSingleCancelBatchDisallowed);
+                });
+            });
+            describe('successful batch cancels', () => {
+                it('should cancel a batch of orders', async () => {
+                    await zeroEx.exchange.batchCancelOrdersAsync(cancelBatch);
+                    const cancelledAmount = await zeroEx.exchange.getCancelledTakerAmountAsync(orderHashHex);
+                    const anotherCancelledAmount = await zeroEx.exchange.getCancelledTakerAmountAsync(
+                        anotherOrderHashHex,
+                    );
+                    expect(cancelledAmount).to.be.bignumber.equal(cancelAmount);
+                    expect(anotherCancelledAmount).to.be.bignumber.equal(cancelAmount);
+                });
+            });
+            describe('order transaction options', () => {
+                beforeEach(async () => {
+                    const emptyTakerTokenCancelAmount = new BigNumber(0);
+                    cancelBatch = [
+                        {
+                            order: signedOrder,
+                            takerTokenCancelAmount: emptyTakerTokenCancelAmount,
+                        },
+                        {
+                            order: anotherSignedOrder,
+                            takerTokenCancelAmount: emptyTakerTokenCancelAmount,
+                        },
+                    ];
+                });
+                it('should validate when orderTransactionOptions are not present', async () => {
+                    return expect(zeroEx.exchange.batchCancelOrdersAsync(cancelBatch)).to.be.rejectedWith(
+                        ExchangeContractErrs.OrderCancelAmountZero,
+                    );
+                });
+                it('should validate when orderTransactionOptions specify to validate', async () => {
+                    return expect(
+                        zeroEx.exchange.batchCancelOrdersAsync(cancelBatch, {
+                            shouldValidate: true,
+                        }),
+                    ).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
+                });
+                it('should not validate when orderTransactionOptions specify not to validate', async () => {
+                    return expect(
+                        zeroEx.exchange.batchCancelOrdersAsync(cancelBatch, {
+                            shouldValidate: false,
+                        }),
+                    ).to.not.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
+                });
+            });
+        });
+    });
+    describe('tests that require partially filled order', () => {
+        let makerTokenAddress: string;
+        let takerTokenAddress: string;
+        let takerAddress: string;
+        let fillableAmount: BigNumber;
+        let partialFillAmount: BigNumber;
+        let signedOrder: SignedOrder;
+        let orderHash: string;
+        before(() => {
+            takerAddress = userAddresses[1];
+            tokenUtils = new TokenUtils(tokens);
+            const [makerToken, takerToken] = tokenUtils.getDummyTokens();
+            makerTokenAddress = makerToken.address;
+            takerTokenAddress = takerToken.address;
+        });
+        beforeEach(async () => {
+            fillableAmount = new BigNumber(5);
+            partialFillAmount = new BigNumber(2);
+            signedOrder = await fillScenarios.createPartiallyFilledSignedOrderAsync(
+                makerTokenAddress,
+                takerTokenAddress,
+                takerAddress,
+                fillableAmount,
+                partialFillAmount,
+            );
+            orderHash = ZeroEx.getOrderHashHex(signedOrder);
+        });
+        describe('#getUnavailableTakerAmountAsync', () => {
+            it('should throw if passed an invalid orderHash', async () => {
+                const invalidOrderHashHex = '0x123';
+                return expect(zeroEx.exchange.getUnavailableTakerAmountAsync(invalidOrderHashHex)).to.be.rejected();
+            });
+            it('should return zero if passed a valid but non-existent orderHash', async () => {
+                const unavailableValueT = await zeroEx.exchange.getUnavailableTakerAmountAsync(NON_EXISTENT_ORDER_HASH);
+                expect(unavailableValueT).to.be.bignumber.equal(0);
+            });
+            it('should return the unavailableValueT for a valid and partially filled orderHash', async () => {
+                const unavailableValueT = await zeroEx.exchange.getUnavailableTakerAmountAsync(orderHash);
+                expect(unavailableValueT).to.be.bignumber.equal(partialFillAmount);
+            });
+        });
+        describe('#getFilledTakerAmountAsync', () => {
+            it('should throw if passed an invalid orderHash', async () => {
+                const invalidOrderHashHex = '0x123';
+                return expect(zeroEx.exchange.getFilledTakerAmountAsync(invalidOrderHashHex)).to.be.rejected();
+            });
+            it('should return zero if passed a valid but non-existent orderHash', async () => {
+                const filledValueT = await zeroEx.exchange.getFilledTakerAmountAsync(NON_EXISTENT_ORDER_HASH);
+                expect(filledValueT).to.be.bignumber.equal(0);
+            });
+            it('should return the filledValueT for a valid and partially filled orderHash', async () => {
+                const filledValueT = await zeroEx.exchange.getFilledTakerAmountAsync(orderHash);
+                expect(filledValueT).to.be.bignumber.equal(partialFillAmount);
+            });
+        });
+        describe('#getCancelledTakerAmountAsync', () => {
+            it('should throw if passed an invalid orderHash', async () => {
+                const invalidOrderHashHex = '0x123';
+                return expect(zeroEx.exchange.getCancelledTakerAmountAsync(invalidOrderHashHex)).to.be.rejected();
+            });
+            it('should return zero if passed a valid but non-existent orderHash', async () => {
+                const cancelledValueT = await zeroEx.exchange.getCancelledTakerAmountAsync(NON_EXISTENT_ORDER_HASH);
+                expect(cancelledValueT).to.be.bignumber.equal(0);
+            });
+            it('should return the cancelledValueT for a valid and partially filled orderHash', async () => {
+                const cancelledValueT = await zeroEx.exchange.getCancelledTakerAmountAsync(orderHash);
+                expect(cancelledValueT).to.be.bignumber.equal(0);
+            });
+            it('should return the cancelledValueT for a valid and cancelled orderHash', async () => {
+                const cancelAmount = fillableAmount.minus(partialFillAmount);
+                await zeroEx.exchange.cancelOrderAsync(signedOrder, cancelAmount);
+                const cancelledValueT = await zeroEx.exchange.getCancelledTakerAmountAsync(orderHash);
+                expect(cancelledValueT).to.be.bignumber.equal(cancelAmount);
+            });
+        });
+    });
+    describe('#subscribe', () => {
+        const indexFilterValues = {};
+        const shouldThrowOnInsufficientBalanceOrAllowance = true;
+        let makerTokenAddress: string;
+        let takerTokenAddress: string;
+        let coinbase: string;
+        let takerAddress: string;
+        let makerAddress: string;
+        let fillableAmount: BigNumber;
+        let signedOrder: SignedOrder;
+        const takerTokenFillAmountInBaseUnits = new BigNumber(1);
+        const cancelTakerAmountInBaseUnits = new BigNumber(1);
+        before(() => {
+            [coinbase, makerAddress, takerAddress] = userAddresses;
+            const [makerToken, takerToken] = tokenUtils.getDummyTokens();
+            makerTokenAddress = makerToken.address;
+            takerTokenAddress = takerToken.address;
+        });
+        beforeEach(async () => {
+            fillableAmount = new BigNumber(5);
+            signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                makerTokenAddress,
+                takerTokenAddress,
+                makerAddress,
+                takerAddress,
+                fillableAmount,
+            );
+        });
+        afterEach(async () => {
+            zeroEx.exchange.unsubscribeAll();
+        });
+        // Hack: Mocha does not allow a test to be both async and have a `done` callback
+        // Since we need to await the receipt of the event in the `subscribe` callback,
+        // we do need both. A hack is to make the top-level a sync fn w/ a done callback and then
+        // wrap the rest of the test in an async block
+        // Source: https://github.com/mochajs/mocha/issues/2407
+        it('Should receive the LogFill event when an order is filled', (done: DoneCallback) => {
+            (async () => {
+                const callback = reportNodeCallbackErrors(done)(
+                    (logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
+                        expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogFill);
+                    },
+                );
+                zeroEx.exchange.subscribe(ExchangeEvents.LogFill, indexFilterValues, callback);
+                await zeroEx.exchange.fillOrderAsync(
+                    signedOrder,
+                    takerTokenFillAmountInBaseUnits,
+                    shouldThrowOnInsufficientBalanceOrAllowance,
+                    takerAddress,
+                );
+            })().catch(done);
+        });
+        it('Should receive the LogCancel event when an order is cancelled', (done: DoneCallback) => {
+            (async () => {
+                const callback = reportNodeCallbackErrors(done)(
+                    (logEvent: DecodedLogEvent<LogCancelContractEventArgs>) => {
+                        expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogCancel);
+                    },
+                );
+                zeroEx.exchange.subscribe(ExchangeEvents.LogCancel, indexFilterValues, callback);
+                await zeroEx.exchange.cancelOrderAsync(signedOrder, cancelTakerAmountInBaseUnits);
+            })().catch(done);
+        });
+        it('Outstanding subscriptions are cancelled when zeroEx.setProvider called', (done: DoneCallback) => {
+            (async () => {
+                const callbackNeverToBeCalled = reportNodeCallbackErrors(done)(
+                    (logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
+                        done(new Error('Expected this subscription to have been cancelled'));
+                    },
+                );
+                zeroEx.exchange.subscribe(ExchangeEvents.LogFill, indexFilterValues, callbackNeverToBeCalled);
 
-				const newProvider = web3Factory.getRpcProvider();
-				zeroEx.setProvider(newProvider, constants.TESTRPC_NETWORK_ID);
+                const newProvider = web3Factory.getRpcProvider();
+                zeroEx.setProvider(newProvider, constants.TESTRPC_NETWORK_ID);
 
-				const callback = reportNodeCallbackErrors(done)(
-					(logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
-						expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogFill);
-					},
-				);
-				zeroEx.exchange.subscribe(ExchangeEvents.LogFill, indexFilterValues, callback);
-				await zeroEx.exchange.fillOrderAsync(
-					signedOrder,
-					takerTokenFillAmountInBaseUnits,
-					shouldThrowOnInsufficientBalanceOrAllowance,
-					takerAddress,
-				);
-			})().catch(done);
-		});
-		it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => {
-			(async () => {
-				const callbackNeverToBeCalled = reportNodeCallbackErrors(done)(
-					(logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
-						done(new Error('Expected this subscription to have been cancelled'));
-					},
-				);
-				const subscriptionToken = zeroEx.exchange.subscribe(
-					ExchangeEvents.LogFill,
-					indexFilterValues,
-					callbackNeverToBeCalled,
-				);
-				zeroEx.exchange.unsubscribe(subscriptionToken);
-				await zeroEx.exchange.fillOrderAsync(
-					signedOrder,
-					takerTokenFillAmountInBaseUnits,
-					shouldThrowOnInsufficientBalanceOrAllowance,
-					takerAddress,
-				);
-				done();
-			})().catch(done);
-		});
-	});
-	describe('#getOrderHashHexUsingContractCallAsync', () => {
-		let makerTokenAddress: string;
-		let takerTokenAddress: string;
-		let makerAddress: string;
-		let takerAddress: string;
-		const fillableAmount = new BigNumber(5);
-		before(async () => {
-			[, makerAddress, takerAddress] = userAddresses;
-			const [makerToken, takerToken] = tokenUtils.getDummyTokens();
-			makerTokenAddress = makerToken.address;
-			takerTokenAddress = takerToken.address;
-		});
-		it("get's the same hash as the local function", async () => {
-			const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-				makerTokenAddress,
-				takerTokenAddress,
-				makerAddress,
-				takerAddress,
-				fillableAmount,
-			);
-			const orderHash = ZeroEx.getOrderHashHex(signedOrder);
-			const orderHashFromContract = await (zeroEx.exchange as any)._getOrderHashHexUsingContractCallAsync(
-				signedOrder,
-			);
-			expect(orderHash).to.equal(orderHashFromContract);
-		});
-	});
-	describe('#getZRXTokenAddressAsync', () => {
-		it('gets the same token as is in token registry', () => {
-			const zrxAddress = zeroEx.exchange.getZRXTokenAddress();
-			const zrxToken = tokenUtils.getProtocolTokenOrThrow();
-			expect(zrxAddress).to.equal(zrxToken.address);
-		});
-	});
-	describe('#getLogsAsync', () => {
-		let makerTokenAddress: string;
-		let takerTokenAddress: string;
-		let makerAddress: string;
-		let takerAddress: string;
-		const fillableAmount = new BigNumber(5);
-		const shouldThrowOnInsufficientBalanceOrAllowance = true;
-		const blockRange: BlockRange = {
-			fromBlock: 0,
-			toBlock: BlockParamLiteral.Latest,
-		};
-		let txHash: string;
-		before(async () => {
-			[, makerAddress, takerAddress] = userAddresses;
-			const [makerToken, takerToken] = tokenUtils.getDummyTokens();
-			makerTokenAddress = makerToken.address;
-			takerTokenAddress = takerToken.address;
-		});
-		it('should get logs with decoded args emitted by LogFill', async () => {
-			const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-				makerTokenAddress,
-				takerTokenAddress,
-				makerAddress,
-				takerAddress,
-				fillableAmount,
-			);
-			txHash = await zeroEx.exchange.fillOrderAsync(
-				signedOrder,
-				fillableAmount,
-				shouldThrowOnInsufficientBalanceOrAllowance,
-				takerAddress,
-			);
-			await zeroEx.awaitTransactionMinedAsync(txHash);
-			const eventName = ExchangeEvents.LogFill;
-			const indexFilterValues = {};
-			const logs = await zeroEx.exchange.getLogsAsync(eventName, blockRange, indexFilterValues);
-			expect(logs).to.have.length(1);
-			expect(logs[0].event).to.be.equal(eventName);
-		});
-		it('should only get the logs with the correct event name', async () => {
-			const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-				makerTokenAddress,
-				takerTokenAddress,
-				makerAddress,
-				takerAddress,
-				fillableAmount,
-			);
-			txHash = await zeroEx.exchange.fillOrderAsync(
-				signedOrder,
-				fillableAmount,
-				shouldThrowOnInsufficientBalanceOrAllowance,
-				takerAddress,
-			);
-			await zeroEx.awaitTransactionMinedAsync(txHash);
-			const differentEventName = ExchangeEvents.LogCancel;
-			const indexFilterValues = {};
-			const logs = await zeroEx.exchange.getLogsAsync(differentEventName, blockRange, indexFilterValues);
-			expect(logs).to.have.length(0);
-		});
-		it('should only get the logs with the correct indexed fields', async () => {
-			const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-				makerTokenAddress,
-				takerTokenAddress,
-				makerAddress,
-				takerAddress,
-				fillableAmount,
-			);
-			txHash = await zeroEx.exchange.fillOrderAsync(
-				signedOrder,
-				fillableAmount,
-				shouldThrowOnInsufficientBalanceOrAllowance,
-				takerAddress,
-			);
-			await zeroEx.awaitTransactionMinedAsync(txHash);
+                const callback = reportNodeCallbackErrors(done)(
+                    (logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
+                        expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogFill);
+                    },
+                );
+                zeroEx.exchange.subscribe(ExchangeEvents.LogFill, indexFilterValues, callback);
+                await zeroEx.exchange.fillOrderAsync(
+                    signedOrder,
+                    takerTokenFillAmountInBaseUnits,
+                    shouldThrowOnInsufficientBalanceOrAllowance,
+                    takerAddress,
+                );
+            })().catch(done);
+        });
+        it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => {
+            (async () => {
+                const callbackNeverToBeCalled = reportNodeCallbackErrors(done)(
+                    (logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
+                        done(new Error('Expected this subscription to have been cancelled'));
+                    },
+                );
+                const subscriptionToken = zeroEx.exchange.subscribe(
+                    ExchangeEvents.LogFill,
+                    indexFilterValues,
+                    callbackNeverToBeCalled,
+                );
+                zeroEx.exchange.unsubscribe(subscriptionToken);
+                await zeroEx.exchange.fillOrderAsync(
+                    signedOrder,
+                    takerTokenFillAmountInBaseUnits,
+                    shouldThrowOnInsufficientBalanceOrAllowance,
+                    takerAddress,
+                );
+                done();
+            })().catch(done);
+        });
+    });
+    describe('#getOrderHashHexUsingContractCallAsync', () => {
+        let makerTokenAddress: string;
+        let takerTokenAddress: string;
+        let makerAddress: string;
+        let takerAddress: string;
+        const fillableAmount = new BigNumber(5);
+        before(async () => {
+            [, makerAddress, takerAddress] = userAddresses;
+            const [makerToken, takerToken] = tokenUtils.getDummyTokens();
+            makerTokenAddress = makerToken.address;
+            takerTokenAddress = takerToken.address;
+        });
+        it("get's the same hash as the local function", async () => {
+            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                makerTokenAddress,
+                takerTokenAddress,
+                makerAddress,
+                takerAddress,
+                fillableAmount,
+            );
+            const orderHash = ZeroEx.getOrderHashHex(signedOrder);
+            const orderHashFromContract = await (zeroEx.exchange as any)._getOrderHashHexUsingContractCallAsync(
+                signedOrder,
+            );
+            expect(orderHash).to.equal(orderHashFromContract);
+        });
+    });
+    describe('#getZRXTokenAddressAsync', () => {
+        it('gets the same token as is in token registry', () => {
+            const zrxAddress = zeroEx.exchange.getZRXTokenAddress();
+            const zrxToken = tokenUtils.getProtocolTokenOrThrow();
+            expect(zrxAddress).to.equal(zrxToken.address);
+        });
+    });
+    describe('#getLogsAsync', () => {
+        let makerTokenAddress: string;
+        let takerTokenAddress: string;
+        let makerAddress: string;
+        let takerAddress: string;
+        const fillableAmount = new BigNumber(5);
+        const shouldThrowOnInsufficientBalanceOrAllowance = true;
+        const blockRange: BlockRange = {
+            fromBlock: 0,
+            toBlock: BlockParamLiteral.Latest,
+        };
+        let txHash: string;
+        before(async () => {
+            [, makerAddress, takerAddress] = userAddresses;
+            const [makerToken, takerToken] = tokenUtils.getDummyTokens();
+            makerTokenAddress = makerToken.address;
+            takerTokenAddress = takerToken.address;
+        });
+        it('should get logs with decoded args emitted by LogFill', async () => {
+            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                makerTokenAddress,
+                takerTokenAddress,
+                makerAddress,
+                takerAddress,
+                fillableAmount,
+            );
+            txHash = await zeroEx.exchange.fillOrderAsync(
+                signedOrder,
+                fillableAmount,
+                shouldThrowOnInsufficientBalanceOrAllowance,
+                takerAddress,
+            );
+            await zeroEx.awaitTransactionMinedAsync(txHash);
+            const eventName = ExchangeEvents.LogFill;
+            const indexFilterValues = {};
+            const logs = await zeroEx.exchange.getLogsAsync(eventName, blockRange, indexFilterValues);
+            expect(logs).to.have.length(1);
+            expect(logs[0].event).to.be.equal(eventName);
+        });
+        it('should only get the logs with the correct event name', async () => {
+            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                makerTokenAddress,
+                takerTokenAddress,
+                makerAddress,
+                takerAddress,
+                fillableAmount,
+            );
+            txHash = await zeroEx.exchange.fillOrderAsync(
+                signedOrder,
+                fillableAmount,
+                shouldThrowOnInsufficientBalanceOrAllowance,
+                takerAddress,
+            );
+            await zeroEx.awaitTransactionMinedAsync(txHash);
+            const differentEventName = ExchangeEvents.LogCancel;
+            const indexFilterValues = {};
+            const logs = await zeroEx.exchange.getLogsAsync(differentEventName, blockRange, indexFilterValues);
+            expect(logs).to.have.length(0);
+        });
+        it('should only get the logs with the correct indexed fields', async () => {
+            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                makerTokenAddress,
+                takerTokenAddress,
+                makerAddress,
+                takerAddress,
+                fillableAmount,
+            );
+            txHash = await zeroEx.exchange.fillOrderAsync(
+                signedOrder,
+                fillableAmount,
+                shouldThrowOnInsufficientBalanceOrAllowance,
+                takerAddress,
+            );
+            await zeroEx.awaitTransactionMinedAsync(txHash);
 
-			const differentMakerAddress = userAddresses[2];
-			const anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
-				makerTokenAddress,
-				takerTokenAddress,
-				differentMakerAddress,
-				takerAddress,
-				fillableAmount,
-			);
-			txHash = await zeroEx.exchange.fillOrderAsync(
-				anotherSignedOrder,
-				fillableAmount,
-				shouldThrowOnInsufficientBalanceOrAllowance,
-				takerAddress,
-			);
-			await zeroEx.awaitTransactionMinedAsync(txHash);
+            const differentMakerAddress = userAddresses[2];
+            const anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                makerTokenAddress,
+                takerTokenAddress,
+                differentMakerAddress,
+                takerAddress,
+                fillableAmount,
+            );
+            txHash = await zeroEx.exchange.fillOrderAsync(
+                anotherSignedOrder,
+                fillableAmount,
+                shouldThrowOnInsufficientBalanceOrAllowance,
+                takerAddress,
+            );
+            await zeroEx.awaitTransactionMinedAsync(txHash);
 
-			const eventName = ExchangeEvents.LogFill;
-			const indexFilterValues = {
-				maker: differentMakerAddress,
-			};
-			const logs = await zeroEx.exchange.getLogsAsync<LogFillContractEventArgs>(
-				eventName,
-				blockRange,
-				indexFilterValues,
-			);
-			expect(logs).to.have.length(1);
-			const args = logs[0].args;
-			expect(args.maker).to.be.equal(differentMakerAddress);
-		});
-	});
+            const eventName = ExchangeEvents.LogFill;
+            const indexFilterValues = {
+                maker: differentMakerAddress,
+            };
+            const logs = await zeroEx.exchange.getLogsAsync<LogFillContractEventArgs>(
+                eventName,
+                blockRange,
+                indexFilterValues,
+            );
+            expect(logs).to.have.length(1);
+            const args = logs[0].args;
+            expect(args.maker).to.be.equal(differentMakerAddress);
+        });
+    });
 }); // tslint:disable:max-file-line-count
diff --git a/packages/0x.js/test/expiration_watcher_test.ts b/packages/0x.js/test/expiration_watcher_test.ts
index a76d84da1..770615f88 100644
--- a/packages/0x.js/test/expiration_watcher_test.ts
+++ b/packages/0x.js/test/expiration_watcher_test.ts
@@ -24,137 +24,137 @@ const expect = chai.expect;
 const blockchainLifecycle = new BlockchainLifecycle(testConstants.RPC_URL);
 
 describe('ExpirationWatcher', () => {
-	let web3: Web3;
-	let zeroEx: ZeroEx;
-	let tokenUtils: TokenUtils;
-	let tokens: Token[];
-	let userAddresses: string[];
-	let zrxTokenAddress: string;
-	let fillScenarios: FillScenarios;
-	let exchangeContractAddress: string;
-	let makerTokenAddress: string;
-	let takerTokenAddress: string;
-	let coinbase: string;
-	let makerAddress: string;
-	let takerAddress: string;
-	let feeRecipient: string;
-	const fillableAmount = new BigNumber(5);
-	let currentUnixTimestampSec: BigNumber;
-	let timer: Sinon.SinonFakeTimers;
-	let expirationWatcher: ExpirationWatcher;
-	before(async () => {
-		web3 = web3Factory.create();
-		const config = {
-			networkId: constants.TESTRPC_NETWORK_ID,
-		};
-		zeroEx = new ZeroEx(web3.currentProvider, config);
-		exchangeContractAddress = zeroEx.exchange.getContractAddress();
-		userAddresses = await zeroEx.getAvailableAddressesAsync();
-		tokens = await zeroEx.tokenRegistry.getTokensAsync();
-		tokenUtils = new TokenUtils(tokens);
-		zrxTokenAddress = tokenUtils.getProtocolTokenOrThrow().address;
-		fillScenarios = new FillScenarios(zeroEx, userAddresses, tokens, zrxTokenAddress, exchangeContractAddress);
-		[coinbase, makerAddress, takerAddress, feeRecipient] = userAddresses;
-		tokens = await zeroEx.tokenRegistry.getTokensAsync();
-		const [makerToken, takerToken] = tokenUtils.getDummyTokens();
-		makerTokenAddress = makerToken.address;
-		takerTokenAddress = takerToken.address;
-	});
-	beforeEach(async () => {
-		await blockchainLifecycle.startAsync();
-		const sinonTimerConfig = { shouldAdvanceTime: true } as any;
-		// This constructor has incorrect types
-		timer = Sinon.useFakeTimers(sinonTimerConfig);
-		currentUnixTimestampSec = utils.getCurrentUnixTimestampSec();
-		expirationWatcher = new ExpirationWatcher();
-	});
-	afterEach(async () => {
-		await blockchainLifecycle.revertAsync();
-		timer.restore();
-		expirationWatcher.unsubscribe();
-	});
-	it('correctly emits events when order expires', (done: DoneCallback) => {
-		(async () => {
-			const orderLifetimeSec = 60;
-			const expirationUnixTimestampSec = currentUnixTimestampSec.plus(orderLifetimeSec);
-			const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-				makerTokenAddress,
-				takerTokenAddress,
-				makerAddress,
-				takerAddress,
-				fillableAmount,
-				expirationUnixTimestampSec,
-			);
-			const orderHash = ZeroEx.getOrderHashHex(signedOrder);
-			expirationWatcher.addOrder(orderHash, signedOrder.expirationUnixTimestampSec.times(1000));
-			const callbackAsync = reportNoErrorCallbackErrors(done)((hash: string) => {
-				expect(hash).to.be.equal(orderHash);
-				expect(utils.getCurrentUnixTimestampSec()).to.be.bignumber.gte(expirationUnixTimestampSec);
-			});
-			expirationWatcher.subscribe(callbackAsync);
-			timer.tick(orderLifetimeSec * 1000);
-		})().catch(done);
-	});
-	it("doesn't emit events before order expires", (done: DoneCallback) => {
-		(async () => {
-			const orderLifetimeSec = 60;
-			const expirationUnixTimestampSec = currentUnixTimestampSec.plus(orderLifetimeSec);
-			const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-				makerTokenAddress,
-				takerTokenAddress,
-				makerAddress,
-				takerAddress,
-				fillableAmount,
-				expirationUnixTimestampSec,
-			);
-			const orderHash = ZeroEx.getOrderHashHex(signedOrder);
-			expirationWatcher.addOrder(orderHash, signedOrder.expirationUnixTimestampSec.times(1000));
-			const callbackAsync = reportNoErrorCallbackErrors(done)(async (hash: string) => {
-				done(new Error('Emitted expiration went before the order actually expired'));
-			});
-			expirationWatcher.subscribe(callbackAsync);
-			const notEnoughTime = orderLifetimeSec - 1;
-			timer.tick(notEnoughTime * 1000);
-			done();
-		})().catch(done);
-	});
-	it('emits events in correct order', (done: DoneCallback) => {
-		(async () => {
-			const order1Lifetime = 60;
-			const order2Lifetime = 120;
-			const order1ExpirationUnixTimestampSec = currentUnixTimestampSec.plus(order1Lifetime);
-			const order2ExpirationUnixTimestampSec = currentUnixTimestampSec.plus(order2Lifetime);
-			const signedOrder1 = await fillScenarios.createFillableSignedOrderAsync(
-				makerTokenAddress,
-				takerTokenAddress,
-				makerAddress,
-				takerAddress,
-				fillableAmount,
-				order1ExpirationUnixTimestampSec,
-			);
-			const signedOrder2 = await fillScenarios.createFillableSignedOrderAsync(
-				makerTokenAddress,
-				takerTokenAddress,
-				makerAddress,
-				takerAddress,
-				fillableAmount,
-				order2ExpirationUnixTimestampSec,
-			);
-			const orderHash1 = ZeroEx.getOrderHashHex(signedOrder1);
-			const orderHash2 = ZeroEx.getOrderHashHex(signedOrder2);
-			expirationWatcher.addOrder(orderHash2, signedOrder2.expirationUnixTimestampSec.times(1000));
-			expirationWatcher.addOrder(orderHash1, signedOrder1.expirationUnixTimestampSec.times(1000));
-			const expirationOrder = [orderHash1, orderHash2];
-			const expectToBeCalledOnce = false;
-			const callbackAsync = reportNoErrorCallbackErrors(done, expectToBeCalledOnce)((hash: string) => {
-				const orderHash = expirationOrder.shift();
-				expect(hash).to.be.equal(orderHash);
-				if (_.isEmpty(expirationOrder)) {
-					done();
-				}
-			});
-			expirationWatcher.subscribe(callbackAsync);
-			timer.tick(order2Lifetime * 1000);
-		})().catch(done);
-	});
+    let web3: Web3;
+    let zeroEx: ZeroEx;
+    let tokenUtils: TokenUtils;
+    let tokens: Token[];
+    let userAddresses: string[];
+    let zrxTokenAddress: string;
+    let fillScenarios: FillScenarios;
+    let exchangeContractAddress: string;
+    let makerTokenAddress: string;
+    let takerTokenAddress: string;
+    let coinbase: string;
+    let makerAddress: string;
+    let takerAddress: string;
+    let feeRecipient: string;
+    const fillableAmount = new BigNumber(5);
+    let currentUnixTimestampSec: BigNumber;
+    let timer: Sinon.SinonFakeTimers;
+    let expirationWatcher: ExpirationWatcher;
+    before(async () => {
+        web3 = web3Factory.create();
+        const config = {
+            networkId: constants.TESTRPC_NETWORK_ID,
+        };
+        zeroEx = new ZeroEx(web3.currentProvider, config);
+        exchangeContractAddress = zeroEx.exchange.getContractAddress();
+        userAddresses = await zeroEx.getAvailableAddressesAsync();
+        tokens = await zeroEx.tokenRegistry.getTokensAsync();
+        tokenUtils = new TokenUtils(tokens);
+        zrxTokenAddress = tokenUtils.getProtocolTokenOrThrow().address;
+        fillScenarios = new FillScenarios(zeroEx, userAddresses, tokens, zrxTokenAddress, exchangeContractAddress);
+        [coinbase, makerAddress, takerAddress, feeRecipient] = userAddresses;
+        tokens = await zeroEx.tokenRegistry.getTokensAsync();
+        const [makerToken, takerToken] = tokenUtils.getDummyTokens();
+        makerTokenAddress = makerToken.address;
+        takerTokenAddress = takerToken.address;
+    });
+    beforeEach(async () => {
+        await blockchainLifecycle.startAsync();
+        const sinonTimerConfig = { shouldAdvanceTime: true } as any;
+        // This constructor has incorrect types
+        timer = Sinon.useFakeTimers(sinonTimerConfig);
+        currentUnixTimestampSec = utils.getCurrentUnixTimestampSec();
+        expirationWatcher = new ExpirationWatcher();
+    });
+    afterEach(async () => {
+        await blockchainLifecycle.revertAsync();
+        timer.restore();
+        expirationWatcher.unsubscribe();
+    });
+    it('correctly emits events when order expires', (done: DoneCallback) => {
+        (async () => {
+            const orderLifetimeSec = 60;
+            const expirationUnixTimestampSec = currentUnixTimestampSec.plus(orderLifetimeSec);
+            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                makerTokenAddress,
+                takerTokenAddress,
+                makerAddress,
+                takerAddress,
+                fillableAmount,
+                expirationUnixTimestampSec,
+            );
+            const orderHash = ZeroEx.getOrderHashHex(signedOrder);
+            expirationWatcher.addOrder(orderHash, signedOrder.expirationUnixTimestampSec.times(1000));
+            const callbackAsync = reportNoErrorCallbackErrors(done)((hash: string) => {
+                expect(hash).to.be.equal(orderHash);
+                expect(utils.getCurrentUnixTimestampSec()).to.be.bignumber.gte(expirationUnixTimestampSec);
+            });
+            expirationWatcher.subscribe(callbackAsync);
+            timer.tick(orderLifetimeSec * 1000);
+        })().catch(done);
+    });
+    it("doesn't emit events before order expires", (done: DoneCallback) => {
+        (async () => {
+            const orderLifetimeSec = 60;
+            const expirationUnixTimestampSec = currentUnixTimestampSec.plus(orderLifetimeSec);
+            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                makerTokenAddress,
+                takerTokenAddress,
+                makerAddress,
+                takerAddress,
+                fillableAmount,
+                expirationUnixTimestampSec,
+            );
+            const orderHash = ZeroEx.getOrderHashHex(signedOrder);
+            expirationWatcher.addOrder(orderHash, signedOrder.expirationUnixTimestampSec.times(1000));
+            const callbackAsync = reportNoErrorCallbackErrors(done)(async (hash: string) => {
+                done(new Error('Emitted expiration went before the order actually expired'));
+            });
+            expirationWatcher.subscribe(callbackAsync);
+            const notEnoughTime = orderLifetimeSec - 1;
+            timer.tick(notEnoughTime * 1000);
+            done();
+        })().catch(done);
+    });
+    it('emits events in correct order', (done: DoneCallback) => {
+        (async () => {
+            const order1Lifetime = 60;
+            const order2Lifetime = 120;
+            const order1ExpirationUnixTimestampSec = currentUnixTimestampSec.plus(order1Lifetime);
+            const order2ExpirationUnixTimestampSec = currentUnixTimestampSec.plus(order2Lifetime);
+            const signedOrder1 = await fillScenarios.createFillableSignedOrderAsync(
+                makerTokenAddress,
+                takerTokenAddress,
+                makerAddress,
+                takerAddress,
+                fillableAmount,
+                order1ExpirationUnixTimestampSec,
+            );
+            const signedOrder2 = await fillScenarios.createFillableSignedOrderAsync(
+                makerTokenAddress,
+                takerTokenAddress,
+                makerAddress,
+                takerAddress,
+                fillableAmount,
+                order2ExpirationUnixTimestampSec,
+            );
+            const orderHash1 = ZeroEx.getOrderHashHex(signedOrder1);
+            const orderHash2 = ZeroEx.getOrderHashHex(signedOrder2);
+            expirationWatcher.addOrder(orderHash2, signedOrder2.expirationUnixTimestampSec.times(1000));
+            expirationWatcher.addOrder(orderHash1, signedOrder1.expirationUnixTimestampSec.times(1000));
+            const expirationOrder = [orderHash1, orderHash2];
+            const expectToBeCalledOnce = false;
+            const callbackAsync = reportNoErrorCallbackErrors(done, expectToBeCalledOnce)((hash: string) => {
+                const orderHash = expirationOrder.shift();
+                expect(hash).to.be.equal(orderHash);
+                if (_.isEmpty(expirationOrder)) {
+                    done();
+                }
+            });
+            expirationWatcher.subscribe(callbackAsync);
+            timer.tick(order2Lifetime * 1000);
+        })().catch(done);
+    });
 });
diff --git a/packages/0x.js/test/order_state_watcher_test.ts b/packages/0x.js/test/order_state_watcher_test.ts
index 22ed80446..2e9202fe2 100644
--- a/packages/0x.js/test/order_state_watcher_test.ts
+++ b/packages/0x.js/test/order_state_watcher_test.ts
@@ -6,14 +6,14 @@ import 'mocha';
 import * as Web3 from 'web3';
 
 import {
-	ExchangeContractErrs,
-	OrderState,
-	OrderStateInvalid,
-	OrderStateValid,
-	SignedOrder,
-	Token,
-	ZeroEx,
-	ZeroExError,
+    ExchangeContractErrs,
+    OrderState,
+    OrderStateInvalid,
+    OrderStateValid,
+    SignedOrder,
+    Token,
+    ZeroEx,
+    ZeroExError,
 } from '../src';
 import { DoneCallback } from '../src/types';
 
@@ -31,528 +31,528 @@ const expect = chai.expect;
 const blockchainLifecycle = new BlockchainLifecycle(constants.RPC_URL);
 
 describe('OrderStateWatcher', () => {
-	let web3: Web3;
-	let zeroEx: ZeroEx;
-	let tokens: Token[];
-	let tokenUtils: TokenUtils;
-	let fillScenarios: FillScenarios;
-	let userAddresses: string[];
-	let zrxTokenAddress: string;
-	let exchangeContractAddress: string;
-	let makerToken: Token;
-	let takerToken: Token;
-	let maker: string;
-	let taker: string;
-	let signedOrder: SignedOrder;
-	const config = {
-		networkId: constants.TESTRPC_NETWORK_ID,
-	};
-	const decimals = constants.ZRX_DECIMALS;
-	const fillableAmount = ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals);
-	before(async () => {
-		web3 = web3Factory.create();
-		zeroEx = new ZeroEx(web3.currentProvider, config);
-		exchangeContractAddress = zeroEx.exchange.getContractAddress();
-		userAddresses = await zeroEx.getAvailableAddressesAsync();
-		[, maker, taker] = userAddresses;
-		tokens = await zeroEx.tokenRegistry.getTokensAsync();
-		tokenUtils = new TokenUtils(tokens);
-		zrxTokenAddress = tokenUtils.getProtocolTokenOrThrow().address;
-		fillScenarios = new FillScenarios(zeroEx, userAddresses, tokens, zrxTokenAddress, exchangeContractAddress);
-		await fillScenarios.initTokenBalancesAsync();
-		[makerToken, takerToken] = tokenUtils.getDummyTokens();
-	});
-	beforeEach(async () => {
-		await blockchainLifecycle.startAsync();
-	});
-	afterEach(async () => {
-		await blockchainLifecycle.revertAsync();
-	});
-	describe('#removeOrder', async () => {
-		it('should successfully remove existing order', async () => {
-			signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-				makerToken.address,
-				takerToken.address,
-				maker,
-				taker,
-				fillableAmount,
-			);
-			const orderHash = ZeroEx.getOrderHashHex(signedOrder);
-			zeroEx.orderStateWatcher.addOrder(signedOrder);
-			expect((zeroEx.orderStateWatcher as any)._orderByOrderHash).to.include({
-				[orderHash]: signedOrder,
-			});
-			let dependentOrderHashes = (zeroEx.orderStateWatcher as any)._dependentOrderHashes;
-			expect(dependentOrderHashes[signedOrder.maker][signedOrder.makerTokenAddress]).to.have.keys(orderHash);
-			zeroEx.orderStateWatcher.removeOrder(orderHash);
-			expect((zeroEx.orderStateWatcher as any)._orderByOrderHash).to.not.include({
-				[orderHash]: signedOrder,
-			});
-			dependentOrderHashes = (zeroEx.orderStateWatcher as any)._dependentOrderHashes;
-			expect(dependentOrderHashes[signedOrder.maker]).to.be.undefined();
-		});
-		it('should no-op when removing a non-existing order', async () => {
-			signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-				makerToken.address,
-				takerToken.address,
-				maker,
-				taker,
-				fillableAmount,
-			);
-			const orderHash = ZeroEx.getOrderHashHex(signedOrder);
-			const nonExistentOrderHash = `0x${orderHash
-				.substr(2)
-				.split('')
-				.reverse()
-				.join('')}`;
-			zeroEx.orderStateWatcher.removeOrder(nonExistentOrderHash);
-		});
-	});
-	describe('#subscribe', async () => {
-		afterEach(async () => {
-			zeroEx.orderStateWatcher.unsubscribe();
-		});
-		it('should fail when trying to subscribe twice', async () => {
-			zeroEx.orderStateWatcher.subscribe(_.noop);
-			expect(() => zeroEx.orderStateWatcher.subscribe(_.noop)).to.throw(ZeroExError.SubscriptionAlreadyPresent);
-		});
-	});
-	describe('tests with cleanup', async () => {
-		afterEach(async () => {
-			zeroEx.orderStateWatcher.unsubscribe();
-			const orderHash = ZeroEx.getOrderHashHex(signedOrder);
-			zeroEx.orderStateWatcher.removeOrder(orderHash);
-		});
-		it('should emit orderStateInvalid when maker allowance set to 0 for watched order', (done: DoneCallback) => {
-			(async () => {
-				signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-					makerToken.address,
-					takerToken.address,
-					maker,
-					taker,
-					fillableAmount,
-				);
-				const orderHash = ZeroEx.getOrderHashHex(signedOrder);
-				zeroEx.orderStateWatcher.addOrder(signedOrder);
-				const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
-					expect(orderState.isValid).to.be.false();
-					const invalidOrderState = orderState as OrderStateInvalid;
-					expect(invalidOrderState.orderHash).to.be.equal(orderHash);
-					expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.InsufficientMakerAllowance);
-				});
-				zeroEx.orderStateWatcher.subscribe(callback);
-				await zeroEx.token.setProxyAllowanceAsync(makerToken.address, maker, new BigNumber(0));
-			})().catch(done);
-		});
-		it('should not emit an orderState event when irrelevant Transfer event received', (done: DoneCallback) => {
-			(async () => {
-				signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-					makerToken.address,
-					takerToken.address,
-					maker,
-					taker,
-					fillableAmount,
-				);
-				zeroEx.orderStateWatcher.addOrder(signedOrder);
-				const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
-					throw new Error('OrderState callback fired for irrelevant order');
-				});
-				zeroEx.orderStateWatcher.subscribe(callback);
-				const notTheMaker = userAddresses[0];
-				const anyRecipient = taker;
-				const transferAmount = new BigNumber(2);
-				await zeroEx.token.transferAsync(makerToken.address, notTheMaker, anyRecipient, transferAmount);
-				setTimeout(() => {
-					done();
-				}, TIMEOUT_MS);
-			})().catch(done);
-		});
-		it('should emit orderStateInvalid when maker moves balance backing watched order', (done: DoneCallback) => {
-			(async () => {
-				signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-					makerToken.address,
-					takerToken.address,
-					maker,
-					taker,
-					fillableAmount,
-				);
-				const orderHash = ZeroEx.getOrderHashHex(signedOrder);
-				zeroEx.orderStateWatcher.addOrder(signedOrder);
-				const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
-					expect(orderState.isValid).to.be.false();
-					const invalidOrderState = orderState as OrderStateInvalid;
-					expect(invalidOrderState.orderHash).to.be.equal(orderHash);
-					expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.InsufficientMakerBalance);
-				});
-				zeroEx.orderStateWatcher.subscribe(callback);
-				const anyRecipient = taker;
-				const makerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, maker);
-				await zeroEx.token.transferAsync(makerToken.address, maker, anyRecipient, makerBalance);
-			})().catch(done);
-		});
-		it('should emit orderStateInvalid when watched order fully filled', (done: DoneCallback) => {
-			(async () => {
-				signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-					makerToken.address,
-					takerToken.address,
-					maker,
-					taker,
-					fillableAmount,
-				);
-				const orderHash = ZeroEx.getOrderHashHex(signedOrder);
-				zeroEx.orderStateWatcher.addOrder(signedOrder);
+    let web3: Web3;
+    let zeroEx: ZeroEx;
+    let tokens: Token[];
+    let tokenUtils: TokenUtils;
+    let fillScenarios: FillScenarios;
+    let userAddresses: string[];
+    let zrxTokenAddress: string;
+    let exchangeContractAddress: string;
+    let makerToken: Token;
+    let takerToken: Token;
+    let maker: string;
+    let taker: string;
+    let signedOrder: SignedOrder;
+    const config = {
+        networkId: constants.TESTRPC_NETWORK_ID,
+    };
+    const decimals = constants.ZRX_DECIMALS;
+    const fillableAmount = ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals);
+    before(async () => {
+        web3 = web3Factory.create();
+        zeroEx = new ZeroEx(web3.currentProvider, config);
+        exchangeContractAddress = zeroEx.exchange.getContractAddress();
+        userAddresses = await zeroEx.getAvailableAddressesAsync();
+        [, maker, taker] = userAddresses;
+        tokens = await zeroEx.tokenRegistry.getTokensAsync();
+        tokenUtils = new TokenUtils(tokens);
+        zrxTokenAddress = tokenUtils.getProtocolTokenOrThrow().address;
+        fillScenarios = new FillScenarios(zeroEx, userAddresses, tokens, zrxTokenAddress, exchangeContractAddress);
+        await fillScenarios.initTokenBalancesAsync();
+        [makerToken, takerToken] = tokenUtils.getDummyTokens();
+    });
+    beforeEach(async () => {
+        await blockchainLifecycle.startAsync();
+    });
+    afterEach(async () => {
+        await blockchainLifecycle.revertAsync();
+    });
+    describe('#removeOrder', async () => {
+        it('should successfully remove existing order', async () => {
+            signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                makerToken.address,
+                takerToken.address,
+                maker,
+                taker,
+                fillableAmount,
+            );
+            const orderHash = ZeroEx.getOrderHashHex(signedOrder);
+            zeroEx.orderStateWatcher.addOrder(signedOrder);
+            expect((zeroEx.orderStateWatcher as any)._orderByOrderHash).to.include({
+                [orderHash]: signedOrder,
+            });
+            let dependentOrderHashes = (zeroEx.orderStateWatcher as any)._dependentOrderHashes;
+            expect(dependentOrderHashes[signedOrder.maker][signedOrder.makerTokenAddress]).to.have.keys(orderHash);
+            zeroEx.orderStateWatcher.removeOrder(orderHash);
+            expect((zeroEx.orderStateWatcher as any)._orderByOrderHash).to.not.include({
+                [orderHash]: signedOrder,
+            });
+            dependentOrderHashes = (zeroEx.orderStateWatcher as any)._dependentOrderHashes;
+            expect(dependentOrderHashes[signedOrder.maker]).to.be.undefined();
+        });
+        it('should no-op when removing a non-existing order', async () => {
+            signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                makerToken.address,
+                takerToken.address,
+                maker,
+                taker,
+                fillableAmount,
+            );
+            const orderHash = ZeroEx.getOrderHashHex(signedOrder);
+            const nonExistentOrderHash = `0x${orderHash
+                .substr(2)
+                .split('')
+                .reverse()
+                .join('')}`;
+            zeroEx.orderStateWatcher.removeOrder(nonExistentOrderHash);
+        });
+    });
+    describe('#subscribe', async () => {
+        afterEach(async () => {
+            zeroEx.orderStateWatcher.unsubscribe();
+        });
+        it('should fail when trying to subscribe twice', async () => {
+            zeroEx.orderStateWatcher.subscribe(_.noop);
+            expect(() => zeroEx.orderStateWatcher.subscribe(_.noop)).to.throw(ZeroExError.SubscriptionAlreadyPresent);
+        });
+    });
+    describe('tests with cleanup', async () => {
+        afterEach(async () => {
+            zeroEx.orderStateWatcher.unsubscribe();
+            const orderHash = ZeroEx.getOrderHashHex(signedOrder);
+            zeroEx.orderStateWatcher.removeOrder(orderHash);
+        });
+        it('should emit orderStateInvalid when maker allowance set to 0 for watched order', (done: DoneCallback) => {
+            (async () => {
+                signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                    makerToken.address,
+                    takerToken.address,
+                    maker,
+                    taker,
+                    fillableAmount,
+                );
+                const orderHash = ZeroEx.getOrderHashHex(signedOrder);
+                zeroEx.orderStateWatcher.addOrder(signedOrder);
+                const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
+                    expect(orderState.isValid).to.be.false();
+                    const invalidOrderState = orderState as OrderStateInvalid;
+                    expect(invalidOrderState.orderHash).to.be.equal(orderHash);
+                    expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.InsufficientMakerAllowance);
+                });
+                zeroEx.orderStateWatcher.subscribe(callback);
+                await zeroEx.token.setProxyAllowanceAsync(makerToken.address, maker, new BigNumber(0));
+            })().catch(done);
+        });
+        it('should not emit an orderState event when irrelevant Transfer event received', (done: DoneCallback) => {
+            (async () => {
+                signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                    makerToken.address,
+                    takerToken.address,
+                    maker,
+                    taker,
+                    fillableAmount,
+                );
+                zeroEx.orderStateWatcher.addOrder(signedOrder);
+                const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
+                    throw new Error('OrderState callback fired for irrelevant order');
+                });
+                zeroEx.orderStateWatcher.subscribe(callback);
+                const notTheMaker = userAddresses[0];
+                const anyRecipient = taker;
+                const transferAmount = new BigNumber(2);
+                await zeroEx.token.transferAsync(makerToken.address, notTheMaker, anyRecipient, transferAmount);
+                setTimeout(() => {
+                    done();
+                }, TIMEOUT_MS);
+            })().catch(done);
+        });
+        it('should emit orderStateInvalid when maker moves balance backing watched order', (done: DoneCallback) => {
+            (async () => {
+                signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                    makerToken.address,
+                    takerToken.address,
+                    maker,
+                    taker,
+                    fillableAmount,
+                );
+                const orderHash = ZeroEx.getOrderHashHex(signedOrder);
+                zeroEx.orderStateWatcher.addOrder(signedOrder);
+                const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
+                    expect(orderState.isValid).to.be.false();
+                    const invalidOrderState = orderState as OrderStateInvalid;
+                    expect(invalidOrderState.orderHash).to.be.equal(orderHash);
+                    expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.InsufficientMakerBalance);
+                });
+                zeroEx.orderStateWatcher.subscribe(callback);
+                const anyRecipient = taker;
+                const makerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, maker);
+                await zeroEx.token.transferAsync(makerToken.address, maker, anyRecipient, makerBalance);
+            })().catch(done);
+        });
+        it('should emit orderStateInvalid when watched order fully filled', (done: DoneCallback) => {
+            (async () => {
+                signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                    makerToken.address,
+                    takerToken.address,
+                    maker,
+                    taker,
+                    fillableAmount,
+                );
+                const orderHash = ZeroEx.getOrderHashHex(signedOrder);
+                zeroEx.orderStateWatcher.addOrder(signedOrder);
 
-				const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
-					expect(orderState.isValid).to.be.false();
-					const invalidOrderState = orderState as OrderStateInvalid;
-					expect(invalidOrderState.orderHash).to.be.equal(orderHash);
-					expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.OrderRemainingFillAmountZero);
-				});
-				zeroEx.orderStateWatcher.subscribe(callback);
+                const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
+                    expect(orderState.isValid).to.be.false();
+                    const invalidOrderState = orderState as OrderStateInvalid;
+                    expect(invalidOrderState.orderHash).to.be.equal(orderHash);
+                    expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.OrderRemainingFillAmountZero);
+                });
+                zeroEx.orderStateWatcher.subscribe(callback);
 
-				const shouldThrowOnInsufficientBalanceOrAllowance = true;
-				await zeroEx.exchange.fillOrderAsync(
-					signedOrder,
-					fillableAmount,
-					shouldThrowOnInsufficientBalanceOrAllowance,
-					taker,
-				);
-			})().catch(done);
-		});
-		it('should emit orderStateValid when watched order partially filled', (done: DoneCallback) => {
-			(async () => {
-				signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-					makerToken.address,
-					takerToken.address,
-					maker,
-					taker,
-					fillableAmount,
-				);
+                const shouldThrowOnInsufficientBalanceOrAllowance = true;
+                await zeroEx.exchange.fillOrderAsync(
+                    signedOrder,
+                    fillableAmount,
+                    shouldThrowOnInsufficientBalanceOrAllowance,
+                    taker,
+                );
+            })().catch(done);
+        });
+        it('should emit orderStateValid when watched order partially filled', (done: DoneCallback) => {
+            (async () => {
+                signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                    makerToken.address,
+                    takerToken.address,
+                    maker,
+                    taker,
+                    fillableAmount,
+                );
 
-				const makerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, maker);
-				const fillAmountInBaseUnits = new BigNumber(2);
-				const orderHash = ZeroEx.getOrderHashHex(signedOrder);
-				zeroEx.orderStateWatcher.addOrder(signedOrder);
+                const makerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, maker);
+                const fillAmountInBaseUnits = new BigNumber(2);
+                const orderHash = ZeroEx.getOrderHashHex(signedOrder);
+                zeroEx.orderStateWatcher.addOrder(signedOrder);
 
-				const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
-					expect(orderState.isValid).to.be.true();
-					const validOrderState = orderState as OrderStateValid;
-					expect(validOrderState.orderHash).to.be.equal(orderHash);
-					const orderRelevantState = validOrderState.orderRelevantState;
-					const remainingMakerBalance = makerBalance.sub(fillAmountInBaseUnits);
-					const remainingFillable = fillableAmount.minus(fillAmountInBaseUnits);
-					expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
-						remainingFillable,
-					);
-					expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal(
-						remainingFillable,
-					);
-					expect(orderRelevantState.makerBalance).to.be.bignumber.equal(remainingMakerBalance);
-				});
-				zeroEx.orderStateWatcher.subscribe(callback);
-				const shouldThrowOnInsufficientBalanceOrAllowance = true;
-				await zeroEx.exchange.fillOrderAsync(
-					signedOrder,
-					fillAmountInBaseUnits,
-					shouldThrowOnInsufficientBalanceOrAllowance,
-					taker,
-				);
-			})().catch(done);
-		});
-		it('should trigger the callback when orders backing ZRX allowance changes', (done: DoneCallback) => {
-			(async () => {
-				const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(2), 18);
-				const takerFee = ZeroEx.toBaseUnitAmount(new BigNumber(0), 18);
-				signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
-					makerToken.address,
-					takerToken.address,
-					makerFee,
-					takerFee,
-					maker,
-					taker,
-					fillableAmount,
-					taker,
-				);
-				const callback = reportNodeCallbackErrors(done)();
-				zeroEx.orderStateWatcher.addOrder(signedOrder);
-				zeroEx.orderStateWatcher.subscribe(callback);
-				await zeroEx.token.setProxyAllowanceAsync(zrxTokenAddress, maker, new BigNumber(0));
-			})().catch(done);
-		});
-		describe('remainingFillable(M|T)akerTokenAmount', () => {
-			it('should calculate correct remaining fillable', (done: DoneCallback) => {
-				(async () => {
-					const takerFillableAmount = ZeroEx.toBaseUnitAmount(new BigNumber(10), decimals);
-					const makerFillableAmount = ZeroEx.toBaseUnitAmount(new BigNumber(20), decimals);
-					signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
-						makerToken.address,
-						takerToken.address,
-						maker,
-						taker,
-						makerFillableAmount,
-						takerFillableAmount,
-					);
-					const fillAmountInBaseUnits = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
-					const orderHash = ZeroEx.getOrderHashHex(signedOrder);
-					zeroEx.orderStateWatcher.addOrder(signedOrder);
-					const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
-						expect(orderState.isValid).to.be.true();
-						const validOrderState = orderState as OrderStateValid;
-						expect(validOrderState.orderHash).to.be.equal(orderHash);
-						const orderRelevantState = validOrderState.orderRelevantState;
-						expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
-							ZeroEx.toBaseUnitAmount(new BigNumber(16), decimals),
-						);
-						expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal(
-							ZeroEx.toBaseUnitAmount(new BigNumber(8), decimals),
-						);
-					});
-					zeroEx.orderStateWatcher.subscribe(callback);
-					const shouldThrowOnInsufficientBalanceOrAllowance = true;
-					await zeroEx.exchange.fillOrderAsync(
-						signedOrder,
-						fillAmountInBaseUnits,
-						shouldThrowOnInsufficientBalanceOrAllowance,
-						taker,
-					);
-				})().catch(done);
-			});
-			it('should equal approved amount when approved amount is lowest', (done: DoneCallback) => {
-				(async () => {
-					signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-						makerToken.address,
-						takerToken.address,
-						maker,
-						taker,
-						fillableAmount,
-					);
+                const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
+                    expect(orderState.isValid).to.be.true();
+                    const validOrderState = orderState as OrderStateValid;
+                    expect(validOrderState.orderHash).to.be.equal(orderHash);
+                    const orderRelevantState = validOrderState.orderRelevantState;
+                    const remainingMakerBalance = makerBalance.sub(fillAmountInBaseUnits);
+                    const remainingFillable = fillableAmount.minus(fillAmountInBaseUnits);
+                    expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
+                        remainingFillable,
+                    );
+                    expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal(
+                        remainingFillable,
+                    );
+                    expect(orderRelevantState.makerBalance).to.be.bignumber.equal(remainingMakerBalance);
+                });
+                zeroEx.orderStateWatcher.subscribe(callback);
+                const shouldThrowOnInsufficientBalanceOrAllowance = true;
+                await zeroEx.exchange.fillOrderAsync(
+                    signedOrder,
+                    fillAmountInBaseUnits,
+                    shouldThrowOnInsufficientBalanceOrAllowance,
+                    taker,
+                );
+            })().catch(done);
+        });
+        it('should trigger the callback when orders backing ZRX allowance changes', (done: DoneCallback) => {
+            (async () => {
+                const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(2), 18);
+                const takerFee = ZeroEx.toBaseUnitAmount(new BigNumber(0), 18);
+                signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
+                    makerToken.address,
+                    takerToken.address,
+                    makerFee,
+                    takerFee,
+                    maker,
+                    taker,
+                    fillableAmount,
+                    taker,
+                );
+                const callback = reportNodeCallbackErrors(done)();
+                zeroEx.orderStateWatcher.addOrder(signedOrder);
+                zeroEx.orderStateWatcher.subscribe(callback);
+                await zeroEx.token.setProxyAllowanceAsync(zrxTokenAddress, maker, new BigNumber(0));
+            })().catch(done);
+        });
+        describe('remainingFillable(M|T)akerTokenAmount', () => {
+            it('should calculate correct remaining fillable', (done: DoneCallback) => {
+                (async () => {
+                    const takerFillableAmount = ZeroEx.toBaseUnitAmount(new BigNumber(10), decimals);
+                    const makerFillableAmount = ZeroEx.toBaseUnitAmount(new BigNumber(20), decimals);
+                    signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
+                        makerToken.address,
+                        takerToken.address,
+                        maker,
+                        taker,
+                        makerFillableAmount,
+                        takerFillableAmount,
+                    );
+                    const fillAmountInBaseUnits = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
+                    const orderHash = ZeroEx.getOrderHashHex(signedOrder);
+                    zeroEx.orderStateWatcher.addOrder(signedOrder);
+                    const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
+                        expect(orderState.isValid).to.be.true();
+                        const validOrderState = orderState as OrderStateValid;
+                        expect(validOrderState.orderHash).to.be.equal(orderHash);
+                        const orderRelevantState = validOrderState.orderRelevantState;
+                        expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
+                            ZeroEx.toBaseUnitAmount(new BigNumber(16), decimals),
+                        );
+                        expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal(
+                            ZeroEx.toBaseUnitAmount(new BigNumber(8), decimals),
+                        );
+                    });
+                    zeroEx.orderStateWatcher.subscribe(callback);
+                    const shouldThrowOnInsufficientBalanceOrAllowance = true;
+                    await zeroEx.exchange.fillOrderAsync(
+                        signedOrder,
+                        fillAmountInBaseUnits,
+                        shouldThrowOnInsufficientBalanceOrAllowance,
+                        taker,
+                    );
+                })().catch(done);
+            });
+            it('should equal approved amount when approved amount is lowest', (done: DoneCallback) => {
+                (async () => {
+                    signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                        makerToken.address,
+                        takerToken.address,
+                        maker,
+                        taker,
+                        fillableAmount,
+                    );
 
-					const changedMakerApprovalAmount = ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals);
-					zeroEx.orderStateWatcher.addOrder(signedOrder);
+                    const changedMakerApprovalAmount = ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals);
+                    zeroEx.orderStateWatcher.addOrder(signedOrder);
 
-					const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
-						const validOrderState = orderState as OrderStateValid;
-						const orderRelevantState = validOrderState.orderRelevantState;
-						expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
-							changedMakerApprovalAmount,
-						);
-						expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal(
-							changedMakerApprovalAmount,
-						);
-					});
-					zeroEx.orderStateWatcher.subscribe(callback);
-					await zeroEx.token.setProxyAllowanceAsync(makerToken.address, maker, changedMakerApprovalAmount);
-				})().catch(done);
-			});
-			it('should equal balance amount when balance amount is lowest', (done: DoneCallback) => {
-				(async () => {
-					signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-						makerToken.address,
-						takerToken.address,
-						maker,
-						taker,
-						fillableAmount,
-					);
+                    const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
+                        const validOrderState = orderState as OrderStateValid;
+                        const orderRelevantState = validOrderState.orderRelevantState;
+                        expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
+                            changedMakerApprovalAmount,
+                        );
+                        expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal(
+                            changedMakerApprovalAmount,
+                        );
+                    });
+                    zeroEx.orderStateWatcher.subscribe(callback);
+                    await zeroEx.token.setProxyAllowanceAsync(makerToken.address, maker, changedMakerApprovalAmount);
+                })().catch(done);
+            });
+            it('should equal balance amount when balance amount is lowest', (done: DoneCallback) => {
+                (async () => {
+                    signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                        makerToken.address,
+                        takerToken.address,
+                        maker,
+                        taker,
+                        fillableAmount,
+                    );
 
-					const makerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, maker);
+                    const makerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, maker);
 
-					const remainingAmount = ZeroEx.toBaseUnitAmount(new BigNumber(1), decimals);
-					const transferAmount = makerBalance.sub(remainingAmount);
-					zeroEx.orderStateWatcher.addOrder(signedOrder);
+                    const remainingAmount = ZeroEx.toBaseUnitAmount(new BigNumber(1), decimals);
+                    const transferAmount = makerBalance.sub(remainingAmount);
+                    zeroEx.orderStateWatcher.addOrder(signedOrder);
 
-					const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
-						expect(orderState.isValid).to.be.true();
-						const validOrderState = orderState as OrderStateValid;
-						const orderRelevantState = validOrderState.orderRelevantState;
-						expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
-							remainingAmount,
-						);
-						expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal(
-							remainingAmount,
-						);
-					});
-					zeroEx.orderStateWatcher.subscribe(callback);
-					await zeroEx.token.transferAsync(makerToken.address, maker, ZeroEx.NULL_ADDRESS, transferAmount);
-				})().catch(done);
-			});
-			it('should equal remaining amount when partially cancelled and order has fees', (done: DoneCallback) => {
-				(async () => {
-					const takerFee = ZeroEx.toBaseUnitAmount(new BigNumber(0), decimals);
-					const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals);
-					const feeRecipient = taker;
-					signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
-						makerToken.address,
-						takerToken.address,
-						makerFee,
-						takerFee,
-						maker,
-						taker,
-						fillableAmount,
-						feeRecipient,
-					);
+                    const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
+                        expect(orderState.isValid).to.be.true();
+                        const validOrderState = orderState as OrderStateValid;
+                        const orderRelevantState = validOrderState.orderRelevantState;
+                        expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
+                            remainingAmount,
+                        );
+                        expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal(
+                            remainingAmount,
+                        );
+                    });
+                    zeroEx.orderStateWatcher.subscribe(callback);
+                    await zeroEx.token.transferAsync(makerToken.address, maker, ZeroEx.NULL_ADDRESS, transferAmount);
+                })().catch(done);
+            });
+            it('should equal remaining amount when partially cancelled and order has fees', (done: DoneCallback) => {
+                (async () => {
+                    const takerFee = ZeroEx.toBaseUnitAmount(new BigNumber(0), decimals);
+                    const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals);
+                    const feeRecipient = taker;
+                    signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
+                        makerToken.address,
+                        takerToken.address,
+                        makerFee,
+                        takerFee,
+                        maker,
+                        taker,
+                        fillableAmount,
+                        feeRecipient,
+                    );
 
-					const remainingTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(4), decimals);
-					const transferTokenAmount = makerFee.sub(remainingTokenAmount);
-					zeroEx.orderStateWatcher.addOrder(signedOrder);
+                    const remainingTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(4), decimals);
+                    const transferTokenAmount = makerFee.sub(remainingTokenAmount);
+                    zeroEx.orderStateWatcher.addOrder(signedOrder);
 
-					const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
-						expect(orderState.isValid).to.be.true();
-						const validOrderState = orderState as OrderStateValid;
-						const orderRelevantState = validOrderState.orderRelevantState;
-						expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
-							remainingTokenAmount,
-						);
-					});
-					zeroEx.orderStateWatcher.subscribe(callback);
-					await zeroEx.exchange.cancelOrderAsync(signedOrder, transferTokenAmount);
-				})().catch(done);
-			});
-			it('should equal ratio amount when fee balance is lowered', (done: DoneCallback) => {
-				(async () => {
-					const takerFee = ZeroEx.toBaseUnitAmount(new BigNumber(0), decimals);
-					const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals);
-					const feeRecipient = taker;
-					signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
-						makerToken.address,
-						takerToken.address,
-						makerFee,
-						takerFee,
-						maker,
-						taker,
-						fillableAmount,
-						feeRecipient,
-					);
+                    const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
+                        expect(orderState.isValid).to.be.true();
+                        const validOrderState = orderState as OrderStateValid;
+                        const orderRelevantState = validOrderState.orderRelevantState;
+                        expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
+                            remainingTokenAmount,
+                        );
+                    });
+                    zeroEx.orderStateWatcher.subscribe(callback);
+                    await zeroEx.exchange.cancelOrderAsync(signedOrder, transferTokenAmount);
+                })().catch(done);
+            });
+            it('should equal ratio amount when fee balance is lowered', (done: DoneCallback) => {
+                (async () => {
+                    const takerFee = ZeroEx.toBaseUnitAmount(new BigNumber(0), decimals);
+                    const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals);
+                    const feeRecipient = taker;
+                    signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
+                        makerToken.address,
+                        takerToken.address,
+                        makerFee,
+                        takerFee,
+                        maker,
+                        taker,
+                        fillableAmount,
+                        feeRecipient,
+                    );
 
-					const remainingFeeAmount = ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals);
+                    const remainingFeeAmount = ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals);
 
-					const remainingTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(4), decimals);
-					const transferTokenAmount = makerFee.sub(remainingTokenAmount);
-					zeroEx.orderStateWatcher.addOrder(signedOrder);
+                    const remainingTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(4), decimals);
+                    const transferTokenAmount = makerFee.sub(remainingTokenAmount);
+                    zeroEx.orderStateWatcher.addOrder(signedOrder);
 
-					const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
-						const validOrderState = orderState as OrderStateValid;
-						const orderRelevantState = validOrderState.orderRelevantState;
-						expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
-							remainingFeeAmount,
-						);
-					});
-					zeroEx.orderStateWatcher.subscribe(callback);
-					await zeroEx.token.setProxyAllowanceAsync(zrxTokenAddress, maker, remainingFeeAmount);
-					await zeroEx.token.transferAsync(
-						makerToken.address,
-						maker,
-						ZeroEx.NULL_ADDRESS,
-						transferTokenAmount,
-					);
-				})().catch(done);
-			});
-			it('should calculate full amount when all available and non-divisible', (done: DoneCallback) => {
-				(async () => {
-					const takerFee = ZeroEx.toBaseUnitAmount(new BigNumber(0), decimals);
-					const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
-					const feeRecipient = taker;
-					signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
-						makerToken.address,
-						takerToken.address,
-						makerFee,
-						takerFee,
-						maker,
-						taker,
-						fillableAmount,
-						feeRecipient,
-					);
+                    const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
+                        const validOrderState = orderState as OrderStateValid;
+                        const orderRelevantState = validOrderState.orderRelevantState;
+                        expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
+                            remainingFeeAmount,
+                        );
+                    });
+                    zeroEx.orderStateWatcher.subscribe(callback);
+                    await zeroEx.token.setProxyAllowanceAsync(zrxTokenAddress, maker, remainingFeeAmount);
+                    await zeroEx.token.transferAsync(
+                        makerToken.address,
+                        maker,
+                        ZeroEx.NULL_ADDRESS,
+                        transferTokenAmount,
+                    );
+                })().catch(done);
+            });
+            it('should calculate full amount when all available and non-divisible', (done: DoneCallback) => {
+                (async () => {
+                    const takerFee = ZeroEx.toBaseUnitAmount(new BigNumber(0), decimals);
+                    const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
+                    const feeRecipient = taker;
+                    signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
+                        makerToken.address,
+                        takerToken.address,
+                        makerFee,
+                        takerFee,
+                        maker,
+                        taker,
+                        fillableAmount,
+                        feeRecipient,
+                    );
 
-					zeroEx.orderStateWatcher.addOrder(signedOrder);
+                    zeroEx.orderStateWatcher.addOrder(signedOrder);
 
-					const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
-						const validOrderState = orderState as OrderStateValid;
-						const orderRelevantState = validOrderState.orderRelevantState;
-						expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
-							fillableAmount,
-						);
-					});
-					zeroEx.orderStateWatcher.subscribe(callback);
-					await zeroEx.token.setProxyAllowanceAsync(
-						makerToken.address,
-						maker,
-						ZeroEx.toBaseUnitAmount(new BigNumber(100), decimals),
-					);
-				})().catch(done);
-			});
-		});
-		it('should emit orderStateInvalid when watched order cancelled', (done: DoneCallback) => {
-			(async () => {
-				signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-					makerToken.address,
-					takerToken.address,
-					maker,
-					taker,
-					fillableAmount,
-				);
-				const orderHash = ZeroEx.getOrderHashHex(signedOrder);
-				zeroEx.orderStateWatcher.addOrder(signedOrder);
+                    const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
+                        const validOrderState = orderState as OrderStateValid;
+                        const orderRelevantState = validOrderState.orderRelevantState;
+                        expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
+                            fillableAmount,
+                        );
+                    });
+                    zeroEx.orderStateWatcher.subscribe(callback);
+                    await zeroEx.token.setProxyAllowanceAsync(
+                        makerToken.address,
+                        maker,
+                        ZeroEx.toBaseUnitAmount(new BigNumber(100), decimals),
+                    );
+                })().catch(done);
+            });
+        });
+        it('should emit orderStateInvalid when watched order cancelled', (done: DoneCallback) => {
+            (async () => {
+                signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                    makerToken.address,
+                    takerToken.address,
+                    maker,
+                    taker,
+                    fillableAmount,
+                );
+                const orderHash = ZeroEx.getOrderHashHex(signedOrder);
+                zeroEx.orderStateWatcher.addOrder(signedOrder);
 
-				const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
-					expect(orderState.isValid).to.be.false();
-					const invalidOrderState = orderState as OrderStateInvalid;
-					expect(invalidOrderState.orderHash).to.be.equal(orderHash);
-					expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.OrderRemainingFillAmountZero);
-				});
-				zeroEx.orderStateWatcher.subscribe(callback);
+                const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
+                    expect(orderState.isValid).to.be.false();
+                    const invalidOrderState = orderState as OrderStateInvalid;
+                    expect(invalidOrderState.orderHash).to.be.equal(orderHash);
+                    expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.OrderRemainingFillAmountZero);
+                });
+                zeroEx.orderStateWatcher.subscribe(callback);
 
-				await zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount);
-			})().catch(done);
-		});
-		it('should emit orderStateInvalid when within rounding error range', (done: DoneCallback) => {
-			(async () => {
-				const remainingFillableAmountInBaseUnits = new BigNumber(100);
-				signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-					makerToken.address,
-					takerToken.address,
-					maker,
-					taker,
-					fillableAmount,
-				);
-				const orderHash = ZeroEx.getOrderHashHex(signedOrder);
-				zeroEx.orderStateWatcher.addOrder(signedOrder);
+                await zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount);
+            })().catch(done);
+        });
+        it('should emit orderStateInvalid when within rounding error range', (done: DoneCallback) => {
+            (async () => {
+                const remainingFillableAmountInBaseUnits = new BigNumber(100);
+                signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                    makerToken.address,
+                    takerToken.address,
+                    maker,
+                    taker,
+                    fillableAmount,
+                );
+                const orderHash = ZeroEx.getOrderHashHex(signedOrder);
+                zeroEx.orderStateWatcher.addOrder(signedOrder);
 
-				const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
-					expect(orderState.isValid).to.be.false();
-					const invalidOrderState = orderState as OrderStateInvalid;
-					expect(invalidOrderState.orderHash).to.be.equal(orderHash);
-					expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.OrderFillRoundingError);
-				});
-				zeroEx.orderStateWatcher.subscribe(callback);
-				await zeroEx.exchange.cancelOrderAsync(
-					signedOrder,
-					fillableAmount.minus(remainingFillableAmountInBaseUnits),
-				);
-			})().catch(done);
-		});
-		it('should emit orderStateValid when watched order partially cancelled', (done: DoneCallback) => {
-			(async () => {
-				signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-					makerToken.address,
-					takerToken.address,
-					maker,
-					taker,
-					fillableAmount,
-				);
+                const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
+                    expect(orderState.isValid).to.be.false();
+                    const invalidOrderState = orderState as OrderStateInvalid;
+                    expect(invalidOrderState.orderHash).to.be.equal(orderHash);
+                    expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.OrderFillRoundingError);
+                });
+                zeroEx.orderStateWatcher.subscribe(callback);
+                await zeroEx.exchange.cancelOrderAsync(
+                    signedOrder,
+                    fillableAmount.minus(remainingFillableAmountInBaseUnits),
+                );
+            })().catch(done);
+        });
+        it('should emit orderStateValid when watched order partially cancelled', (done: DoneCallback) => {
+            (async () => {
+                signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                    makerToken.address,
+                    takerToken.address,
+                    maker,
+                    taker,
+                    fillableAmount,
+                );
 
-				const cancelAmountInBaseUnits = new BigNumber(2);
-				const orderHash = ZeroEx.getOrderHashHex(signedOrder);
-				zeroEx.orderStateWatcher.addOrder(signedOrder);
+                const cancelAmountInBaseUnits = new BigNumber(2);
+                const orderHash = ZeroEx.getOrderHashHex(signedOrder);
+                zeroEx.orderStateWatcher.addOrder(signedOrder);
 
-				const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
-					expect(orderState.isValid).to.be.true();
-					const validOrderState = orderState as OrderStateValid;
-					expect(validOrderState.orderHash).to.be.equal(orderHash);
-					const orderRelevantState = validOrderState.orderRelevantState;
-					expect(orderRelevantState.cancelledTakerTokenAmount).to.be.bignumber.equal(cancelAmountInBaseUnits);
-				});
-				zeroEx.orderStateWatcher.subscribe(callback);
-				await zeroEx.exchange.cancelOrderAsync(signedOrder, cancelAmountInBaseUnits);
-			})().catch(done);
-		});
-	});
+                const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
+                    expect(orderState.isValid).to.be.true();
+                    const validOrderState = orderState as OrderStateValid;
+                    expect(validOrderState.orderHash).to.be.equal(orderHash);
+                    const orderRelevantState = validOrderState.orderRelevantState;
+                    expect(orderRelevantState.cancelledTakerTokenAmount).to.be.bignumber.equal(cancelAmountInBaseUnits);
+                });
+                zeroEx.orderStateWatcher.subscribe(callback);
+                await zeroEx.exchange.cancelOrderAsync(signedOrder, cancelAmountInBaseUnits);
+            })().catch(done);
+        });
+    });
 }); // tslint:disable:max-file-line-count
diff --git a/packages/0x.js/test/order_validation_test.ts b/packages/0x.js/test/order_validation_test.ts
index 4e023a9cc..be3e0590c 100644
--- a/packages/0x.js/test/order_validation_test.ts
+++ b/packages/0x.js/test/order_validation_test.ts
@@ -20,455 +20,455 @@ const expect = chai.expect;
 const blockchainLifecycle = new BlockchainLifecycle(constants.RPC_URL);
 
 describe('OrderValidation', () => {
-	let web3: Web3;
-	let zeroEx: ZeroEx;
-	let userAddresses: string[];
-	let tokens: Token[];
-	let tokenUtils: TokenUtils;
-	let exchangeContractAddress: string;
-	let zrxTokenAddress: string;
-	let fillScenarios: FillScenarios;
-	let makerTokenAddress: string;
-	let takerTokenAddress: string;
-	let coinbase: string;
-	let makerAddress: string;
-	let takerAddress: string;
-	let feeRecipient: string;
-	const fillableAmount = new BigNumber(5);
-	const fillTakerAmount = new BigNumber(5);
-	const config = {
-		networkId: constants.TESTRPC_NETWORK_ID,
-	};
-	before(async () => {
-		web3 = web3Factory.create();
-		zeroEx = new ZeroEx(web3.currentProvider, config);
-		exchangeContractAddress = zeroEx.exchange.getContractAddress();
-		userAddresses = await zeroEx.getAvailableAddressesAsync();
-		[coinbase, makerAddress, takerAddress, feeRecipient] = userAddresses;
-		tokens = await zeroEx.tokenRegistry.getTokensAsync();
-		tokenUtils = new TokenUtils(tokens);
-		zrxTokenAddress = tokenUtils.getProtocolTokenOrThrow().address;
-		fillScenarios = new FillScenarios(zeroEx, userAddresses, tokens, zrxTokenAddress, exchangeContractAddress);
-		const [makerToken, takerToken] = tokenUtils.getDummyTokens();
-		makerTokenAddress = makerToken.address;
-		takerTokenAddress = takerToken.address;
-	});
-	beforeEach(async () => {
-		await blockchainLifecycle.startAsync();
-	});
-	afterEach(async () => {
-		await blockchainLifecycle.revertAsync();
-	});
-	describe('validateOrderFillableOrThrowAsync', () => {
-		it('should succeed if the order is fillable', async () => {
-			const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-				makerTokenAddress,
-				takerTokenAddress,
-				makerAddress,
-				takerAddress,
-				fillableAmount,
-			);
-			await zeroEx.exchange.validateOrderFillableOrThrowAsync(signedOrder);
-		});
-		it('should succeed if the order is asymmetric and fillable', async () => {
-			const makerFillableAmount = fillableAmount;
-			const takerFillableAmount = fillableAmount.minus(4);
-			const signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
-				makerTokenAddress,
-				takerTokenAddress,
-				makerAddress,
-				takerAddress,
-				makerFillableAmount,
-				takerFillableAmount,
-			);
-			await zeroEx.exchange.validateOrderFillableOrThrowAsync(signedOrder);
-		});
-		it('should throw when the order is fully filled or cancelled', async () => {
-			const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-				makerTokenAddress,
-				takerTokenAddress,
-				makerAddress,
-				takerAddress,
-				fillableAmount,
-			);
-			await zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount);
-			return expect(zeroEx.exchange.validateOrderFillableOrThrowAsync(signedOrder)).to.be.rejectedWith(
-				ExchangeContractErrs.OrderRemainingFillAmountZero,
-			);
-		});
-		it('should throw when order is expired', async () => {
-			const expirationInPast = new BigNumber(1496826058); // 7th Jun 2017
-			const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-				makerTokenAddress,
-				takerTokenAddress,
-				makerAddress,
-				takerAddress,
-				fillableAmount,
-				expirationInPast,
-			);
-			return expect(zeroEx.exchange.validateOrderFillableOrThrowAsync(signedOrder)).to.be.rejectedWith(
-				ExchangeContractErrs.OrderFillExpired,
-			);
-		});
-	});
-	describe('validateFillOrderAndThrowIfInvalidAsync', () => {
-		it('should throw when the fill amount is zero', async () => {
-			const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-				makerTokenAddress,
-				takerTokenAddress,
-				makerAddress,
-				takerAddress,
-				fillableAmount,
-			);
-			const zeroFillAmount = new BigNumber(0);
-			return expect(
-				zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(signedOrder, zeroFillAmount, takerAddress),
-			).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
-		});
-		it('should throw when the signature is invalid', async () => {
-			const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-				makerTokenAddress,
-				takerTokenAddress,
-				makerAddress,
-				takerAddress,
-				fillableAmount,
-			);
-			// 27 <--> 28
-			signedOrder.ecSignature.v = 28 - signedOrder.ecSignature.v + 27;
-			return expect(
-				zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(signedOrder, fillableAmount, takerAddress),
-			).to.be.rejectedWith(ZeroExError.InvalidSignature);
-		});
-		it('should throw when the order is fully filled or cancelled', async () => {
-			const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-				makerTokenAddress,
-				takerTokenAddress,
-				makerAddress,
-				takerAddress,
-				fillableAmount,
-			);
-			await zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount);
-			return expect(
-				zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(signedOrder, fillableAmount, takerAddress),
-			).to.be.rejectedWith(ExchangeContractErrs.OrderRemainingFillAmountZero);
-		});
-		it('should throw when sender is not a taker', async () => {
-			const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-				makerTokenAddress,
-				takerTokenAddress,
-				makerAddress,
-				takerAddress,
-				fillableAmount,
-			);
-			const nonTakerAddress = userAddresses[6];
-			return expect(
-				zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(signedOrder, fillTakerAmount, nonTakerAddress),
-			).to.be.rejectedWith(ExchangeContractErrs.TransactionSenderIsNotFillOrderTaker);
-		});
-		it('should throw when order is expired', async () => {
-			const expirationInPast = new BigNumber(1496826058); // 7th Jun 2017
-			const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-				makerTokenAddress,
-				takerTokenAddress,
-				makerAddress,
-				takerAddress,
-				fillableAmount,
-				expirationInPast,
-			);
-			return expect(
-				zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(signedOrder, fillTakerAmount, takerAddress),
-			).to.be.rejectedWith(ExchangeContractErrs.OrderFillExpired);
-		});
-		it('should throw when there a rounding error would have occurred', async () => {
-			const makerAmount = new BigNumber(3);
-			const takerAmount = new BigNumber(5);
-			const signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
-				makerTokenAddress,
-				takerTokenAddress,
-				makerAddress,
-				takerAddress,
-				makerAmount,
-				takerAmount,
-			);
-			const fillTakerAmountThatCausesRoundingError = new BigNumber(3);
-			return expect(
-				zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(
-					signedOrder,
-					fillTakerAmountThatCausesRoundingError,
-					takerAddress,
-				),
-			).to.be.rejectedWith(ExchangeContractErrs.OrderFillRoundingError);
-		});
-	});
-	describe('#validateFillOrKillOrderAndThrowIfInvalidAsync', () => {
-		it('should throw if remaining fillAmount is less then the desired fillAmount', async () => {
-			const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-				makerTokenAddress,
-				takerTokenAddress,
-				makerAddress,
-				takerAddress,
-				fillableAmount,
-			);
-			const tooLargeFillAmount = new BigNumber(7);
-			const fillAmountDifference = tooLargeFillAmount.minus(fillableAmount);
-			await zeroEx.token.transferAsync(takerTokenAddress, coinbase, takerAddress, fillAmountDifference);
-			await zeroEx.token.setProxyAllowanceAsync(takerTokenAddress, takerAddress, tooLargeFillAmount);
-			await zeroEx.token.transferAsync(makerTokenAddress, coinbase, makerAddress, fillAmountDifference);
-			await zeroEx.token.setProxyAllowanceAsync(makerTokenAddress, makerAddress, tooLargeFillAmount);
+    let web3: Web3;
+    let zeroEx: ZeroEx;
+    let userAddresses: string[];
+    let tokens: Token[];
+    let tokenUtils: TokenUtils;
+    let exchangeContractAddress: string;
+    let zrxTokenAddress: string;
+    let fillScenarios: FillScenarios;
+    let makerTokenAddress: string;
+    let takerTokenAddress: string;
+    let coinbase: string;
+    let makerAddress: string;
+    let takerAddress: string;
+    let feeRecipient: string;
+    const fillableAmount = new BigNumber(5);
+    const fillTakerAmount = new BigNumber(5);
+    const config = {
+        networkId: constants.TESTRPC_NETWORK_ID,
+    };
+    before(async () => {
+        web3 = web3Factory.create();
+        zeroEx = new ZeroEx(web3.currentProvider, config);
+        exchangeContractAddress = zeroEx.exchange.getContractAddress();
+        userAddresses = await zeroEx.getAvailableAddressesAsync();
+        [coinbase, makerAddress, takerAddress, feeRecipient] = userAddresses;
+        tokens = await zeroEx.tokenRegistry.getTokensAsync();
+        tokenUtils = new TokenUtils(tokens);
+        zrxTokenAddress = tokenUtils.getProtocolTokenOrThrow().address;
+        fillScenarios = new FillScenarios(zeroEx, userAddresses, tokens, zrxTokenAddress, exchangeContractAddress);
+        const [makerToken, takerToken] = tokenUtils.getDummyTokens();
+        makerTokenAddress = makerToken.address;
+        takerTokenAddress = takerToken.address;
+    });
+    beforeEach(async () => {
+        await blockchainLifecycle.startAsync();
+    });
+    afterEach(async () => {
+        await blockchainLifecycle.revertAsync();
+    });
+    describe('validateOrderFillableOrThrowAsync', () => {
+        it('should succeed if the order is fillable', async () => {
+            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                makerTokenAddress,
+                takerTokenAddress,
+                makerAddress,
+                takerAddress,
+                fillableAmount,
+            );
+            await zeroEx.exchange.validateOrderFillableOrThrowAsync(signedOrder);
+        });
+        it('should succeed if the order is asymmetric and fillable', async () => {
+            const makerFillableAmount = fillableAmount;
+            const takerFillableAmount = fillableAmount.minus(4);
+            const signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
+                makerTokenAddress,
+                takerTokenAddress,
+                makerAddress,
+                takerAddress,
+                makerFillableAmount,
+                takerFillableAmount,
+            );
+            await zeroEx.exchange.validateOrderFillableOrThrowAsync(signedOrder);
+        });
+        it('should throw when the order is fully filled or cancelled', async () => {
+            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                makerTokenAddress,
+                takerTokenAddress,
+                makerAddress,
+                takerAddress,
+                fillableAmount,
+            );
+            await zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount);
+            return expect(zeroEx.exchange.validateOrderFillableOrThrowAsync(signedOrder)).to.be.rejectedWith(
+                ExchangeContractErrs.OrderRemainingFillAmountZero,
+            );
+        });
+        it('should throw when order is expired', async () => {
+            const expirationInPast = new BigNumber(1496826058); // 7th Jun 2017
+            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                makerTokenAddress,
+                takerTokenAddress,
+                makerAddress,
+                takerAddress,
+                fillableAmount,
+                expirationInPast,
+            );
+            return expect(zeroEx.exchange.validateOrderFillableOrThrowAsync(signedOrder)).to.be.rejectedWith(
+                ExchangeContractErrs.OrderFillExpired,
+            );
+        });
+    });
+    describe('validateFillOrderAndThrowIfInvalidAsync', () => {
+        it('should throw when the fill amount is zero', async () => {
+            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                makerTokenAddress,
+                takerTokenAddress,
+                makerAddress,
+                takerAddress,
+                fillableAmount,
+            );
+            const zeroFillAmount = new BigNumber(0);
+            return expect(
+                zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(signedOrder, zeroFillAmount, takerAddress),
+            ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
+        });
+        it('should throw when the signature is invalid', async () => {
+            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                makerTokenAddress,
+                takerTokenAddress,
+                makerAddress,
+                takerAddress,
+                fillableAmount,
+            );
+            // 27 <--> 28
+            signedOrder.ecSignature.v = 28 - signedOrder.ecSignature.v + 27;
+            return expect(
+                zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(signedOrder, fillableAmount, takerAddress),
+            ).to.be.rejectedWith(ZeroExError.InvalidSignature);
+        });
+        it('should throw when the order is fully filled or cancelled', async () => {
+            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                makerTokenAddress,
+                takerTokenAddress,
+                makerAddress,
+                takerAddress,
+                fillableAmount,
+            );
+            await zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount);
+            return expect(
+                zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(signedOrder, fillableAmount, takerAddress),
+            ).to.be.rejectedWith(ExchangeContractErrs.OrderRemainingFillAmountZero);
+        });
+        it('should throw when sender is not a taker', async () => {
+            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                makerTokenAddress,
+                takerTokenAddress,
+                makerAddress,
+                takerAddress,
+                fillableAmount,
+            );
+            const nonTakerAddress = userAddresses[6];
+            return expect(
+                zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(signedOrder, fillTakerAmount, nonTakerAddress),
+            ).to.be.rejectedWith(ExchangeContractErrs.TransactionSenderIsNotFillOrderTaker);
+        });
+        it('should throw when order is expired', async () => {
+            const expirationInPast = new BigNumber(1496826058); // 7th Jun 2017
+            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                makerTokenAddress,
+                takerTokenAddress,
+                makerAddress,
+                takerAddress,
+                fillableAmount,
+                expirationInPast,
+            );
+            return expect(
+                zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(signedOrder, fillTakerAmount, takerAddress),
+            ).to.be.rejectedWith(ExchangeContractErrs.OrderFillExpired);
+        });
+        it('should throw when there a rounding error would have occurred', async () => {
+            const makerAmount = new BigNumber(3);
+            const takerAmount = new BigNumber(5);
+            const signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
+                makerTokenAddress,
+                takerTokenAddress,
+                makerAddress,
+                takerAddress,
+                makerAmount,
+                takerAmount,
+            );
+            const fillTakerAmountThatCausesRoundingError = new BigNumber(3);
+            return expect(
+                zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(
+                    signedOrder,
+                    fillTakerAmountThatCausesRoundingError,
+                    takerAddress,
+                ),
+            ).to.be.rejectedWith(ExchangeContractErrs.OrderFillRoundingError);
+        });
+    });
+    describe('#validateFillOrKillOrderAndThrowIfInvalidAsync', () => {
+        it('should throw if remaining fillAmount is less then the desired fillAmount', async () => {
+            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                makerTokenAddress,
+                takerTokenAddress,
+                makerAddress,
+                takerAddress,
+                fillableAmount,
+            );
+            const tooLargeFillAmount = new BigNumber(7);
+            const fillAmountDifference = tooLargeFillAmount.minus(fillableAmount);
+            await zeroEx.token.transferAsync(takerTokenAddress, coinbase, takerAddress, fillAmountDifference);
+            await zeroEx.token.setProxyAllowanceAsync(takerTokenAddress, takerAddress, tooLargeFillAmount);
+            await zeroEx.token.transferAsync(makerTokenAddress, coinbase, makerAddress, fillAmountDifference);
+            await zeroEx.token.setProxyAllowanceAsync(makerTokenAddress, makerAddress, tooLargeFillAmount);
 
-			return expect(
-				zeroEx.exchange.validateFillOrKillOrderThrowIfInvalidAsync(
-					signedOrder,
-					tooLargeFillAmount,
-					takerAddress,
-				),
-			).to.be.rejectedWith(ExchangeContractErrs.InsufficientRemainingFillAmount);
-		});
-	});
-	describe('validateCancelOrderAndThrowIfInvalidAsync', () => {
-		let signedOrder: SignedOrder;
-		const cancelAmount = new BigNumber(3);
-		beforeEach(async () => {
-			[coinbase, makerAddress, takerAddress] = userAddresses;
-			const [makerToken, takerToken] = tokenUtils.getDummyTokens();
-			makerTokenAddress = makerToken.address;
-			takerTokenAddress = takerToken.address;
-			signedOrder = await fillScenarios.createFillableSignedOrderAsync(
-				makerTokenAddress,
-				takerTokenAddress,
-				makerAddress,
-				takerAddress,
-				fillableAmount,
-			);
-		});
-		it('should throw when cancel amount is zero', async () => {
-			const zeroCancelAmount = new BigNumber(0);
-			return expect(
-				zeroEx.exchange.validateCancelOrderThrowIfInvalidAsync(signedOrder, zeroCancelAmount),
-			).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
-		});
-		it('should throw when order is expired', async () => {
-			const expirationInPast = new BigNumber(1496826058); // 7th Jun 2017
-			const expiredSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
-				makerTokenAddress,
-				takerTokenAddress,
-				makerAddress,
-				takerAddress,
-				fillableAmount,
-				expirationInPast,
-			);
-			return expect(
-				zeroEx.exchange.validateCancelOrderThrowIfInvalidAsync(expiredSignedOrder, cancelAmount),
-			).to.be.rejectedWith(ExchangeContractErrs.OrderCancelExpired);
-		});
-		it('should throw when order is already cancelled or filled', async () => {
-			await zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount);
-			return expect(
-				zeroEx.exchange.validateCancelOrderThrowIfInvalidAsync(signedOrder, fillableAmount),
-			).to.be.rejectedWith(ExchangeContractErrs.OrderAlreadyCancelledOrFilled);
-		});
-	});
-	describe('#validateFillOrderBalancesAllowancesThrowIfInvalidAsync', () => {
-		let exchangeTransferSimulator: ExchangeTransferSimulator;
-		let transferFromAsync: Sinon.SinonSpy;
-		const bigNumberMatch = (expected: BigNumber) => {
-			return Sinon.match((value: BigNumber) => value.eq(expected));
-		};
-		beforeEach('create exchangeTransferSimulator', async () => {
-			exchangeTransferSimulator = new ExchangeTransferSimulator(zeroEx.token, BlockParamLiteral.Latest);
-			transferFromAsync = Sinon.spy();
-			exchangeTransferSimulator.transferFromAsync = transferFromAsync as any;
-		});
-		it('should call exchangeTransferSimulator.transferFrom in a correct order', async () => {
-			const makerFee = new BigNumber(2);
-			const takerFee = new BigNumber(2);
-			const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
-				makerTokenAddress,
-				takerTokenAddress,
-				makerFee,
-				takerFee,
-				makerAddress,
-				takerAddress,
-				fillableAmount,
-				feeRecipient,
-			);
-			await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
-				exchangeTransferSimulator,
-				signedOrder,
-				fillableAmount,
-				takerAddress,
-				zrxTokenAddress,
-			);
-			expect(transferFromAsync.callCount).to.be.equal(4);
-			expect(
-				transferFromAsync
-					.getCall(0)
-					.calledWith(
-						makerTokenAddress,
-						makerAddress,
-						takerAddress,
-						bigNumberMatch(fillableAmount),
-						TradeSide.Maker,
-						TransferType.Trade,
-					),
-			).to.be.true();
-			expect(
-				transferFromAsync
-					.getCall(1)
-					.calledWith(
-						takerTokenAddress,
-						takerAddress,
-						makerAddress,
-						bigNumberMatch(fillableAmount),
-						TradeSide.Taker,
-						TransferType.Trade,
-					),
-			).to.be.true();
-			expect(
-				transferFromAsync
-					.getCall(2)
-					.calledWith(
-						zrxTokenAddress,
-						makerAddress,
-						feeRecipient,
-						bigNumberMatch(makerFee),
-						TradeSide.Maker,
-						TransferType.Fee,
-					),
-			).to.be.true();
-			expect(
-				transferFromAsync
-					.getCall(3)
-					.calledWith(
-						zrxTokenAddress,
-						takerAddress,
-						feeRecipient,
-						bigNumberMatch(takerFee),
-						TradeSide.Taker,
-						TransferType.Fee,
-					),
-			).to.be.true();
-		});
-		it('should call exchangeTransferSimulator.transferFrom with correct values for an open order', async () => {
-			const makerFee = new BigNumber(2);
-			const takerFee = new BigNumber(2);
-			const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
-				makerTokenAddress,
-				takerTokenAddress,
-				makerFee,
-				takerFee,
-				makerAddress,
-				ZeroEx.NULL_ADDRESS,
-				fillableAmount,
-				feeRecipient,
-			);
-			await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
-				exchangeTransferSimulator,
-				signedOrder,
-				fillableAmount,
-				takerAddress,
-				zrxTokenAddress,
-			);
-			expect(transferFromAsync.callCount).to.be.equal(4);
-			expect(
-				transferFromAsync
-					.getCall(0)
-					.calledWith(
-						makerTokenAddress,
-						makerAddress,
-						takerAddress,
-						bigNumberMatch(fillableAmount),
-						TradeSide.Maker,
-						TransferType.Trade,
-					),
-			).to.be.true();
-			expect(
-				transferFromAsync
-					.getCall(1)
-					.calledWith(
-						takerTokenAddress,
-						takerAddress,
-						makerAddress,
-						bigNumberMatch(fillableAmount),
-						TradeSide.Taker,
-						TransferType.Trade,
-					),
-			).to.be.true();
-			expect(
-				transferFromAsync
-					.getCall(2)
-					.calledWith(
-						zrxTokenAddress,
-						makerAddress,
-						feeRecipient,
-						bigNumberMatch(makerFee),
-						TradeSide.Maker,
-						TransferType.Fee,
-					),
-			).to.be.true();
-			expect(
-				transferFromAsync
-					.getCall(3)
-					.calledWith(
-						zrxTokenAddress,
-						takerAddress,
-						feeRecipient,
-						bigNumberMatch(takerFee),
-						TradeSide.Taker,
-						TransferType.Fee,
-					),
-			).to.be.true();
-		});
-		it('should correctly round the fillMakerTokenAmount', async () => {
-			const makerTokenAmount = new BigNumber(3);
-			const takerTokenAmount = new BigNumber(1);
-			const signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
-				makerTokenAddress,
-				takerTokenAddress,
-				makerAddress,
-				takerAddress,
-				makerTokenAmount,
-				takerTokenAmount,
-			);
-			await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
-				exchangeTransferSimulator,
-				signedOrder,
-				takerTokenAmount,
-				takerAddress,
-				zrxTokenAddress,
-			);
-			expect(transferFromAsync.callCount).to.be.equal(4);
-			const makerFillAmount = transferFromAsync.getCall(0).args[3];
-			expect(makerFillAmount).to.be.bignumber.equal(makerTokenAmount);
-		});
-		it('should correctly round the makerFeeAmount', async () => {
-			const makerFee = new BigNumber(2);
-			const takerFee = new BigNumber(4);
-			const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
-				makerTokenAddress,
-				takerTokenAddress,
-				makerFee,
-				takerFee,
-				makerAddress,
-				takerAddress,
-				fillableAmount,
-				ZeroEx.NULL_ADDRESS,
-			);
-			const fillTakerTokenAmount = fillableAmount.div(2).round(0);
-			await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
-				exchangeTransferSimulator,
-				signedOrder,
-				fillTakerTokenAmount,
-				takerAddress,
-				zrxTokenAddress,
-			);
-			const makerPartialFee = makerFee.div(2);
-			const takerPartialFee = takerFee.div(2);
-			expect(transferFromAsync.callCount).to.be.equal(4);
-			const partialMakerFee = transferFromAsync.getCall(2).args[3];
-			expect(partialMakerFee).to.be.bignumber.equal(makerPartialFee);
-			const partialTakerFee = transferFromAsync.getCall(3).args[3];
-			expect(partialTakerFee).to.be.bignumber.equal(takerPartialFee);
-		});
-	});
+            return expect(
+                zeroEx.exchange.validateFillOrKillOrderThrowIfInvalidAsync(
+                    signedOrder,
+                    tooLargeFillAmount,
+                    takerAddress,
+                ),
+            ).to.be.rejectedWith(ExchangeContractErrs.InsufficientRemainingFillAmount);
+        });
+    });
+    describe('validateCancelOrderAndThrowIfInvalidAsync', () => {
+        let signedOrder: SignedOrder;
+        const cancelAmount = new BigNumber(3);
+        beforeEach(async () => {
+            [coinbase, makerAddress, takerAddress] = userAddresses;
+            const [makerToken, takerToken] = tokenUtils.getDummyTokens();
+            makerTokenAddress = makerToken.address;
+            takerTokenAddress = takerToken.address;
+            signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                makerTokenAddress,
+                takerTokenAddress,
+                makerAddress,
+                takerAddress,
+                fillableAmount,
+            );
+        });
+        it('should throw when cancel amount is zero', async () => {
+            const zeroCancelAmount = new BigNumber(0);
+            return expect(
+                zeroEx.exchange.validateCancelOrderThrowIfInvalidAsync(signedOrder, zeroCancelAmount),
+            ).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
+        });
+        it('should throw when order is expired', async () => {
+            const expirationInPast = new BigNumber(1496826058); // 7th Jun 2017
+            const expiredSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
+                makerTokenAddress,
+                takerTokenAddress,
+                makerAddress,
+                takerAddress,
+                fillableAmount,
+                expirationInPast,
+            );
+            return expect(
+                zeroEx.exchange.validateCancelOrderThrowIfInvalidAsync(expiredSignedOrder, cancelAmount),
+            ).to.be.rejectedWith(ExchangeContractErrs.OrderCancelExpired);
+        });
+        it('should throw when order is already cancelled or filled', async () => {
+            await zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount);
+            return expect(
+                zeroEx.exchange.validateCancelOrderThrowIfInvalidAsync(signedOrder, fillableAmount),
+            ).to.be.rejectedWith(ExchangeContractErrs.OrderAlreadyCancelledOrFilled);
+        });
+    });
+    describe('#validateFillOrderBalancesAllowancesThrowIfInvalidAsync', () => {
+        let exchangeTransferSimulator: ExchangeTransferSimulator;
+        let transferFromAsync: Sinon.SinonSpy;
+        const bigNumberMatch = (expected: BigNumber) => {
+            return Sinon.match((value: BigNumber) => value.eq(expected));
+        };
+        beforeEach('create exchangeTransferSimulator', async () => {
+            exchangeTransferSimulator = new ExchangeTransferSimulator(zeroEx.token, BlockParamLiteral.Latest);
+            transferFromAsync = Sinon.spy();
+            exchangeTransferSimulator.transferFromAsync = transferFromAsync as any;
+        });
+        it('should call exchangeTransferSimulator.transferFrom in a correct order', async () => {
+            const makerFee = new BigNumber(2);
+            const takerFee = new BigNumber(2);
+            const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
+                makerTokenAddress,
+                takerTokenAddress,
+                makerFee,
+                takerFee,
+                makerAddress,
+                takerAddress,
+                fillableAmount,
+                feeRecipient,
+            );
+            await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
+                exchangeTransferSimulator,
+                signedOrder,
+                fillableAmount,
+                takerAddress,
+                zrxTokenAddress,
+            );
+            expect(transferFromAsync.callCount).to.be.equal(4);
+            expect(
+                transferFromAsync
+                    .getCall(0)
+                    .calledWith(
+                        makerTokenAddress,
+                        makerAddress,
+                        takerAddress,
+                        bigNumberMatch(fillableAmount),
+                        TradeSide.Maker,
+                        TransferType.Trade,
+                    ),
+            ).to.be.true();
+            expect(
+                transferFromAsync
+                    .getCall(1)
+                    .calledWith(
+                        takerTokenAddress,
+                        takerAddress,
+                        makerAddress,
+                        bigNumberMatch(fillableAmount),
+                        TradeSide.Taker,
+                        TransferType.Trade,
+                    ),
+            ).to.be.true();
+            expect(
+                transferFromAsync
+                    .getCall(2)
+                    .calledWith(
+                        zrxTokenAddress,
+                        makerAddress,
+                        feeRecipient,
+                        bigNumberMatch(makerFee),
+                        TradeSide.Maker,
+                        TransferType.Fee,
+                    ),
+            ).to.be.true();
+            expect(
+                transferFromAsync
+                    .getCall(3)
+                    .calledWith(
+                        zrxTokenAddress,
+                        takerAddress,
+                        feeRecipient,
+                        bigNumberMatch(takerFee),
+                        TradeSide.Taker,
+                        TransferType.Fee,
+                    ),
+            ).to.be.true();
+        });
+        it('should call exchangeTransferSimulator.transferFrom with correct values for an open order', async () => {
+            const makerFee = new BigNumber(2);
+            const takerFee = new BigNumber(2);
+            const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
+                makerTokenAddress,
+                takerTokenAddress,
+                makerFee,
+                takerFee,
+                makerAddress,
+                ZeroEx.NULL_ADDRESS,
+                fillableAmount,
+                feeRecipient,
+            );
+            await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
+                exchangeTransferSimulator,
+                signedOrder,
+                fillableAmount,
+                takerAddress,
+                zrxTokenAddress,
+            );
+            expect(transferFromAsync.callCount).to.be.equal(4);
+            expect(
+                transferFromAsync
+                    .getCall(0)
+                    .calledWith(
+                        makerTokenAddress,
+                        makerAddress,
+                        takerAddress,
+                        bigNumberMatch(fillableAmount),
+                        TradeSide.Maker,
+                        TransferType.Trade,
+                    ),
+            ).to.be.true();
+            expect(
+                transferFromAsync
+                    .getCall(1)
+                    .calledWith(
+                        takerTokenAddress,
+                        takerAddress,
+                        makerAddress,
+                        bigNumberMatch(fillableAmount),
+                        TradeSide.Taker,
+                        TransferType.Trade,
+                    ),
+            ).to.be.true();
+            expect(
+                transferFromAsync
+                    .getCall(2)
+                    .calledWith(
+                        zrxTokenAddress,
+                        makerAddress,
+                        feeRecipient,
+                        bigNumberMatch(makerFee),
+                        TradeSide.Maker,
+                        TransferType.Fee,
+                    ),
+            ).to.be.true();
+            expect(
+                transferFromAsync
+                    .getCall(3)
+                    .calledWith(
+                        zrxTokenAddress,
+                        takerAddress,
+                        feeRecipient,
+                        bigNumberMatch(takerFee),
+                        TradeSide.Taker,
+                        TransferType.Fee,
+                    ),
+            ).to.be.true();
+        });
+        it('should correctly round the fillMakerTokenAmount', async () => {
+            const makerTokenAmount = new BigNumber(3);
+            const takerTokenAmount = new BigNumber(1);
+            const signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
+                makerTokenAddress,
+                takerTokenAddress,
+                makerAddress,
+                takerAddress,
+                makerTokenAmount,
+                takerTokenAmount,
+            );
+            await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
+                exchangeTransferSimulator,
+                signedOrder,
+                takerTokenAmount,
+                takerAddress,
+                zrxTokenAddress,
+            );
+            expect(transferFromAsync.callCount).to.be.equal(4);
+            const makerFillAmount = transferFromAsync.getCall(0).args[3];
+            expect(makerFillAmount).to.be.bignumber.equal(makerTokenAmount);
+        });
+        it('should correctly round the makerFeeAmount', async () => {
+            const makerFee = new BigNumber(2);
+            const takerFee = new BigNumber(4);
+            const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
+                makerTokenAddress,
+                takerTokenAddress,
+                makerFee,
+                takerFee,
+                makerAddress,
+                takerAddress,
+                fillableAmount,
+                ZeroEx.NULL_ADDRESS,
+            );
+            const fillTakerTokenAmount = fillableAmount.div(2).round(0);
+            await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
+                exchangeTransferSimulator,
+                signedOrder,
+                fillTakerTokenAmount,
+                takerAddress,
+                zrxTokenAddress,
+            );
+            const makerPartialFee = makerFee.div(2);
+            const takerPartialFee = takerFee.div(2);
+            expect(transferFromAsync.callCount).to.be.equal(4);
+            const partialMakerFee = transferFromAsync.getCall(2).args[3];
+            expect(partialMakerFee).to.be.bignumber.equal(makerPartialFee);
+            const partialTakerFee = transferFromAsync.getCall(3).args[3];
+            expect(partialTakerFee).to.be.bignumber.equal(takerPartialFee);
+        });
+    });
 });
diff --git a/packages/0x.js/test/remaining_fillable_calculator_test.ts b/packages/0x.js/test/remaining_fillable_calculator_test.ts
index 58e9dd93b..4c6b8f3ac 100644
--- a/packages/0x.js/test/remaining_fillable_calculator_test.ts
+++ b/packages/0x.js/test/remaining_fillable_calculator_test.ts
@@ -12,223 +12,223 @@ chaiSetup.configure();
 const expect = chai.expect;
 
 describe('RemainingFillableCalculator', () => {
-	let calculator: RemainingFillableCalculator;
-	let signedOrder: SignedOrder;
-	let transferrableMakerTokenAmount: BigNumber;
-	let transferrableMakerFeeTokenAmount: BigNumber;
-	let remainingMakerTokenAmount: BigNumber;
-	let makerAmount: BigNumber;
-	let takerAmount: BigNumber;
-	let makerFeeAmount: BigNumber;
-	let isMakerTokenZRX: boolean;
-	const makerToken: string = '0x1';
-	const takerToken: string = '0x2';
-	const decimals: number = 4;
-	const zero: BigNumber = new BigNumber(0);
-	const zeroAddress = '0x0';
-	const signature: ECSignature = { v: 27, r: '', s: '' };
-	beforeEach(async () => {
-		[makerAmount, takerAmount, makerFeeAmount] = [
-			ZeroEx.toBaseUnitAmount(new BigNumber(50), decimals),
-			ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals),
-			ZeroEx.toBaseUnitAmount(new BigNumber(1), decimals),
-		];
-		[transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount] = [
-			ZeroEx.toBaseUnitAmount(new BigNumber(50), decimals),
-			ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals),
-		];
-	});
-	function buildSignedOrder(): SignedOrder {
-		return {
-			ecSignature: signature,
-			exchangeContractAddress: zeroAddress,
-			feeRecipient: zeroAddress,
-			maker: zeroAddress,
-			taker: zeroAddress,
-			makerFee: makerFeeAmount,
-			takerFee: zero,
-			makerTokenAmount: makerAmount,
-			takerTokenAmount: takerAmount,
-			makerTokenAddress: makerToken,
-			takerTokenAddress: takerToken,
-			salt: zero,
-			expirationUnixTimestampSec: zero,
-		};
-	}
-	describe('Maker token is NOT ZRX', () => {
-		before(async () => {
-			isMakerTokenZRX = false;
-		});
-		it('calculates the correct amount when unfilled and funds available', () => {
-			signedOrder = buildSignedOrder();
-			remainingMakerTokenAmount = signedOrder.makerTokenAmount;
-			calculator = new RemainingFillableCalculator(
-				signedOrder,
-				isMakerTokenZRX,
-				transferrableMakerTokenAmount,
-				transferrableMakerFeeTokenAmount,
-				remainingMakerTokenAmount,
-			);
-			expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount);
-		});
-		it('calculates the correct amount when partially filled and funds available', () => {
-			signedOrder = buildSignedOrder();
-			remainingMakerTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(1), decimals);
-			calculator = new RemainingFillableCalculator(
-				signedOrder,
-				isMakerTokenZRX,
-				transferrableMakerTokenAmount,
-				transferrableMakerFeeTokenAmount,
-				remainingMakerTokenAmount,
-			);
-			expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount);
-		});
-		it('calculates the amount to be 0 when all fee funds are transferred', () => {
-			signedOrder = buildSignedOrder();
-			transferrableMakerFeeTokenAmount = zero;
-			remainingMakerTokenAmount = signedOrder.makerTokenAmount;
-			calculator = new RemainingFillableCalculator(
-				signedOrder,
-				isMakerTokenZRX,
-				transferrableMakerTokenAmount,
-				transferrableMakerFeeTokenAmount,
-				remainingMakerTokenAmount,
-			);
-			expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(zero);
-		});
-		it('calculates the correct amount when balance is less than remaining fillable', () => {
-			signedOrder = buildSignedOrder();
-			const partiallyFilledAmount = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
-			remainingMakerTokenAmount = signedOrder.makerTokenAmount.minus(partiallyFilledAmount);
-			transferrableMakerTokenAmount = remainingMakerTokenAmount.minus(partiallyFilledAmount);
-			calculator = new RemainingFillableCalculator(
-				signedOrder,
-				isMakerTokenZRX,
-				transferrableMakerTokenAmount,
-				transferrableMakerFeeTokenAmount,
-				remainingMakerTokenAmount,
-			);
-			expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(transferrableMakerTokenAmount);
-		});
-		describe('Order to Fee Ratio is < 1', () => {
-			beforeEach(async () => {
-				[makerAmount, takerAmount, makerFeeAmount] = [
-					ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals),
-					ZeroEx.toBaseUnitAmount(new BigNumber(6), decimals),
-					ZeroEx.toBaseUnitAmount(new BigNumber(6), decimals),
-				];
-			});
-			it('calculates the correct amount when funds unavailable', () => {
-				signedOrder = buildSignedOrder();
-				remainingMakerTokenAmount = signedOrder.makerTokenAmount;
-				const transferredAmount = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
-				transferrableMakerTokenAmount = remainingMakerTokenAmount.minus(transferredAmount);
-				calculator = new RemainingFillableCalculator(
-					signedOrder,
-					isMakerTokenZRX,
-					transferrableMakerTokenAmount,
-					transferrableMakerFeeTokenAmount,
-					remainingMakerTokenAmount,
-				);
-				expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(transferrableMakerTokenAmount);
-			});
-		});
-		describe('Ratio is not evenly divisble', () => {
-			beforeEach(async () => {
-				[makerAmount, takerAmount, makerFeeAmount] = [
-					ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals),
-					ZeroEx.toBaseUnitAmount(new BigNumber(7), decimals),
-					ZeroEx.toBaseUnitAmount(new BigNumber(7), decimals),
-				];
-			});
-			it('calculates the correct amount when funds unavailable', () => {
-				signedOrder = buildSignedOrder();
-				remainingMakerTokenAmount = signedOrder.makerTokenAmount;
-				const transferredAmount = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
-				transferrableMakerTokenAmount = remainingMakerTokenAmount.minus(transferredAmount);
-				calculator = new RemainingFillableCalculator(
-					signedOrder,
-					isMakerTokenZRX,
-					transferrableMakerTokenAmount,
-					transferrableMakerFeeTokenAmount,
-					remainingMakerTokenAmount,
-				);
-				const calculatedFillableAmount = calculator.computeRemainingMakerFillable();
-				expect(calculatedFillableAmount.lessThanOrEqualTo(transferrableMakerTokenAmount)).to.be.true();
-				expect(calculatedFillableAmount).to.be.bignumber.greaterThan(new BigNumber(0));
-				const orderToFeeRatio = signedOrder.makerTokenAmount.dividedBy(signedOrder.makerFee);
-				const calculatedFeeAmount = calculatedFillableAmount.dividedBy(orderToFeeRatio);
-				expect(calculatedFeeAmount).to.be.bignumber.lessThan(transferrableMakerFeeTokenAmount);
-			});
-		});
-	});
-	describe('Maker Token is ZRX', () => {
-		before(async () => {
-			isMakerTokenZRX = true;
-		});
-		it('calculates the correct amount when unfilled and funds available', () => {
-			signedOrder = buildSignedOrder();
-			transferrableMakerTokenAmount = makerAmount.plus(makerFeeAmount);
-			transferrableMakerFeeTokenAmount = transferrableMakerTokenAmount;
-			remainingMakerTokenAmount = signedOrder.makerTokenAmount;
-			calculator = new RemainingFillableCalculator(
-				signedOrder,
-				isMakerTokenZRX,
-				transferrableMakerTokenAmount,
-				transferrableMakerFeeTokenAmount,
-				remainingMakerTokenAmount,
-			);
-			expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount);
-		});
-		it('calculates the correct amount when partially filled and funds available', () => {
-			signedOrder = buildSignedOrder();
-			remainingMakerTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(1), decimals);
-			calculator = new RemainingFillableCalculator(
-				signedOrder,
-				isMakerTokenZRX,
-				transferrableMakerTokenAmount,
-				transferrableMakerFeeTokenAmount,
-				remainingMakerTokenAmount,
-			);
-			expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount);
-		});
-		it('calculates the amount to be 0 when all fee funds are transferred', () => {
-			signedOrder = buildSignedOrder();
-			transferrableMakerTokenAmount = zero;
-			transferrableMakerFeeTokenAmount = zero;
-			remainingMakerTokenAmount = signedOrder.makerTokenAmount;
-			calculator = new RemainingFillableCalculator(
-				signedOrder,
-				isMakerTokenZRX,
-				transferrableMakerTokenAmount,
-				transferrableMakerFeeTokenAmount,
-				remainingMakerTokenAmount,
-			);
-			expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(zero);
-		});
-		it('calculates the correct amount when balance is less than remaining fillable', () => {
-			signedOrder = buildSignedOrder();
-			const partiallyFilledAmount = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
-			remainingMakerTokenAmount = signedOrder.makerTokenAmount.minus(partiallyFilledAmount);
-			transferrableMakerTokenAmount = remainingMakerTokenAmount.minus(partiallyFilledAmount);
-			transferrableMakerFeeTokenAmount = transferrableMakerTokenAmount;
+    let calculator: RemainingFillableCalculator;
+    let signedOrder: SignedOrder;
+    let transferrableMakerTokenAmount: BigNumber;
+    let transferrableMakerFeeTokenAmount: BigNumber;
+    let remainingMakerTokenAmount: BigNumber;
+    let makerAmount: BigNumber;
+    let takerAmount: BigNumber;
+    let makerFeeAmount: BigNumber;
+    let isMakerTokenZRX: boolean;
+    const makerToken: string = '0x1';
+    const takerToken: string = '0x2';
+    const decimals: number = 4;
+    const zero: BigNumber = new BigNumber(0);
+    const zeroAddress = '0x0';
+    const signature: ECSignature = { v: 27, r: '', s: '' };
+    beforeEach(async () => {
+        [makerAmount, takerAmount, makerFeeAmount] = [
+            ZeroEx.toBaseUnitAmount(new BigNumber(50), decimals),
+            ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals),
+            ZeroEx.toBaseUnitAmount(new BigNumber(1), decimals),
+        ];
+        [transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount] = [
+            ZeroEx.toBaseUnitAmount(new BigNumber(50), decimals),
+            ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals),
+        ];
+    });
+    function buildSignedOrder(): SignedOrder {
+        return {
+            ecSignature: signature,
+            exchangeContractAddress: zeroAddress,
+            feeRecipient: zeroAddress,
+            maker: zeroAddress,
+            taker: zeroAddress,
+            makerFee: makerFeeAmount,
+            takerFee: zero,
+            makerTokenAmount: makerAmount,
+            takerTokenAmount: takerAmount,
+            makerTokenAddress: makerToken,
+            takerTokenAddress: takerToken,
+            salt: zero,
+            expirationUnixTimestampSec: zero,
+        };
+    }
+    describe('Maker token is NOT ZRX', () => {
+        before(async () => {
+            isMakerTokenZRX = false;
+        });
+        it('calculates the correct amount when unfilled and funds available', () => {
+            signedOrder = buildSignedOrder();
+            remainingMakerTokenAmount = signedOrder.makerTokenAmount;
+            calculator = new RemainingFillableCalculator(
+                signedOrder,
+                isMakerTokenZRX,
+                transferrableMakerTokenAmount,
+                transferrableMakerFeeTokenAmount,
+                remainingMakerTokenAmount,
+            );
+            expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount);
+        });
+        it('calculates the correct amount when partially filled and funds available', () => {
+            signedOrder = buildSignedOrder();
+            remainingMakerTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(1), decimals);
+            calculator = new RemainingFillableCalculator(
+                signedOrder,
+                isMakerTokenZRX,
+                transferrableMakerTokenAmount,
+                transferrableMakerFeeTokenAmount,
+                remainingMakerTokenAmount,
+            );
+            expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount);
+        });
+        it('calculates the amount to be 0 when all fee funds are transferred', () => {
+            signedOrder = buildSignedOrder();
+            transferrableMakerFeeTokenAmount = zero;
+            remainingMakerTokenAmount = signedOrder.makerTokenAmount;
+            calculator = new RemainingFillableCalculator(
+                signedOrder,
+                isMakerTokenZRX,
+                transferrableMakerTokenAmount,
+                transferrableMakerFeeTokenAmount,
+                remainingMakerTokenAmount,
+            );
+            expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(zero);
+        });
+        it('calculates the correct amount when balance is less than remaining fillable', () => {
+            signedOrder = buildSignedOrder();
+            const partiallyFilledAmount = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
+            remainingMakerTokenAmount = signedOrder.makerTokenAmount.minus(partiallyFilledAmount);
+            transferrableMakerTokenAmount = remainingMakerTokenAmount.minus(partiallyFilledAmount);
+            calculator = new RemainingFillableCalculator(
+                signedOrder,
+                isMakerTokenZRX,
+                transferrableMakerTokenAmount,
+                transferrableMakerFeeTokenAmount,
+                remainingMakerTokenAmount,
+            );
+            expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(transferrableMakerTokenAmount);
+        });
+        describe('Order to Fee Ratio is < 1', () => {
+            beforeEach(async () => {
+                [makerAmount, takerAmount, makerFeeAmount] = [
+                    ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals),
+                    ZeroEx.toBaseUnitAmount(new BigNumber(6), decimals),
+                    ZeroEx.toBaseUnitAmount(new BigNumber(6), decimals),
+                ];
+            });
+            it('calculates the correct amount when funds unavailable', () => {
+                signedOrder = buildSignedOrder();
+                remainingMakerTokenAmount = signedOrder.makerTokenAmount;
+                const transferredAmount = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
+                transferrableMakerTokenAmount = remainingMakerTokenAmount.minus(transferredAmount);
+                calculator = new RemainingFillableCalculator(
+                    signedOrder,
+                    isMakerTokenZRX,
+                    transferrableMakerTokenAmount,
+                    transferrableMakerFeeTokenAmount,
+                    remainingMakerTokenAmount,
+                );
+                expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(transferrableMakerTokenAmount);
+            });
+        });
+        describe('Ratio is not evenly divisble', () => {
+            beforeEach(async () => {
+                [makerAmount, takerAmount, makerFeeAmount] = [
+                    ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals),
+                    ZeroEx.toBaseUnitAmount(new BigNumber(7), decimals),
+                    ZeroEx.toBaseUnitAmount(new BigNumber(7), decimals),
+                ];
+            });
+            it('calculates the correct amount when funds unavailable', () => {
+                signedOrder = buildSignedOrder();
+                remainingMakerTokenAmount = signedOrder.makerTokenAmount;
+                const transferredAmount = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
+                transferrableMakerTokenAmount = remainingMakerTokenAmount.minus(transferredAmount);
+                calculator = new RemainingFillableCalculator(
+                    signedOrder,
+                    isMakerTokenZRX,
+                    transferrableMakerTokenAmount,
+                    transferrableMakerFeeTokenAmount,
+                    remainingMakerTokenAmount,
+                );
+                const calculatedFillableAmount = calculator.computeRemainingMakerFillable();
+                expect(calculatedFillableAmount.lessThanOrEqualTo(transferrableMakerTokenAmount)).to.be.true();
+                expect(calculatedFillableAmount).to.be.bignumber.greaterThan(new BigNumber(0));
+                const orderToFeeRatio = signedOrder.makerTokenAmount.dividedBy(signedOrder.makerFee);
+                const calculatedFeeAmount = calculatedFillableAmount.dividedBy(orderToFeeRatio);
+                expect(calculatedFeeAmount).to.be.bignumber.lessThan(transferrableMakerFeeTokenAmount);
+            });
+        });
+    });
+    describe('Maker Token is ZRX', () => {
+        before(async () => {
+            isMakerTokenZRX = true;
+        });
+        it('calculates the correct amount when unfilled and funds available', () => {
+            signedOrder = buildSignedOrder();
+            transferrableMakerTokenAmount = makerAmount.plus(makerFeeAmount);
+            transferrableMakerFeeTokenAmount = transferrableMakerTokenAmount;
+            remainingMakerTokenAmount = signedOrder.makerTokenAmount;
+            calculator = new RemainingFillableCalculator(
+                signedOrder,
+                isMakerTokenZRX,
+                transferrableMakerTokenAmount,
+                transferrableMakerFeeTokenAmount,
+                remainingMakerTokenAmount,
+            );
+            expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount);
+        });
+        it('calculates the correct amount when partially filled and funds available', () => {
+            signedOrder = buildSignedOrder();
+            remainingMakerTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(1), decimals);
+            calculator = new RemainingFillableCalculator(
+                signedOrder,
+                isMakerTokenZRX,
+                transferrableMakerTokenAmount,
+                transferrableMakerFeeTokenAmount,
+                remainingMakerTokenAmount,
+            );
+            expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount);
+        });
+        it('calculates the amount to be 0 when all fee funds are transferred', () => {
+            signedOrder = buildSignedOrder();
+            transferrableMakerTokenAmount = zero;
+            transferrableMakerFeeTokenAmount = zero;
+            remainingMakerTokenAmount = signedOrder.makerTokenAmount;
+            calculator = new RemainingFillableCalculator(
+                signedOrder,
+                isMakerTokenZRX,
+                transferrableMakerTokenAmount,
+                transferrableMakerFeeTokenAmount,
+                remainingMakerTokenAmount,
+            );
+            expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(zero);
+        });
+        it('calculates the correct amount when balance is less than remaining fillable', () => {
+            signedOrder = buildSignedOrder();
+            const partiallyFilledAmount = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
+            remainingMakerTokenAmount = signedOrder.makerTokenAmount.minus(partiallyFilledAmount);
+            transferrableMakerTokenAmount = remainingMakerTokenAmount.minus(partiallyFilledAmount);
+            transferrableMakerFeeTokenAmount = transferrableMakerTokenAmount;
 
-			const orderToFeeRatio = signedOrder.makerTokenAmount.dividedToIntegerBy(signedOrder.makerFee);
-			const expectedFillableAmount = new BigNumber(450980);
-			calculator = new RemainingFillableCalculator(
-				signedOrder,
-				isMakerTokenZRX,
-				transferrableMakerTokenAmount,
-				transferrableMakerFeeTokenAmount,
-				remainingMakerTokenAmount,
-			);
-			const calculatedFillableAmount = calculator.computeRemainingMakerFillable();
-			const numberOfFillsInRatio = calculatedFillableAmount.dividedToIntegerBy(orderToFeeRatio);
-			const calculatedFillableAmountPlusFees = calculatedFillableAmount.plus(numberOfFillsInRatio);
-			expect(calculatedFillableAmountPlusFees).to.be.bignumber.lessThan(transferrableMakerTokenAmount);
-			expect(calculatedFillableAmountPlusFees).to.be.bignumber.lessThan(remainingMakerTokenAmount);
-			expect(calculatedFillableAmount).to.be.bignumber.equal(expectedFillableAmount);
-			expect(numberOfFillsInRatio.decimalPlaces()).to.be.equal(0);
-		});
-	});
+            const orderToFeeRatio = signedOrder.makerTokenAmount.dividedToIntegerBy(signedOrder.makerFee);
+            const expectedFillableAmount = new BigNumber(450980);
+            calculator = new RemainingFillableCalculator(
+                signedOrder,
+                isMakerTokenZRX,
+                transferrableMakerTokenAmount,
+                transferrableMakerFeeTokenAmount,
+                remainingMakerTokenAmount,
+            );
+            const calculatedFillableAmount = calculator.computeRemainingMakerFillable();
+            const numberOfFillsInRatio = calculatedFillableAmount.dividedToIntegerBy(orderToFeeRatio);
+            const calculatedFillableAmountPlusFees = calculatedFillableAmount.plus(numberOfFillsInRatio);
+            expect(calculatedFillableAmountPlusFees).to.be.bignumber.lessThan(transferrableMakerTokenAmount);
+            expect(calculatedFillableAmountPlusFees).to.be.bignumber.lessThan(remainingMakerTokenAmount);
+            expect(calculatedFillableAmount).to.be.bignumber.equal(expectedFillableAmount);
+            expect(numberOfFillsInRatio.decimalPlaces()).to.be.equal(0);
+        });
+    });
 });
diff --git a/packages/0x.js/test/subscription_test.ts b/packages/0x.js/test/subscription_test.ts
index f70ecd6cd..f4c6f748f 100644
--- a/packages/0x.js/test/subscription_test.ts
+++ b/packages/0x.js/test/subscription_test.ts
@@ -17,69 +17,69 @@ chaiSetup.configure();
 const blockchainLifecycle = new BlockchainLifecycle(constants.RPC_URL);
 
 describe('SubscriptionTest', () => {
-	let web3: Web3;
-	let zeroEx: ZeroEx;
-	let userAddresses: string[];
-	let tokens: Token[];
-	let coinbase: string;
-	let addressWithoutFunds: string;
-	const config = {
-		networkId: constants.TESTRPC_NETWORK_ID,
-	};
-	before(async () => {
-		web3 = web3Factory.create();
-		zeroEx = new ZeroEx(web3.currentProvider, config);
-		userAddresses = await zeroEx.getAvailableAddressesAsync();
-		tokens = await zeroEx.tokenRegistry.getTokensAsync();
-		coinbase = userAddresses[0];
-		addressWithoutFunds = userAddresses[1];
-	});
-	beforeEach(async () => {
-		await blockchainLifecycle.startAsync();
-	});
-	afterEach(async () => {
-		await blockchainLifecycle.revertAsync();
-	});
-	describe('#subscribe', () => {
-		const indexFilterValues = {};
-		let tokenAddress: string;
-		const allowanceAmount = new BigNumber(42);
-		let stubs: Sinon.SinonStub[] = [];
-		before(() => {
-			const token = tokens[0];
-			tokenAddress = token.address;
-		});
-		afterEach(() => {
-			zeroEx.token.unsubscribeAll();
-			_.each(stubs, s => s.restore());
-			stubs = [];
-		});
-		it('Should receive the Error when an error occurs while fetching the block', (done: DoneCallback) => {
-			(async () => {
-				const errMsg = 'Error fetching block';
-				const callback = assertNodeCallbackError(done, errMsg);
-				stubs = [Sinon.stub((zeroEx as any)._web3Wrapper, 'getBlockAsync').throws(new Error(errMsg))];
-				zeroEx.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
-				await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount);
-			})().catch(done);
-		});
-		it('Should receive the Error when an error occurs while reconciling the new block', (done: DoneCallback) => {
-			(async () => {
-				const errMsg = 'Error fetching logs';
-				const callback = assertNodeCallbackError(done, errMsg);
-				stubs = [Sinon.stub((zeroEx as any)._web3Wrapper, 'getLogsAsync').throws(new Error(errMsg))];
-				zeroEx.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
-				await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount);
-			})().catch(done);
-		});
-		it('Should allow unsubscribeAll to be called successfully after an error', (done: DoneCallback) => {
-			(async () => {
-				const callback = (err: Error | null, logEvent?: DecodedLogEvent<ApprovalContractEventArgs>) => _.noop;
-				zeroEx.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
-				stubs = [Sinon.stub((zeroEx as any)._web3Wrapper, 'getBlockAsync').throws(new Error('JSON RPC error'))];
-				zeroEx.token.unsubscribeAll();
-				done();
-			})().catch(done);
-		});
-	});
+    let web3: Web3;
+    let zeroEx: ZeroEx;
+    let userAddresses: string[];
+    let tokens: Token[];
+    let coinbase: string;
+    let addressWithoutFunds: string;
+    const config = {
+        networkId: constants.TESTRPC_NETWORK_ID,
+    };
+    before(async () => {
+        web3 = web3Factory.create();
+        zeroEx = new ZeroEx(web3.currentProvider, config);
+        userAddresses = await zeroEx.getAvailableAddressesAsync();
+        tokens = await zeroEx.tokenRegistry.getTokensAsync();
+        coinbase = userAddresses[0];
+        addressWithoutFunds = userAddresses[1];
+    });
+    beforeEach(async () => {
+        await blockchainLifecycle.startAsync();
+    });
+    afterEach(async () => {
+        await blockchainLifecycle.revertAsync();
+    });
+    describe('#subscribe', () => {
+        const indexFilterValues = {};
+        let tokenAddress: string;
+        const allowanceAmount = new BigNumber(42);
+        let stubs: Sinon.SinonStub[] = [];
+        before(() => {
+            const token = tokens[0];
+            tokenAddress = token.address;
+        });
+        afterEach(() => {
+            zeroEx.token.unsubscribeAll();
+            _.each(stubs, s => s.restore());
+            stubs = [];
+        });
+        it('Should receive the Error when an error occurs while fetching the block', (done: DoneCallback) => {
+            (async () => {
+                const errMsg = 'Error fetching block';
+                const callback = assertNodeCallbackError(done, errMsg);
+                stubs = [Sinon.stub((zeroEx as any)._web3Wrapper, 'getBlockAsync').throws(new Error(errMsg))];
+                zeroEx.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
+                await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount);
+            })().catch(done);
+        });
+        it('Should receive the Error when an error occurs while reconciling the new block', (done: DoneCallback) => {
+            (async () => {
+                const errMsg = 'Error fetching logs';
+                const callback = assertNodeCallbackError(done, errMsg);
+                stubs = [Sinon.stub((zeroEx as any)._web3Wrapper, 'getLogsAsync').throws(new Error(errMsg))];
+                zeroEx.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
+                await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount);
+            })().catch(done);
+        });
+        it('Should allow unsubscribeAll to be called successfully after an error', (done: DoneCallback) => {
+            (async () => {
+                const callback = (err: Error | null, logEvent?: DecodedLogEvent<ApprovalContractEventArgs>) => _.noop;
+                zeroEx.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
+                stubs = [Sinon.stub((zeroEx as any)._web3Wrapper, 'getBlockAsync').throws(new Error('JSON RPC error'))];
+                zeroEx.token.unsubscribeAll();
+                done();
+            })().catch(done);
+        });
+    });
 });
diff --git a/packages/0x.js/test/token_registry_wrapper_test.ts b/packages/0x.js/test/token_registry_wrapper_test.ts
index c798c00d7..0a170db8f 100644
--- a/packages/0x.js/test/token_registry_wrapper_test.ts
+++ b/packages/0x.js/test/token_registry_wrapper_test.ts
@@ -17,113 +17,113 @@ const blockchainLifecycle = new BlockchainLifecycle(constants.RPC_URL);
 const TOKEN_REGISTRY_SIZE_AFTER_MIGRATION = 7;
 
 describe('TokenRegistryWrapper', () => {
-	let zeroEx: ZeroEx;
-	let tokens: Token[];
-	const tokenAddressBySymbol: { [symbol: string]: string } = {};
-	const tokenAddressByName: { [symbol: string]: string } = {};
-	const tokenBySymbol: { [symbol: string]: Token } = {};
-	const tokenByName: { [symbol: string]: Token } = {};
-	const registeredSymbol = 'ZRX';
-	const registeredName = '0x Protocol Token';
-	const unregisteredSymbol = 'MAL';
-	const unregisteredName = 'Malicious Token';
-	const config = {
-		networkId: constants.TESTRPC_NETWORK_ID,
-	};
-	before(async () => {
-		const web3 = web3Factory.create();
-		zeroEx = new ZeroEx(web3.currentProvider, config);
-		tokens = await zeroEx.tokenRegistry.getTokensAsync();
-		_.map(tokens, token => {
-			tokenAddressBySymbol[token.symbol] = token.address;
-			tokenAddressByName[token.name] = token.address;
-			tokenBySymbol[token.symbol] = token;
-			tokenByName[token.name] = token;
-		});
-	});
-	beforeEach(async () => {
-		await blockchainLifecycle.startAsync();
-	});
-	afterEach(async () => {
-		await blockchainLifecycle.revertAsync();
-	});
-	describe('#getTokensAsync', () => {
-		it('should return all the tokens added to the tokenRegistry during the migration', async () => {
-			expect(tokens).to.have.lengthOf(TOKEN_REGISTRY_SIZE_AFTER_MIGRATION);
+    let zeroEx: ZeroEx;
+    let tokens: Token[];
+    const tokenAddressBySymbol: { [symbol: string]: string } = {};
+    const tokenAddressByName: { [symbol: string]: string } = {};
+    const tokenBySymbol: { [symbol: string]: Token } = {};
+    const tokenByName: { [symbol: string]: Token } = {};
+    const registeredSymbol = 'ZRX';
+    const registeredName = '0x Protocol Token';
+    const unregisteredSymbol = 'MAL';
+    const unregisteredName = 'Malicious Token';
+    const config = {
+        networkId: constants.TESTRPC_NETWORK_ID,
+    };
+    before(async () => {
+        const web3 = web3Factory.create();
+        zeroEx = new ZeroEx(web3.currentProvider, config);
+        tokens = await zeroEx.tokenRegistry.getTokensAsync();
+        _.map(tokens, token => {
+            tokenAddressBySymbol[token.symbol] = token.address;
+            tokenAddressByName[token.name] = token.address;
+            tokenBySymbol[token.symbol] = token;
+            tokenByName[token.name] = token;
+        });
+    });
+    beforeEach(async () => {
+        await blockchainLifecycle.startAsync();
+    });
+    afterEach(async () => {
+        await blockchainLifecycle.revertAsync();
+    });
+    describe('#getTokensAsync', () => {
+        it('should return all the tokens added to the tokenRegistry during the migration', async () => {
+            expect(tokens).to.have.lengthOf(TOKEN_REGISTRY_SIZE_AFTER_MIGRATION);
 
-			const schemaValidator = new SchemaValidator();
-			_.each(tokens, token => {
-				const validationResult = schemaValidator.validate(token, schemas.tokenSchema);
-				expect(validationResult.errors).to.have.lengthOf(0);
-			});
-		});
-	});
-	describe('#getTokenAddressesAsync', () => {
-		it('should return all the token addresses added to the tokenRegistry during the migration', async () => {
-			const tokenAddresses = await zeroEx.tokenRegistry.getTokenAddressesAsync();
-			expect(tokenAddresses).to.have.lengthOf(TOKEN_REGISTRY_SIZE_AFTER_MIGRATION);
+            const schemaValidator = new SchemaValidator();
+            _.each(tokens, token => {
+                const validationResult = schemaValidator.validate(token, schemas.tokenSchema);
+                expect(validationResult.errors).to.have.lengthOf(0);
+            });
+        });
+    });
+    describe('#getTokenAddressesAsync', () => {
+        it('should return all the token addresses added to the tokenRegistry during the migration', async () => {
+            const tokenAddresses = await zeroEx.tokenRegistry.getTokenAddressesAsync();
+            expect(tokenAddresses).to.have.lengthOf(TOKEN_REGISTRY_SIZE_AFTER_MIGRATION);
 
-			const schemaValidator = new SchemaValidator();
-			_.each(tokenAddresses, tokenAddress => {
-				const validationResult = schemaValidator.validate(tokenAddress, schemas.addressSchema);
-				expect(validationResult.errors).to.have.lengthOf(0);
-				expect(tokenAddress).to.not.be.equal(ZeroEx.NULL_ADDRESS);
-			});
-		});
-	});
-	describe('#getTokenAddressBySymbol', () => {
-		it('should return correct address for a token in the registry', async () => {
-			const tokenAddress = await zeroEx.tokenRegistry.getTokenAddressBySymbolIfExistsAsync(registeredSymbol);
-			expect(tokenAddress).to.be.equal(tokenAddressBySymbol[registeredSymbol]);
-		});
-		it('should return undefined for a token out of registry', async () => {
-			const tokenAddress = await zeroEx.tokenRegistry.getTokenAddressBySymbolIfExistsAsync(unregisteredSymbol);
-			expect(tokenAddress).to.be.undefined();
-		});
-	});
-	describe('#getTokenAddressByName', () => {
-		it('should return correct address for a token in the registry', async () => {
-			const tokenAddress = await zeroEx.tokenRegistry.getTokenAddressByNameIfExistsAsync(registeredName);
-			expect(tokenAddress).to.be.equal(tokenAddressByName[registeredName]);
-		});
-		it('should return undefined for a token out of registry', async () => {
-			const tokenAddress = await zeroEx.tokenRegistry.getTokenAddressByNameIfExistsAsync(unregisteredName);
-			expect(tokenAddress).to.be.undefined();
-		});
-	});
-	describe('#getTokenBySymbol', () => {
-		it('should return correct token for a token in the registry', async () => {
-			const token = await zeroEx.tokenRegistry.getTokenBySymbolIfExistsAsync(registeredSymbol);
-			expect(token).to.be.deep.equal(tokenBySymbol[registeredSymbol]);
-		});
-		it('should return undefined for a token out of registry', async () => {
-			const token = await zeroEx.tokenRegistry.getTokenBySymbolIfExistsAsync(unregisteredSymbol);
-			expect(token).to.be.undefined();
-		});
-	});
-	describe('#getTokenByName', () => {
-		it('should return correct token for a token in the registry', async () => {
-			const token = await zeroEx.tokenRegistry.getTokenByNameIfExistsAsync(registeredName);
-			expect(token).to.be.deep.equal(tokenByName[registeredName]);
-		});
-		it('should return undefined for a token out of registry', async () => {
-			const token = await zeroEx.tokenRegistry.getTokenByNameIfExistsAsync(unregisteredName);
-			expect(token).to.be.undefined();
-		});
-	});
-	describe('#getTokenIfExistsAsync', () => {
-		it('should return the token added to the tokenRegistry during the migration', async () => {
-			const aToken = tokens[0];
+            const schemaValidator = new SchemaValidator();
+            _.each(tokenAddresses, tokenAddress => {
+                const validationResult = schemaValidator.validate(tokenAddress, schemas.addressSchema);
+                expect(validationResult.errors).to.have.lengthOf(0);
+                expect(tokenAddress).to.not.be.equal(ZeroEx.NULL_ADDRESS);
+            });
+        });
+    });
+    describe('#getTokenAddressBySymbol', () => {
+        it('should return correct address for a token in the registry', async () => {
+            const tokenAddress = await zeroEx.tokenRegistry.getTokenAddressBySymbolIfExistsAsync(registeredSymbol);
+            expect(tokenAddress).to.be.equal(tokenAddressBySymbol[registeredSymbol]);
+        });
+        it('should return undefined for a token out of registry', async () => {
+            const tokenAddress = await zeroEx.tokenRegistry.getTokenAddressBySymbolIfExistsAsync(unregisteredSymbol);
+            expect(tokenAddress).to.be.undefined();
+        });
+    });
+    describe('#getTokenAddressByName', () => {
+        it('should return correct address for a token in the registry', async () => {
+            const tokenAddress = await zeroEx.tokenRegistry.getTokenAddressByNameIfExistsAsync(registeredName);
+            expect(tokenAddress).to.be.equal(tokenAddressByName[registeredName]);
+        });
+        it('should return undefined for a token out of registry', async () => {
+            const tokenAddress = await zeroEx.tokenRegistry.getTokenAddressByNameIfExistsAsync(unregisteredName);
+            expect(tokenAddress).to.be.undefined();
+        });
+    });
+    describe('#getTokenBySymbol', () => {
+        it('should return correct token for a token in the registry', async () => {
+            const token = await zeroEx.tokenRegistry.getTokenBySymbolIfExistsAsync(registeredSymbol);
+            expect(token).to.be.deep.equal(tokenBySymbol[registeredSymbol]);
+        });
+        it('should return undefined for a token out of registry', async () => {
+            const token = await zeroEx.tokenRegistry.getTokenBySymbolIfExistsAsync(unregisteredSymbol);
+            expect(token).to.be.undefined();
+        });
+    });
+    describe('#getTokenByName', () => {
+        it('should return correct token for a token in the registry', async () => {
+            const token = await zeroEx.tokenRegistry.getTokenByNameIfExistsAsync(registeredName);
+            expect(token).to.be.deep.equal(tokenByName[registeredName]);
+        });
+        it('should return undefined for a token out of registry', async () => {
+            const token = await zeroEx.tokenRegistry.getTokenByNameIfExistsAsync(unregisteredName);
+            expect(token).to.be.undefined();
+        });
+    });
+    describe('#getTokenIfExistsAsync', () => {
+        it('should return the token added to the tokenRegistry during the migration', async () => {
+            const aToken = tokens[0];
 
-			const token = await zeroEx.tokenRegistry.getTokenIfExistsAsync(aToken.address);
-			const schemaValidator = new SchemaValidator();
-			const validationResult = schemaValidator.validate(token, schemas.tokenSchema);
-			expect(validationResult.errors).to.have.lengthOf(0);
-		});
-		it('should return return undefined when passed a token address not in the tokenRegistry', async () => {
-			const unregisteredTokenAddress = '0x5409ed021d9299bf6814279a6a1411a7e866a631';
-			const tokenIfExists = await zeroEx.tokenRegistry.getTokenIfExistsAsync(unregisteredTokenAddress);
-			expect(tokenIfExists).to.be.undefined();
-		});
-	});
+            const token = await zeroEx.tokenRegistry.getTokenIfExistsAsync(aToken.address);
+            const schemaValidator = new SchemaValidator();
+            const validationResult = schemaValidator.validate(token, schemas.tokenSchema);
+            expect(validationResult.errors).to.have.lengthOf(0);
+        });
+        it('should return return undefined when passed a token address not in the tokenRegistry', async () => {
+            const unregisteredTokenAddress = '0x5409ed021d9299bf6814279a6a1411a7e866a631';
+            const tokenIfExists = await zeroEx.tokenRegistry.getTokenIfExistsAsync(unregisteredTokenAddress);
+            expect(tokenIfExists).to.be.undefined();
+        });
+    });
 });
diff --git a/packages/0x.js/test/token_transfer_proxy_wrapper_test.ts b/packages/0x.js/test/token_transfer_proxy_wrapper_test.ts
index 622919be2..15bd7a8ba 100644
--- a/packages/0x.js/test/token_transfer_proxy_wrapper_test.ts
+++ b/packages/0x.js/test/token_transfer_proxy_wrapper_test.ts
@@ -10,27 +10,27 @@ chaiSetup.configure();
 const expect = chai.expect;
 
 describe('TokenTransferProxyWrapper', () => {
-	let zeroEx: ZeroEx;
-	const config = {
-		networkId: constants.TESTRPC_NETWORK_ID,
-	};
-	before(async () => {
-		const web3 = web3Factory.create();
-		zeroEx = new ZeroEx(web3.currentProvider, config);
-	});
-	describe('#isAuthorizedAsync', () => {
-		it('should return false if the address is not authorized', async () => {
-			const isAuthorized = await zeroEx.proxy.isAuthorizedAsync(ZeroEx.NULL_ADDRESS);
-			expect(isAuthorized).to.be.false();
-		});
-	});
-	describe('#getAuthorizedAddressesAsync', () => {
-		it('should return the list of authorized addresses', async () => {
-			const authorizedAddresses = await zeroEx.proxy.getAuthorizedAddressesAsync();
-			for (const authorizedAddress of authorizedAddresses) {
-				const isAuthorized = await zeroEx.proxy.isAuthorizedAsync(authorizedAddress);
-				expect(isAuthorized).to.be.true();
-			}
-		});
-	});
+    let zeroEx: ZeroEx;
+    const config = {
+        networkId: constants.TESTRPC_NETWORK_ID,
+    };
+    before(async () => {
+        const web3 = web3Factory.create();
+        zeroEx = new ZeroEx(web3.currentProvider, config);
+    });
+    describe('#isAuthorizedAsync', () => {
+        it('should return false if the address is not authorized', async () => {
+            const isAuthorized = await zeroEx.proxy.isAuthorizedAsync(ZeroEx.NULL_ADDRESS);
+            expect(isAuthorized).to.be.false();
+        });
+    });
+    describe('#getAuthorizedAddressesAsync', () => {
+        it('should return the list of authorized addresses', async () => {
+            const authorizedAddresses = await zeroEx.proxy.getAuthorizedAddressesAsync();
+            for (const authorizedAddress of authorizedAddresses) {
+                const isAuthorized = await zeroEx.proxy.isAuthorizedAsync(authorizedAddress);
+                expect(isAuthorized).to.be.true();
+            }
+        });
+    });
 });
diff --git a/packages/0x.js/test/token_wrapper_test.ts b/packages/0x.js/test/token_wrapper_test.ts
index 6919183cb..4ba1f07c5 100644
--- a/packages/0x.js/test/token_wrapper_test.ts
+++ b/packages/0x.js/test/token_wrapper_test.ts
@@ -6,15 +6,15 @@ import 'mocha';
 import * as Web3 from 'web3';
 
 import {
-	ApprovalContractEventArgs,
-	BlockParamLiteral,
-	BlockRange,
-	DecodedLogEvent,
-	Token,
-	TokenEvents,
-	TransferContractEventArgs,
-	ZeroEx,
-	ZeroExError,
+    ApprovalContractEventArgs,
+    BlockParamLiteral,
+    BlockRange,
+    DecodedLogEvent,
+    Token,
+    TokenEvents,
+    TransferContractEventArgs,
+    ZeroEx,
+    ZeroExError,
 } from '../src';
 import { DoneCallback } from '../src/types';
 
@@ -29,493 +29,493 @@ const expect = chai.expect;
 const blockchainLifecycle = new BlockchainLifecycle(constants.RPC_URL);
 
 describe('TokenWrapper', () => {
-	let web3: Web3;
-	let zeroEx: ZeroEx;
-	let userAddresses: string[];
-	let tokens: Token[];
-	let tokenUtils: TokenUtils;
-	let coinbase: string;
-	let addressWithoutFunds: string;
-	let web3Wrapper: Web3Wrapper;
-	const config = {
-		networkId: constants.TESTRPC_NETWORK_ID,
-	};
-	before(async () => {
-		web3 = web3Factory.create();
-		zeroEx = new ZeroEx(web3.currentProvider, config);
-		web3Wrapper = new Web3Wrapper(web3.currentProvider);
-		userAddresses = await zeroEx.getAvailableAddressesAsync();
-		tokens = await zeroEx.tokenRegistry.getTokensAsync();
-		tokenUtils = new TokenUtils(tokens);
-		coinbase = userAddresses[0];
-		addressWithoutFunds = userAddresses[1];
-	});
-	beforeEach(async () => {
-		await blockchainLifecycle.startAsync();
-	});
-	afterEach(async () => {
-		await blockchainLifecycle.revertAsync();
-	});
-	describe('#transferAsync', () => {
-		let token: Token;
-		let transferAmount: BigNumber;
-		before(() => {
-			token = tokens[0];
-			transferAmount = new BigNumber(42);
-		});
-		it('should successfully transfer tokens', async () => {
-			const fromAddress = coinbase;
-			const toAddress = addressWithoutFunds;
-			const preBalance = await zeroEx.token.getBalanceAsync(token.address, toAddress);
-			expect(preBalance).to.be.bignumber.equal(0);
-			await zeroEx.token.transferAsync(token.address, fromAddress, toAddress, transferAmount);
-			const postBalance = await zeroEx.token.getBalanceAsync(token.address, toAddress);
-			return expect(postBalance).to.be.bignumber.equal(transferAmount);
-		});
-		it('should fail to transfer tokens if fromAddress has an insufficient balance', async () => {
-			const fromAddress = addressWithoutFunds;
-			const toAddress = coinbase;
-			return expect(
-				zeroEx.token.transferAsync(token.address, fromAddress, toAddress, transferAmount),
-			).to.be.rejectedWith(ZeroExError.InsufficientBalanceForTransfer);
-		});
-		it('should throw a CONTRACT_DOES_NOT_EXIST error for a non-existent token contract', async () => {
-			const nonExistentTokenAddress = '0x9dd402f14d67e001d8efbe6583e51bf9706aa065';
-			const fromAddress = coinbase;
-			const toAddress = coinbase;
-			return expect(
-				zeroEx.token.transferAsync(nonExistentTokenAddress, fromAddress, toAddress, transferAmount),
-			).to.be.rejectedWith(ZeroExError.TokenContractDoesNotExist);
-		});
-	});
-	describe('#transferFromAsync', () => {
-		let token: Token;
-		let toAddress: string;
-		let senderAddress: string;
-		before(async () => {
-			token = tokens[0];
-			toAddress = addressWithoutFunds;
-			senderAddress = userAddresses[2];
-		});
-		it('should fail to transfer tokens if fromAddress has insufficient allowance set', async () => {
-			const fromAddress = coinbase;
-			const transferAmount = new BigNumber(42);
-
-			const fromAddressBalance = await zeroEx.token.getBalanceAsync(token.address, fromAddress);
-			expect(fromAddressBalance).to.be.bignumber.greaterThan(transferAmount);
-
-			const fromAddressAllowance = await zeroEx.token.getAllowanceAsync(token.address, fromAddress, toAddress);
-			expect(fromAddressAllowance).to.be.bignumber.equal(0);
-
-			return expect(
-				zeroEx.token.transferFromAsync(token.address, fromAddress, toAddress, senderAddress, transferAmount),
-			).to.be.rejectedWith(ZeroExError.InsufficientAllowanceForTransfer);
-		});
-		it('[regression] should fail to transfer tokens if set allowance for toAddress instead of senderAddress', async () => {
-			const fromAddress = coinbase;
-			const transferAmount = new BigNumber(42);
-
-			await zeroEx.token.setAllowanceAsync(token.address, fromAddress, toAddress, transferAmount);
-
-			return expect(
-				zeroEx.token.transferFromAsync(token.address, fromAddress, toAddress, senderAddress, transferAmount),
-			).to.be.rejectedWith(ZeroExError.InsufficientAllowanceForTransfer);
-		});
-		it('should fail to transfer tokens if fromAddress has insufficient balance', async () => {
-			const fromAddress = addressWithoutFunds;
-			const transferAmount = new BigNumber(42);
-
-			const fromAddressBalance = await zeroEx.token.getBalanceAsync(token.address, fromAddress);
-			expect(fromAddressBalance).to.be.bignumber.equal(0);
-
-			await zeroEx.token.setAllowanceAsync(token.address, fromAddress, senderAddress, transferAmount);
-			const fromAddressAllowance = await zeroEx.token.getAllowanceAsync(
-				token.address,
-				fromAddress,
-				senderAddress,
-			);
-			expect(fromAddressAllowance).to.be.bignumber.equal(transferAmount);
-
-			return expect(
-				zeroEx.token.transferFromAsync(token.address, fromAddress, toAddress, senderAddress, transferAmount),
-			).to.be.rejectedWith(ZeroExError.InsufficientBalanceForTransfer);
-		});
-		it('should successfully transfer tokens', async () => {
-			const fromAddress = coinbase;
-
-			const preBalance = await zeroEx.token.getBalanceAsync(token.address, toAddress);
-			expect(preBalance).to.be.bignumber.equal(0);
-
-			const transferAmount = new BigNumber(42);
-			await zeroEx.token.setAllowanceAsync(token.address, fromAddress, senderAddress, transferAmount);
-
-			await zeroEx.token.transferFromAsync(token.address, fromAddress, toAddress, senderAddress, transferAmount);
-			const postBalance = await zeroEx.token.getBalanceAsync(token.address, toAddress);
-			return expect(postBalance).to.be.bignumber.equal(transferAmount);
-		});
-		it('should throw a CONTRACT_DOES_NOT_EXIST error for a non-existent token contract', async () => {
-			const fromAddress = coinbase;
-			const nonExistentTokenAddress = '0x9dd402f14d67e001d8efbe6583e51bf9706aa065';
-			return expect(
-				zeroEx.token.transferFromAsync(
-					nonExistentTokenAddress,
-					fromAddress,
-					toAddress,
-					senderAddress,
-					new BigNumber(42),
-				),
-			).to.be.rejectedWith(ZeroExError.TokenContractDoesNotExist);
-		});
-	});
-	describe('#getBalanceAsync', () => {
-		describe('With web3 provider with accounts', () => {
-			it('should return the balance for an existing ERC20 token', async () => {
-				const token = tokens[0];
-				const ownerAddress = coinbase;
-				const balance = await zeroEx.token.getBalanceAsync(token.address, ownerAddress);
-				const expectedBalance = new BigNumber('1000000000000000000000000000');
-				return expect(balance).to.be.bignumber.equal(expectedBalance);
-			});
-			it('should throw a CONTRACT_DOES_NOT_EXIST error for a non-existent token contract', async () => {
-				const nonExistentTokenAddress = '0x9dd402f14d67e001d8efbe6583e51bf9706aa065';
-				const ownerAddress = coinbase;
-				return expect(zeroEx.token.getBalanceAsync(nonExistentTokenAddress, ownerAddress)).to.be.rejectedWith(
-					ZeroExError.TokenContractDoesNotExist,
-				);
-			});
-			it('should return a balance of 0 for a non-existent owner address', async () => {
-				const token = tokens[0];
-				const nonExistentOwner = '0x198c6ad858f213fb31b6fe809e25040e6b964593';
-				const balance = await zeroEx.token.getBalanceAsync(token.address, nonExistentOwner);
-				const expectedBalance = new BigNumber(0);
-				return expect(balance).to.be.bignumber.equal(expectedBalance);
-			});
-		});
-		describe('With web3 provider without accounts', () => {
-			let zeroExWithoutAccounts: ZeroEx;
-			before(async () => {
-				const hasAddresses = false;
-				const web3WithoutAccounts = web3Factory.create(hasAddresses);
-				zeroExWithoutAccounts = new ZeroEx(web3WithoutAccounts.currentProvider, config);
-			});
-			it('should return balance even when called with Web3 provider instance without addresses', async () => {
-				const token = tokens[0];
-				const ownerAddress = coinbase;
-				const balance = await zeroExWithoutAccounts.token.getBalanceAsync(token.address, ownerAddress);
-				const expectedBalance = new BigNumber('1000000000000000000000000000');
-				return expect(balance).to.be.bignumber.equal(expectedBalance);
-			});
-		});
-	});
-	describe('#setAllowanceAsync', () => {
-		it("should set the spender's allowance", async () => {
-			const token = tokens[0];
-			const ownerAddress = coinbase;
-			const spenderAddress = addressWithoutFunds;
-
-			const allowanceBeforeSet = await zeroEx.token.getAllowanceAsync(
-				token.address,
-				ownerAddress,
-				spenderAddress,
-			);
-			const expectedAllowanceBeforeAllowanceSet = new BigNumber(0);
-			expect(allowanceBeforeSet).to.be.bignumber.equal(expectedAllowanceBeforeAllowanceSet);
-
-			const amountInBaseUnits = new BigNumber(50);
-			await zeroEx.token.setAllowanceAsync(token.address, ownerAddress, spenderAddress, amountInBaseUnits);
-
-			const allowanceAfterSet = await zeroEx.token.getAllowanceAsync(token.address, ownerAddress, spenderAddress);
-			const expectedAllowanceAfterAllowanceSet = amountInBaseUnits;
-			return expect(allowanceAfterSet).to.be.bignumber.equal(expectedAllowanceAfterAllowanceSet);
-		});
-	});
-	describe('#setUnlimitedAllowanceAsync', () => {
-		it("should set the unlimited spender's allowance", async () => {
-			const token = tokens[0];
-			const ownerAddress = coinbase;
-			const spenderAddress = addressWithoutFunds;
-
-			await zeroEx.token.setUnlimitedAllowanceAsync(token.address, ownerAddress, spenderAddress);
-			const allowance = await zeroEx.token.getAllowanceAsync(token.address, ownerAddress, spenderAddress);
-			return expect(allowance).to.be.bignumber.equal(zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
-		});
-		it('should reduce the gas cost for transfers including tokens with unlimited allowance support', async () => {
-			const transferAmount = new BigNumber(5);
-			const zrx = tokenUtils.getProtocolTokenOrThrow();
-			const [, userWithNormalAllowance, userWithUnlimitedAllowance] = userAddresses;
-			await zeroEx.token.setAllowanceAsync(zrx.address, coinbase, userWithNormalAllowance, transferAmount);
-			await zeroEx.token.setUnlimitedAllowanceAsync(zrx.address, coinbase, userWithUnlimitedAllowance);
-
-			const initBalanceWithNormalAllowance = await web3Wrapper.getBalanceInWeiAsync(userWithNormalAllowance);
-			const initBalanceWithUnlimitedAllowance = await web3Wrapper.getBalanceInWeiAsync(
-				userWithUnlimitedAllowance,
-			);
-
-			await zeroEx.token.transferFromAsync(
-				zrx.address,
-				coinbase,
-				userWithNormalAllowance,
-				userWithNormalAllowance,
-				transferAmount,
-			);
-			await zeroEx.token.transferFromAsync(
-				zrx.address,
-				coinbase,
-				userWithUnlimitedAllowance,
-				userWithUnlimitedAllowance,
-				transferAmount,
-			);
-
-			const finalBalanceWithNormalAllowance = await web3Wrapper.getBalanceInWeiAsync(userWithNormalAllowance);
-			const finalBalanceWithUnlimitedAllowance = await web3Wrapper.getBalanceInWeiAsync(
-				userWithUnlimitedAllowance,
-			);
-
-			const normalGasCost = initBalanceWithNormalAllowance.minus(finalBalanceWithNormalAllowance);
-			const unlimitedGasCost = initBalanceWithUnlimitedAllowance.minus(finalBalanceWithUnlimitedAllowance);
-
-			// In theory the gas cost with unlimited allowance should be smaller, but with testrpc it's actually bigger.
-			// This needs to be investigated in ethereumjs-vm. This test is essentially a repro.
-			// TODO: Make this test pass with inverted assertion.
-			expect(unlimitedGasCost.toNumber()).to.be.gt(normalGasCost.toNumber());
-		});
-	});
-	describe('#getAllowanceAsync', () => {
-		describe('With web3 provider with accounts', () => {
-			it('should get the proxy allowance', async () => {
-				const token = tokens[0];
-				const ownerAddress = coinbase;
-				const spenderAddress = addressWithoutFunds;
-
-				const amountInBaseUnits = new BigNumber(50);
-				await zeroEx.token.setAllowanceAsync(token.address, ownerAddress, spenderAddress, amountInBaseUnits);
-
-				const allowance = await zeroEx.token.getAllowanceAsync(token.address, ownerAddress, spenderAddress);
-				const expectedAllowance = amountInBaseUnits;
-				return expect(allowance).to.be.bignumber.equal(expectedAllowance);
-			});
-			it('should return 0 if no allowance set yet', async () => {
-				const token = tokens[0];
-				const ownerAddress = coinbase;
-				const spenderAddress = addressWithoutFunds;
-				const allowance = await zeroEx.token.getAllowanceAsync(token.address, ownerAddress, spenderAddress);
-				const expectedAllowance = new BigNumber(0);
-				return expect(allowance).to.be.bignumber.equal(expectedAllowance);
-			});
-		});
-		describe('With web3 provider without accounts', () => {
-			let zeroExWithoutAccounts: ZeroEx;
-			before(async () => {
-				const hasAddresses = false;
-				const web3WithoutAccounts = web3Factory.create(hasAddresses);
-				zeroExWithoutAccounts = new ZeroEx(web3WithoutAccounts.currentProvider, config);
-			});
-			it('should get the proxy allowance', async () => {
-				const token = tokens[0];
-				const ownerAddress = coinbase;
-				const spenderAddress = addressWithoutFunds;
-
-				const amountInBaseUnits = new BigNumber(50);
-				await zeroEx.token.setAllowanceAsync(token.address, ownerAddress, spenderAddress, amountInBaseUnits);
-
-				const allowance = await zeroExWithoutAccounts.token.getAllowanceAsync(
-					token.address,
-					ownerAddress,
-					spenderAddress,
-				);
-				const expectedAllowance = amountInBaseUnits;
-				return expect(allowance).to.be.bignumber.equal(expectedAllowance);
-			});
-		});
-	});
-	describe('#getProxyAllowanceAsync', () => {
-		it('should get the proxy allowance', async () => {
-			const token = tokens[0];
-			const ownerAddress = coinbase;
-
-			const amountInBaseUnits = new BigNumber(50);
-			await zeroEx.token.setProxyAllowanceAsync(token.address, ownerAddress, amountInBaseUnits);
-
-			const allowance = await zeroEx.token.getProxyAllowanceAsync(token.address, ownerAddress);
-			const expectedAllowance = amountInBaseUnits;
-			return expect(allowance).to.be.bignumber.equal(expectedAllowance);
-		});
-	});
-	describe('#setProxyAllowanceAsync', () => {
-		it('should set the proxy allowance', async () => {
-			const token = tokens[0];
-			const ownerAddress = coinbase;
-
-			const allowanceBeforeSet = await zeroEx.token.getProxyAllowanceAsync(token.address, ownerAddress);
-			const expectedAllowanceBeforeAllowanceSet = new BigNumber(0);
-			expect(allowanceBeforeSet).to.be.bignumber.equal(expectedAllowanceBeforeAllowanceSet);
-
-			const amountInBaseUnits = new BigNumber(50);
-			await zeroEx.token.setProxyAllowanceAsync(token.address, ownerAddress, amountInBaseUnits);
-
-			const allowanceAfterSet = await zeroEx.token.getProxyAllowanceAsync(token.address, ownerAddress);
-			const expectedAllowanceAfterAllowanceSet = amountInBaseUnits;
-			return expect(allowanceAfterSet).to.be.bignumber.equal(expectedAllowanceAfterAllowanceSet);
-		});
-	});
-	describe('#setUnlimitedProxyAllowanceAsync', () => {
-		it('should set the unlimited proxy allowance', async () => {
-			const token = tokens[0];
-			const ownerAddress = coinbase;
-
-			await zeroEx.token.setUnlimitedProxyAllowanceAsync(token.address, ownerAddress);
-			const allowance = await zeroEx.token.getProxyAllowanceAsync(token.address, ownerAddress);
-			return expect(allowance).to.be.bignumber.equal(zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
-		});
-	});
-	describe('#subscribe', () => {
-		const indexFilterValues = {};
-		let tokenAddress: string;
-		const transferAmount = new BigNumber(42);
-		const allowanceAmount = new BigNumber(42);
-		before(() => {
-			const token = tokens[0];
-			tokenAddress = token.address;
-		});
-		afterEach(() => {
-			zeroEx.token.unsubscribeAll();
-		});
-		// Hack: Mocha does not allow a test to be both async and have a `done` callback
-		// Since we need to await the receipt of the event in the `subscribe` callback,
-		// we do need both. A hack is to make the top-level a sync fn w/ a done callback and then
-		// wrap the rest of the test in an async block
-		// Source: https://github.com/mochajs/mocha/issues/2407
-		it('Should receive the Transfer event when tokens are transfered', (done: DoneCallback) => {
-			(async () => {
-				const callback = reportNodeCallbackErrors(done)(
-					(logEvent: DecodedLogEvent<TransferContractEventArgs>) => {
-						expect(logEvent.isRemoved).to.be.false();
-						expect(logEvent.log.logIndex).to.be.equal(0);
-						expect(logEvent.log.transactionIndex).to.be.equal(0);
-						expect(logEvent.log.blockNumber).to.be.a('number');
-						const args = logEvent.log.args;
-						expect(args._from).to.be.equal(coinbase);
-						expect(args._to).to.be.equal(addressWithoutFunds);
-						expect(args._value).to.be.bignumber.equal(transferAmount);
-					},
-				);
-				zeroEx.token.subscribe(tokenAddress, TokenEvents.Transfer, indexFilterValues, callback);
-				await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
-			})().catch(done);
-		});
-		it('Should receive the Approval event when allowance is being set', (done: DoneCallback) => {
-			(async () => {
-				const callback = reportNodeCallbackErrors(done)(
-					(logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
-						expect(logEvent).to.not.be.undefined();
-						expect(logEvent.isRemoved).to.be.false();
-						const args = logEvent.log.args;
-						expect(args._owner).to.be.equal(coinbase);
-						expect(args._spender).to.be.equal(addressWithoutFunds);
-						expect(args._value).to.be.bignumber.equal(allowanceAmount);
-					},
-				);
-				zeroEx.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
-				await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount);
-			})().catch(done);
-		});
-		it('Outstanding subscriptions are cancelled when zeroEx.setProvider called', (done: DoneCallback) => {
-			(async () => {
-				const callbackNeverToBeCalled = reportNodeCallbackErrors(done)(
-					(logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
-						done(new Error('Expected this subscription to have been cancelled'));
-					},
-				);
-				zeroEx.token.subscribe(tokenAddress, TokenEvents.Transfer, indexFilterValues, callbackNeverToBeCalled);
-				const callbackToBeCalled = reportNodeCallbackErrors(done)();
-				const newProvider = web3Factory.getRpcProvider();
-				zeroEx.setProvider(newProvider, constants.TESTRPC_NETWORK_ID);
-				zeroEx.token.subscribe(tokenAddress, TokenEvents.Transfer, indexFilterValues, callbackToBeCalled);
-				await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
-			})().catch(done);
-		});
-		it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => {
-			(async () => {
-				const callbackNeverToBeCalled = reportNodeCallbackErrors(done)(
-					(logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
-						done(new Error('Expected this subscription to have been cancelled'));
-					},
-				);
-				const subscriptionToken = zeroEx.token.subscribe(
-					tokenAddress,
-					TokenEvents.Transfer,
-					indexFilterValues,
-					callbackNeverToBeCalled,
-				);
-				zeroEx.token.unsubscribe(subscriptionToken);
-				await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
-				done();
-			})().catch(done);
-		});
-	});
-	describe('#getLogsAsync', () => {
-		let tokenAddress: string;
-		let tokenTransferProxyAddress: string;
-		const blockRange: BlockRange = {
-			fromBlock: 0,
-			toBlock: BlockParamLiteral.Latest,
-		};
-		let txHash: string;
-		before(() => {
-			const token = tokens[0];
-			tokenAddress = token.address;
-			tokenTransferProxyAddress = zeroEx.proxy.getContractAddress();
-		});
-		it('should get logs with decoded args emitted by Approval', async () => {
-			txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(tokenAddress, coinbase);
-			await zeroEx.awaitTransactionMinedAsync(txHash);
-			const eventName = TokenEvents.Approval;
-			const indexFilterValues = {};
-			const logs = await zeroEx.token.getLogsAsync<ApprovalContractEventArgs>(
-				tokenAddress,
-				eventName,
-				blockRange,
-				indexFilterValues,
-			);
-			expect(logs).to.have.length(1);
-			const args = logs[0].args;
-			expect(logs[0].event).to.be.equal(eventName);
-			expect(args._owner).to.be.equal(coinbase);
-			expect(args._spender).to.be.equal(tokenTransferProxyAddress);
-			expect(args._value).to.be.bignumber.equal(zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
-		});
-		it('should only get the logs with the correct event name', async () => {
-			txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(tokenAddress, coinbase);
-			await zeroEx.awaitTransactionMinedAsync(txHash);
-			const differentEventName = TokenEvents.Transfer;
-			const indexFilterValues = {};
-			const logs = await zeroEx.token.getLogsAsync(
-				tokenAddress,
-				differentEventName,
-				blockRange,
-				indexFilterValues,
-			);
-			expect(logs).to.have.length(0);
-		});
-		it('should only get the logs with the correct indexed fields', async () => {
-			txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(tokenAddress, coinbase);
-			await zeroEx.awaitTransactionMinedAsync(txHash);
-			txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(tokenAddress, addressWithoutFunds);
-			await zeroEx.awaitTransactionMinedAsync(txHash);
-			const eventName = TokenEvents.Approval;
-			const indexFilterValues = {
-				_owner: coinbase,
-			};
-			const logs = await zeroEx.token.getLogsAsync<ApprovalContractEventArgs>(
-				tokenAddress,
-				eventName,
-				blockRange,
-				indexFilterValues,
-			);
-			expect(logs).to.have.length(1);
-			const args = logs[0].args;
-			expect(args._owner).to.be.equal(coinbase);
-		});
-	});
+    let web3: Web3;
+    let zeroEx: ZeroEx;
+    let userAddresses: string[];
+    let tokens: Token[];
+    let tokenUtils: TokenUtils;
+    let coinbase: string;
+    let addressWithoutFunds: string;
+    let web3Wrapper: Web3Wrapper;
+    const config = {
+        networkId: constants.TESTRPC_NETWORK_ID,
+    };
+    before(async () => {
+        web3 = web3Factory.create();
+        zeroEx = new ZeroEx(web3.currentProvider, config);
+        web3Wrapper = new Web3Wrapper(web3.currentProvider);
+        userAddresses = await zeroEx.getAvailableAddressesAsync();
+        tokens = await zeroEx.tokenRegistry.getTokensAsync();
+        tokenUtils = new TokenUtils(tokens);
+        coinbase = userAddresses[0];
+        addressWithoutFunds = userAddresses[1];
+    });
+    beforeEach(async () => {
+        await blockchainLifecycle.startAsync();
+    });
+    afterEach(async () => {
+        await blockchainLifecycle.revertAsync();
+    });
+    describe('#transferAsync', () => {
+        let token: Token;
+        let transferAmount: BigNumber;
+        before(() => {
+            token = tokens[0];
+            transferAmount = new BigNumber(42);
+        });
+        it('should successfully transfer tokens', async () => {
+            const fromAddress = coinbase;
+            const toAddress = addressWithoutFunds;
+            const preBalance = await zeroEx.token.getBalanceAsync(token.address, toAddress);
+            expect(preBalance).to.be.bignumber.equal(0);
+            await zeroEx.token.transferAsync(token.address, fromAddress, toAddress, transferAmount);
+            const postBalance = await zeroEx.token.getBalanceAsync(token.address, toAddress);
+            return expect(postBalance).to.be.bignumber.equal(transferAmount);
+        });
+        it('should fail to transfer tokens if fromAddress has an insufficient balance', async () => {
+            const fromAddress = addressWithoutFunds;
+            const toAddress = coinbase;
+            return expect(
+                zeroEx.token.transferAsync(token.address, fromAddress, toAddress, transferAmount),
+            ).to.be.rejectedWith(ZeroExError.InsufficientBalanceForTransfer);
+        });
+        it('should throw a CONTRACT_DOES_NOT_EXIST error for a non-existent token contract', async () => {
+            const nonExistentTokenAddress = '0x9dd402f14d67e001d8efbe6583e51bf9706aa065';
+            const fromAddress = coinbase;
+            const toAddress = coinbase;
+            return expect(
+                zeroEx.token.transferAsync(nonExistentTokenAddress, fromAddress, toAddress, transferAmount),
+            ).to.be.rejectedWith(ZeroExError.TokenContractDoesNotExist);
+        });
+    });
+    describe('#transferFromAsync', () => {
+        let token: Token;
+        let toAddress: string;
+        let senderAddress: string;
+        before(async () => {
+            token = tokens[0];
+            toAddress = addressWithoutFunds;
+            senderAddress = userAddresses[2];
+        });
+        it('should fail to transfer tokens if fromAddress has insufficient allowance set', async () => {
+            const fromAddress = coinbase;
+            const transferAmount = new BigNumber(42);
+
+            const fromAddressBalance = await zeroEx.token.getBalanceAsync(token.address, fromAddress);
+            expect(fromAddressBalance).to.be.bignumber.greaterThan(transferAmount);
+
+            const fromAddressAllowance = await zeroEx.token.getAllowanceAsync(token.address, fromAddress, toAddress);
+            expect(fromAddressAllowance).to.be.bignumber.equal(0);
+
+            return expect(
+                zeroEx.token.transferFromAsync(token.address, fromAddress, toAddress, senderAddress, transferAmount),
+            ).to.be.rejectedWith(ZeroExError.InsufficientAllowanceForTransfer);
+        });
+        it('[regression] should fail to transfer tokens if set allowance for toAddress instead of senderAddress', async () => {
+            const fromAddress = coinbase;
+            const transferAmount = new BigNumber(42);
+
+            await zeroEx.token.setAllowanceAsync(token.address, fromAddress, toAddress, transferAmount);
+
+            return expect(
+                zeroEx.token.transferFromAsync(token.address, fromAddress, toAddress, senderAddress, transferAmount),
+            ).to.be.rejectedWith(ZeroExError.InsufficientAllowanceForTransfer);
+        });
+        it('should fail to transfer tokens if fromAddress has insufficient balance', async () => {
+            const fromAddress = addressWithoutFunds;
+            const transferAmount = new BigNumber(42);
+
+            const fromAddressBalance = await zeroEx.token.getBalanceAsync(token.address, fromAddress);
+            expect(fromAddressBalance).to.be.bignumber.equal(0);
+
+            await zeroEx.token.setAllowanceAsync(token.address, fromAddress, senderAddress, transferAmount);
+            const fromAddressAllowance = await zeroEx.token.getAllowanceAsync(
+                token.address,
+                fromAddress,
+                senderAddress,
+            );
+            expect(fromAddressAllowance).to.be.bignumber.equal(transferAmount);
+
+            return expect(
+                zeroEx.token.transferFromAsync(token.address, fromAddress, toAddress, senderAddress, transferAmount),
+            ).to.be.rejectedWith(ZeroExError.InsufficientBalanceForTransfer);
+        });
+        it('should successfully transfer tokens', async () => {
+            const fromAddress = coinbase;
+
+            const preBalance = await zeroEx.token.getBalanceAsync(token.address, toAddress);
+            expect(preBalance).to.be.bignumber.equal(0);
+
+            const transferAmount = new BigNumber(42);
+            await zeroEx.token.setAllowanceAsync(token.address, fromAddress, senderAddress, transferAmount);
+
+            await zeroEx.token.transferFromAsync(token.address, fromAddress, toAddress, senderAddress, transferAmount);
+            const postBalance = await zeroEx.token.getBalanceAsync(token.address, toAddress);
+            return expect(postBalance).to.be.bignumber.equal(transferAmount);
+        });
+        it('should throw a CONTRACT_DOES_NOT_EXIST error for a non-existent token contract', async () => {
+            const fromAddress = coinbase;
+            const nonExistentTokenAddress = '0x9dd402f14d67e001d8efbe6583e51bf9706aa065';
+            return expect(
+                zeroEx.token.transferFromAsync(
+                    nonExistentTokenAddress,
+                    fromAddress,
+                    toAddress,
+                    senderAddress,
+                    new BigNumber(42),
+                ),
+            ).to.be.rejectedWith(ZeroExError.TokenContractDoesNotExist);
+        });
+    });
+    describe('#getBalanceAsync', () => {
+        describe('With web3 provider with accounts', () => {
+            it('should return the balance for an existing ERC20 token', async () => {
+                const token = tokens[0];
+                const ownerAddress = coinbase;
+                const balance = await zeroEx.token.getBalanceAsync(token.address, ownerAddress);
+                const expectedBalance = new BigNumber('1000000000000000000000000000');
+                return expect(balance).to.be.bignumber.equal(expectedBalance);
+            });
+            it('should throw a CONTRACT_DOES_NOT_EXIST error for a non-existent token contract', async () => {
+                const nonExistentTokenAddress = '0x9dd402f14d67e001d8efbe6583e51bf9706aa065';
+                const ownerAddress = coinbase;
+                return expect(zeroEx.token.getBalanceAsync(nonExistentTokenAddress, ownerAddress)).to.be.rejectedWith(
+                    ZeroExError.TokenContractDoesNotExist,
+                );
+            });
+            it('should return a balance of 0 for a non-existent owner address', async () => {
+                const token = tokens[0];
+                const nonExistentOwner = '0x198c6ad858f213fb31b6fe809e25040e6b964593';
+                const balance = await zeroEx.token.getBalanceAsync(token.address, nonExistentOwner);
+                const expectedBalance = new BigNumber(0);
+                return expect(balance).to.be.bignumber.equal(expectedBalance);
+            });
+        });
+        describe('With web3 provider without accounts', () => {
+            let zeroExWithoutAccounts: ZeroEx;
+            before(async () => {
+                const hasAddresses = false;
+                const web3WithoutAccounts = web3Factory.create(hasAddresses);
+                zeroExWithoutAccounts = new ZeroEx(web3WithoutAccounts.currentProvider, config);
+            });
+            it('should return balance even when called with Web3 provider instance without addresses', async () => {
+                const token = tokens[0];
+                const ownerAddress = coinbase;
+                const balance = await zeroExWithoutAccounts.token.getBalanceAsync(token.address, ownerAddress);
+                const expectedBalance = new BigNumber('1000000000000000000000000000');
+                return expect(balance).to.be.bignumber.equal(expectedBalance);
+            });
+        });
+    });
+    describe('#setAllowanceAsync', () => {
+        it("should set the spender's allowance", async () => {
+            const token = tokens[0];
+            const ownerAddress = coinbase;
+            const spenderAddress = addressWithoutFunds;
+
+            const allowanceBeforeSet = await zeroEx.token.getAllowanceAsync(
+                token.address,
+                ownerAddress,
+                spenderAddress,
+            );
+            const expectedAllowanceBeforeAllowanceSet = new BigNumber(0);
+            expect(allowanceBeforeSet).to.be.bignumber.equal(expectedAllowanceBeforeAllowanceSet);
+
+            const amountInBaseUnits = new BigNumber(50);
+            await zeroEx.token.setAllowanceAsync(token.address, ownerAddress, spenderAddress, amountInBaseUnits);
+
+            const allowanceAfterSet = await zeroEx.token.getAllowanceAsync(token.address, ownerAddress, spenderAddress);
+            const expectedAllowanceAfterAllowanceSet = amountInBaseUnits;
+            return expect(allowanceAfterSet).to.be.bignumber.equal(expectedAllowanceAfterAllowanceSet);
+        });
+    });
+    describe('#setUnlimitedAllowanceAsync', () => {
+        it("should set the unlimited spender's allowance", async () => {
+            const token = tokens[0];
+            const ownerAddress = coinbase;
+            const spenderAddress = addressWithoutFunds;
+
+            await zeroEx.token.setUnlimitedAllowanceAsync(token.address, ownerAddress, spenderAddress);
+            const allowance = await zeroEx.token.getAllowanceAsync(token.address, ownerAddress, spenderAddress);
+            return expect(allowance).to.be.bignumber.equal(zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
+        });
+        it('should reduce the gas cost for transfers including tokens with unlimited allowance support', async () => {
+            const transferAmount = new BigNumber(5);
+            const zrx = tokenUtils.getProtocolTokenOrThrow();
+            const [, userWithNormalAllowance, userWithUnlimitedAllowance] = userAddresses;
+            await zeroEx.token.setAllowanceAsync(zrx.address, coinbase, userWithNormalAllowance, transferAmount);
+            await zeroEx.token.setUnlimitedAllowanceAsync(zrx.address, coinbase, userWithUnlimitedAllowance);
+
+            const initBalanceWithNormalAllowance = await web3Wrapper.getBalanceInWeiAsync(userWithNormalAllowance);
+            const initBalanceWithUnlimitedAllowance = await web3Wrapper.getBalanceInWeiAsync(
+                userWithUnlimitedAllowance,
+            );
+
+            await zeroEx.token.transferFromAsync(
+                zrx.address,
+                coinbase,
+                userWithNormalAllowance,
+                userWithNormalAllowance,
+                transferAmount,
+            );
+            await zeroEx.token.transferFromAsync(
+                zrx.address,
+                coinbase,
+                userWithUnlimitedAllowance,
+                userWithUnlimitedAllowance,
+                transferAmount,
+            );
+
+            const finalBalanceWithNormalAllowance = await web3Wrapper.getBalanceInWeiAsync(userWithNormalAllowance);
+            const finalBalanceWithUnlimitedAllowance = await web3Wrapper.getBalanceInWeiAsync(
+                userWithUnlimitedAllowance,
+            );
+
+            const normalGasCost = initBalanceWithNormalAllowance.minus(finalBalanceWithNormalAllowance);
+            const unlimitedGasCost = initBalanceWithUnlimitedAllowance.minus(finalBalanceWithUnlimitedAllowance);
+
+            // In theory the gas cost with unlimited allowance should be smaller, but with testrpc it's actually bigger.
+            // This needs to be investigated in ethereumjs-vm. This test is essentially a repro.
+            // TODO: Make this test pass with inverted assertion.
+            expect(unlimitedGasCost.toNumber()).to.be.gt(normalGasCost.toNumber());
+        });
+    });
+    describe('#getAllowanceAsync', () => {
+        describe('With web3 provider with accounts', () => {
+            it('should get the proxy allowance', async () => {
+                const token = tokens[0];
+                const ownerAddress = coinbase;
+                const spenderAddress = addressWithoutFunds;
+
+                const amountInBaseUnits = new BigNumber(50);
+                await zeroEx.token.setAllowanceAsync(token.address, ownerAddress, spenderAddress, amountInBaseUnits);
+
+                const allowance = await zeroEx.token.getAllowanceAsync(token.address, ownerAddress, spenderAddress);
+                const expectedAllowance = amountInBaseUnits;
+                return expect(allowance).to.be.bignumber.equal(expectedAllowance);
+            });
+            it('should return 0 if no allowance set yet', async () => {
+                const token = tokens[0];
+                const ownerAddress = coinbase;
+                const spenderAddress = addressWithoutFunds;
+                const allowance = await zeroEx.token.getAllowanceAsync(token.address, ownerAddress, spenderAddress);
+                const expectedAllowance = new BigNumber(0);
+                return expect(allowance).to.be.bignumber.equal(expectedAllowance);
+            });
+        });
+        describe('With web3 provider without accounts', () => {
+            let zeroExWithoutAccounts: ZeroEx;
+            before(async () => {
+                const hasAddresses = false;
+                const web3WithoutAccounts = web3Factory.create(hasAddresses);
+                zeroExWithoutAccounts = new ZeroEx(web3WithoutAccounts.currentProvider, config);
+            });
+            it('should get the proxy allowance', async () => {
+                const token = tokens[0];
+                const ownerAddress = coinbase;
+                const spenderAddress = addressWithoutFunds;
+
+                const amountInBaseUnits = new BigNumber(50);
+                await zeroEx.token.setAllowanceAsync(token.address, ownerAddress, spenderAddress, amountInBaseUnits);
+
+                const allowance = await zeroExWithoutAccounts.token.getAllowanceAsync(
+                    token.address,
+                    ownerAddress,
+                    spenderAddress,
+                );
+                const expectedAllowance = amountInBaseUnits;
+                return expect(allowance).to.be.bignumber.equal(expectedAllowance);
+            });
+        });
+    });
+    describe('#getProxyAllowanceAsync', () => {
+        it('should get the proxy allowance', async () => {
+            const token = tokens[0];
+            const ownerAddress = coinbase;
+
+            const amountInBaseUnits = new BigNumber(50);
+            await zeroEx.token.setProxyAllowanceAsync(token.address, ownerAddress, amountInBaseUnits);
+
+            const allowance = await zeroEx.token.getProxyAllowanceAsync(token.address, ownerAddress);
+            const expectedAllowance = amountInBaseUnits;
+            return expect(allowance).to.be.bignumber.equal(expectedAllowance);
+        });
+    });
+    describe('#setProxyAllowanceAsync', () => {
+        it('should set the proxy allowance', async () => {
+            const token = tokens[0];
+            const ownerAddress = coinbase;
+
+            const allowanceBeforeSet = await zeroEx.token.getProxyAllowanceAsync(token.address, ownerAddress);
+            const expectedAllowanceBeforeAllowanceSet = new BigNumber(0);
+            expect(allowanceBeforeSet).to.be.bignumber.equal(expectedAllowanceBeforeAllowanceSet);
+
+            const amountInBaseUnits = new BigNumber(50);
+            await zeroEx.token.setProxyAllowanceAsync(token.address, ownerAddress, amountInBaseUnits);
+
+            const allowanceAfterSet = await zeroEx.token.getProxyAllowanceAsync(token.address, ownerAddress);
+            const expectedAllowanceAfterAllowanceSet = amountInBaseUnits;
+            return expect(allowanceAfterSet).to.be.bignumber.equal(expectedAllowanceAfterAllowanceSet);
+        });
+    });
+    describe('#setUnlimitedProxyAllowanceAsync', () => {
+        it('should set the unlimited proxy allowance', async () => {
+            const token = tokens[0];
+            const ownerAddress = coinbase;
+
+            await zeroEx.token.setUnlimitedProxyAllowanceAsync(token.address, ownerAddress);
+            const allowance = await zeroEx.token.getProxyAllowanceAsync(token.address, ownerAddress);
+            return expect(allowance).to.be.bignumber.equal(zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
+        });
+    });
+    describe('#subscribe', () => {
+        const indexFilterValues = {};
+        let tokenAddress: string;
+        const transferAmount = new BigNumber(42);
+        const allowanceAmount = new BigNumber(42);
+        before(() => {
+            const token = tokens[0];
+            tokenAddress = token.address;
+        });
+        afterEach(() => {
+            zeroEx.token.unsubscribeAll();
+        });
+        // Hack: Mocha does not allow a test to be both async and have a `done` callback
+        // Since we need to await the receipt of the event in the `subscribe` callback,
+        // we do need both. A hack is to make the top-level a sync fn w/ a done callback and then
+        // wrap the rest of the test in an async block
+        // Source: https://github.com/mochajs/mocha/issues/2407
+        it('Should receive the Transfer event when tokens are transfered', (done: DoneCallback) => {
+            (async () => {
+                const callback = reportNodeCallbackErrors(done)(
+                    (logEvent: DecodedLogEvent<TransferContractEventArgs>) => {
+                        expect(logEvent.isRemoved).to.be.false();
+                        expect(logEvent.log.logIndex).to.be.equal(0);
+                        expect(logEvent.log.transactionIndex).to.be.equal(0);
+                        expect(logEvent.log.blockNumber).to.be.a('number');
+                        const args = logEvent.log.args;
+                        expect(args._from).to.be.equal(coinbase);
+                        expect(args._to).to.be.equal(addressWithoutFunds);
+                        expect(args._value).to.be.bignumber.equal(transferAmount);
+                    },
+                );
+                zeroEx.token.subscribe(tokenAddress, TokenEvents.Transfer, indexFilterValues, callback);
+                await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
+            })().catch(done);
+        });
+        it('Should receive the Approval event when allowance is being set', (done: DoneCallback) => {
+            (async () => {
+                const callback = reportNodeCallbackErrors(done)(
+                    (logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
+                        expect(logEvent).to.not.be.undefined();
+                        expect(logEvent.isRemoved).to.be.false();
+                        const args = logEvent.log.args;
+                        expect(args._owner).to.be.equal(coinbase);
+                        expect(args._spender).to.be.equal(addressWithoutFunds);
+                        expect(args._value).to.be.bignumber.equal(allowanceAmount);
+                    },
+                );
+                zeroEx.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
+                await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount);
+            })().catch(done);
+        });
+        it('Outstanding subscriptions are cancelled when zeroEx.setProvider called', (done: DoneCallback) => {
+            (async () => {
+                const callbackNeverToBeCalled = reportNodeCallbackErrors(done)(
+                    (logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
+                        done(new Error('Expected this subscription to have been cancelled'));
+                    },
+                );
+                zeroEx.token.subscribe(tokenAddress, TokenEvents.Transfer, indexFilterValues, callbackNeverToBeCalled);
+                const callbackToBeCalled = reportNodeCallbackErrors(done)();
+                const newProvider = web3Factory.getRpcProvider();
+                zeroEx.setProvider(newProvider, constants.TESTRPC_NETWORK_ID);
+                zeroEx.token.subscribe(tokenAddress, TokenEvents.Transfer, indexFilterValues, callbackToBeCalled);
+                await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
+            })().catch(done);
+        });
+        it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => {
+            (async () => {
+                const callbackNeverToBeCalled = reportNodeCallbackErrors(done)(
+                    (logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
+                        done(new Error('Expected this subscription to have been cancelled'));
+                    },
+                );
+                const subscriptionToken = zeroEx.token.subscribe(
+                    tokenAddress,
+                    TokenEvents.Transfer,
+                    indexFilterValues,
+                    callbackNeverToBeCalled,
+                );
+                zeroEx.token.unsubscribe(subscriptionToken);
+                await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
+                done();
+            })().catch(done);
+        });
+    });
+    describe('#getLogsAsync', () => {
+        let tokenAddress: string;
+        let tokenTransferProxyAddress: string;
+        const blockRange: BlockRange = {
+            fromBlock: 0,
+            toBlock: BlockParamLiteral.Latest,
+        };
+        let txHash: string;
+        before(() => {
+            const token = tokens[0];
+            tokenAddress = token.address;
+            tokenTransferProxyAddress = zeroEx.proxy.getContractAddress();
+        });
+        it('should get logs with decoded args emitted by Approval', async () => {
+            txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(tokenAddress, coinbase);
+            await zeroEx.awaitTransactionMinedAsync(txHash);
+            const eventName = TokenEvents.Approval;
+            const indexFilterValues = {};
+            const logs = await zeroEx.token.getLogsAsync<ApprovalContractEventArgs>(
+                tokenAddress,
+                eventName,
+                blockRange,
+                indexFilterValues,
+            );
+            expect(logs).to.have.length(1);
+            const args = logs[0].args;
+            expect(logs[0].event).to.be.equal(eventName);
+            expect(args._owner).to.be.equal(coinbase);
+            expect(args._spender).to.be.equal(tokenTransferProxyAddress);
+            expect(args._value).to.be.bignumber.equal(zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
+        });
+        it('should only get the logs with the correct event name', async () => {
+            txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(tokenAddress, coinbase);
+            await zeroEx.awaitTransactionMinedAsync(txHash);
+            const differentEventName = TokenEvents.Transfer;
+            const indexFilterValues = {};
+            const logs = await zeroEx.token.getLogsAsync(
+                tokenAddress,
+                differentEventName,
+                blockRange,
+                indexFilterValues,
+            );
+            expect(logs).to.have.length(0);
+        });
+        it('should only get the logs with the correct indexed fields', async () => {
+            txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(tokenAddress, coinbase);
+            await zeroEx.awaitTransactionMinedAsync(txHash);
+            txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(tokenAddress, addressWithoutFunds);
+            await zeroEx.awaitTransactionMinedAsync(txHash);
+            const eventName = TokenEvents.Approval;
+            const indexFilterValues = {
+                _owner: coinbase,
+            };
+            const logs = await zeroEx.token.getLogsAsync<ApprovalContractEventArgs>(
+                tokenAddress,
+                eventName,
+                blockRange,
+                indexFilterValues,
+            );
+            expect(logs).to.have.length(1);
+            const args = logs[0].args;
+            expect(args._owner).to.be.equal(coinbase);
+        });
+    });
 });
 // tslint:disable:max-file-line-count
diff --git a/packages/0x.js/test/utils/chai_setup.ts b/packages/0x.js/test/utils/chai_setup.ts
index e156b5f7c..078edd309 100644
--- a/packages/0x.js/test/utils/chai_setup.ts
+++ b/packages/0x.js/test/utils/chai_setup.ts
@@ -4,10 +4,10 @@ import ChaiBigNumber = require('chai-bignumber');
 import * as dirtyChai from 'dirty-chai';
 
 export const chaiSetup = {
-	configure() {
-		chai.config.includeStack = true;
-		chai.use(ChaiBigNumber());
-		chai.use(dirtyChai);
-		chai.use(chaiAsPromised);
-	},
+    configure() {
+        chai.config.includeStack = true;
+        chai.use(ChaiBigNumber());
+        chai.use(dirtyChai);
+        chai.use(chaiAsPromised);
+    },
 };
diff --git a/packages/0x.js/test/utils/constants.ts b/packages/0x.js/test/utils/constants.ts
index b7161e9ab..a9e665c25 100644
--- a/packages/0x.js/test/utils/constants.ts
+++ b/packages/0x.js/test/utils/constants.ts
@@ -1,11 +1,11 @@
 export const constants = {
-	NULL_ADDRESS: '0x0000000000000000000000000000000000000000',
-	RPC_URL: 'http://localhost:8545',
-	ROPSTEN_NETWORK_ID: 3,
-	KOVAN_NETWORK_ID: 42,
-	TESTRPC_NETWORK_ID: 50,
-	KOVAN_RPC_URL: 'https://kovan.infura.io/',
-	ROPSTEN_RPC_URL: 'https://ropsten.infura.io/',
-	ZRX_DECIMALS: 18,
-	GAS_ESTIMATE: 500000,
+    NULL_ADDRESS: '0x0000000000000000000000000000000000000000',
+    RPC_URL: 'http://localhost:8545',
+    ROPSTEN_NETWORK_ID: 3,
+    KOVAN_NETWORK_ID: 42,
+    TESTRPC_NETWORK_ID: 50,
+    KOVAN_RPC_URL: 'https://kovan.infura.io/',
+    ROPSTEN_RPC_URL: 'https://ropsten.infura.io/',
+    ZRX_DECIMALS: 18,
+    GAS_ESTIMATE: 500000,
 };
diff --git a/packages/0x.js/test/utils/fill_scenarios.ts b/packages/0x.js/test/utils/fill_scenarios.ts
index 1d4b8b6f4..1a61487f4 100644
--- a/packages/0x.js/test/utils/fill_scenarios.ts
+++ b/packages/0x.js/test/utils/fill_scenarios.ts
@@ -11,192 +11,192 @@ import { constants } from './constants';
 const INITIAL_COINBASE_TOKEN_SUPPLY_IN_UNITS = new BigNumber(100);
 
 export class FillScenarios {
-	private _zeroEx: ZeroEx;
-	private _userAddresses: string[];
-	private _tokens: Token[];
-	private _coinbase: string;
-	private _zrxTokenAddress: string;
-	private _exchangeContractAddress: string;
-	constructor(
-		zeroEx: ZeroEx,
-		userAddresses: string[],
-		tokens: Token[],
-		zrxTokenAddress: string,
-		exchangeContractAddress: string,
-	) {
-		this._zeroEx = zeroEx;
-		this._userAddresses = userAddresses;
-		this._tokens = tokens;
-		this._coinbase = userAddresses[0];
-		this._zrxTokenAddress = zrxTokenAddress;
-		this._exchangeContractAddress = exchangeContractAddress;
-	}
-	public async initTokenBalancesAsync() {
-		const web3Wrapper = (this._zeroEx as any)._web3Wrapper as Web3Wrapper;
-		for (const token of this._tokens) {
-			if (token.symbol !== 'ZRX' && token.symbol !== 'WETH') {
-				const contractInstance = web3Wrapper.getContractInstance(
-					artifacts.DummyTokenArtifact.abi,
-					token.address,
-				);
-				const defaults = {};
-				const dummyToken = new DummyTokenContract(contractInstance, defaults);
-				const tokenSupply = ZeroEx.toBaseUnitAmount(INITIAL_COINBASE_TOKEN_SUPPLY_IN_UNITS, token.decimals);
-				const txHash = await dummyToken.setBalance.sendTransactionAsync(this._coinbase, tokenSupply, {
-					from: this._coinbase,
-				});
-				await this._zeroEx.awaitTransactionMinedAsync(txHash);
-			}
-		}
-	}
-	public async createFillableSignedOrderAsync(
-		makerTokenAddress: string,
-		takerTokenAddress: string,
-		makerAddress: string,
-		takerAddress: string,
-		fillableAmount: BigNumber,
-		expirationUnixTimestampSec?: BigNumber,
-	): Promise<SignedOrder> {
-		return this.createAsymmetricFillableSignedOrderAsync(
-			makerTokenAddress,
-			takerTokenAddress,
-			makerAddress,
-			takerAddress,
-			fillableAmount,
-			fillableAmount,
-			expirationUnixTimestampSec,
-		);
-	}
-	public async createFillableSignedOrderWithFeesAsync(
-		makerTokenAddress: string,
-		takerTokenAddress: string,
-		makerFee: BigNumber,
-		takerFee: BigNumber,
-		makerAddress: string,
-		takerAddress: string,
-		fillableAmount: BigNumber,
-		feeRecepient: string,
-		expirationUnixTimestampSec?: BigNumber,
-	): Promise<SignedOrder> {
-		return this._createAsymmetricFillableSignedOrderWithFeesAsync(
-			makerTokenAddress,
-			takerTokenAddress,
-			makerFee,
-			takerFee,
-			makerAddress,
-			takerAddress,
-			fillableAmount,
-			fillableAmount,
-			feeRecepient,
-			expirationUnixTimestampSec,
-		);
-	}
-	public async createAsymmetricFillableSignedOrderAsync(
-		makerTokenAddress: string,
-		takerTokenAddress: string,
-		makerAddress: string,
-		takerAddress: string,
-		makerFillableAmount: BigNumber,
-		takerFillableAmount: BigNumber,
-		expirationUnixTimestampSec?: BigNumber,
-	): Promise<SignedOrder> {
-		const makerFee = new BigNumber(0);
-		const takerFee = new BigNumber(0);
-		const feeRecepient = constants.NULL_ADDRESS;
-		return this._createAsymmetricFillableSignedOrderWithFeesAsync(
-			makerTokenAddress,
-			takerTokenAddress,
-			makerFee,
-			takerFee,
-			makerAddress,
-			takerAddress,
-			makerFillableAmount,
-			takerFillableAmount,
-			feeRecepient,
-			expirationUnixTimestampSec,
-		);
-	}
-	public async createPartiallyFilledSignedOrderAsync(
-		makerTokenAddress: string,
-		takerTokenAddress: string,
-		takerAddress: string,
-		fillableAmount: BigNumber,
-		partialFillAmount: BigNumber,
-	) {
-		const [makerAddress] = this._userAddresses;
-		const signedOrder = await this.createAsymmetricFillableSignedOrderAsync(
-			makerTokenAddress,
-			takerTokenAddress,
-			makerAddress,
-			takerAddress,
-			fillableAmount,
-			fillableAmount,
-		);
-		const shouldThrowOnInsufficientBalanceOrAllowance = false;
-		await this._zeroEx.exchange.fillOrderAsync(
-			signedOrder,
-			partialFillAmount,
-			shouldThrowOnInsufficientBalanceOrAllowance,
-			takerAddress,
-		);
-		return signedOrder;
-	}
-	private async _createAsymmetricFillableSignedOrderWithFeesAsync(
-		makerTokenAddress: string,
-		takerTokenAddress: string,
-		makerFee: BigNumber,
-		takerFee: BigNumber,
-		makerAddress: string,
-		takerAddress: string,
-		makerFillableAmount: BigNumber,
-		takerFillableAmount: BigNumber,
-		feeRecepient: string,
-		expirationUnixTimestampSec?: BigNumber,
-	): Promise<SignedOrder> {
-		await Promise.all([
-			this._increaseBalanceAndAllowanceAsync(makerTokenAddress, makerAddress, makerFillableAmount),
-			this._increaseBalanceAndAllowanceAsync(takerTokenAddress, takerAddress, takerFillableAmount),
-		]);
-		await Promise.all([
-			this._increaseBalanceAndAllowanceAsync(this._zrxTokenAddress, makerAddress, makerFee),
-			this._increaseBalanceAndAllowanceAsync(this._zrxTokenAddress, takerAddress, takerFee),
-		]);
+    private _zeroEx: ZeroEx;
+    private _userAddresses: string[];
+    private _tokens: Token[];
+    private _coinbase: string;
+    private _zrxTokenAddress: string;
+    private _exchangeContractAddress: string;
+    constructor(
+        zeroEx: ZeroEx,
+        userAddresses: string[],
+        tokens: Token[],
+        zrxTokenAddress: string,
+        exchangeContractAddress: string,
+    ) {
+        this._zeroEx = zeroEx;
+        this._userAddresses = userAddresses;
+        this._tokens = tokens;
+        this._coinbase = userAddresses[0];
+        this._zrxTokenAddress = zrxTokenAddress;
+        this._exchangeContractAddress = exchangeContractAddress;
+    }
+    public async initTokenBalancesAsync() {
+        const web3Wrapper = (this._zeroEx as any)._web3Wrapper as Web3Wrapper;
+        for (const token of this._tokens) {
+            if (token.symbol !== 'ZRX' && token.symbol !== 'WETH') {
+                const contractInstance = web3Wrapper.getContractInstance(
+                    artifacts.DummyTokenArtifact.abi,
+                    token.address,
+                );
+                const defaults = {};
+                const dummyToken = new DummyTokenContract(contractInstance, defaults);
+                const tokenSupply = ZeroEx.toBaseUnitAmount(INITIAL_COINBASE_TOKEN_SUPPLY_IN_UNITS, token.decimals);
+                const txHash = await dummyToken.setBalance.sendTransactionAsync(this._coinbase, tokenSupply, {
+                    from: this._coinbase,
+                });
+                await this._zeroEx.awaitTransactionMinedAsync(txHash);
+            }
+        }
+    }
+    public async createFillableSignedOrderAsync(
+        makerTokenAddress: string,
+        takerTokenAddress: string,
+        makerAddress: string,
+        takerAddress: string,
+        fillableAmount: BigNumber,
+        expirationUnixTimestampSec?: BigNumber,
+    ): Promise<SignedOrder> {
+        return this.createAsymmetricFillableSignedOrderAsync(
+            makerTokenAddress,
+            takerTokenAddress,
+            makerAddress,
+            takerAddress,
+            fillableAmount,
+            fillableAmount,
+            expirationUnixTimestampSec,
+        );
+    }
+    public async createFillableSignedOrderWithFeesAsync(
+        makerTokenAddress: string,
+        takerTokenAddress: string,
+        makerFee: BigNumber,
+        takerFee: BigNumber,
+        makerAddress: string,
+        takerAddress: string,
+        fillableAmount: BigNumber,
+        feeRecepient: string,
+        expirationUnixTimestampSec?: BigNumber,
+    ): Promise<SignedOrder> {
+        return this._createAsymmetricFillableSignedOrderWithFeesAsync(
+            makerTokenAddress,
+            takerTokenAddress,
+            makerFee,
+            takerFee,
+            makerAddress,
+            takerAddress,
+            fillableAmount,
+            fillableAmount,
+            feeRecepient,
+            expirationUnixTimestampSec,
+        );
+    }
+    public async createAsymmetricFillableSignedOrderAsync(
+        makerTokenAddress: string,
+        takerTokenAddress: string,
+        makerAddress: string,
+        takerAddress: string,
+        makerFillableAmount: BigNumber,
+        takerFillableAmount: BigNumber,
+        expirationUnixTimestampSec?: BigNumber,
+    ): Promise<SignedOrder> {
+        const makerFee = new BigNumber(0);
+        const takerFee = new BigNumber(0);
+        const feeRecepient = constants.NULL_ADDRESS;
+        return this._createAsymmetricFillableSignedOrderWithFeesAsync(
+            makerTokenAddress,
+            takerTokenAddress,
+            makerFee,
+            takerFee,
+            makerAddress,
+            takerAddress,
+            makerFillableAmount,
+            takerFillableAmount,
+            feeRecepient,
+            expirationUnixTimestampSec,
+        );
+    }
+    public async createPartiallyFilledSignedOrderAsync(
+        makerTokenAddress: string,
+        takerTokenAddress: string,
+        takerAddress: string,
+        fillableAmount: BigNumber,
+        partialFillAmount: BigNumber,
+    ) {
+        const [makerAddress] = this._userAddresses;
+        const signedOrder = await this.createAsymmetricFillableSignedOrderAsync(
+            makerTokenAddress,
+            takerTokenAddress,
+            makerAddress,
+            takerAddress,
+            fillableAmount,
+            fillableAmount,
+        );
+        const shouldThrowOnInsufficientBalanceOrAllowance = false;
+        await this._zeroEx.exchange.fillOrderAsync(
+            signedOrder,
+            partialFillAmount,
+            shouldThrowOnInsufficientBalanceOrAllowance,
+            takerAddress,
+        );
+        return signedOrder;
+    }
+    private async _createAsymmetricFillableSignedOrderWithFeesAsync(
+        makerTokenAddress: string,
+        takerTokenAddress: string,
+        makerFee: BigNumber,
+        takerFee: BigNumber,
+        makerAddress: string,
+        takerAddress: string,
+        makerFillableAmount: BigNumber,
+        takerFillableAmount: BigNumber,
+        feeRecepient: string,
+        expirationUnixTimestampSec?: BigNumber,
+    ): Promise<SignedOrder> {
+        await Promise.all([
+            this._increaseBalanceAndAllowanceAsync(makerTokenAddress, makerAddress, makerFillableAmount),
+            this._increaseBalanceAndAllowanceAsync(takerTokenAddress, takerAddress, takerFillableAmount),
+        ]);
+        await Promise.all([
+            this._increaseBalanceAndAllowanceAsync(this._zrxTokenAddress, makerAddress, makerFee),
+            this._increaseBalanceAndAllowanceAsync(this._zrxTokenAddress, takerAddress, takerFee),
+        ]);
 
-		const signedOrder = await orderFactory.createSignedOrderAsync(
-			this._zeroEx,
-			makerAddress,
-			takerAddress,
-			makerFee,
-			takerFee,
-			makerFillableAmount,
-			makerTokenAddress,
-			takerFillableAmount,
-			takerTokenAddress,
-			this._exchangeContractAddress,
-			feeRecepient,
-			expirationUnixTimestampSec,
-		);
-		return signedOrder;
-	}
-	private async _increaseBalanceAndAllowanceAsync(
-		tokenAddress: string,
-		address: string,
-		amount: BigNumber,
-	): Promise<void> {
-		if (amount.isZero() || address === ZeroEx.NULL_ADDRESS) {
-			return; // noop
-		}
-		await Promise.all([
-			this._increaseBalanceAsync(tokenAddress, address, amount),
-			this._increaseAllowanceAsync(tokenAddress, address, amount),
-		]);
-	}
-	private async _increaseBalanceAsync(tokenAddress: string, address: string, amount: BigNumber): Promise<void> {
-		await this._zeroEx.token.transferAsync(tokenAddress, this._coinbase, address, amount);
-	}
-	private async _increaseAllowanceAsync(tokenAddress: string, address: string, amount: BigNumber): Promise<void> {
-		const oldMakerAllowance = await this._zeroEx.token.getProxyAllowanceAsync(tokenAddress, address);
-		const newMakerAllowance = oldMakerAllowance.plus(amount);
-		await this._zeroEx.token.setProxyAllowanceAsync(tokenAddress, address, newMakerAllowance);
-	}
+        const signedOrder = await orderFactory.createSignedOrderAsync(
+            this._zeroEx,
+            makerAddress,
+            takerAddress,
+            makerFee,
+            takerFee,
+            makerFillableAmount,
+            makerTokenAddress,
+            takerFillableAmount,
+            takerTokenAddress,
+            this._exchangeContractAddress,
+            feeRecepient,
+            expirationUnixTimestampSec,
+        );
+        return signedOrder;
+    }
+    private async _increaseBalanceAndAllowanceAsync(
+        tokenAddress: string,
+        address: string,
+        amount: BigNumber,
+    ): Promise<void> {
+        if (amount.isZero() || address === ZeroEx.NULL_ADDRESS) {
+            return; // noop
+        }
+        await Promise.all([
+            this._increaseBalanceAsync(tokenAddress, address, amount),
+            this._increaseAllowanceAsync(tokenAddress, address, amount),
+        ]);
+    }
+    private async _increaseBalanceAsync(tokenAddress: string, address: string, amount: BigNumber): Promise<void> {
+        await this._zeroEx.token.transferAsync(tokenAddress, this._coinbase, address, amount);
+    }
+    private async _increaseAllowanceAsync(tokenAddress: string, address: string, amount: BigNumber): Promise<void> {
+        const oldMakerAllowance = await this._zeroEx.token.getProxyAllowanceAsync(tokenAddress, address);
+        const newMakerAllowance = oldMakerAllowance.plus(amount);
+        await this._zeroEx.token.setProxyAllowanceAsync(tokenAddress, address, newMakerAllowance);
+    }
 }
diff --git a/packages/0x.js/test/utils/order_factory.ts b/packages/0x.js/test/utils/order_factory.ts
index b65920e64..08f2081a4 100644
--- a/packages/0x.js/test/utils/order_factory.ts
+++ b/packages/0x.js/test/utils/order_factory.ts
@@ -6,41 +6,41 @@ import { SignedOrder, ZeroEx } from '../../src';
 const SHOULD_ADD_PERSONAL_MESSAGE_PREFIX = false;
 
 export const orderFactory = {
-	async createSignedOrderAsync(
-		zeroEx: ZeroEx,
-		maker: string,
-		taker: string,
-		makerFee: BigNumber,
-		takerFee: BigNumber,
-		makerTokenAmount: BigNumber,
-		makerTokenAddress: string,
-		takerTokenAmount: BigNumber,
-		takerTokenAddress: string,
-		exchangeContractAddress: string,
-		feeRecipient: string,
-		expirationUnixTimestampSecIfExists?: BigNumber,
-	): Promise<SignedOrder> {
-		const defaultExpirationUnixTimestampSec = new BigNumber(2524604400); // Close to infinite
-		const expirationUnixTimestampSec = _.isUndefined(expirationUnixTimestampSecIfExists)
-			? defaultExpirationUnixTimestampSec
-			: expirationUnixTimestampSecIfExists;
-		const order = {
-			maker,
-			taker,
-			makerFee,
-			takerFee,
-			makerTokenAmount,
-			takerTokenAmount,
-			makerTokenAddress,
-			takerTokenAddress,
-			salt: ZeroEx.generatePseudoRandomSalt(),
-			exchangeContractAddress,
-			feeRecipient,
-			expirationUnixTimestampSec,
-		};
-		const orderHash = ZeroEx.getOrderHashHex(order);
-		const ecSignature = await zeroEx.signOrderHashAsync(orderHash, maker, SHOULD_ADD_PERSONAL_MESSAGE_PREFIX);
-		const signedOrder: SignedOrder = _.assign(order, { ecSignature });
-		return signedOrder;
-	},
+    async createSignedOrderAsync(
+        zeroEx: ZeroEx,
+        maker: string,
+        taker: string,
+        makerFee: BigNumber,
+        takerFee: BigNumber,
+        makerTokenAmount: BigNumber,
+        makerTokenAddress: string,
+        takerTokenAmount: BigNumber,
+        takerTokenAddress: string,
+        exchangeContractAddress: string,
+        feeRecipient: string,
+        expirationUnixTimestampSecIfExists?: BigNumber,
+    ): Promise<SignedOrder> {
+        const defaultExpirationUnixTimestampSec = new BigNumber(2524604400); // Close to infinite
+        const expirationUnixTimestampSec = _.isUndefined(expirationUnixTimestampSecIfExists)
+            ? defaultExpirationUnixTimestampSec
+            : expirationUnixTimestampSecIfExists;
+        const order = {
+            maker,
+            taker,
+            makerFee,
+            takerFee,
+            makerTokenAmount,
+            takerTokenAmount,
+            makerTokenAddress,
+            takerTokenAddress,
+            salt: ZeroEx.generatePseudoRandomSalt(),
+            exchangeContractAddress,
+            feeRecipient,
+            expirationUnixTimestampSec,
+        };
+        const orderHash = ZeroEx.getOrderHashHex(order);
+        const ecSignature = await zeroEx.signOrderHashAsync(orderHash, maker, SHOULD_ADD_PERSONAL_MESSAGE_PREFIX);
+        const signedOrder: SignedOrder = _.assign(order, { ecSignature });
+        return signedOrder;
+    },
 };
diff --git a/packages/0x.js/test/utils/report_callback_errors.ts b/packages/0x.js/test/utils/report_callback_errors.ts
index 0b619f73e..27c9745c9 100644
--- a/packages/0x.js/test/utils/report_callback_errors.ts
+++ b/packages/0x.js/test/utils/report_callback_errors.ts
@@ -6,61 +6,61 @@ import { DoneCallback } from '../../src/types';
 const expect = chai.expect;
 
 export const reportNoErrorCallbackErrors = (done: DoneCallback, expectToBeCalledOnce = true) => {
-	return <T>(f?: (value: T) => void) => {
-		const wrapped = (value: T) => {
-			if (_.isUndefined(f)) {
-				done();
-				return;
-			}
-			try {
-				f(value);
-				if (expectToBeCalledOnce) {
-					done();
-				}
-			} catch (err) {
-				done(err);
-			}
-		};
-		return wrapped;
-	};
+    return <T>(f?: (value: T) => void) => {
+        const wrapped = (value: T) => {
+            if (_.isUndefined(f)) {
+                done();
+                return;
+            }
+            try {
+                f(value);
+                if (expectToBeCalledOnce) {
+                    done();
+                }
+            } catch (err) {
+                done(err);
+            }
+        };
+        return wrapped;
+    };
 };
 
 export const reportNodeCallbackErrors = (done: DoneCallback, expectToBeCalledOnce = true) => {
-	return <T>(f?: (value: T) => void) => {
-		const wrapped = (error: Error | null, value: T | undefined) => {
-			if (!_.isNull(error)) {
-				done(error);
-			} else {
-				if (_.isUndefined(f)) {
-					done();
-					return;
-				}
-				try {
-					f(value as T);
-					if (expectToBeCalledOnce) {
-						done();
-					}
-				} catch (err) {
-					done(err);
-				}
-			}
-		};
-		return wrapped;
-	};
+    return <T>(f?: (value: T) => void) => {
+        const wrapped = (error: Error | null, value: T | undefined) => {
+            if (!_.isNull(error)) {
+                done(error);
+            } else {
+                if (_.isUndefined(f)) {
+                    done();
+                    return;
+                }
+                try {
+                    f(value as T);
+                    if (expectToBeCalledOnce) {
+                        done();
+                    }
+                } catch (err) {
+                    done(err);
+                }
+            }
+        };
+        return wrapped;
+    };
 };
 
 export const assertNodeCallbackError = (done: DoneCallback, errMsg: string) => {
-	const wrapped = <T>(error: Error | null, value: T | undefined) => {
-		if (_.isNull(error)) {
-			done(new Error('Expected callback to receive an error'));
-		} else {
-			try {
-				expect(error.message).to.be.equal(errMsg);
-				done();
-			} catch (err) {
-				done(err);
-			}
-		}
-	};
-	return wrapped;
+    const wrapped = <T>(error: Error | null, value: T | undefined) => {
+        if (_.isNull(error)) {
+            done(new Error('Expected callback to receive an error'));
+        } else {
+            try {
+                expect(error.message).to.be.equal(errMsg);
+                done();
+            } catch (err) {
+                done(err);
+            }
+        }
+    };
+    return wrapped;
 };
diff --git a/packages/0x.js/test/utils/subproviders/empty_wallet_subprovider.ts b/packages/0x.js/test/utils/subproviders/empty_wallet_subprovider.ts
index 466b0f350..53f2be83d 100644
--- a/packages/0x.js/test/utils/subproviders/empty_wallet_subprovider.ts
+++ b/packages/0x.js/test/utils/subproviders/empty_wallet_subprovider.ts
@@ -6,22 +6,22 @@ import { JSONRPCPayload } from '../../../src/types';
  * Source: https://github.com/MetaMask/provider-engine/blob/master/subproviders/subprovider.js
  */
 export class EmptyWalletSubprovider {
-	// This method needs to be here to satisfy the interface but linter wants it to be static.
-	// tslint:disable-next-line:prefer-function-over-method
-	public handleRequest(payload: JSONRPCPayload, next: () => void, end: (err: Error | null, result: any) => void) {
-		switch (payload.method) {
-			case 'eth_accounts':
-				end(null, []);
-				return;
+    // This method needs to be here to satisfy the interface but linter wants it to be static.
+    // tslint:disable-next-line:prefer-function-over-method
+    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
-	// tslint:disable-next-line:prefer-function-over-method
-	public setEngine(engine: any) {
-		// noop
-	}
+            default:
+                next();
+                return;
+        }
+    }
+    // Required to implement this method despite not needing it for this subprovider
+    // tslint:disable-next-line:prefer-function-over-method
+    public setEngine(engine: any) {
+        // noop
+    }
 }
diff --git a/packages/0x.js/test/utils/subproviders/fake_gas_estimate_subprovider.ts b/packages/0x.js/test/utils/subproviders/fake_gas_estimate_subprovider.ts
index 307bfb188..e1113a851 100644
--- a/packages/0x.js/test/utils/subproviders/fake_gas_estimate_subprovider.ts
+++ b/packages/0x.js/test/utils/subproviders/fake_gas_estimate_subprovider.ts
@@ -9,26 +9,26 @@ import { JSONRPCPayload } from '../../../src/types';
  * Source: https://github.com/MetaMask/provider-engine/blob/master/subproviders/subprovider.js
  */
 export class FakeGasEstimateSubprovider {
-	private _constantGasAmount: number;
-	constructor(constantGasAmount: number) {
-		this._constantGasAmount = constantGasAmount;
-	}
-	// This method needs to be here to satisfy the interface but linter wants it to be static.
-	// tslint:disable-next-line:prefer-function-over-method
-	public handleRequest(payload: JSONRPCPayload, next: () => void, end: (err: Error | null, result: any) => void) {
-		switch (payload.method) {
-			case 'eth_estimateGas':
-				end(null, this._constantGasAmount);
-				return;
+    private _constantGasAmount: number;
+    constructor(constantGasAmount: number) {
+        this._constantGasAmount = constantGasAmount;
+    }
+    // This method needs to be here to satisfy the interface but linter wants it to be static.
+    // tslint:disable-next-line:prefer-function-over-method
+    public handleRequest(payload: JSONRPCPayload, next: () => void, end: (err: Error | null, result: any) => void) {
+        switch (payload.method) {
+            case 'eth_estimateGas':
+                end(null, this._constantGasAmount);
+                return;
 
-			default:
-				next();
-				return;
-		}
-	}
-	// Required to implement this method despite not needing it for this subprovider
-	// tslint:disable-next-line:prefer-function-over-method
-	public setEngine(engine: any) {
-		// noop
-	}
+            default:
+                next();
+                return;
+        }
+    }
+    // Required to implement this method despite not needing it for this subprovider
+    // tslint:disable-next-line:prefer-function-over-method
+    public setEngine(engine: any) {
+        // noop
+    }
 }
diff --git a/packages/0x.js/test/utils/token_utils.ts b/packages/0x.js/test/utils/token_utils.ts
index 9cbefcf8e..d3fc22ff4 100644
--- a/packages/0x.js/test/utils/token_utils.ts
+++ b/packages/0x.js/test/utils/token_utils.ts
@@ -6,28 +6,28 @@ const PROTOCOL_TOKEN_SYMBOL = 'ZRX';
 const WETH_TOKEN_SYMBOL = 'WETH';
 
 export class TokenUtils {
-	private _tokens: Token[];
-	constructor(tokens: Token[]) {
-		this._tokens = tokens;
-	}
-	public getProtocolTokenOrThrow(): Token {
-		const zrxToken = _.find(this._tokens, { symbol: PROTOCOL_TOKEN_SYMBOL });
-		if (_.isUndefined(zrxToken)) {
-			throw new Error(InternalZeroExError.ZrxNotInTokenRegistry);
-		}
-		return zrxToken;
-	}
-	public getWethTokenOrThrow(): Token {
-		const wethToken = _.find(this._tokens, { symbol: WETH_TOKEN_SYMBOL });
-		if (_.isUndefined(wethToken)) {
-			throw new Error(InternalZeroExError.WethNotInTokenRegistry);
-		}
-		return wethToken;
-	}
-	public getDummyTokens(): Token[] {
-		const dummyTokens = _.filter(this._tokens, token => {
-			return !_.includes([PROTOCOL_TOKEN_SYMBOL, WETH_TOKEN_SYMBOL], token.symbol);
-		});
-		return dummyTokens;
-	}
+    private _tokens: Token[];
+    constructor(tokens: Token[]) {
+        this._tokens = tokens;
+    }
+    public getProtocolTokenOrThrow(): Token {
+        const zrxToken = _.find(this._tokens, { symbol: PROTOCOL_TOKEN_SYMBOL });
+        if (_.isUndefined(zrxToken)) {
+            throw new Error(InternalZeroExError.ZrxNotInTokenRegistry);
+        }
+        return zrxToken;
+    }
+    public getWethTokenOrThrow(): Token {
+        const wethToken = _.find(this._tokens, { symbol: WETH_TOKEN_SYMBOL });
+        if (_.isUndefined(wethToken)) {
+            throw new Error(InternalZeroExError.WethNotInTokenRegistry);
+        }
+        return wethToken;
+    }
+    public getDummyTokens(): Token[] {
+        const dummyTokens = _.filter(this._tokens, token => {
+            return !_.includes([PROTOCOL_TOKEN_SYMBOL, WETH_TOKEN_SYMBOL], token.symbol);
+        });
+        return dummyTokens;
+    }
 }
diff --git a/packages/0x.js/test/utils/web3_factory.ts b/packages/0x.js/test/utils/web3_factory.ts
index 640b96256..26c26e03d 100644
--- a/packages/0x.js/test/utils/web3_factory.ts
+++ b/packages/0x.js/test/utils/web3_factory.ts
@@ -19,24 +19,24 @@ import { constants } from './constants';
 import * as Web3 from 'web3';
 
 export const web3Factory = {
-	create(hasAddresses: boolean = true): Web3 {
-		const provider = this.getRpcProvider(hasAddresses);
-		const web3 = new Web3();
-		web3.setProvider(provider);
-		return web3;
-	},
-	getRpcProvider(hasAddresses: boolean = true): Web3.Provider {
-		const provider = new ProviderEngine();
-		if (!hasAddresses) {
-			provider.addProvider(new EmptyWalletSubprovider());
-		}
-		provider.addProvider(new FakeGasEstimateSubprovider(constants.GAS_ESTIMATE));
-		provider.addProvider(
-			new RpcSubprovider({
-				rpcUrl: constants.RPC_URL,
-			}),
-		);
-		provider.start();
-		return provider;
-	},
+    create(hasAddresses: boolean = true): Web3 {
+        const provider = this.getRpcProvider(hasAddresses);
+        const web3 = new Web3();
+        web3.setProvider(provider);
+        return web3;
+    },
+    getRpcProvider(hasAddresses: boolean = true): Web3.Provider {
+        const provider = new ProviderEngine();
+        if (!hasAddresses) {
+            provider.addProvider(new EmptyWalletSubprovider());
+        }
+        provider.addProvider(new FakeGasEstimateSubprovider(constants.GAS_ESTIMATE));
+        provider.addProvider(
+            new RpcSubprovider({
+                rpcUrl: constants.RPC_URL,
+            }),
+        );
+        provider.start();
+        return provider;
+    },
 };
diff --git a/packages/0x.js/tsconfig.json b/packages/0x.js/tsconfig.json
index 0666fbd82..117f51e83 100644
--- a/packages/0x.js/tsconfig.json
+++ b/packages/0x.js/tsconfig.json
@@ -1,16 +1,16 @@
 {
-	"extends": "../../tsconfig",
-	"compilerOptions": {
-		"outDir": "lib",
-		"noImplicitThis": false
-	},
-	"include": [
-		"./src/**/*",
-		"./test/**/*",
-		"../../node_modules/types-bn/index.d.ts",
-		"../../node_modules/types-ethereumjs-util/index.d.ts",
-		"../../node_modules/web3-typescript-typings/index.d.ts",
-		"../../node_modules/chai-typescript-typings/index.d.ts",
-		"../../node_modules/chai-as-promised-typescript-typings/index.d.ts"
-	]
+    "extends": "../../tsconfig",
+    "compilerOptions": {
+        "outDir": "lib",
+        "noImplicitThis": false
+    },
+    "include": [
+        "./src/**/*",
+        "./test/**/*",
+        "../../node_modules/types-bn/index.d.ts",
+        "../../node_modules/types-ethereumjs-util/index.d.ts",
+        "../../node_modules/web3-typescript-typings/index.d.ts",
+        "../../node_modules/chai-typescript-typings/index.d.ts",
+        "../../node_modules/chai-as-promised-typescript-typings/index.d.ts"
+    ]
 }
diff --git a/packages/0x.js/tslint.json b/packages/0x.js/tslint.json
index e63054bfc..ffaefe83a 100644
--- a/packages/0x.js/tslint.json
+++ b/packages/0x.js/tslint.json
@@ -1,3 +1,3 @@
 {
-	"extends": ["@0xproject/tslint-config"]
+    "extends": ["@0xproject/tslint-config"]
 }
diff --git a/packages/abi-gen/package.json b/packages/abi-gen/package.json
index 58ee12220..31a0f7f55 100644
--- a/packages/abi-gen/package.json
+++ b/packages/abi-gen/package.json
@@ -1,48 +1,48 @@
 {
-	"name": "@0xproject/abi-gen",
-	"version": "0.1.4",
-	"description": "Generate contract wrappers from ABI and handlebars templates",
-	"main": "lib/index.js",
-	"types": "lib/index.d.ts",
-	"scripts": {
-		"lint": "tslint --project . 'src/**/*.ts'",
-		"clean": "shx rm -rf lib",
-		"build": "tsc"
-	},
-	"bin": {
-		"abi-gen": "lib/index.js"
-	},
-	"repository": {
-		"type": "git",
-		"url": "https://github.com/0xProject/0x.js.git"
-	},
-	"license": "Apache-2.0",
-	"bugs": {
-		"url": "https://github.com/0xProject/0x.js/issues"
-	},
-	"homepage": "https://github.com/0xProject/0x.js/packages/abi-gen/README.md",
-	"dependencies": {
-		"@0xproject/utils": "^0.2.2",
-		"chalk": "^2.3.0",
-		"glob": "^7.1.2",
-		"handlebars": "^4.0.11",
-		"lodash": "^4.17.4",
-		"mkdirp": "^0.5.1",
-		"to-snake-case": "^1.0.0",
-		"web3": "^0.20.0",
-		"yargs": "^10.0.3"
-	},
-	"devDependencies": {
-		"@0xproject/tslint-config": "^0.4.4",
-		"@types/glob": "^5.0.33",
-		"@types/handlebars": "^4.0.36",
-		"@types/mkdirp": "^0.5.1",
-		"@types/node": "^8.0.53",
-		"@types/yargs": "^10.0.0",
-		"npm-run-all": "^4.1.2",
-		"shx": "^0.2.2",
-		"tslint": "5.8.0",
-		"typescript": "~2.6.1",
-		"web3-typescript-typings": "^0.9.6"
-	}
+    "name": "@0xproject/abi-gen",
+    "version": "0.1.4",
+    "description": "Generate contract wrappers from ABI and handlebars templates",
+    "main": "lib/index.js",
+    "types": "lib/index.d.ts",
+    "scripts": {
+        "lint": "tslint --project . 'src/**/*.ts'",
+        "clean": "shx rm -rf lib",
+        "build": "tsc"
+    },
+    "bin": {
+        "abi-gen": "lib/index.js"
+    },
+    "repository": {
+        "type": "git",
+        "url": "https://github.com/0xProject/0x.js.git"
+    },
+    "license": "Apache-2.0",
+    "bugs": {
+        "url": "https://github.com/0xProject/0x.js/issues"
+    },
+    "homepage": "https://github.com/0xProject/0x.js/packages/abi-gen/README.md",
+    "dependencies": {
+        "@0xproject/utils": "^0.2.2",
+        "chalk": "^2.3.0",
+        "glob": "^7.1.2",
+        "handlebars": "^4.0.11",
+        "lodash": "^4.17.4",
+        "mkdirp": "^0.5.1",
+        "to-snake-case": "^1.0.0",
+        "web3": "^0.20.0",
+        "yargs": "^10.0.3"
+    },
+    "devDependencies": {
+        "@0xproject/tslint-config": "^0.4.4",
+        "@types/glob": "^5.0.33",
+        "@types/handlebars": "^4.0.36",
+        "@types/mkdirp": "^0.5.1",
+        "@types/node": "^8.0.53",
+        "@types/yargs": "^10.0.0",
+        "npm-run-all": "^4.1.2",
+        "shx": "^0.2.2",
+        "tslint": "5.8.0",
+        "typescript": "~2.6.1",
+        "web3-typescript-typings": "^0.9.6"
+    }
 }
diff --git a/packages/abi-gen/src/globals.d.ts b/packages/abi-gen/src/globals.d.ts
index 0b46f2c40..39df3f852 100644
--- a/packages/abi-gen/src/globals.d.ts
+++ b/packages/abi-gen/src/globals.d.ts
@@ -1,4 +1,4 @@
 declare function toSnakeCase(str: string): string;
 declare module 'to-snake-case' {
-	export = toSnakeCase;
+    export = toSnakeCase;
 }
diff --git a/packages/abi-gen/src/index.ts b/packages/abi-gen/src/index.ts
index 15d218711..527af32b1 100644
--- a/packages/abi-gen/src/index.ts
+++ b/packages/abi-gen/src/index.ts
@@ -20,91 +20,91 @@ const ABI_TYPE_EVENT = 'event';
 const MAIN_TEMPLATE_NAME = 'contract.mustache';
 
 const args = yargs
-	.option('abiGlob', {
-		describe: 'Glob pattern to search for ABI JSON files',
-		type: 'string',
-		demand: true,
-	})
-	.option('templates', {
-		describe: 'Folder where to search for templates',
-		type: 'string',
-		demand: true,
-	})
-	.option('output', {
-		describe: 'Folder where to put the output files',
-		type: 'string',
-		demand: true,
-	}).argv;
+    .option('abiGlob', {
+        describe: 'Glob pattern to search for ABI JSON files',
+        type: 'string',
+        demand: true,
+    })
+    .option('templates', {
+        describe: 'Folder where to search for templates',
+        type: 'string',
+        demand: true,
+    })
+    .option('output', {
+        describe: 'Folder where to put the output files',
+        type: 'string',
+        demand: true,
+    }).argv;
 
 function writeOutputFile(name: string, renderedTsCode: string): void {
-	const fileName = toSnakeCase(name);
-	const filePath = `${args.output}/${fileName}.ts`;
-	fs.writeFileSync(filePath, renderedTsCode);
-	utils.log(`Created: ${chalk.bold(filePath)}`);
+    const fileName = toSnakeCase(name);
+    const filePath = `${args.output}/${fileName}.ts`;
+    fs.writeFileSync(filePath, renderedTsCode);
+    utils.log(`Created: ${chalk.bold(filePath)}`);
 }
 
 Handlebars.registerHelper('parameterType', utils.solTypeToTsType.bind(utils, ParamKind.Input));
 Handlebars.registerHelper('returnType', utils.solTypeToTsType.bind(utils, ParamKind.Output));
 const partialTemplateFileNames = globSync(`${args.templates}/partials/**/*.mustache`);
 for (const partialTemplateFileName of partialTemplateFileNames) {
-	const namedContent = utils.getNamedContent(partialTemplateFileName);
-	Handlebars.registerPartial(namedContent.name, namedContent.content);
+    const namedContent = utils.getNamedContent(partialTemplateFileName);
+    Handlebars.registerPartial(namedContent.name, namedContent.content);
 }
 
 const mainTemplate = utils.getNamedContent(`${args.templates}/${MAIN_TEMPLATE_NAME}`);
 const template = Handlebars.compile<ContextData>(mainTemplate.content);
 const abiFileNames = globSync(args.abiGlob);
 if (_.isEmpty(abiFileNames)) {
-	utils.log(`${chalk.red(`No ABI files found.`)}`);
-	utils.log(`Please make sure you've passed the correct folder name and that the files have
+    utils.log(`${chalk.red(`No ABI files found.`)}`);
+    utils.log(`Please make sure you've passed the correct folder name and that the files have
                ${chalk.bold('*.json')} extensions`);
-	process.exit(1);
+    process.exit(1);
 } else {
-	utils.log(`Found ${chalk.green(`${abiFileNames.length}`)} ${chalk.bold('ABI')} files`);
-	mkdirp.sync(args.output);
+    utils.log(`Found ${chalk.green(`${abiFileNames.length}`)} ${chalk.bold('ABI')} files`);
+    mkdirp.sync(args.output);
 }
 for (const abiFileName of abiFileNames) {
-	const namedContent = utils.getNamedContent(abiFileName);
-	utils.log(`Processing: ${chalk.bold(namedContent.name)}...`);
-	const parsedContent = JSON.parse(namedContent.content);
-	const ABI = _.isArray(parsedContent)
-		? parsedContent // ABI file
-		: parsedContent.abi; // Truffle contracts file
-	if (_.isUndefined(ABI)) {
-		utils.log(`${chalk.red(`ABI not found in ${abiFileName}.`)}`);
-		utils.log(`Please make sure your ABI file is either an array with ABI entries or an object with the abi key`);
-		process.exit(1);
-	}
+    const namedContent = utils.getNamedContent(abiFileName);
+    utils.log(`Processing: ${chalk.bold(namedContent.name)}...`);
+    const parsedContent = JSON.parse(namedContent.content);
+    const ABI = _.isArray(parsedContent)
+        ? parsedContent // ABI file
+        : parsedContent.abi; // Truffle contracts file
+    if (_.isUndefined(ABI)) {
+        utils.log(`${chalk.red(`ABI not found in ${abiFileName}.`)}`);
+        utils.log(`Please make sure your ABI file is either an array with ABI entries or an object with the abi key`);
+        process.exit(1);
+    }
 
-	let ctor = ABI.find((abi: Web3.AbiDefinition) => abi.type === ABI_TYPE_CONSTRUCTOR) as Web3.ConstructorAbi;
-	if (_.isUndefined(ctor)) {
-		ctor = utils.getEmptyConstructor(); // The constructor exists, but it's implicit in JSON's ABI definition
-	}
+    let ctor = ABI.find((abi: Web3.AbiDefinition) => abi.type === ABI_TYPE_CONSTRUCTOR) as Web3.ConstructorAbi;
+    if (_.isUndefined(ctor)) {
+        ctor = utils.getEmptyConstructor(); // The constructor exists, but it's implicit in JSON's ABI definition
+    }
 
-	const methodAbis = ABI.filter((abi: Web3.AbiDefinition) => abi.type === ABI_TYPE_METHOD) as Web3.MethodAbi[];
-	const methodsData = _.map(methodAbis, methodAbi => {
-		_.map(methodAbi.inputs, input => {
-			if (_.isEmpty(input.name)) {
-				// Auto-generated getters don't have parameter names
-				input.name = 'index';
-			}
-		});
-		// This will make templates simpler
-		const methodData = {
-			...methodAbi,
-			singleReturnValue: methodAbi.outputs.length === 1,
-		};
-		return methodData;
-	});
+    const methodAbis = ABI.filter((abi: Web3.AbiDefinition) => abi.type === ABI_TYPE_METHOD) as Web3.MethodAbi[];
+    const methodsData = _.map(methodAbis, methodAbi => {
+        _.map(methodAbi.inputs, input => {
+            if (_.isEmpty(input.name)) {
+                // Auto-generated getters don't have parameter names
+                input.name = 'index';
+            }
+        });
+        // This will make templates simpler
+        const methodData = {
+            ...methodAbi,
+            singleReturnValue: methodAbi.outputs.length === 1,
+        };
+        return methodData;
+    });
 
-	const eventAbis = ABI.filter((abi: Web3.AbiDefinition) => abi.type === ABI_TYPE_EVENT) as Web3.EventAbi[];
+    const eventAbis = ABI.filter((abi: Web3.AbiDefinition) => abi.type === ABI_TYPE_EVENT) as Web3.EventAbi[];
 
-	const contextData = {
-		contractName: namedContent.name,
-		ctor,
-		methods: methodsData,
-		events: eventAbis,
-	};
-	const renderedTsCode = template(contextData);
-	writeOutputFile(namedContent.name, renderedTsCode);
+    const contextData = {
+        contractName: namedContent.name,
+        ctor,
+        methods: methodsData,
+        events: eventAbis,
+    };
+    const renderedTsCode = template(contextData);
+    writeOutputFile(namedContent.name, renderedTsCode);
 }
diff --git a/packages/abi-gen/src/types.ts b/packages/abi-gen/src/types.ts
index 413f94467..e82ab824b 100644
--- a/packages/abi-gen/src/types.ts
+++ b/packages/abi-gen/src/types.ts
@@ -1,23 +1,23 @@
 import * as Web3 from 'web3';
 
 export enum ParamKind {
-	Input = 'input',
-	Output = 'output',
+    Input = 'input',
+    Output = 'output',
 }
 
 export enum AbiType {
-	Function = 'function',
-	Constructor = 'constructor',
-	Event = 'event',
-	Fallback = 'fallback',
+    Function = 'function',
+    Constructor = 'constructor',
+    Event = 'event',
+    Fallback = 'fallback',
 }
 
 export interface Method extends Web3.MethodAbi {
-	singleReturnValue: boolean;
+    singleReturnValue: boolean;
 }
 
 export interface ContextData {
-	contractName: string;
-	methods: Method[];
-	events: Web3.EventAbi[];
+    contractName: string;
+    methods: Method[];
+    events: Web3.EventAbi[];
 }
diff --git a/packages/abi-gen/src/utils.ts b/packages/abi-gen/src/utils.ts
index 4e1216a77..14255643a 100644
--- a/packages/abi-gen/src/utils.ts
+++ b/packages/abi-gen/src/utils.ts
@@ -6,68 +6,68 @@ import * as Web3 from 'web3';
 import { AbiType, ParamKind } from './types';
 
 export const utils = {
-	solTypeToTsType(paramKind: ParamKind, solType: string): string {
-		const trailingArrayRegex = /\[\d*\]$/;
-		if (solType.match(trailingArrayRegex)) {
-			const arrayItemSolType = solType.replace(trailingArrayRegex, '');
-			const arrayItemTsType = utils.solTypeToTsType(paramKind, arrayItemSolType);
-			const arrayTsType = utils.isUnionType(arrayItemTsType)
-				? `Array<${arrayItemTsType}>`
-				: `${arrayItemTsType}[]`;
-			return arrayTsType;
-		} else {
-			const solTypeRegexToTsType = [
-				{ regex: '^string$', tsType: 'string' },
-				{ regex: '^address$', tsType: 'string' },
-				{ regex: '^bool$', tsType: 'boolean' },
-				{ regex: '^u?int\\d*$', tsType: 'BigNumber' },
-				{ regex: '^bytes\\d*$', tsType: 'string' },
-			];
-			if (paramKind === ParamKind.Input) {
-				// web3 allows to pass those an non-bignumbers and that's nice
-				// but it always returns stuff as BigNumbers
-				solTypeRegexToTsType.unshift({
-					regex: '^u?int(8|16|32)?$',
-					tsType: 'number|BigNumber',
-				});
-			}
-			for (const regexAndTxType of solTypeRegexToTsType) {
-				const { regex, tsType } = regexAndTxType;
-				if (solType.match(regex)) {
-					return tsType;
-				}
-			}
-			throw new Error(`Unknown Solidity type found: ${solType}`);
-		}
-	},
-	isUnionType(tsType: string): boolean {
-		return tsType === 'number|BigNumber';
-	},
-	log(...args: any[]): void {
-		console.log(...args); // tslint:disable-line:no-console
-	},
-	getPartialNameFromFileName(filename: string): string {
-		const name = path.parse(filename).name;
-		return name;
-	},
-	getNamedContent(filename: string): { name: string; content: string } {
-		const name = utils.getPartialNameFromFileName(filename);
-		try {
-			const content = fs.readFileSync(filename).toString();
-			return {
-				name,
-				content,
-			};
-		} catch (err) {
-			throw new Error(`Failed to read ${filename}: ${err}`);
-		}
-	},
-	getEmptyConstructor(): Web3.ConstructorAbi {
-		return {
-			type: AbiType.Constructor,
-			stateMutability: 'nonpayable',
-			payable: false,
-			inputs: [],
-		};
-	},
+    solTypeToTsType(paramKind: ParamKind, solType: string): string {
+        const trailingArrayRegex = /\[\d*\]$/;
+        if (solType.match(trailingArrayRegex)) {
+            const arrayItemSolType = solType.replace(trailingArrayRegex, '');
+            const arrayItemTsType = utils.solTypeToTsType(paramKind, arrayItemSolType);
+            const arrayTsType = utils.isUnionType(arrayItemTsType)
+                ? `Array<${arrayItemTsType}>`
+                : `${arrayItemTsType}[]`;
+            return arrayTsType;
+        } else {
+            const solTypeRegexToTsType = [
+                { regex: '^string$', tsType: 'string' },
+                { regex: '^address$', tsType: 'string' },
+                { regex: '^bool$', tsType: 'boolean' },
+                { regex: '^u?int\\d*$', tsType: 'BigNumber' },
+                { regex: '^bytes\\d*$', tsType: 'string' },
+            ];
+            if (paramKind === ParamKind.Input) {
+                // web3 allows to pass those an non-bignumbers and that's nice
+                // but it always returns stuff as BigNumbers
+                solTypeRegexToTsType.unshift({
+                    regex: '^u?int(8|16|32)?$',
+                    tsType: 'number|BigNumber',
+                });
+            }
+            for (const regexAndTxType of solTypeRegexToTsType) {
+                const { regex, tsType } = regexAndTxType;
+                if (solType.match(regex)) {
+                    return tsType;
+                }
+            }
+            throw new Error(`Unknown Solidity type found: ${solType}`);
+        }
+    },
+    isUnionType(tsType: string): boolean {
+        return tsType === 'number|BigNumber';
+    },
+    log(...args: any[]): void {
+        console.log(...args); // tslint:disable-line:no-console
+    },
+    getPartialNameFromFileName(filename: string): string {
+        const name = path.parse(filename).name;
+        return name;
+    },
+    getNamedContent(filename: string): { name: string; content: string } {
+        const name = utils.getPartialNameFromFileName(filename);
+        try {
+            const content = fs.readFileSync(filename).toString();
+            return {
+                name,
+                content,
+            };
+        } catch (err) {
+            throw new Error(`Failed to read ${filename}: ${err}`);
+        }
+    },
+    getEmptyConstructor(): Web3.ConstructorAbi {
+        return {
+            type: AbiType.Constructor,
+            stateMutability: 'nonpayable',
+            payable: false,
+            inputs: [],
+        };
+    },
 };
diff --git a/packages/abi-gen/tsconfig.json b/packages/abi-gen/tsconfig.json
index 1f89fb820..5e0c7c6d3 100644
--- a/packages/abi-gen/tsconfig.json
+++ b/packages/abi-gen/tsconfig.json
@@ -1,7 +1,7 @@
 {
-	"extends": "../../tsconfig",
-	"compilerOptions": {
-		"outDir": "lib"
-	},
-	"include": ["./src/**/*", "./test/**/*", "../../node_modules/web3-typescript-typings/index.d.ts"]
+    "extends": "../../tsconfig",
+    "compilerOptions": {
+        "outDir": "lib"
+    },
+    "include": ["./src/**/*", "./test/**/*", "../../node_modules/web3-typescript-typings/index.d.ts"]
 }
diff --git a/packages/abi-gen/tslint.json b/packages/abi-gen/tslint.json
index e63054bfc..ffaefe83a 100644
--- a/packages/abi-gen/tslint.json
+++ b/packages/abi-gen/tslint.json
@@ -1,3 +1,3 @@
 {
-	"extends": ["@0xproject/tslint-config"]
+    "extends": ["@0xproject/tslint-config"]
 }
diff --git a/packages/assert/package.json b/packages/assert/package.json
index 0e10b3384..a2d195728 100644
--- a/packages/assert/package.json
+++ b/packages/assert/package.json
@@ -1,45 +1,45 @@
 {
-	"name": "@0xproject/assert",
-	"version": "0.0.13",
-	"description": "Provides a standard way of performing type and schema validation across 0x projects",
-	"main": "lib/src/index.js",
-	"types": "lib/src/index.d.ts",
-	"scripts": {
-		"build": "tsc",
-		"clean": "shx rm -rf _bundles lib test_temp",
-		"lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'",
-		"run_mocha": "mocha lib/test/**/*_test.js",
-		"prepublishOnly": "run-p build",
-		"test": "run-s clean build run_mocha",
-		"test:circleci": "yarn test"
-	},
-	"license": "Apache-2.0",
-	"repository": {
-		"type": "git",
-		"url": "https://github.com/0xProject/0x.js.git"
-	},
-	"bugs": {
-		"url": "https://github.com/0xProject/0x.js/issues"
-	},
-	"homepage": "https://github.com/0xProject/0x.js/packages/assert/README.md",
-	"devDependencies": {
-		"@0xproject/tslint-config": "^0.4.4",
-		"@types/lodash": "^4.14.86",
-		"@types/mocha": "^2.2.42",
-		"@types/valid-url": "^1.0.2",
-		"chai": "^4.0.1",
-		"chai-typescript-typings": "^0.0.2",
-		"dirty-chai": "^2.0.1",
-		"mocha": "^4.0.1",
-		"npm-run-all": "^4.1.2",
-		"shx": "^0.2.2",
-		"tslint": "5.8.0",
-		"typescript": "~2.6.1"
-	},
-	"dependencies": {
-		"@0xproject/json-schemas": "^0.7.5",
-		"@0xproject/utils": "^0.2.2",
-		"lodash": "^4.17.4",
-		"valid-url": "^1.0.9"
-	}
+    "name": "@0xproject/assert",
+    "version": "0.0.13",
+    "description": "Provides a standard way of performing type and schema validation across 0x projects",
+    "main": "lib/src/index.js",
+    "types": "lib/src/index.d.ts",
+    "scripts": {
+        "build": "tsc",
+        "clean": "shx rm -rf _bundles lib test_temp",
+        "lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'",
+        "run_mocha": "mocha lib/test/**/*_test.js",
+        "prepublishOnly": "run-p build",
+        "test": "run-s clean build run_mocha",
+        "test:circleci": "yarn test"
+    },
+    "license": "Apache-2.0",
+    "repository": {
+        "type": "git",
+        "url": "https://github.com/0xProject/0x.js.git"
+    },
+    "bugs": {
+        "url": "https://github.com/0xProject/0x.js/issues"
+    },
+    "homepage": "https://github.com/0xProject/0x.js/packages/assert/README.md",
+    "devDependencies": {
+        "@0xproject/tslint-config": "^0.4.4",
+        "@types/lodash": "^4.14.86",
+        "@types/mocha": "^2.2.42",
+        "@types/valid-url": "^1.0.2",
+        "chai": "^4.0.1",
+        "chai-typescript-typings": "^0.0.2",
+        "dirty-chai": "^2.0.1",
+        "mocha": "^4.0.1",
+        "npm-run-all": "^4.1.2",
+        "shx": "^0.2.2",
+        "tslint": "5.8.0",
+        "typescript": "~2.6.1"
+    },
+    "dependencies": {
+        "@0xproject/json-schemas": "^0.7.5",
+        "@0xproject/utils": "^0.2.2",
+        "lodash": "^4.17.4",
+        "valid-url": "^1.0.9"
+    }
 }
diff --git a/packages/assert/src/index.ts b/packages/assert/src/index.ts
index 0578bd303..7ad574ec7 100644
--- a/packages/assert/src/index.ts
+++ b/packages/assert/src/index.ts
@@ -6,89 +6,89 @@ import * as validUrl from 'valid-url';
 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 isNegative = value.lessThan(0);
-		this.assert(!isNegative, `${variableName} cannot be a negative number, found value: ${value.toNumber()}`);
-		const hasDecimals = value.decimalPlaces() !== 0;
-		this.assert(
-			!hasDecimals,
-			`${variableName} should be in baseUnits (no decimals), found value: ${value.toNumber()}`,
-		);
-	},
-	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 {
-		this.assert(addressUtils.isAddress(value), this.typeAssertionMessage(variableName, 'ETHAddressHex', value));
-		this.assert(
-			addressUtils.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}`,
-		);
-	},
-	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: any): void {
-		const isWeb3Provider = _.isFunction(value.send) || _.isFunction(value.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}
+    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 isNegative = value.lessThan(0);
+        this.assert(!isNegative, `${variableName} cannot be a negative number, found value: ${value.toNumber()}`);
+        const hasDecimals = value.decimalPlaces() !== 0;
+        this.assert(
+            !hasDecimals,
+            `${variableName} should be in baseUnits (no decimals), found value: ${value.toNumber()}`,
+        );
+    },
+    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 {
+        this.assert(addressUtils.isAddress(value), this.typeAssertionMessage(variableName, 'ETHAddressHex', value));
+        this.assert(
+            addressUtils.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}`,
+        );
+    },
+    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: any): void {
+        const isWeb3Provider = _.isFunction(value.send) || _.isFunction(value.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);
-	},
-	isHttpUrl(variableName: string, value: any): void {
-		const isValidUrl = !_.isUndefined(validUrl.isWebUri(value));
-		this.assert(isValidUrl, this.typeAssertionMessage(variableName, 'http url', value));
-	},
-	isUri(variableName: string, value: any): void {
-		const isValidUri = !_.isUndefined(validUrl.isUri(value));
-		this.assert(isValidUri, this.typeAssertionMessage(variableName, 'uri', value));
-	},
-	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}`;
-	},
+        this.assert(!hasValidationErrors, msg);
+    },
+    isHttpUrl(variableName: string, value: any): void {
+        const isValidUrl = !_.isUndefined(validUrl.isWebUri(value));
+        this.assert(isValidUrl, this.typeAssertionMessage(variableName, 'http url', value));
+    },
+    isUri(variableName: string, value: any): void {
+        const isValidUri = !_.isUndefined(validUrl.isUri(value));
+        this.assert(isValidUri, this.typeAssertionMessage(variableName, 'uri', value));
+    },
+    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/packages/assert/test/assert_test.ts b/packages/assert/test/assert_test.ts
index 0af493bda..b0fa398d6 100644
--- a/packages/assert/test/assert_test.ts
+++ b/packages/assert/test/assert_test.ts
@@ -11,243 +11,243 @@ chai.use(dirtyChai);
 const expect = chai.expect;
 
 describe('Assertions', () => {
-	const variableName = 'variable';
-	describe('#isBigNumber', () => {
-		it('should not throw for valid input', () => {
-			const validInputs = [new BigNumber(23), new BigNumber('45')];
-			validInputs.forEach(input => expect(assert.isBigNumber.bind(assert, variableName, input)).to.not.throw());
-		});
-		it('should throw for invalid input', () => {
-			const invalidInputs = ['test', 42, false, { random: 'test' }, undefined];
-			invalidInputs.forEach(input => expect(assert.isBigNumber.bind(assert, variableName, input)).to.throw());
-		});
-	});
-	describe('#isValidBaseUnitAmount', () => {
-		it('should not throw for valid input', () => {
-			const validInputs = [new BigNumber(23), new BigNumber('45000000')];
-			validInputs.forEach(input =>
-				expect(assert.isValidBaseUnitAmount.bind(assert, variableName, input)).to.not.throw(),
-			);
-		});
-		it('should throw for invalid input', () => {
-			const invalidInputs = [0, undefined, new BigNumber(3.145), 3.145, new BigNumber(-400)];
-			invalidInputs.forEach(input =>
-				expect(assert.isValidBaseUnitAmount.bind(assert, variableName, input)).to.throw(),
-			);
-		});
-	});
-	describe('#isString', () => {
-		it('should not throw for valid input', () => {
-			const validInputs = ['hello', 'goodbye'];
-			validInputs.forEach(input => expect(assert.isString.bind(assert, variableName, input)).to.not.throw());
-		});
-		it('should throw for invalid input', () => {
-			const invalidInputs = [42, false, { random: 'test' }, undefined, new BigNumber(45)];
-			invalidInputs.forEach(input => expect(assert.isString.bind(assert, variableName, input)).to.throw());
-		});
-	});
-	describe('#isFunction', () => {
-		it('should not throw for valid input', () => {
-			const validInputs = [BigNumber, assert.isString];
-			validInputs.forEach(input => expect(assert.isFunction.bind(assert, variableName, input)).to.not.throw());
-		});
-		it('should throw for invalid input', () => {
-			const invalidInputs = [42, false, { random: 'test' }, undefined, new BigNumber(45)];
-			invalidInputs.forEach(input => expect(assert.isFunction.bind(assert, variableName, input)).to.throw());
-		});
-	});
-	describe('#isHexString', () => {
-		it('should not throw for valid input', () => {
-			const validInputs = [
-				'0x61a3ed31B43c8780e905a260a35faefEc527be7516aa11c0256729b5b351bc33',
-				'0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
-			];
-			validInputs.forEach(input => expect(assert.isHexString.bind(assert, variableName, input)).to.not.throw());
-		});
-		it('should throw for invalid input', () => {
-			const invalidInputs = [
-				42,
-				false,
-				{ random: 'test' },
-				undefined,
-				new BigNumber(45),
-				'0x61a3ed31B43c8780e905a260a35faYfEc527be7516aa11c0256729b5b351bc33',
-			];
-			invalidInputs.forEach(input => expect(assert.isHexString.bind(assert, variableName, input)).to.throw());
-		});
-	});
-	describe('#isETHAddressHex', () => {
-		it('should not throw for valid input', () => {
-			const validInputs = [
-				'0x0000000000000000000000000000000000000000',
-				'0x6fffd0ae3f7d88c9b4925323f54c6e4b2918c5fd',
-				'0x12459c951127e0c374ff9105dda097662a027093',
-			];
-			validInputs.forEach(input =>
-				expect(assert.isETHAddressHex.bind(assert, variableName, input)).to.not.throw(),
-			);
-		});
-		it('should throw for invalid input', () => {
-			const invalidInputs = [
-				42,
-				false,
-				{ random: 'test' },
-				undefined,
-				new BigNumber(45),
-				'0x6FFFd0ae3f7d88c9b4925323f54c6e4b2918c5fd',
-				'0x6FFFd0ae3f7d88c9b4925323f54c6e4',
-			];
-			invalidInputs.forEach(input => expect(assert.isETHAddressHex.bind(assert, variableName, input)).to.throw());
-		});
-	});
-	describe('#doesBelongToStringEnum', () => {
-		enum TestEnums {
-			Test1 = 'Test1',
-			Test2 = 'Test2',
-		}
-		it('should not throw for valid input', () => {
-			const validInputs = [TestEnums.Test1, TestEnums.Test2];
-			validInputs.forEach(input =>
-				expect(assert.doesBelongToStringEnum.bind(assert, variableName, input, TestEnums)).to.not.throw(),
-			);
-		});
-		it('should throw for invalid input', () => {
-			const invalidInputs = [42, false, { random: 'test' }, undefined, new BigNumber(45)];
-			invalidInputs.forEach(input =>
-				expect(assert.doesBelongToStringEnum.bind(assert, variableName, input, TestEnums)).to.throw(),
-			);
-		});
-	});
-	describe('#hasAtMostOneUniqueValue', () => {
-		const errorMsg = 'more than one unique value';
-		it('should not throw for valid input', () => {
-			const validInputs = [['hello'], ['goodbye', 'goodbye', 'goodbye']];
-			validInputs.forEach(input =>
-				expect(assert.hasAtMostOneUniqueValue.bind(assert, input, errorMsg)).to.not.throw(),
-			);
-		});
-		it('should throw for invalid input', () => {
-			const invalidInputs = [['hello', 'goodbye'], ['goodbye', 42, false, false]];
-			invalidInputs.forEach(input =>
-				expect(assert.hasAtMostOneUniqueValue.bind(assert, input, errorMsg)).to.throw(),
-			);
-		});
-	});
-	describe('#isNumber', () => {
-		it('should not throw for valid input', () => {
-			const validInputs = [42, 0, 21e42];
-			validInputs.forEach(input => expect(assert.isNumber.bind(assert, variableName, input)).to.not.throw());
-		});
-		it('should throw for invalid input', () => {
-			const invalidInputs = [false, { random: 'test' }, undefined, new BigNumber(45)];
-			invalidInputs.forEach(input => expect(assert.isNumber.bind(assert, variableName, input)).to.throw());
-		});
-	});
-	describe('#isBoolean', () => {
-		it('should not throw for valid input', () => {
-			const validInputs = [true, false];
-			validInputs.forEach(input => expect(assert.isBoolean.bind(assert, variableName, input)).to.not.throw());
-		});
-		it('should throw for invalid input', () => {
-			const invalidInputs = [42, { random: 'test' }, undefined, new BigNumber(45)];
-			invalidInputs.forEach(input => expect(assert.isBoolean.bind(assert, variableName, input)).to.throw());
-		});
-	});
-	describe('#isWeb3Provider', () => {
-		it('should not throw for valid input', () => {
-			const validInputs = [{ send: () => 45 }, { sendAsync: () => 45 }];
-			validInputs.forEach(input =>
-				expect(assert.isWeb3Provider.bind(assert, variableName, input)).to.not.throw(),
-			);
-		});
-		it('should throw for invalid input', () => {
-			const invalidInputs = [42, { random: 'test' }, undefined, new BigNumber(45)];
-			invalidInputs.forEach(input => expect(assert.isWeb3Provider.bind(assert, variableName, input)).to.throw());
-		});
-	});
-	describe('#doesConformToSchema', () => {
-		const schema = schemas.addressSchema;
-		it('should not throw for valid input', () => {
-			const validInputs = [
-				'0x6fffd0ae3f7d88c9b4925323f54c6e4b2918c5fd',
-				'0x12459c951127e0c374ff9105dda097662a027093',
-			];
-			validInputs.forEach(input =>
-				expect(assert.doesConformToSchema.bind(assert, variableName, input, schema)).to.not.throw(),
-			);
-		});
-		it('should throw for invalid input', () => {
-			const invalidInputs = [42, { random: 'test' }, undefined, new BigNumber(45)];
-			invalidInputs.forEach(input =>
-				expect(assert.doesConformToSchema.bind(assert, variableName, input, schema)).to.throw(),
-			);
-		});
-	});
-	describe('#isHttpUrl', () => {
-		it('should not throw for valid input', () => {
-			const validInputs = [
-				'http://www.google.com',
-				'https://api.example-relayer.net',
-				'https://api.radarrelay.com/0x/v0/',
-				'https://zeroex.beta.radarrelay.com:8000/0x/v0/',
-			];
-			validInputs.forEach(input => expect(assert.isHttpUrl.bind(assert, variableName, input)).to.not.throw());
-		});
-		it('should throw for invalid input', () => {
-			const invalidInputs = [
-				42,
-				{ random: 'test' },
-				undefined,
-				new BigNumber(45),
-				'ws://www.api.example-relayer.net',
-				'www.google.com',
-				'api.example-relayer.net',
-				'user:password@api.example-relayer.net',
-				'//api.example-relayer.net',
-			];
-			invalidInputs.forEach(input => expect(assert.isHttpUrl.bind(assert, variableName, input)).to.throw());
-		});
-	});
-	describe('#isUri', () => {
-		it('should not throw for valid input', () => {
-			const validInputs = [
-				'http://www.google.com',
-				'https://api.example-relayer.net',
-				'https://api.radarrelay.com/0x/v0/',
-				'https://zeroex.beta.radarrelay.com:8000/0x/v0/',
-				'ws://www.api.example-relayer.net',
-				'wss://www.api.example-relayer.net',
-				'user:password@api.example-relayer.net',
-			];
-			validInputs.forEach(input => expect(assert.isUri.bind(assert, variableName, input)).to.not.throw());
-		});
-		it('should throw for invalid input', () => {
-			const invalidInputs = [
-				42,
-				{ random: 'test' },
-				undefined,
-				new BigNumber(45),
-				'www.google.com',
-				'api.example-relayer.net',
-				'//api.example-relayer.net',
-			];
-			invalidInputs.forEach(input => expect(assert.isUri.bind(assert, variableName, input)).to.throw());
-		});
-	});
-	describe('#assert', () => {
-		const assertMessage = 'assert not satisfied';
-		it('should not throw for valid input', () => {
-			expect(assert.assert.bind(assert, true, assertMessage)).to.not.throw();
-		});
-		it('should throw for invalid input', () => {
-			expect(assert.assert.bind(assert, false, assertMessage)).to.throw();
-		});
-	});
-	describe('#typeAssertionMessage', () => {
-		it('should render correct message', () => {
-			expect(assert.typeAssertionMessage('variable', 'string', 'number')).to.equal(
-				`Expected variable to be of type string, encountered: number`,
-			);
-		});
-	});
+    const variableName = 'variable';
+    describe('#isBigNumber', () => {
+        it('should not throw for valid input', () => {
+            const validInputs = [new BigNumber(23), new BigNumber('45')];
+            validInputs.forEach(input => expect(assert.isBigNumber.bind(assert, variableName, input)).to.not.throw());
+        });
+        it('should throw for invalid input', () => {
+            const invalidInputs = ['test', 42, false, { random: 'test' }, undefined];
+            invalidInputs.forEach(input => expect(assert.isBigNumber.bind(assert, variableName, input)).to.throw());
+        });
+    });
+    describe('#isValidBaseUnitAmount', () => {
+        it('should not throw for valid input', () => {
+            const validInputs = [new BigNumber(23), new BigNumber('45000000')];
+            validInputs.forEach(input =>
+                expect(assert.isValidBaseUnitAmount.bind(assert, variableName, input)).to.not.throw(),
+            );
+        });
+        it('should throw for invalid input', () => {
+            const invalidInputs = [0, undefined, new BigNumber(3.145), 3.145, new BigNumber(-400)];
+            invalidInputs.forEach(input =>
+                expect(assert.isValidBaseUnitAmount.bind(assert, variableName, input)).to.throw(),
+            );
+        });
+    });
+    describe('#isString', () => {
+        it('should not throw for valid input', () => {
+            const validInputs = ['hello', 'goodbye'];
+            validInputs.forEach(input => expect(assert.isString.bind(assert, variableName, input)).to.not.throw());
+        });
+        it('should throw for invalid input', () => {
+            const invalidInputs = [42, false, { random: 'test' }, undefined, new BigNumber(45)];
+            invalidInputs.forEach(input => expect(assert.isString.bind(assert, variableName, input)).to.throw());
+        });
+    });
+    describe('#isFunction', () => {
+        it('should not throw for valid input', () => {
+            const validInputs = [BigNumber, assert.isString];
+            validInputs.forEach(input => expect(assert.isFunction.bind(assert, variableName, input)).to.not.throw());
+        });
+        it('should throw for invalid input', () => {
+            const invalidInputs = [42, false, { random: 'test' }, undefined, new BigNumber(45)];
+            invalidInputs.forEach(input => expect(assert.isFunction.bind(assert, variableName, input)).to.throw());
+        });
+    });
+    describe('#isHexString', () => {
+        it('should not throw for valid input', () => {
+            const validInputs = [
+                '0x61a3ed31B43c8780e905a260a35faefEc527be7516aa11c0256729b5b351bc33',
+                '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
+            ];
+            validInputs.forEach(input => expect(assert.isHexString.bind(assert, variableName, input)).to.not.throw());
+        });
+        it('should throw for invalid input', () => {
+            const invalidInputs = [
+                42,
+                false,
+                { random: 'test' },
+                undefined,
+                new BigNumber(45),
+                '0x61a3ed31B43c8780e905a260a35faYfEc527be7516aa11c0256729b5b351bc33',
+            ];
+            invalidInputs.forEach(input => expect(assert.isHexString.bind(assert, variableName, input)).to.throw());
+        });
+    });
+    describe('#isETHAddressHex', () => {
+        it('should not throw for valid input', () => {
+            const validInputs = [
+                '0x0000000000000000000000000000000000000000',
+                '0x6fffd0ae3f7d88c9b4925323f54c6e4b2918c5fd',
+                '0x12459c951127e0c374ff9105dda097662a027093',
+            ];
+            validInputs.forEach(input =>
+                expect(assert.isETHAddressHex.bind(assert, variableName, input)).to.not.throw(),
+            );
+        });
+        it('should throw for invalid input', () => {
+            const invalidInputs = [
+                42,
+                false,
+                { random: 'test' },
+                undefined,
+                new BigNumber(45),
+                '0x6FFFd0ae3f7d88c9b4925323f54c6e4b2918c5fd',
+                '0x6FFFd0ae3f7d88c9b4925323f54c6e4',
+            ];
+            invalidInputs.forEach(input => expect(assert.isETHAddressHex.bind(assert, variableName, input)).to.throw());
+        });
+    });
+    describe('#doesBelongToStringEnum', () => {
+        enum TestEnums {
+            Test1 = 'Test1',
+            Test2 = 'Test2',
+        }
+        it('should not throw for valid input', () => {
+            const validInputs = [TestEnums.Test1, TestEnums.Test2];
+            validInputs.forEach(input =>
+                expect(assert.doesBelongToStringEnum.bind(assert, variableName, input, TestEnums)).to.not.throw(),
+            );
+        });
+        it('should throw for invalid input', () => {
+            const invalidInputs = [42, false, { random: 'test' }, undefined, new BigNumber(45)];
+            invalidInputs.forEach(input =>
+                expect(assert.doesBelongToStringEnum.bind(assert, variableName, input, TestEnums)).to.throw(),
+            );
+        });
+    });
+    describe('#hasAtMostOneUniqueValue', () => {
+        const errorMsg = 'more than one unique value';
+        it('should not throw for valid input', () => {
+            const validInputs = [['hello'], ['goodbye', 'goodbye', 'goodbye']];
+            validInputs.forEach(input =>
+                expect(assert.hasAtMostOneUniqueValue.bind(assert, input, errorMsg)).to.not.throw(),
+            );
+        });
+        it('should throw for invalid input', () => {
+            const invalidInputs = [['hello', 'goodbye'], ['goodbye', 42, false, false]];
+            invalidInputs.forEach(input =>
+                expect(assert.hasAtMostOneUniqueValue.bind(assert, input, errorMsg)).to.throw(),
+            );
+        });
+    });
+    describe('#isNumber', () => {
+        it('should not throw for valid input', () => {
+            const validInputs = [42, 0, 21e42];
+            validInputs.forEach(input => expect(assert.isNumber.bind(assert, variableName, input)).to.not.throw());
+        });
+        it('should throw for invalid input', () => {
+            const invalidInputs = [false, { random: 'test' }, undefined, new BigNumber(45)];
+            invalidInputs.forEach(input => expect(assert.isNumber.bind(assert, variableName, input)).to.throw());
+        });
+    });
+    describe('#isBoolean', () => {
+        it('should not throw for valid input', () => {
+            const validInputs = [true, false];
+            validInputs.forEach(input => expect(assert.isBoolean.bind(assert, variableName, input)).to.not.throw());
+        });
+        it('should throw for invalid input', () => {
+            const invalidInputs = [42, { random: 'test' }, undefined, new BigNumber(45)];
+            invalidInputs.forEach(input => expect(assert.isBoolean.bind(assert, variableName, input)).to.throw());
+        });
+    });
+    describe('#isWeb3Provider', () => {
+        it('should not throw for valid input', () => {
+            const validInputs = [{ send: () => 45 }, { sendAsync: () => 45 }];
+            validInputs.forEach(input =>
+                expect(assert.isWeb3Provider.bind(assert, variableName, input)).to.not.throw(),
+            );
+        });
+        it('should throw for invalid input', () => {
+            const invalidInputs = [42, { random: 'test' }, undefined, new BigNumber(45)];
+            invalidInputs.forEach(input => expect(assert.isWeb3Provider.bind(assert, variableName, input)).to.throw());
+        });
+    });
+    describe('#doesConformToSchema', () => {
+        const schema = schemas.addressSchema;
+        it('should not throw for valid input', () => {
+            const validInputs = [
+                '0x6fffd0ae3f7d88c9b4925323f54c6e4b2918c5fd',
+                '0x12459c951127e0c374ff9105dda097662a027093',
+            ];
+            validInputs.forEach(input =>
+                expect(assert.doesConformToSchema.bind(assert, variableName, input, schema)).to.not.throw(),
+            );
+        });
+        it('should throw for invalid input', () => {
+            const invalidInputs = [42, { random: 'test' }, undefined, new BigNumber(45)];
+            invalidInputs.forEach(input =>
+                expect(assert.doesConformToSchema.bind(assert, variableName, input, schema)).to.throw(),
+            );
+        });
+    });
+    describe('#isHttpUrl', () => {
+        it('should not throw for valid input', () => {
+            const validInputs = [
+                'http://www.google.com',
+                'https://api.example-relayer.net',
+                'https://api.radarrelay.com/0x/v0/',
+                'https://zeroex.beta.radarrelay.com:8000/0x/v0/',
+            ];
+            validInputs.forEach(input => expect(assert.isHttpUrl.bind(assert, variableName, input)).to.not.throw());
+        });
+        it('should throw for invalid input', () => {
+            const invalidInputs = [
+                42,
+                { random: 'test' },
+                undefined,
+                new BigNumber(45),
+                'ws://www.api.example-relayer.net',
+                'www.google.com',
+                'api.example-relayer.net',
+                'user:password@api.example-relayer.net',
+                '//api.example-relayer.net',
+            ];
+            invalidInputs.forEach(input => expect(assert.isHttpUrl.bind(assert, variableName, input)).to.throw());
+        });
+    });
+    describe('#isUri', () => {
+        it('should not throw for valid input', () => {
+            const validInputs = [
+                'http://www.google.com',
+                'https://api.example-relayer.net',
+                'https://api.radarrelay.com/0x/v0/',
+                'https://zeroex.beta.radarrelay.com:8000/0x/v0/',
+                'ws://www.api.example-relayer.net',
+                'wss://www.api.example-relayer.net',
+                'user:password@api.example-relayer.net',
+            ];
+            validInputs.forEach(input => expect(assert.isUri.bind(assert, variableName, input)).to.not.throw());
+        });
+        it('should throw for invalid input', () => {
+            const invalidInputs = [
+                42,
+                { random: 'test' },
+                undefined,
+                new BigNumber(45),
+                'www.google.com',
+                'api.example-relayer.net',
+                '//api.example-relayer.net',
+            ];
+            invalidInputs.forEach(input => expect(assert.isUri.bind(assert, variableName, input)).to.throw());
+        });
+    });
+    describe('#assert', () => {
+        const assertMessage = 'assert not satisfied';
+        it('should not throw for valid input', () => {
+            expect(assert.assert.bind(assert, true, assertMessage)).to.not.throw();
+        });
+        it('should throw for invalid input', () => {
+            expect(assert.assert.bind(assert, false, assertMessage)).to.throw();
+        });
+    });
+    describe('#typeAssertionMessage', () => {
+        it('should render correct message', () => {
+            expect(assert.typeAssertionMessage('variable', 'string', 'number')).to.equal(
+                `Expected variable to be of type string, encountered: number`,
+            );
+        });
+    });
 });
diff --git a/packages/assert/tsconfig.json b/packages/assert/tsconfig.json
index 8314a9459..88a467ccb 100644
--- a/packages/assert/tsconfig.json
+++ b/packages/assert/tsconfig.json
@@ -1,7 +1,7 @@
 {
-	"extends": "../../tsconfig",
-	"compilerOptions": {
-		"outDir": "lib"
-	},
-	"include": ["./src/**/*", "./test/**/*", "../../node_modules/chai-typescript-typings/index.d.ts"]
+    "extends": "../../tsconfig",
+    "compilerOptions": {
+        "outDir": "lib"
+    },
+    "include": ["./src/**/*", "./test/**/*", "../../node_modules/chai-typescript-typings/index.d.ts"]
 }
diff --git a/packages/assert/tslint.json b/packages/assert/tslint.json
index e63054bfc..ffaefe83a 100644
--- a/packages/assert/tslint.json
+++ b/packages/assert/tslint.json
@@ -1,3 +1,3 @@
 {
-	"extends": ["@0xproject/tslint-config"]
+    "extends": ["@0xproject/tslint-config"]
 }
diff --git a/packages/chai-as-promised-typescript-typings/index.d.ts b/packages/chai-as-promised-typescript-typings/index.d.ts
index 389a076c6..ba6dabdcc 100644
--- a/packages/chai-as-promised-typescript-typings/index.d.ts
+++ b/packages/chai-as-promised-typescript-typings/index.d.ts
@@ -4,265 +4,265 @@
 // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
 
 declare module 'chai-as-promised' {
-	function chaiAsPromised(chai: any, utils: any): void;
-	namespace chaiAsPromised {
+    function chaiAsPromised(chai: any, utils: any): void;
+    namespace chaiAsPromised {
 
-	}
-	export = chaiAsPromised;
+    }
+    export = chaiAsPromised;
 }
 
 // tslint:disable:no-namespace ban-types member-ordering
 declare namespace Chai {
-	// For BDD API
-	interface Assertion extends LanguageChains, NumericComparison, TypeComparison {
-		eventually: PromisedAssertion;
-		fulfilled: PromisedAssertion;
-		become(expected: any): PromisedAssertion;
-		rejected(): PromisedAssertion;
-		rejectedWith(expected: any, message?: string | RegExp): PromisedAssertion;
-		notify(fn: Function): PromisedAssertion;
-	}
-
-	// Eventually does not have .then(), but PromisedAssertion have.
-	interface Eventually extends PromisedLanguageChains, PromisedNumericComparison, PromisedTypeComparison {
-		// From chai-as-promised
-		become(expected: PromiseLike<any>): PromisedAssertion;
-		fulfilled: PromisedAssertion;
-		rejected: () => PromisedAssertion;
-		rejectedWith(expected: any, message?: string | RegExp): PromisedAssertion;
-		notify(fn: Function): PromisedAssertion;
-
-		// From chai
-		not: PromisedAssertion;
-		deep: PromisedDeep;
-		all: PromisedKeyFilter;
-		a: PromisedTypeComparison;
-		an: PromisedTypeComparison;
-		include: PromisedInclude;
-		contain: PromisedInclude;
-		ok: PromisedAssertion;
-		true: () => PromisedAssertion;
-		false: () => PromisedAssertion;
-		null: PromisedAssertion;
-		undefined: PromisedAssertion;
-		exist: PromisedAssertion;
-		empty: PromisedAssertion;
-		arguments: PromisedAssertion;
-		Arguments: PromisedAssertion;
-		equal: PromisedEqual;
-		equals: PromisedEqual;
-		eq: PromisedEqual;
-		eql: PromisedEqual;
-		eqls: PromisedEqual;
-		property: PromisedProperty;
-		ownProperty: PromisedOwnProperty;
-		haveOwnProperty: PromisedOwnProperty;
-		length: PromisedLength;
-		lengthOf: PromisedLength;
-		match(regexp: RegExp | string, message?: string): PromisedAssertion;
-		string(string: string, message?: string): PromisedAssertion;
-		keys: PromisedKeys;
-		key(string: string): PromisedAssertion;
-		throw: PromisedThrow;
-		throws: PromisedThrow;
-		Throw: PromisedThrow;
-		respondTo(method: string, message?: string): PromisedAssertion;
-		itself: PromisedAssertion;
-		satisfy(matcher: Function, message?: string): PromisedAssertion;
-		closeTo(expected: number, delta: number, message?: string): PromisedAssertion;
-		members: PromisedMembers;
-	}
-
-	interface PromisedAssertion extends Eventually, PromiseLike<any> {}
-
-	interface PromisedLanguageChains {
-		eventually: Eventually;
-
-		// From chai
-		to: PromisedAssertion;
-		be: PromisedAssertion;
-		been: PromisedAssertion;
-		is: PromisedAssertion;
-		that: PromisedAssertion;
-		which: PromisedAssertion;
-		and: PromisedAssertion;
-		has: PromisedAssertion;
-		have: PromisedAssertion;
-		with: PromisedAssertion;
-		at: PromisedAssertion;
-		of: PromisedAssertion;
-		same: PromisedAssertion;
-	}
-
-	interface PromisedNumericComparison {
-		above: PromisedNumberComparer;
-		gt: PromisedNumberComparer;
-		greaterThan: PromisedNumberComparer;
-		least: PromisedNumberComparer;
-		gte: PromisedNumberComparer;
-		below: PromisedNumberComparer;
-		lt: PromisedNumberComparer;
-		lessThan: PromisedNumberComparer;
-		most: PromisedNumberComparer;
-		lte: PromisedNumberComparer;
-		within(start: number, finish: number, message?: string): PromisedAssertion;
-	}
-
-	type PromisedNumberComparer = (value: number, message?: string) => PromisedAssertion;
-
-	interface PromisedTypeComparison {
-		(type: string, message?: string): PromisedAssertion;
-		instanceof: PromisedInstanceOf;
-		instanceOf: PromisedInstanceOf;
-	}
-
-	type PromisedInstanceOf = (constructor: Object, message?: string) => PromisedAssertion;
-
-	interface PromisedDeep {
-		equal: PromisedEqual;
-		include: PromisedInclude;
-		property: PromisedProperty;
-	}
-
-	interface PromisedKeyFilter {
-		keys: PromisedKeys;
-	}
-
-	type PromisedEqual = (value: any, message?: string) => PromisedAssertion;
-
-	type PromisedProperty = (name: string, value?: any, message?: string) => PromisedAssertion;
-
-	type PromisedOwnProperty = (name: string, message?: string) => PromisedAssertion;
-
-	interface PromisedLength extends PromisedLanguageChains, PromisedNumericComparison {
-		(length: number, message?: string): PromisedAssertion;
-	}
-
-	interface PromisedInclude {
-		(value: Object | string | number, message?: string): PromisedAssertion;
-		keys: PromisedKeys;
-		members: PromisedMembers;
-		all: PromisedKeyFilter;
-	}
-
-	interface PromisedKeys {
-		(...keys: string[]): PromisedAssertion;
-		(keys: any[]): PromisedAssertion;
-	}
-
-	interface PromisedThrow {
-		(): PromisedAssertion;
-		(expected: string | RegExp, message?: string): PromisedAssertion;
-		(constructor: Error | Function, expected?: string | RegExp, message?: string): PromisedAssertion;
-	}
-
-	type PromisedMembers = (set: any[], message?: string) => PromisedAssertion;
-
-	// For Assert API
-	interface Assert {
-		eventually: PromisedAssert;
-		isFulfilled(promise: PromiseLike<any>, message?: string): PromiseLike<void>;
-		becomes(promise: PromiseLike<any>, expected: any, message?: string): PromiseLike<void>;
-		doesNotBecome(promise: PromiseLike<any>, expected: any, message?: string): PromiseLike<void>;
-		isRejected(promise: PromiseLike<any>, message?: string): PromiseLike<void>;
-		isRejected(promise: PromiseLike<any>, expected: any | RegExp, message?: string): PromiseLike<void>;
-		notify(fn: Function): PromiseLike<void>;
-	}
-
-	export interface PromisedAssert {
-		fail(actual?: any, expected?: any, msg?: string, operator?: string): PromiseLike<void>;
-
-		ok(val: any, msg?: string): PromiseLike<void>;
-		notOk(val: any, msg?: string): PromiseLike<void>;
-
-		equal(act: any, exp: any, msg?: string): PromiseLike<void>;
-		notEqual(act: any, exp: any, msg?: string): PromiseLike<void>;
-
-		strictEqual(act: any, exp: any, msg?: string): PromiseLike<void>;
-		notStrictEqual(act: any, exp: any, msg?: string): PromiseLike<void>;
-
-		deepEqual(act: any, exp: any, msg?: string): PromiseLike<void>;
-		notDeepEqual(act: any, exp: any, msg?: string): PromiseLike<void>;
-
-		isTrue(val: any, msg?: string): PromiseLike<void>;
-		isFalse(val: any, msg?: string): PromiseLike<void>;
+    // For BDD API
+    interface Assertion extends LanguageChains, NumericComparison, TypeComparison {
+        eventually: PromisedAssertion;
+        fulfilled: PromisedAssertion;
+        become(expected: any): PromisedAssertion;
+        rejected(): PromisedAssertion;
+        rejectedWith(expected: any, message?: string | RegExp): PromisedAssertion;
+        notify(fn: Function): PromisedAssertion;
+    }
+
+    // Eventually does not have .then(), but PromisedAssertion have.
+    interface Eventually extends PromisedLanguageChains, PromisedNumericComparison, PromisedTypeComparison {
+        // From chai-as-promised
+        become(expected: PromiseLike<any>): PromisedAssertion;
+        fulfilled: PromisedAssertion;
+        rejected: () => PromisedAssertion;
+        rejectedWith(expected: any, message?: string | RegExp): PromisedAssertion;
+        notify(fn: Function): PromisedAssertion;
+
+        // From chai
+        not: PromisedAssertion;
+        deep: PromisedDeep;
+        all: PromisedKeyFilter;
+        a: PromisedTypeComparison;
+        an: PromisedTypeComparison;
+        include: PromisedInclude;
+        contain: PromisedInclude;
+        ok: PromisedAssertion;
+        true: () => PromisedAssertion;
+        false: () => PromisedAssertion;
+        null: PromisedAssertion;
+        undefined: PromisedAssertion;
+        exist: PromisedAssertion;
+        empty: PromisedAssertion;
+        arguments: PromisedAssertion;
+        Arguments: PromisedAssertion;
+        equal: PromisedEqual;
+        equals: PromisedEqual;
+        eq: PromisedEqual;
+        eql: PromisedEqual;
+        eqls: PromisedEqual;
+        property: PromisedProperty;
+        ownProperty: PromisedOwnProperty;
+        haveOwnProperty: PromisedOwnProperty;
+        length: PromisedLength;
+        lengthOf: PromisedLength;
+        match(regexp: RegExp | string, message?: string): PromisedAssertion;
+        string(string: string, message?: string): PromisedAssertion;
+        keys: PromisedKeys;
+        key(string: string): PromisedAssertion;
+        throw: PromisedThrow;
+        throws: PromisedThrow;
+        Throw: PromisedThrow;
+        respondTo(method: string, message?: string): PromisedAssertion;
+        itself: PromisedAssertion;
+        satisfy(matcher: Function, message?: string): PromisedAssertion;
+        closeTo(expected: number, delta: number, message?: string): PromisedAssertion;
+        members: PromisedMembers;
+    }
+
+    interface PromisedAssertion extends Eventually, PromiseLike<any> {}
+
+    interface PromisedLanguageChains {
+        eventually: Eventually;
+
+        // From chai
+        to: PromisedAssertion;
+        be: PromisedAssertion;
+        been: PromisedAssertion;
+        is: PromisedAssertion;
+        that: PromisedAssertion;
+        which: PromisedAssertion;
+        and: PromisedAssertion;
+        has: PromisedAssertion;
+        have: PromisedAssertion;
+        with: PromisedAssertion;
+        at: PromisedAssertion;
+        of: PromisedAssertion;
+        same: PromisedAssertion;
+    }
+
+    interface PromisedNumericComparison {
+        above: PromisedNumberComparer;
+        gt: PromisedNumberComparer;
+        greaterThan: PromisedNumberComparer;
+        least: PromisedNumberComparer;
+        gte: PromisedNumberComparer;
+        below: PromisedNumberComparer;
+        lt: PromisedNumberComparer;
+        lessThan: PromisedNumberComparer;
+        most: PromisedNumberComparer;
+        lte: PromisedNumberComparer;
+        within(start: number, finish: number, message?: string): PromisedAssertion;
+    }
+
+    type PromisedNumberComparer = (value: number, message?: string) => PromisedAssertion;
+
+    interface PromisedTypeComparison {
+        (type: string, message?: string): PromisedAssertion;
+        instanceof: PromisedInstanceOf;
+        instanceOf: PromisedInstanceOf;
+    }
+
+    type PromisedInstanceOf = (constructor: Object, message?: string) => PromisedAssertion;
+
+    interface PromisedDeep {
+        equal: PromisedEqual;
+        include: PromisedInclude;
+        property: PromisedProperty;
+    }
+
+    interface PromisedKeyFilter {
+        keys: PromisedKeys;
+    }
+
+    type PromisedEqual = (value: any, message?: string) => PromisedAssertion;
+
+    type PromisedProperty = (name: string, value?: any, message?: string) => PromisedAssertion;
+
+    type PromisedOwnProperty = (name: string, message?: string) => PromisedAssertion;
+
+    interface PromisedLength extends PromisedLanguageChains, PromisedNumericComparison {
+        (length: number, message?: string): PromisedAssertion;
+    }
+
+    interface PromisedInclude {
+        (value: Object | string | number, message?: string): PromisedAssertion;
+        keys: PromisedKeys;
+        members: PromisedMembers;
+        all: PromisedKeyFilter;
+    }
+
+    interface PromisedKeys {
+        (...keys: string[]): PromisedAssertion;
+        (keys: any[]): PromisedAssertion;
+    }
+
+    interface PromisedThrow {
+        (): PromisedAssertion;
+        (expected: string | RegExp, message?: string): PromisedAssertion;
+        (constructor: Error | Function, expected?: string | RegExp, message?: string): PromisedAssertion;
+    }
+
+    type PromisedMembers = (set: any[], message?: string) => PromisedAssertion;
+
+    // For Assert API
+    interface Assert {
+        eventually: PromisedAssert;
+        isFulfilled(promise: PromiseLike<any>, message?: string): PromiseLike<void>;
+        becomes(promise: PromiseLike<any>, expected: any, message?: string): PromiseLike<void>;
+        doesNotBecome(promise: PromiseLike<any>, expected: any, message?: string): PromiseLike<void>;
+        isRejected(promise: PromiseLike<any>, message?: string): PromiseLike<void>;
+        isRejected(promise: PromiseLike<any>, expected: any | RegExp, message?: string): PromiseLike<void>;
+        notify(fn: Function): PromiseLike<void>;
+    }
+
+    export interface PromisedAssert {
+        fail(actual?: any, expected?: any, msg?: string, operator?: string): PromiseLike<void>;
+
+        ok(val: any, msg?: string): PromiseLike<void>;
+        notOk(val: any, msg?: string): PromiseLike<void>;
+
+        equal(act: any, exp: any, msg?: string): PromiseLike<void>;
+        notEqual(act: any, exp: any, msg?: string): PromiseLike<void>;
+
+        strictEqual(act: any, exp: any, msg?: string): PromiseLike<void>;
+        notStrictEqual(act: any, exp: any, msg?: string): PromiseLike<void>;
+
+        deepEqual(act: any, exp: any, msg?: string): PromiseLike<void>;
+        notDeepEqual(act: any, exp: any, msg?: string): PromiseLike<void>;
+
+        isTrue(val: any, msg?: string): PromiseLike<void>;
+        isFalse(val: any, msg?: string): PromiseLike<void>;
 
-		isNull(val: any, msg?: string): PromiseLike<void>;
-		isNotNull(val: any, msg?: string): PromiseLike<void>;
+        isNull(val: any, msg?: string): PromiseLike<void>;
+        isNotNull(val: any, msg?: string): PromiseLike<void>;
 
-		isUndefined(val: any, msg?: string): PromiseLike<void>;
-		isDefined(val: any, msg?: string): PromiseLike<void>;
+        isUndefined(val: any, msg?: string): PromiseLike<void>;
+        isDefined(val: any, msg?: string): PromiseLike<void>;
 
-		isFunction(val: any, msg?: string): PromiseLike<void>;
-		isNotFunction(val: any, msg?: string): PromiseLike<void>;
+        isFunction(val: any, msg?: string): PromiseLike<void>;
+        isNotFunction(val: any, msg?: string): PromiseLike<void>;
 
-		isObject(val: any, msg?: string): PromiseLike<void>;
-		isNotObject(val: any, msg?: string): PromiseLike<void>;
+        isObject(val: any, msg?: string): PromiseLike<void>;
+        isNotObject(val: any, msg?: string): PromiseLike<void>;
 
-		isArray(val: any, msg?: string): PromiseLike<void>;
-		isNotArray(val: any, msg?: string): PromiseLike<void>;
+        isArray(val: any, msg?: string): PromiseLike<void>;
+        isNotArray(val: any, msg?: string): PromiseLike<void>;
 
-		isString(val: any, msg?: string): PromiseLike<void>;
-		isNotString(val: any, msg?: string): PromiseLike<void>;
+        isString(val: any, msg?: string): PromiseLike<void>;
+        isNotString(val: any, msg?: string): PromiseLike<void>;
 
-		isNumber(val: any, msg?: string): PromiseLike<void>;
-		isNotNumber(val: any, msg?: string): PromiseLike<void>;
+        isNumber(val: any, msg?: string): PromiseLike<void>;
+        isNotNumber(val: any, msg?: string): PromiseLike<void>;
 
-		isBoolean(val: any, msg?: string): PromiseLike<void>;
-		isNotBoolean(val: any, msg?: string): PromiseLike<void>;
+        isBoolean(val: any, msg?: string): PromiseLike<void>;
+        isNotBoolean(val: any, msg?: string): PromiseLike<void>;
 
-		typeOf(val: any, type: string, msg?: string): PromiseLike<void>;
-		notTypeOf(val: any, type: string, msg?: string): PromiseLike<void>;
+        typeOf(val: any, type: string, msg?: string): PromiseLike<void>;
+        notTypeOf(val: any, type: string, msg?: string): PromiseLike<void>;
 
-		instanceOf(val: any, type: Function, msg?: string): PromiseLike<void>;
-		notInstanceOf(val: any, type: Function, msg?: string): PromiseLike<void>;
+        instanceOf(val: any, type: Function, msg?: string): PromiseLike<void>;
+        notInstanceOf(val: any, type: Function, msg?: string): PromiseLike<void>;
 
-		include(exp: string | any[], inc: any, msg?: string): PromiseLike<void>;
+        include(exp: string | any[], inc: any, msg?: string): PromiseLike<void>;
 
-		notInclude(exp: string | any[], inc: any, msg?: string): PromiseLike<void>;
+        notInclude(exp: string | any[], inc: any, msg?: string): PromiseLike<void>;
 
-		match(exp: any, re: RegExp, msg?: string): PromiseLike<void>;
-		notMatch(exp: any, re: RegExp, msg?: string): PromiseLike<void>;
+        match(exp: any, re: RegExp, msg?: string): PromiseLike<void>;
+        notMatch(exp: any, re: RegExp, msg?: string): PromiseLike<void>;
 
-		property(obj: Object, prop: string, msg?: string): PromiseLike<void>;
-		notProperty(obj: Object, prop: string, msg?: string): PromiseLike<void>;
-		deepProperty(obj: Object, prop: string, msg?: string): PromiseLike<void>;
-		notDeepProperty(obj: Object, prop: string, msg?: string): PromiseLike<void>;
+        property(obj: Object, prop: string, msg?: string): PromiseLike<void>;
+        notProperty(obj: Object, prop: string, msg?: string): PromiseLike<void>;
+        deepProperty(obj: Object, prop: string, msg?: string): PromiseLike<void>;
+        notDeepProperty(obj: Object, prop: string, msg?: string): PromiseLike<void>;
 
-		propertyVal(obj: Object, prop: string, val: any, msg?: string): PromiseLike<void>;
-		propertyNotVal(obj: Object, prop: string, val: any, msg?: string): PromiseLike<void>;
+        propertyVal(obj: Object, prop: string, val: any, msg?: string): PromiseLike<void>;
+        propertyNotVal(obj: Object, prop: string, val: any, msg?: string): PromiseLike<void>;
 
-		deepPropertyVal(obj: Object, prop: string, val: any, msg?: string): PromiseLike<void>;
-		deepPropertyNotVal(obj: Object, prop: string, val: any, msg?: string): PromiseLike<void>;
+        deepPropertyVal(obj: Object, prop: string, val: any, msg?: string): PromiseLike<void>;
+        deepPropertyNotVal(obj: Object, prop: string, val: any, msg?: string): PromiseLike<void>;
 
-		lengthOf(exp: any, len: number, msg?: string): PromiseLike<void>;
-		// alias frenzy
-		throw(fn: Function, msg?: string): PromiseLike<void>;
-		throw(fn: Function, regExp: RegExp): PromiseLike<void>;
-		throw(fn: Function, errType: Function, msg?: string): PromiseLike<void>;
-		throw(fn: Function, errType: Function, regExp: RegExp): PromiseLike<void>;
+        lengthOf(exp: any, len: number, msg?: string): PromiseLike<void>;
+        // alias frenzy
+        throw(fn: Function, msg?: string): PromiseLike<void>;
+        throw(fn: Function, regExp: RegExp): PromiseLike<void>;
+        throw(fn: Function, errType: Function, msg?: string): PromiseLike<void>;
+        throw(fn: Function, errType: Function, regExp: RegExp): PromiseLike<void>;
 
-		throws(fn: Function, msg?: string): PromiseLike<void>;
-		throws(fn: Function, regExp: RegExp): PromiseLike<void>;
-		throws(fn: Function, errType: Function, msg?: string): PromiseLike<void>;
-		throws(fn: Function, errType: Function, regExp: RegExp): PromiseLike<void>;
+        throws(fn: Function, msg?: string): PromiseLike<void>;
+        throws(fn: Function, regExp: RegExp): PromiseLike<void>;
+        throws(fn: Function, errType: Function, msg?: string): PromiseLike<void>;
+        throws(fn: Function, errType: Function, regExp: RegExp): PromiseLike<void>;
 
-		Throw(fn: Function, msg?: string): PromiseLike<void>;
-		Throw(fn: Function, regExp: RegExp): PromiseLike<void>;
-		Throw(fn: Function, errType: Function, msg?: string): PromiseLike<void>;
-		Throw(fn: Function, errType: Function, regExp: RegExp): PromiseLike<void>;
+        Throw(fn: Function, msg?: string): PromiseLike<void>;
+        Throw(fn: Function, regExp: RegExp): PromiseLike<void>;
+        Throw(fn: Function, errType: Function, msg?: string): PromiseLike<void>;
+        Throw(fn: Function, errType: Function, regExp: RegExp): PromiseLike<void>;
 
-		doesNotThrow(fn: Function, msg?: string): PromiseLike<void>;
-		doesNotThrow(fn: Function, regExp: RegExp): PromiseLike<void>;
-		doesNotThrow(fn: Function, errType: Function, msg?: string): PromiseLike<void>;
-		doesNotThrow(fn: Function, errType: Function, regExp: RegExp): PromiseLike<void>;
+        doesNotThrow(fn: Function, msg?: string): PromiseLike<void>;
+        doesNotThrow(fn: Function, regExp: RegExp): PromiseLike<void>;
+        doesNotThrow(fn: Function, errType: Function, msg?: string): PromiseLike<void>;
+        doesNotThrow(fn: Function, errType: Function, regExp: RegExp): PromiseLike<void>;
 
-		operator(val: any, operator: string, val2: any, msg?: string): PromiseLike<void>;
-		closeTo(act: number, exp: number, delta: number, msg?: string): PromiseLike<void>;
+        operator(val: any, operator: string, val2: any, msg?: string): PromiseLike<void>;
+        closeTo(act: number, exp: number, delta: number, msg?: string): PromiseLike<void>;
 
-		sameMembers(set1: any[], set2: any[], msg?: string): PromiseLike<void>;
-		includeMembers(set1: any[], set2: any[], msg?: string): PromiseLike<void>;
+        sameMembers(set1: any[], set2: any[], msg?: string): PromiseLike<void>;
+        includeMembers(set1: any[], set2: any[], msg?: string): PromiseLike<void>;
 
-		ifError(val: any, msg?: string): PromiseLike<void>;
-	}
+        ifError(val: any, msg?: string): PromiseLike<void>;
+    }
 }
diff --git a/packages/chai-as-promised-typescript-typings/package.json b/packages/chai-as-promised-typescript-typings/package.json
index 77985de05..bea3d273d 100644
--- a/packages/chai-as-promised-typescript-typings/package.json
+++ b/packages/chai-as-promised-typescript-typings/package.json
@@ -1,21 +1,21 @@
 {
-	"name": "chai-as-promised-typescript-typings",
-	"version": "0.0.6",
-	"description": "Typescript type definitions for chai-as-promised",
-	"main": "index.d.ts",
-	"types": "index.d.ts",
-	"repository": {
-		"type": "git",
-		"url": "git+https://github.com/0xProject/0x.js.git"
-	},
-	"author": "Fabio Berger",
-	"contributors": ["Leonid Logvinov <logvinov.leon@gmail.com>"],
-	"license": "Apache-2.0",
-	"bugs": {
-		"url": "https://github.com/0xProject/0x.js/issues"
-	},
-	"homepage": "https://github.com/0xProject/0x.js/packages/chai-as-promised-typescript-typings#readme",
-	"dependencies": {
-		"chai-typescript-typings": "^0.0.0"
-	}
+    "name": "chai-as-promised-typescript-typings",
+    "version": "0.0.6",
+    "description": "Typescript type definitions for chai-as-promised",
+    "main": "index.d.ts",
+    "types": "index.d.ts",
+    "repository": {
+        "type": "git",
+        "url": "git+https://github.com/0xProject/0x.js.git"
+    },
+    "author": "Fabio Berger",
+    "contributors": ["Leonid Logvinov <logvinov.leon@gmail.com>"],
+    "license": "Apache-2.0",
+    "bugs": {
+        "url": "https://github.com/0xProject/0x.js/issues"
+    },
+    "homepage": "https://github.com/0xProject/0x.js/packages/chai-as-promised-typescript-typings#readme",
+    "dependencies": {
+        "chai-typescript-typings": "^0.0.0"
+    }
 }
diff --git a/packages/chai-as-promised-typescript-typings/tslint.json b/packages/chai-as-promised-typescript-typings/tslint.json
index ef528b22e..9a93a1f74 100644
--- a/packages/chai-as-promised-typescript-typings/tslint.json
+++ b/packages/chai-as-promised-typescript-typings/tslint.json
@@ -1,3 +1,3 @@
 {
-	"extends": ["tslint-config-0xproject"]
+    "extends": ["tslint-config-0xproject"]
 }
diff --git a/packages/chai-typescript-typings/index.d.ts b/packages/chai-typescript-typings/index.d.ts
index 73d87a887..8b3e4c079 100644
--- a/packages/chai-typescript-typings/index.d.ts
+++ b/packages/chai-typescript-typings/index.d.ts
@@ -12,1243 +12,1243 @@
 
 // tslint:disable:no-namespace member-ordering ban-types unified-signatures variable-name callable-types
 declare namespace Chai {
-	interface ChaiStatic {
-		expect: ExpectStatic;
-		should(): Should;
-		/**
-		 * Provides a way to extend the internals of Chai
-		 */
-		use(fn: (chai: any, utils: any) => void): ChaiStatic;
-		assert: AssertStatic;
-		config: Config;
-		AssertionError: typeof AssertionError;
-		version: string;
-	}
-
-	export interface ExpectStatic extends AssertionStatic {
-		fail(actual?: any, expected?: any, message?: string, operator?: Operator): void;
-	}
-
-	export interface AssertStatic extends Assert {}
-
-	type AssertionStatic = (target: any, message?: string) => Assertion;
-
-	export type Operator = string; // "==" | "===" | ">" | ">=" | "<" | "<=" | "!=" | "!==";
-
-	export type OperatorComparable = boolean | null | number | string | undefined | Date;
-
-	interface ShouldAssertion {
-		equal(value1: any, value2: any, message?: string): void;
-		Throw: ShouldThrow;
-		throw: ShouldThrow;
-		exist(value: any, message?: string): void;
-	}
-
-	interface Should extends ShouldAssertion {
-		not: ShouldAssertion;
-		fail(actual: any, expected: any, message?: string, operator?: Operator): void;
-	}
-
-	interface ShouldThrow {
-		(actual: Function): void;
-		(actual: Function, expected: string | RegExp, message?: string): void;
-		(actual: Function, constructor: Error | Function, expected?: string | RegExp, message?: string): void;
-	}
-
-	interface Assertion extends LanguageChains, NumericComparison, TypeComparison {
-		not: Assertion;
-		deep: Deep;
-		nested: Nested;
-		any: KeyFilter;
-		all: KeyFilter;
-		a: TypeComparison;
-		an: TypeComparison;
-		include: Include;
-		includes: Include;
-		contain: Include;
-		contains: Include;
-		ok: Assertion;
-		true: () => Assertion;
-		false: () => Assertion;
-		null: () => Assertion;
-		undefined: () => Assertion;
-		NaN: Assertion;
-		exist: Assertion;
-		empty: Assertion;
-		arguments: Assertion;
-		Arguments: Assertion;
-		equal: Equal;
-		equals: Equal;
-		eq: Equal;
-		eql: Equal;
-		eqls: Equal;
-		property: Property;
-		ownProperty: OwnProperty;
-		haveOwnProperty: OwnProperty;
-		ownPropertyDescriptor: OwnPropertyDescriptor;
-		haveOwnPropertyDescriptor: OwnPropertyDescriptor;
-		length: Length;
-		lengthOf: Length;
-		match: Match;
-		matches: Match;
-		string(string: string, message?: string): Assertion;
-		keys: Keys;
-		key(string: string): Assertion;
-		throw: (message?: string) => Assertion;
-		throws: Throw;
-		Throw: Throw;
-		respondTo: RespondTo;
-		respondsTo: RespondTo;
-		itself: Assertion;
-		satisfy: Satisfy;
-		satisfies: Satisfy;
-		closeTo: CloseTo;
-		approximately: CloseTo;
-		members: Members;
-		increase: PropertyChange;
-		increases: PropertyChange;
-		decrease: PropertyChange;
-		decreases: PropertyChange;
-		change: PropertyChange;
-		changes: PropertyChange;
-		extensible: Assertion;
-		sealed: Assertion;
-		frozen: Assertion;
-		oneOf(list: any[], message?: string): Assertion;
-	}
-
-	interface LanguageChains {
-		to: Assertion;
-		be: Assertion;
-		been: Assertion;
-		is: Assertion;
-		that: Assertion;
-		which: Assertion;
-		and: Assertion;
-		has: Assertion;
-		have: Assertion;
-		with: Assertion;
-		at: Assertion;
-		of: Assertion;
-		same: Assertion;
-	}
-
-	interface NumericComparison {
-		above: NumberComparer;
-		gt: NumberComparer;
-		greaterThan: NumberComparer;
-		least: NumberComparer;
-		gte: NumberComparer;
-		below: NumberComparer;
-		lt: NumberComparer;
-		lessThan: NumberComparer;
-		most: NumberComparer;
-		lte: NumberComparer;
-		within(start: number, finish: number, message?: string): Assertion;
-	}
-
-	interface NumberComparer {
-		(value: number, message?: string): Assertion;
-	}
-
-	interface TypeComparison {
-		(type: string, message?: string): Assertion;
-		instanceof: InstanceOf;
-		instanceOf: InstanceOf;
-	}
-
-	interface InstanceOf {
-		(constructor: Object, message?: string): Assertion;
-	}
-
-	interface CloseTo {
-		(expected: number, delta: number, message?: string): Assertion;
-	}
-
-	interface Nested {
-		include: Include;
-		property: Property;
-		members: Members;
-	}
-
-	interface Deep {
-		equal: Equal;
-		equals: Equal;
-		eq: Equal;
-		include: Include;
-		property: Property;
-		members: Members;
-	}
-
-	interface KeyFilter {
-		keys: Keys;
-	}
-
-	interface Equal {
-		(value: any, message?: string): Assertion;
-	}
-
-	interface Property {
-		(name: string, value?: any, message?: string): Assertion;
-	}
-
-	interface OwnProperty {
-		(name: string, message?: string): Assertion;
-	}
-
-	interface OwnPropertyDescriptor {
-		(name: string, descriptor: PropertyDescriptor, message?: string): Assertion;
-		(name: string, message?: string): Assertion;
-	}
-
-	interface Length extends LanguageChains, NumericComparison {
-		(length: number, message?: string): Assertion;
-	}
-
-	interface Include {
-		(value: Object | string | number, message?: string): Assertion;
-		keys: Keys;
-		members: Members;
-		any: KeyFilter;
-		all: KeyFilter;
-	}
-
-	interface Match {
-		(regexp: RegExp | string, message?: string): Assertion;
-	}
-
-	interface Keys {
-		(...keys: string[]): Assertion;
-		(keys: any[]): Assertion;
-		(keys: Object): Assertion;
-	}
-
-	interface Throw {
-		(): Assertion;
-		(expected: string, message?: string): Assertion;
-		(expected: RegExp, message?: string): Assertion;
-		(constructor: Error, expected?: string, message?: string): Assertion;
-		(constructor: Error, expected?: RegExp, message?: string): Assertion;
-		(constructor: Function, expected?: string, message?: string): Assertion;
-		(constructor: Function, expected?: RegExp, message?: string): Assertion;
-	}
-
-	interface RespondTo {
-		(method: string, message?: string): Assertion;
-	}
-
-	interface Satisfy {
-		(matcher: Function, message?: string): Assertion;
-	}
-
-	interface Members {
-		(set: any[], message?: string): Assertion;
-	}
-
-	interface PropertyChange {
-		(object: Object, property: string, message?: string): Assertion;
-	}
-
-	export interface Assert {
-		/**
-		 * @param expression    Expression to test for truthiness.
-		 * @param message    Message to display on error.
-		 */
-		(expression: any, message?: string): void;
-
-		/**
-		 * Throws a failure.
-		 *
-		 * @type T   Type of the objects.
-		 * @param actual   Actual value.
-		 * @param expected   Potential expected value.
-		 * @param message    Message to display on error.
-		 * @param operator   Comparison operator, if not strict equality.
-		 * @remarks Node.js assert module-compatible.
-		 */
-		fail<T>(actual?: T, expected?: T, message?: string, operator?: Operator): void;
-
-		/**
-		 * Asserts that object is truthy.
-		 *
-		 * @type T   Type of object.
-		 * @param object   Object to test.
-		 * @param message    Message to display on error.
-		 */
-		isOk<T>(value: T, message?: string): void;
-
-		/**
-		 * Asserts that object is truthy.
-		 *
-		 * @type T   Type of object.
-		 * @param object   Object to test.
-		 * @param message    Message to display on error.
-		 */
-		ok<T>(value: T, message?: string): void;
-
-		/**
-		 * Asserts that object is falsy.
-		 *
-		 * @type T   Type of object.
-		 * @param object   Object to test.
-		 * @param message    Message to display on error.
-		 */
-		isNotOk<T>(value: T, message?: string): void;
-
-		/**
-		 * Asserts that object is falsy.
-		 *
-		 * @type T   Type of object.
-		 * @param object   Object to test.
-		 * @param message    Message to display on error.
-		 */
-		notOk<T>(value: T, message?: string): void;
-
-		/**
-		 * Asserts non-strict equality (==) of actual and expected.
-		 *
-		 * @type T   Type of the objects.
-		 * @param actual   Actual value.
-		 * @param expected   Potential expected value.
-		 * @param message   Message to display on error.
-		 */
-		equal<T>(actual: T, expected: T, message?: string): void;
-
-		/**
-		 * Asserts non-strict inequality (==) of actual and expected.
-		 *
-		 * @type T   Type of the objects.
-		 * @param actual   Actual value.
-		 * @param expected   Potential expected value.
-		 * @param message   Message to display on error.
-		 */
-		notEqual<T>(actual: T, expected: T, message?: string): void;
-
-		/**
-		 * Asserts strict equality (===) of actual and expected.
-		 *
-		 * @type T   Type of the objects.
-		 * @param actual   Actual value.
-		 * @param expected   Potential expected value.
-		 * @param message   Message to display on error.
-		 */
-		strictEqual<T>(actual: T, expected: T, message?: string): void;
-
-		/**
-		 * Asserts strict inequality (==) of actual and expected.
-		 *
-		 * @type T   Type of the objects.
-		 * @param actual   Actual value.
-		 * @param expected   Potential expected value.
-		 * @param message   Message to display on error.
-		 */
-		notStrictEqual<T>(actual: T, expected: T, message?: string): void;
-
-		/**
-		 * Asserts that actual is deeply equal to expected.
-		 *
-		 * @type T   Type of the objects.
-		 * @param actual   Actual value.
-		 * @param expected   Potential expected value.
-		 * @param message   Message to display on error.
-		 */
-		deepEqual<T>(actual: T, expected: T, message?: string): void;
-
-		/**
-		 * Asserts that actual is not deeply equal to expected.
-		 *
-		 * @type T   Type of the objects.
-		 * @param actual   Actual value.
-		 * @param expected   Potential expected value.
-		 * @param message   Message to display on error.
-		 */
-		notDeepEqual<T>(actual: T, expected: T, message?: string): void;
-
-		/**
-		 * Asserts valueToCheck is strictly greater than (>) valueToBeAbove.
-		 *
-		 * @param valueToCheck   Actual value.
-		 * @param valueToBeAbove   Minimum Potential expected value.
-		 * @param message   Message to display on error.
-		 */
-		isAbove(valueToCheck: number, valueToBeAbove: number, message?: string): void;
-
-		/**
-		 * Asserts valueToCheck is greater than or equal to (>=) valueToBeAtLeast.
-		 *
-		 * @param valueToCheck   Actual value.
-		 * @param valueToBeAtLeast   Minimum Potential expected value.
-		 * @param message   Message to display on error.
-		 */
-		isAtLeast(valueToCheck: number, valueToBeAtLeast: number, message?: string): void;
-
-		/**
-		 * Asserts valueToCheck is strictly less than (<) valueToBeBelow.
-		 *
-		 * @param valueToCheck   Actual value.
-		 * @param valueToBeBelow   Minimum Potential expected value.
-		 * @param message   Message to display on error.
-		 */
-		isBelow(valueToCheck: number, valueToBeBelow: number, message?: string): void;
-
-		/**
-		 * Asserts valueToCheck is greater than or equal to (>=) valueToBeAtMost.
-		 *
-		 * @param valueToCheck   Actual value.
-		 * @param valueToBeAtMost   Minimum Potential expected value.
-		 * @param message   Message to display on error.
-		 */
-		isAtMost(valueToCheck: number, valueToBeAtMost: number, message?: string): void;
-
-		/**
-		 * Asserts that value is true.
-		 *
-		 * @type T   Type of value.
-		 * @param value   Actual value.
-		 * @param message   Message to display on error.
-		 */
-		isTrue<T>(value: T, message?: string): void;
-
-		/**
-		 * Asserts that value is false.
-		 *
-		 * @type T   Type of value.
-		 * @param value   Actual value.
-		 * @param message   Message to display on error.
-		 */
-		isFalse<T>(value: T, message?: string): void;
-
-		/**
-		 * Asserts that value is not true.
-		 *
-		 * @type T   Type of value.
-		 * @param value   Actual value.
-		 * @param message   Message to display on error.
-		 */
-		isNotTrue<T>(value: T, message?: string): void;
-
-		/**
-		 * Asserts that value is not false.
-		 *
-		 * @type T   Type of value.
-		 * @param value   Actual value.
-		 * @param message   Message to display on error.
-		 */
-		isNotFalse<T>(value: T, message?: string): void;
-
-		/**
-		 * Asserts that value is null.
-		 *
-		 * @type T   Type of value.
-		 * @param value   Actual value.
-		 * @param message   Message to display on error.
-		 */
-		isNull<T>(value: T, message?: string): void;
-
-		/**
-		 * Asserts that value is not null.
-		 *
-		 * @type T   Type of value.
-		 * @param value   Actual value.
-		 * @param message   Message to display on error.
-		 */
-		isNotNull<T>(value: T, message?: string): void;
-
-		/**
-		 * Asserts that value is not null.
-		 *
-		 * @type T   Type of value.
-		 * @param value   Actual value.
-		 * @param message   Message to display on error.
-		 */
-		isNaN<T>(value: T, message?: string): void;
-
-		/**
-		 * Asserts that value is not null.
-		 *
-		 * @type T   Type of value.
-		 * @param value   Actual value.
-		 * @param message   Message to display on error.
-		 */
-		isNotNaN<T>(value: T, message?: string): void;
-
-		/**
-		 * Asserts that value is undefined.
-		 *
-		 * @type T   Type of value.
-		 * @param value   Actual value.
-		 * @param message   Message to display on error.
-		 */
-		isUndefined<T>(value: T, message?: string): void;
-
-		/**
-		 * Asserts that value is not undefined.
-		 *
-		 * @type T   Type of value.
-		 * @param value   Actual value.
-		 * @param message   Message to display on error.
-		 */
-		isDefined<T>(value: T, message?: string): void;
-
-		/**
-		 * Asserts that value is a function.
-		 *
-		 * @type T   Type of value.
-		 * @param value   Actual value.
-		 * @param message   Message to display on error.
-		 */
-		isFunction<T>(value: T, message?: string): void;
-
-		/**
-		 * Asserts that value is not a function.
-		 *
-		 * @type T   Type of value.
-		 * @param value   Actual value.
-		 * @param message   Message to display on error.
-		 */
-		isNotFunction<T>(value: T, message?: string): void;
-
-		/**
-		 * Asserts that value is an object of type 'Object'
-		 * (as revealed by Object.prototype.toString).
-		 *
-		 * @type T   Type of value.
-		 * @param value   Actual value.
-		 * @param message   Message to display on error.
-		 * @remarks The assertion does not match subclassed objects.
-		 */
-		isObject<T>(value: T, message?: string): void;
-
-		/**
-		 * Asserts that value is not an object of type 'Object'
-		 * (as revealed by Object.prototype.toString).
-		 *
-		 * @type T   Type of value.
-		 * @param value   Actual value.
-		 * @param message   Message to display on error.
-		 */
-		isNotObject<T>(value: T, message?: string): void;
-
-		/**
-		 * Asserts that value is an array.
-		 *
-		 * @type T   Type of value.
-		 * @param value   Actual value.
-		 * @param message   Message to display on error.
-		 */
-		isArray<T>(value: T, message?: string): void;
-
-		/**
-		 * Asserts that value is not an array.
-		 *
-		 * @type T   Type of value.
-		 * @param value   Actual value.
-		 * @param message   Message to display on error.
-		 */
-		isNotArray<T>(value: T, message?: string): void;
-
-		/**
-		 * Asserts that value is a string.
-		 *
-		 * @type T   Type of value.
-		 * @param value   Actual value.
-		 * @param message   Message to display on error.
-		 */
-		isString<T>(value: T, message?: string): void;
-
-		/**
-		 * Asserts that value is not a string.
-		 *
-		 * @type T   Type of value.
-		 * @param value   Actual value.
-		 * @param message   Message to display on error.
-		 */
-		isNotString<T>(value: T, message?: string): void;
-
-		/**
-		 * Asserts that value is a number.
-		 *
-		 * @type T   Type of value.
-		 * @param value   Actual value.
-		 * @param message   Message to display on error.
-		 */
-		isNumber<T>(value: T, message?: string): void;
-
-		/**
-		 * Asserts that value is not a number.
-		 *
-		 * @type T   Type of value.
-		 * @param value   Actual value.
-		 * @param message   Message to display on error.
-		 */
-		isNotNumber<T>(value: T, message?: string): void;
-
-		/**
-		 * Asserts that value is a boolean.
-		 *
-		 * @type T   Type of value.
-		 * @param value   Actual value.
-		 * @param message   Message to display on error.
-		 */
-		isBoolean<T>(value: T, message?: string): void;
-
-		/**
-		 * Asserts that value is not a boolean.
-		 *
-		 * @type T   Type of value.
-		 * @param value   Actual value.
-		 * @param message   Message to display on error.
-		 */
-		isNotBoolean<T>(value: T, message?: string): void;
-
-		/**
-		 * Asserts that value's type is name, as determined by Object.prototype.toString.
-		 *
-		 * @type T   Type of value.
-		 * @param value   Actual value.
-		 * @param name   Potential expected type name of value.
-		 * @param message   Message to display on error.
-		 */
-		typeOf<T>(value: T, name: string, message?: string): void;
-
-		/**
-		 * Asserts that value's type is not name, as determined by Object.prototype.toString.
-		 *
-		 * @type T   Type of value.
-		 * @param value   Actual value.
-		 * @param name   Potential expected type name of value.
-		 * @param message   Message to display on error.
-		 */
-		notTypeOf<T>(value: T, name: string, message?: string): void;
-
-		/**
-		 * Asserts that value is an instance of constructor.
-		 *
-		 * @type T   Type of value.
-		 * @param value   Actual value.
-		 * @param constructor   Potential expected contructor of value.
-		 * @param message   Message to display on error.
-		 */
-		instanceOf<T>(value: T, constructor: Function, message?: string): void;
-
-		/**
-		 * Asserts that value is not an instance of constructor.
-		 *
-		 * @type T   Type of value.
-		 * @param value   Actual value.
-		 * @param constructor   Potential expected contructor of value.
-		 * @param message   Message to display on error.
-		 */
-		notInstanceOf<T>(value: T, type: Function, message?: string): void;
-
-		/**
-		 * Asserts that haystack includes needle.
-		 *
-		 * @param haystack   Container string.
-		 * @param needle   Potential expected substring of haystack.
-		 * @param message   Message to display on error.
-		 */
-		include(haystack: string, needle: string, message?: string): void;
-
-		/**
-		 * Asserts that haystack includes needle.
-		 *
-		 * @type T   Type of values in haystack.
-		 * @param haystack   Container array.
-		 * @param needle   Potential value contained in haystack.
-		 * @param message   Message to display on error.
-		 */
-		include<T>(haystack: T[], needle: T, message?: string): void;
-
-		/**
-		 * Asserts that haystack does not include needle.
-		 *
-		 * @param haystack   Container string.
-		 * @param needle   Potential expected substring of haystack.
-		 * @param message   Message to display on error.
-		 */
-		notInclude(haystack: string, needle: any, message?: string): void;
-
-		/**
-		 * Asserts that haystack does not include needle.
-		 *
-		 * @type T   Type of values in haystack.
-		 * @param haystack   Container array.
-		 * @param needle   Potential value contained in haystack.
-		 * @param message   Message to display on error.
-		 */
-		notInclude(haystack: any[], needle: any, message?: string): void;
-
-		/**
-		 * Asserts that value matches the regular expression regexp.
-		 *
-		 * @param value   Actual value.
-		 * @param regexp   Potential match of value.
-		 * @param message   Message to display on error.
-		 */
-		match(value: string, regexp: RegExp, message?: string): void;
-
-		/**
-		 * Asserts that value does not match the regular expression regexp.
-		 *
-		 * @param value   Actual value.
-		 * @param regexp   Potential match of value.
-		 * @param message   Message to display on error.
-		 */
-		notMatch(expected: any, regexp: RegExp, message?: string): void;
-
-		/**
-		 * Asserts that object has a property named by property.
-		 *
-		 * @type T   Type of object.
-		 * @param object   Container object.
-		 * @param property   Potential contained property of object.
-		 * @param message   Message to display on error.
-		 */
-		property<T>(object: T, property: string /* keyof T */, message?: string): void;
-
-		/**
-		 * Asserts that object has a property named by property.
-		 *
-		 * @type T   Type of object.
-		 * @param object   Container object.
-		 * @param property   Potential contained property of object.
-		 * @param message   Message to display on error.
-		 */
-		notProperty<T>(object: T, property: string /* keyof T */, message?: string): void;
-
-		/**
-		 * Asserts that object has a property named by property, which can be a string
-		 * using dot- and bracket-notation for deep reference.
-		 *
-		 * @type T   Type of object.
-		 * @param object   Container object.
-		 * @param property   Potential contained property of object.
-		 * @param message   Message to display on error.
-		 */
-		deepProperty<T>(object: T, property: string, message?: string): void;
-
-		/**
-		 * Asserts that object does not have a property named by property, which can be a
-		 * string using dot- and bracket-notation for deep reference.
-		 *
-		 * @type T   Type of object.
-		 * @param object   Container object.
-		 * @param property   Potential contained property of object.
-		 * @param message   Message to display on error.
-		 */
-		notDeepProperty<T>(object: T, property: string, message?: string): void;
-
-		/**
-		 * Asserts that object has a property named by property with value given by value.
-		 *
-		 * @type T   Type of object.
-		 * @type V   Type of value.
-		 * @param object   Container object.
-		 * @param property   Potential contained property of object.
-		 * @param value   Potential expected property value.
-		 * @param message   Message to display on error.
-		 */
-		propertyVal<T, V>(object: T, property: string /* keyof T */, value: V, message?: string): void;
-
-		/**
-		 * Asserts that object has a property named by property with value given by value.
-		 *
-		 * @type T   Type of object.
-		 * @type V   Type of value.
-		 * @param object   Container object.
-		 * @param property   Potential contained property of object.
-		 * @param value   Potential expected property value.
-		 * @param message   Message to display on error.
-		 */
-		propertyNotVal<T, V>(object: T, property: string /* keyof T */, value: V, message?: string): void;
-
-		/**
-		 * Asserts that object has a property named by property, which can be a string
-		 * using dot- and bracket-notation for deep reference.
-		 *
-		 * @type T   Type of object.
-		 * @type V   Type of value.
-		 * @param object   Container object.
-		 * @param property   Potential contained property of object.
-		 * @param value   Potential expected property value.
-		 * @param message   Message to display on error.
-		 */
-		deepPropertyVal<T, V>(object: T, property: string, value: V, message?: string): void;
-
-		/**
-		 * Asserts that object does not have a property named by property, which can be a
-		 * string using dot- and bracket-notation for deep reference.
-		 *
-		 * @type T   Type of object.
-		 * @type V   Type of value.
-		 * @param object   Container object.
-		 * @param property   Potential contained property of object.
-		 * @param value   Potential expected property value.
-		 * @param message   Message to display on error.
-		 */
-		deepPropertyNotVal<T, V>(object: T, property: string, value: V, message?: string): void;
-
-		/**
-		 * Asserts that object has a length property with the expected value.
-		 *
-		 * @type T   Type of object.
-		 * @param object   Container object.
-		 * @param length   Potential expected length of object.
-		 * @param message   Message to display on error.
-		 */
-		lengthOf<T extends { readonly length?: number }>(object: T, length: number, message?: string): void;
-
-		/**
-		 * Asserts that fn will throw an error.
-		 *
-		 * @param fn   Function that may throw.
-		 * @param message   Message to display on error.
-		 */
-		throw(fn: Function, message?: string): void;
-
-		/**
-		 * Asserts that function will throw an error with message matching regexp.
-		 *
-		 * @param fn   Function that may throw.
-		 * @param regExp   Potential expected message match.
-		 * @param message   Message to display on error.
-		 */
-		throw(fn: Function, regExp: RegExp): void;
-
-		/**
-		 * Asserts that function will throw an error that is an instance of constructor.
-		 *
-		 * @param fn   Function that may throw.
-		 * @param constructor   Potential expected error constructor.
-		 * @param message   Message to display on error.
-		 */
-		throw(fn: Function, constructor: Function, message?: string): void;
-
-		/**
-		 * Asserts that function will throw an error that is an instance of constructor
-		 * and an error with message matching regexp.
-		 *
-		 * @param fn   Function that may throw.
-		 * @param constructor   Potential expected error constructor.
-		 * @param message   Message to display on error.
-		 */
-		throw(fn: Function, constructor: Function, regExp: RegExp): void;
-
-		/**
-		 * Asserts that fn will throw an error.
-		 *
-		 * @param fn   Function that may throw.
-		 * @param message   Message to display on error.
-		 */
-		throws(fn: Function, message?: string): void;
-
-		/**
-		 * Asserts that function will throw an error with message matching regexp.
-		 *
-		 * @param fn   Function that may throw.
-		 * @param regExp   Potential expected message match.
-		 * @param message   Message to display on error.
-		 */
-		throws(fn: Function, regExp: RegExp, message?: string): void;
-
-		/**
-		 * Asserts that function will throw an error that is an instance of constructor.
-		 *
-		 * @param fn   Function that may throw.
-		 * @param constructor   Potential expected error constructor.
-		 * @param message   Message to display on error.
-		 */
-		throws(fn: Function, errType: Function, message?: string): void;
-
-		/**
-		 * Asserts that function will throw an error that is an instance of constructor
-		 * and an error with message matching regexp.
-		 *
-		 * @param fn   Function that may throw.
-		 * @param constructor   Potential expected error constructor.
-		 * @param message   Message to display on error.
-		 */
-		throws(fn: Function, errType: Function, regExp: RegExp): void;
-
-		/**
-		 * Asserts that fn will throw an error.
-		 *
-		 * @param fn   Function that may throw.
-		 * @param message   Message to display on error.
-		 */
-		Throw(fn: Function, message?: string): void;
-
-		/**
-		 * Asserts that function will throw an error with message matching regexp.
-		 *
-		 * @param fn   Function that may throw.
-		 * @param regExp   Potential expected message match.
-		 * @param message   Message to display on error.
-		 */
-		Throw(fn: Function, regExp: RegExp): void;
-
-		/**
-		 * Asserts that function will throw an error that is an instance of constructor.
-		 *
-		 * @param fn   Function that may throw.
-		 * @param constructor   Potential expected error constructor.
-		 * @param message   Message to display on error.
-		 */
-		Throw(fn: Function, errType: Function, message?: string): void;
-
-		/**
-		 * Asserts that function will throw an error that is an instance of constructor
-		 * and an error with message matching regexp.
-		 *
-		 * @param fn   Function that may throw.
-		 * @param constructor   Potential expected error constructor.
-		 * @param message   Message to display on error.
-		 */
-		Throw(fn: Function, errType: Function, regExp: RegExp): void;
-
-		/**
-		 * Asserts that fn will not throw an error.
-		 *
-		 * @param fn   Function that may throw.
-		 * @param message   Message to display on error.
-		 */
-		doesNotThrow(fn: Function, message?: string): void;
-
-		/**
-		 * Asserts that function will throw an error with message matching regexp.
-		 *
-		 * @param fn   Function that may throw.
-		 * @param regExp   Potential expected message match.
-		 * @param message   Message to display on error.
-		 */
-		doesNotThrow(fn: Function, regExp: RegExp): void;
-
-		/**
-		 * Asserts that function will throw an error that is an instance of constructor.
-		 *
-		 * @param fn   Function that may throw.
-		 * @param constructor   Potential expected error constructor.
-		 * @param message   Message to display on error.
-		 */
-		doesNotThrow(fn: Function, errType: Function, message?: string): void;
-
-		/**
-		 * Asserts that function will throw an error that is an instance of constructor
-		 * and an error with message matching regexp.
-		 *
-		 * @param fn   Function that may throw.
-		 * @param constructor   Potential expected error constructor.
-		 * @param message   Message to display on error.
-		 */
-		doesNotThrow(fn: Function, errType: Function, regExp: RegExp): void;
-
-		/**
-		 * Compares two values using operator.
-		 *
-		 * @param val1   Left value during comparison.
-		 * @param operator   Comparison operator.
-		 * @param val2   Right value during comparison.
-		 * @param message   Message to display on error.
-		 */
-		operator(val1: OperatorComparable, operator: Operator, val2: OperatorComparable, message?: string): void;
-
-		/**
-		 * Asserts that the target is equal to expected, to within a +/- delta range.
-		 *
-		 * @param actual   Actual value
-		 * @param expected   Potential expected value.
-		 * @param delta   Maximum differenced between values.
-		 * @param message   Message to display on error.
-		 */
-		closeTo(actual: number, expected: number, delta: number, message?: string): void;
-
-		/**
-		 * Asserts that the target is equal to expected, to within a +/- delta range.
-		 *
-		 * @param actual   Actual value
-		 * @param expected   Potential expected value.
-		 * @param delta   Maximum differenced between values.
-		 * @param message   Message to display on error.
-		 */
-		approximately(act: number, exp: number, delta: number, message?: string): void;
-
-		/**
-		 * Asserts that set1 and set2 have the same members. Order is not take into account.
-		 *
-		 * @type T   Type of set values.
-		 * @param set1   Actual set of values.
-		 * @param set2   Potential expected set of values.
-		 * @param message   Message to display on error.
-		 */
-		sameMembers<T>(set1: T[], set2: T[], message?: string): void;
-
-		/**
-		 * Asserts that set1 and set2 have the same members using deep equality checking.
-		 * Order is not take into account.
-		 *
-		 * @type T   Type of set values.
-		 * @param set1   Actual set of values.
-		 * @param set2   Potential expected set of values.
-		 * @param message   Message to display on error.
-		 */
-		sameDeepMembers<T>(set1: T[], set2: T[], message?: string): void;
-
-		/**
-		 * Asserts that subset is included in superset. Order is not take into account.
-		 *
-		 * @type T   Type of set values.
-		 * @param superset   Actual set of values.
-		 * @param subset   Potential contained set of values.
-		 * @param message   Message to display on error.
-		 */
-		includeMembers<T>(superset: T[], subset: T[], message?: string): void;
-
-		/**
-		 * Asserts that subset is included in superset using deep equality checking.
-		 * Order is not take into account.
-		 *
-		 * @type T   Type of set values.
-		 * @param superset   Actual set of values.
-		 * @param subset   Potential contained set of values.
-		 * @param message   Message to display on error.
-		 */
-		includeDeepMembers<T>(superset: T[], subset: T[], message?: string): void;
-
-		/**
-		 * Asserts that non-object, non-array value inList appears in the flat array list.
-		 *
-		 * @type T   Type of list values.
-		 * @param inList   Value expected to be in the list.
-		 * @param list   List of values.
-		 * @param message   Message to display on error.
-		 */
-		oneOf<T>(inList: T, list: T[], message?: string): void;
-
-		/**
-		 * Asserts that a function changes the value of a property.
-		 *
-		 * @type T   Type of object.
-		 * @param modifier   Function to run.
-		 * @param object   Container object.
-		 * @param property   Property of object expected to be modified.
-		 * @param message   Message to display on error.
-		 */
-		changes<T>(modifier: Function, object: T, property: string /* keyof T */, message?: string): void;
-
-		/**
-		 * Asserts that a function does not change the value of a property.
-		 *
-		 * @type T   Type of object.
-		 * @param modifier   Function to run.
-		 * @param object   Container object.
-		 * @param property   Property of object expected not to be modified.
-		 * @param message   Message to display on error.
-		 */
-		doesNotChange<T>(modifier: Function, object: T, property: string /* keyof T */, message?: string): void;
-
-		/**
-		 * Asserts that a function increases an object property.
-		 *
-		 * @type T   Type of object.
-		 * @param modifier   Function to run.
-		 * @param object   Container object.
-		 * @param property   Property of object expected to be increased.
-		 * @param message   Message to display on error.
-		 */
-		increases<T>(modifier: Function, object: T, property: string /* keyof T */, message?: string): void;
-
-		/**
-		 * Asserts that a function does not increase an object property.
-		 *
-		 * @type T   Type of object.
-		 * @param modifier   Function to run.
-		 * @param object   Container object.
-		 * @param property   Property of object expected not to be increased.
-		 * @param message   Message to display on error.
-		 */
-		doesNotIncrease<T>(modifier: Function, object: T, property: string /* keyof T */, message?: string): void;
-
-		/**
-		 * Asserts that a function decreases an object property.
-		 *
-		 * @type T   Type of object.
-		 * @param modifier   Function to run.
-		 * @param object   Container object.
-		 * @param property   Property of object expected to be decreased.
-		 * @param message   Message to display on error.
-		 */
-		decreases<T>(modifier: Function, object: T, property: string /* keyof T */, message?: string): void;
-
-		/**
-		 * Asserts that a function does not decrease an object property.
-		 *
-		 * @type T   Type of object.
-		 * @param modifier   Function to run.
-		 * @param object   Container object.
-		 * @param property   Property of object expected not to be decreased.
-		 * @param message   Message to display on error.
-		 */
-		doesNotDecrease<T>(modifier: Function, object: T, property: string /* keyof T */, message?: string): void;
-
-		/**
-		 * Asserts if value is not a false value, and throws if it is a true value.
-		 *
-		 * @type T   Type of object.
-		 * @param object   Actual value.
-		 * @param message   Message to display on error.
-		 * @remarks This is added to allow for chai to be a drop-in replacement for
-		 *          Node’s assert class.
-		 */
-		ifError<T>(object: T, message?: string): void;
-
-		/**
-		 * Asserts that object is extensible (can have new properties added to it).
-		 *
-		 * @type T   Type of object
-		 * @param object   Actual value.
-		 * @param message   Message to display on error.
-		 */
-		isExtensible<T>(object: T, message?: string): void;
-
-		/**
-		 * Asserts that object is extensible (can have new properties added to it).
-		 *
-		 * @type T   Type of object
-		 * @param object   Actual value.
-		 * @param message   Message to display on error.
-		 */
-		extensible<T>(object: T, message?: string): void;
-
-		/**
-		 * Asserts that object is not extensible.
-		 *
-		 * @type T   Type of object
-		 * @param object   Actual value.
-		 * @param message   Message to display on error.
-		 */
-		isNotExtensible<T>(object: T, message?: string): void;
-
-		/**
-		 * Asserts that object is not extensible.
-		 *
-		 * @type T   Type of object
-		 * @param object   Actual value.
-		 * @param message   Message to display on error.
-		 */
-		notExtensible<T>(object: T, message?: string): void;
-
-		/**
-		 * Asserts that object is sealed (can have new properties added to it
-		 * and its existing properties cannot be removed).
-		 *
-		 * @type T   Type of object
-		 * @param object   Actual value.
-		 * @param message   Message to display on error.
-		 */
-		isSealed<T>(object: T, message?: string): void;
-
-		/**
-		 * Asserts that object is sealed (can have new properties added to it
-		 * and its existing properties cannot be removed).
-		 *
-		 * @type T   Type of object
-		 * @param object   Actual value.
-		 * @param message   Message to display on error.
-		 */
-		sealed<T>(object: T, message?: string): void;
-
-		/**
-		 * Asserts that object is not sealed.
-		 *
-		 * @type T   Type of object
-		 * @param object   Actual value.
-		 * @param message   Message to display on error.
-		 */
-		isNotSealed<T>(object: T, message?: string): void;
-
-		/**
-		 * Asserts that object is not sealed.
-		 *
-		 * @type T   Type of object
-		 * @param object   Actual value.
-		 * @param message   Message to display on error.
-		 */
-		notSealed<T>(object: T, message?: string): void;
-
-		/**
-		 * Asserts that object is frozen (cannot have new properties added to it
-		 * and its existing properties cannot be removed).
-		 *
-		 * @type T   Type of object
-		 * @param object   Actual value.
-		 * @param message   Message to display on error.
-		 */
-		isFrozen<T>(object: T, message?: string): void;
-
-		/**
-		 * Asserts that object is frozen (cannot have new properties added to it
-		 * and its existing properties cannot be removed).
-		 *
-		 * @type T   Type of object
-		 * @param object   Actual value.
-		 * @param message   Message to display on error.
-		 */
-		frozen<T>(object: T, message?: string): void;
-
-		/**
-		 * Asserts that object is not frozen (cannot have new properties added to it
-		 * and its existing properties cannot be removed).
-		 *
-		 * @type T   Type of object
-		 * @param object   Actual value.
-		 * @param message   Message to display on error.
-		 */
-		isNotFrozen<T>(object: T, message?: string): void;
-
-		/**
-		 * Asserts that object is not frozen (cannot have new properties added to it
-		 * and its existing properties cannot be removed).
-		 *
-		 * @type T   Type of object
-		 * @param object   Actual value.
-		 * @param message   Message to display on error.
-		 */
-		notFrozen<T>(object: T, message?: string): void;
-	}
-
-	export interface Config {
-		/**
-		 * Default: false
-		 */
-		includeStack: boolean;
-
-		/**
-		 * Default: true
-		 */
-		showDiff: boolean;
-
-		/**
-		 * Default: 40
-		 */
-		truncateThreshold: number;
-	}
-
-	export class AssertionError {
-		constructor(message: string, _props?: any, ssf?: Function);
-		public name: string;
-		public message: string;
-		public showDiff: boolean;
-		public stack: string;
-	}
+    interface ChaiStatic {
+        expect: ExpectStatic;
+        should(): Should;
+        /**
+         * Provides a way to extend the internals of Chai
+         */
+        use(fn: (chai: any, utils: any) => void): ChaiStatic;
+        assert: AssertStatic;
+        config: Config;
+        AssertionError: typeof AssertionError;
+        version: string;
+    }
+
+    export interface ExpectStatic extends AssertionStatic {
+        fail(actual?: any, expected?: any, message?: string, operator?: Operator): void;
+    }
+
+    export interface AssertStatic extends Assert {}
+
+    type AssertionStatic = (target: any, message?: string) => Assertion;
+
+    export type Operator = string; // "==" | "===" | ">" | ">=" | "<" | "<=" | "!=" | "!==";
+
+    export type OperatorComparable = boolean | null | number | string | undefined | Date;
+
+    interface ShouldAssertion {
+        equal(value1: any, value2: any, message?: string): void;
+        Throw: ShouldThrow;
+        throw: ShouldThrow;
+        exist(value: any, message?: string): void;
+    }
+
+    interface Should extends ShouldAssertion {
+        not: ShouldAssertion;
+        fail(actual: any, expected: any, message?: string, operator?: Operator): void;
+    }
+
+    interface ShouldThrow {
+        (actual: Function): void;
+        (actual: Function, expected: string | RegExp, message?: string): void;
+        (actual: Function, constructor: Error | Function, expected?: string | RegExp, message?: string): void;
+    }
+
+    interface Assertion extends LanguageChains, NumericComparison, TypeComparison {
+        not: Assertion;
+        deep: Deep;
+        nested: Nested;
+        any: KeyFilter;
+        all: KeyFilter;
+        a: TypeComparison;
+        an: TypeComparison;
+        include: Include;
+        includes: Include;
+        contain: Include;
+        contains: Include;
+        ok: Assertion;
+        true: () => Assertion;
+        false: () => Assertion;
+        null: () => Assertion;
+        undefined: () => Assertion;
+        NaN: Assertion;
+        exist: Assertion;
+        empty: Assertion;
+        arguments: Assertion;
+        Arguments: Assertion;
+        equal: Equal;
+        equals: Equal;
+        eq: Equal;
+        eql: Equal;
+        eqls: Equal;
+        property: Property;
+        ownProperty: OwnProperty;
+        haveOwnProperty: OwnProperty;
+        ownPropertyDescriptor: OwnPropertyDescriptor;
+        haveOwnPropertyDescriptor: OwnPropertyDescriptor;
+        length: Length;
+        lengthOf: Length;
+        match: Match;
+        matches: Match;
+        string(string: string, message?: string): Assertion;
+        keys: Keys;
+        key(string: string): Assertion;
+        throw: (message?: string) => Assertion;
+        throws: Throw;
+        Throw: Throw;
+        respondTo: RespondTo;
+        respondsTo: RespondTo;
+        itself: Assertion;
+        satisfy: Satisfy;
+        satisfies: Satisfy;
+        closeTo: CloseTo;
+        approximately: CloseTo;
+        members: Members;
+        increase: PropertyChange;
+        increases: PropertyChange;
+        decrease: PropertyChange;
+        decreases: PropertyChange;
+        change: PropertyChange;
+        changes: PropertyChange;
+        extensible: Assertion;
+        sealed: Assertion;
+        frozen: Assertion;
+        oneOf(list: any[], message?: string): Assertion;
+    }
+
+    interface LanguageChains {
+        to: Assertion;
+        be: Assertion;
+        been: Assertion;
+        is: Assertion;
+        that: Assertion;
+        which: Assertion;
+        and: Assertion;
+        has: Assertion;
+        have: Assertion;
+        with: Assertion;
+        at: Assertion;
+        of: Assertion;
+        same: Assertion;
+    }
+
+    interface NumericComparison {
+        above: NumberComparer;
+        gt: NumberComparer;
+        greaterThan: NumberComparer;
+        least: NumberComparer;
+        gte: NumberComparer;
+        below: NumberComparer;
+        lt: NumberComparer;
+        lessThan: NumberComparer;
+        most: NumberComparer;
+        lte: NumberComparer;
+        within(start: number, finish: number, message?: string): Assertion;
+    }
+
+    interface NumberComparer {
+        (value: number, message?: string): Assertion;
+    }
+
+    interface TypeComparison {
+        (type: string, message?: string): Assertion;
+        instanceof: InstanceOf;
+        instanceOf: InstanceOf;
+    }
+
+    interface InstanceOf {
+        (constructor: Object, message?: string): Assertion;
+    }
+
+    interface CloseTo {
+        (expected: number, delta: number, message?: string): Assertion;
+    }
+
+    interface Nested {
+        include: Include;
+        property: Property;
+        members: Members;
+    }
+
+    interface Deep {
+        equal: Equal;
+        equals: Equal;
+        eq: Equal;
+        include: Include;
+        property: Property;
+        members: Members;
+    }
+
+    interface KeyFilter {
+        keys: Keys;
+    }
+
+    interface Equal {
+        (value: any, message?: string): Assertion;
+    }
+
+    interface Property {
+        (name: string, value?: any, message?: string): Assertion;
+    }
+
+    interface OwnProperty {
+        (name: string, message?: string): Assertion;
+    }
+
+    interface OwnPropertyDescriptor {
+        (name: string, descriptor: PropertyDescriptor, message?: string): Assertion;
+        (name: string, message?: string): Assertion;
+    }
+
+    interface Length extends LanguageChains, NumericComparison {
+        (length: number, message?: string): Assertion;
+    }
+
+    interface Include {
+        (value: Object | string | number, message?: string): Assertion;
+        keys: Keys;
+        members: Members;
+        any: KeyFilter;
+        all: KeyFilter;
+    }
+
+    interface Match {
+        (regexp: RegExp | string, message?: string): Assertion;
+    }
+
+    interface Keys {
+        (...keys: string[]): Assertion;
+        (keys: any[]): Assertion;
+        (keys: Object): Assertion;
+    }
+
+    interface Throw {
+        (): Assertion;
+        (expected: string, message?: string): Assertion;
+        (expected: RegExp, message?: string): Assertion;
+        (constructor: Error, expected?: string, message?: string): Assertion;
+        (constructor: Error, expected?: RegExp, message?: string): Assertion;
+        (constructor: Function, expected?: string, message?: string): Assertion;
+        (constructor: Function, expected?: RegExp, message?: string): Assertion;
+    }
+
+    interface RespondTo {
+        (method: string, message?: string): Assertion;
+    }
+
+    interface Satisfy {
+        (matcher: Function, message?: string): Assertion;
+    }
+
+    interface Members {
+        (set: any[], message?: string): Assertion;
+    }
+
+    interface PropertyChange {
+        (object: Object, property: string, message?: string): Assertion;
+    }
+
+    export interface Assert {
+        /**
+         * @param expression    Expression to test for truthiness.
+         * @param message    Message to display on error.
+         */
+        (expression: any, message?: string): void;
+
+        /**
+         * Throws a failure.
+         *
+         * @type T   Type of the objects.
+         * @param actual   Actual value.
+         * @param expected   Potential expected value.
+         * @param message    Message to display on error.
+         * @param operator   Comparison operator, if not strict equality.
+         * @remarks Node.js assert module-compatible.
+         */
+        fail<T>(actual?: T, expected?: T, message?: string, operator?: Operator): void;
+
+        /**
+         * Asserts that object is truthy.
+         *
+         * @type T   Type of object.
+         * @param object   Object to test.
+         * @param message    Message to display on error.
+         */
+        isOk<T>(value: T, message?: string): void;
+
+        /**
+         * Asserts that object is truthy.
+         *
+         * @type T   Type of object.
+         * @param object   Object to test.
+         * @param message    Message to display on error.
+         */
+        ok<T>(value: T, message?: string): void;
+
+        /**
+         * Asserts that object is falsy.
+         *
+         * @type T   Type of object.
+         * @param object   Object to test.
+         * @param message    Message to display on error.
+         */
+        isNotOk<T>(value: T, message?: string): void;
+
+        /**
+         * Asserts that object is falsy.
+         *
+         * @type T   Type of object.
+         * @param object   Object to test.
+         * @param message    Message to display on error.
+         */
+        notOk<T>(value: T, message?: string): void;
+
+        /**
+         * Asserts non-strict equality (==) of actual and expected.
+         *
+         * @type T   Type of the objects.
+         * @param actual   Actual value.
+         * @param expected   Potential expected value.
+         * @param message   Message to display on error.
+         */
+        equal<T>(actual: T, expected: T, message?: string): void;
+
+        /**
+         * Asserts non-strict inequality (==) of actual and expected.
+         *
+         * @type T   Type of the objects.
+         * @param actual   Actual value.
+         * @param expected   Potential expected value.
+         * @param message   Message to display on error.
+         */
+        notEqual<T>(actual: T, expected: T, message?: string): void;
+
+        /**
+         * Asserts strict equality (===) of actual and expected.
+         *
+         * @type T   Type of the objects.
+         * @param actual   Actual value.
+         * @param expected   Potential expected value.
+         * @param message   Message to display on error.
+         */
+        strictEqual<T>(actual: T, expected: T, message?: string): void;
+
+        /**
+         * Asserts strict inequality (==) of actual and expected.
+         *
+         * @type T   Type of the objects.
+         * @param actual   Actual value.
+         * @param expected   Potential expected value.
+         * @param message   Message to display on error.
+         */
+        notStrictEqual<T>(actual: T, expected: T, message?: string): void;
+
+        /**
+         * Asserts that actual is deeply equal to expected.
+         *
+         * @type T   Type of the objects.
+         * @param actual   Actual value.
+         * @param expected   Potential expected value.
+         * @param message   Message to display on error.
+         */
+        deepEqual<T>(actual: T, expected: T, message?: string): void;
+
+        /**
+         * Asserts that actual is not deeply equal to expected.
+         *
+         * @type T   Type of the objects.
+         * @param actual   Actual value.
+         * @param expected   Potential expected value.
+         * @param message   Message to display on error.
+         */
+        notDeepEqual<T>(actual: T, expected: T, message?: string): void;
+
+        /**
+         * Asserts valueToCheck is strictly greater than (>) valueToBeAbove.
+         *
+         * @param valueToCheck   Actual value.
+         * @param valueToBeAbove   Minimum Potential expected value.
+         * @param message   Message to display on error.
+         */
+        isAbove(valueToCheck: number, valueToBeAbove: number, message?: string): void;
+
+        /**
+         * Asserts valueToCheck is greater than or equal to (>=) valueToBeAtLeast.
+         *
+         * @param valueToCheck   Actual value.
+         * @param valueToBeAtLeast   Minimum Potential expected value.
+         * @param message   Message to display on error.
+         */
+        isAtLeast(valueToCheck: number, valueToBeAtLeast: number, message?: string): void;
+
+        /**
+         * Asserts valueToCheck is strictly less than (<) valueToBeBelow.
+         *
+         * @param valueToCheck   Actual value.
+         * @param valueToBeBelow   Minimum Potential expected value.
+         * @param message   Message to display on error.
+         */
+        isBelow(valueToCheck: number, valueToBeBelow: number, message?: string): void;
+
+        /**
+         * Asserts valueToCheck is greater than or equal to (>=) valueToBeAtMost.
+         *
+         * @param valueToCheck   Actual value.
+         * @param valueToBeAtMost   Minimum Potential expected value.
+         * @param message   Message to display on error.
+         */
+        isAtMost(valueToCheck: number, valueToBeAtMost: number, message?: string): void;
+
+        /**
+         * Asserts that value is true.
+         *
+         * @type T   Type of value.
+         * @param value   Actual value.
+         * @param message   Message to display on error.
+         */
+        isTrue<T>(value: T, message?: string): void;
+
+        /**
+         * Asserts that value is false.
+         *
+         * @type T   Type of value.
+         * @param value   Actual value.
+         * @param message   Message to display on error.
+         */
+        isFalse<T>(value: T, message?: string): void;
+
+        /**
+         * Asserts that value is not true.
+         *
+         * @type T   Type of value.
+         * @param value   Actual value.
+         * @param message   Message to display on error.
+         */
+        isNotTrue<T>(value: T, message?: string): void;
+
+        /**
+         * Asserts that value is not false.
+         *
+         * @type T   Type of value.
+         * @param value   Actual value.
+         * @param message   Message to display on error.
+         */
+        isNotFalse<T>(value: T, message?: string): void;
+
+        /**
+         * Asserts that value is null.
+         *
+         * @type T   Type of value.
+         * @param value   Actual value.
+         * @param message   Message to display on error.
+         */
+        isNull<T>(value: T, message?: string): void;
+
+        /**
+         * Asserts that value is not null.
+         *
+         * @type T   Type of value.
+         * @param value   Actual value.
+         * @param message   Message to display on error.
+         */
+        isNotNull<T>(value: T, message?: string): void;
+
+        /**
+         * Asserts that value is not null.
+         *
+         * @type T   Type of value.
+         * @param value   Actual value.
+         * @param message   Message to display on error.
+         */
+        isNaN<T>(value: T, message?: string): void;
+
+        /**
+         * Asserts that value is not null.
+         *
+         * @type T   Type of value.
+         * @param value   Actual value.
+         * @param message   Message to display on error.
+         */
+        isNotNaN<T>(value: T, message?: string): void;
+
+        /**
+         * Asserts that value is undefined.
+         *
+         * @type T   Type of value.
+         * @param value   Actual value.
+         * @param message   Message to display on error.
+         */
+        isUndefined<T>(value: T, message?: string): void;
+
+        /**
+         * Asserts that value is not undefined.
+         *
+         * @type T   Type of value.
+         * @param value   Actual value.
+         * @param message   Message to display on error.
+         */
+        isDefined<T>(value: T, message?: string): void;
+
+        /**
+         * Asserts that value is a function.
+         *
+         * @type T   Type of value.
+         * @param value   Actual value.
+         * @param message   Message to display on error.
+         */
+        isFunction<T>(value: T, message?: string): void;
+
+        /**
+         * Asserts that value is not a function.
+         *
+         * @type T   Type of value.
+         * @param value   Actual value.
+         * @param message   Message to display on error.
+         */
+        isNotFunction<T>(value: T, message?: string): void;
+
+        /**
+         * Asserts that value is an object of type 'Object'
+         * (as revealed by Object.prototype.toString).
+         *
+         * @type T   Type of value.
+         * @param value   Actual value.
+         * @param message   Message to display on error.
+         * @remarks The assertion does not match subclassed objects.
+         */
+        isObject<T>(value: T, message?: string): void;
+
+        /**
+         * Asserts that value is not an object of type 'Object'
+         * (as revealed by Object.prototype.toString).
+         *
+         * @type T   Type of value.
+         * @param value   Actual value.
+         * @param message   Message to display on error.
+         */
+        isNotObject<T>(value: T, message?: string): void;
+
+        /**
+         * Asserts that value is an array.
+         *
+         * @type T   Type of value.
+         * @param value   Actual value.
+         * @param message   Message to display on error.
+         */
+        isArray<T>(value: T, message?: string): void;
+
+        /**
+         * Asserts that value is not an array.
+         *
+         * @type T   Type of value.
+         * @param value   Actual value.
+         * @param message   Message to display on error.
+         */
+        isNotArray<T>(value: T, message?: string): void;
+
+        /**
+         * Asserts that value is a string.
+         *
+         * @type T   Type of value.
+         * @param value   Actual value.
+         * @param message   Message to display on error.
+         */
+        isString<T>(value: T, message?: string): void;
+
+        /**
+         * Asserts that value is not a string.
+         *
+         * @type T   Type of value.
+         * @param value   Actual value.
+         * @param message   Message to display on error.
+         */
+        isNotString<T>(value: T, message?: string): void;
+
+        /**
+         * Asserts that value is a number.
+         *
+         * @type T   Type of value.
+         * @param value   Actual value.
+         * @param message   Message to display on error.
+         */
+        isNumber<T>(value: T, message?: string): void;
+
+        /**
+         * Asserts that value is not a number.
+         *
+         * @type T   Type of value.
+         * @param value   Actual value.
+         * @param message   Message to display on error.
+         */
+        isNotNumber<T>(value: T, message?: string): void;
+
+        /**
+         * Asserts that value is a boolean.
+         *
+         * @type T   Type of value.
+         * @param value   Actual value.
+         * @param message   Message to display on error.
+         */
+        isBoolean<T>(value: T, message?: string): void;
+
+        /**
+         * Asserts that value is not a boolean.
+         *
+         * @type T   Type of value.
+         * @param value   Actual value.
+         * @param message   Message to display on error.
+         */
+        isNotBoolean<T>(value: T, message?: string): void;
+
+        /**
+         * Asserts that value's type is name, as determined by Object.prototype.toString.
+         *
+         * @type T   Type of value.
+         * @param value   Actual value.
+         * @param name   Potential expected type name of value.
+         * @param message   Message to display on error.
+         */
+        typeOf<T>(value: T, name: string, message?: string): void;
+
+        /**
+         * Asserts that value's type is not name, as determined by Object.prototype.toString.
+         *
+         * @type T   Type of value.
+         * @param value   Actual value.
+         * @param name   Potential expected type name of value.
+         * @param message   Message to display on error.
+         */
+        notTypeOf<T>(value: T, name: string, message?: string): void;
+
+        /**
+         * Asserts that value is an instance of constructor.
+         *
+         * @type T   Type of value.
+         * @param value   Actual value.
+         * @param constructor   Potential expected contructor of value.
+         * @param message   Message to display on error.
+         */
+        instanceOf<T>(value: T, constructor: Function, message?: string): void;
+
+        /**
+         * Asserts that value is not an instance of constructor.
+         *
+         * @type T   Type of value.
+         * @param value   Actual value.
+         * @param constructor   Potential expected contructor of value.
+         * @param message   Message to display on error.
+         */
+        notInstanceOf<T>(value: T, type: Function, message?: string): void;
+
+        /**
+         * Asserts that haystack includes needle.
+         *
+         * @param haystack   Container string.
+         * @param needle   Potential expected substring of haystack.
+         * @param message   Message to display on error.
+         */
+        include(haystack: string, needle: string, message?: string): void;
+
+        /**
+         * Asserts that haystack includes needle.
+         *
+         * @type T   Type of values in haystack.
+         * @param haystack   Container array.
+         * @param needle   Potential value contained in haystack.
+         * @param message   Message to display on error.
+         */
+        include<T>(haystack: T[], needle: T, message?: string): void;
+
+        /**
+         * Asserts that haystack does not include needle.
+         *
+         * @param haystack   Container string.
+         * @param needle   Potential expected substring of haystack.
+         * @param message   Message to display on error.
+         */
+        notInclude(haystack: string, needle: any, message?: string): void;
+
+        /**
+         * Asserts that haystack does not include needle.
+         *
+         * @type T   Type of values in haystack.
+         * @param haystack   Container array.
+         * @param needle   Potential value contained in haystack.
+         * @param message   Message to display on error.
+         */
+        notInclude(haystack: any[], needle: any, message?: string): void;
+
+        /**
+         * Asserts that value matches the regular expression regexp.
+         *
+         * @param value   Actual value.
+         * @param regexp   Potential match of value.
+         * @param message   Message to display on error.
+         */
+        match(value: string, regexp: RegExp, message?: string): void;
+
+        /**
+         * Asserts that value does not match the regular expression regexp.
+         *
+         * @param value   Actual value.
+         * @param regexp   Potential match of value.
+         * @param message   Message to display on error.
+         */
+        notMatch(expected: any, regexp: RegExp, message?: string): void;
+
+        /**
+         * Asserts that object has a property named by property.
+         *
+         * @type T   Type of object.
+         * @param object   Container object.
+         * @param property   Potential contained property of object.
+         * @param message   Message to display on error.
+         */
+        property<T>(object: T, property: string /* keyof T */, message?: string): void;
+
+        /**
+         * Asserts that object has a property named by property.
+         *
+         * @type T   Type of object.
+         * @param object   Container object.
+         * @param property   Potential contained property of object.
+         * @param message   Message to display on error.
+         */
+        notProperty<T>(object: T, property: string /* keyof T */, message?: string): void;
+
+        /**
+         * Asserts that object has a property named by property, which can be a string
+         * using dot- and bracket-notation for deep reference.
+         *
+         * @type T   Type of object.
+         * @param object   Container object.
+         * @param property   Potential contained property of object.
+         * @param message   Message to display on error.
+         */
+        deepProperty<T>(object: T, property: string, message?: string): void;
+
+        /**
+         * Asserts that object does not have a property named by property, which can be a
+         * string using dot- and bracket-notation for deep reference.
+         *
+         * @type T   Type of object.
+         * @param object   Container object.
+         * @param property   Potential contained property of object.
+         * @param message   Message to display on error.
+         */
+        notDeepProperty<T>(object: T, property: string, message?: string): void;
+
+        /**
+         * Asserts that object has a property named by property with value given by value.
+         *
+         * @type T   Type of object.
+         * @type V   Type of value.
+         * @param object   Container object.
+         * @param property   Potential contained property of object.
+         * @param value   Potential expected property value.
+         * @param message   Message to display on error.
+         */
+        propertyVal<T, V>(object: T, property: string /* keyof T */, value: V, message?: string): void;
+
+        /**
+         * Asserts that object has a property named by property with value given by value.
+         *
+         * @type T   Type of object.
+         * @type V   Type of value.
+         * @param object   Container object.
+         * @param property   Potential contained property of object.
+         * @param value   Potential expected property value.
+         * @param message   Message to display on error.
+         */
+        propertyNotVal<T, V>(object: T, property: string /* keyof T */, value: V, message?: string): void;
+
+        /**
+         * Asserts that object has a property named by property, which can be a string
+         * using dot- and bracket-notation for deep reference.
+         *
+         * @type T   Type of object.
+         * @type V   Type of value.
+         * @param object   Container object.
+         * @param property   Potential contained property of object.
+         * @param value   Potential expected property value.
+         * @param message   Message to display on error.
+         */
+        deepPropertyVal<T, V>(object: T, property: string, value: V, message?: string): void;
+
+        /**
+         * Asserts that object does not have a property named by property, which can be a
+         * string using dot- and bracket-notation for deep reference.
+         *
+         * @type T   Type of object.
+         * @type V   Type of value.
+         * @param object   Container object.
+         * @param property   Potential contained property of object.
+         * @param value   Potential expected property value.
+         * @param message   Message to display on error.
+         */
+        deepPropertyNotVal<T, V>(object: T, property: string, value: V, message?: string): void;
+
+        /**
+         * Asserts that object has a length property with the expected value.
+         *
+         * @type T   Type of object.
+         * @param object   Container object.
+         * @param length   Potential expected length of object.
+         * @param message   Message to display on error.
+         */
+        lengthOf<T extends { readonly length?: number }>(object: T, length: number, message?: string): void;
+
+        /**
+         * Asserts that fn will throw an error.
+         *
+         * @param fn   Function that may throw.
+         * @param message   Message to display on error.
+         */
+        throw(fn: Function, message?: string): void;
+
+        /**
+         * Asserts that function will throw an error with message matching regexp.
+         *
+         * @param fn   Function that may throw.
+         * @param regExp   Potential expected message match.
+         * @param message   Message to display on error.
+         */
+        throw(fn: Function, regExp: RegExp): void;
+
+        /**
+         * Asserts that function will throw an error that is an instance of constructor.
+         *
+         * @param fn   Function that may throw.
+         * @param constructor   Potential expected error constructor.
+         * @param message   Message to display on error.
+         */
+        throw(fn: Function, constructor: Function, message?: string): void;
+
+        /**
+         * Asserts that function will throw an error that is an instance of constructor
+         * and an error with message matching regexp.
+         *
+         * @param fn   Function that may throw.
+         * @param constructor   Potential expected error constructor.
+         * @param message   Message to display on error.
+         */
+        throw(fn: Function, constructor: Function, regExp: RegExp): void;
+
+        /**
+         * Asserts that fn will throw an error.
+         *
+         * @param fn   Function that may throw.
+         * @param message   Message to display on error.
+         */
+        throws(fn: Function, message?: string): void;
+
+        /**
+         * Asserts that function will throw an error with message matching regexp.
+         *
+         * @param fn   Function that may throw.
+         * @param regExp   Potential expected message match.
+         * @param message   Message to display on error.
+         */
+        throws(fn: Function, regExp: RegExp, message?: string): void;
+
+        /**
+         * Asserts that function will throw an error that is an instance of constructor.
+         *
+         * @param fn   Function that may throw.
+         * @param constructor   Potential expected error constructor.
+         * @param message   Message to display on error.
+         */
+        throws(fn: Function, errType: Function, message?: string): void;
+
+        /**
+         * Asserts that function will throw an error that is an instance of constructor
+         * and an error with message matching regexp.
+         *
+         * @param fn   Function that may throw.
+         * @param constructor   Potential expected error constructor.
+         * @param message   Message to display on error.
+         */
+        throws(fn: Function, errType: Function, regExp: RegExp): void;
+
+        /**
+         * Asserts that fn will throw an error.
+         *
+         * @param fn   Function that may throw.
+         * @param message   Message to display on error.
+         */
+        Throw(fn: Function, message?: string): void;
+
+        /**
+         * Asserts that function will throw an error with message matching regexp.
+         *
+         * @param fn   Function that may throw.
+         * @param regExp   Potential expected message match.
+         * @param message   Message to display on error.
+         */
+        Throw(fn: Function, regExp: RegExp): void;
+
+        /**
+         * Asserts that function will throw an error that is an instance of constructor.
+         *
+         * @param fn   Function that may throw.
+         * @param constructor   Potential expected error constructor.
+         * @param message   Message to display on error.
+         */
+        Throw(fn: Function, errType: Function, message?: string): void;
+
+        /**
+         * Asserts that function will throw an error that is an instance of constructor
+         * and an error with message matching regexp.
+         *
+         * @param fn   Function that may throw.
+         * @param constructor   Potential expected error constructor.
+         * @param message   Message to display on error.
+         */
+        Throw(fn: Function, errType: Function, regExp: RegExp): void;
+
+        /**
+         * Asserts that fn will not throw an error.
+         *
+         * @param fn   Function that may throw.
+         * @param message   Message to display on error.
+         */
+        doesNotThrow(fn: Function, message?: string): void;
+
+        /**
+         * Asserts that function will throw an error with message matching regexp.
+         *
+         * @param fn   Function that may throw.
+         * @param regExp   Potential expected message match.
+         * @param message   Message to display on error.
+         */
+        doesNotThrow(fn: Function, regExp: RegExp): void;
+
+        /**
+         * Asserts that function will throw an error that is an instance of constructor.
+         *
+         * @param fn   Function that may throw.
+         * @param constructor   Potential expected error constructor.
+         * @param message   Message to display on error.
+         */
+        doesNotThrow(fn: Function, errType: Function, message?: string): void;
+
+        /**
+         * Asserts that function will throw an error that is an instance of constructor
+         * and an error with message matching regexp.
+         *
+         * @param fn   Function that may throw.
+         * @param constructor   Potential expected error constructor.
+         * @param message   Message to display on error.
+         */
+        doesNotThrow(fn: Function, errType: Function, regExp: RegExp): void;
+
+        /**
+         * Compares two values using operator.
+         *
+         * @param val1   Left value during comparison.
+         * @param operator   Comparison operator.
+         * @param val2   Right value during comparison.
+         * @param message   Message to display on error.
+         */
+        operator(val1: OperatorComparable, operator: Operator, val2: OperatorComparable, message?: string): void;
+
+        /**
+         * Asserts that the target is equal to expected, to within a +/- delta range.
+         *
+         * @param actual   Actual value
+         * @param expected   Potential expected value.
+         * @param delta   Maximum differenced between values.
+         * @param message   Message to display on error.
+         */
+        closeTo(actual: number, expected: number, delta: number, message?: string): void;
+
+        /**
+         * Asserts that the target is equal to expected, to within a +/- delta range.
+         *
+         * @param actual   Actual value
+         * @param expected   Potential expected value.
+         * @param delta   Maximum differenced between values.
+         * @param message   Message to display on error.
+         */
+        approximately(act: number, exp: number, delta: number, message?: string): void;
+
+        /**
+         * Asserts that set1 and set2 have the same members. Order is not take into account.
+         *
+         * @type T   Type of set values.
+         * @param set1   Actual set of values.
+         * @param set2   Potential expected set of values.
+         * @param message   Message to display on error.
+         */
+        sameMembers<T>(set1: T[], set2: T[], message?: string): void;
+
+        /**
+         * Asserts that set1 and set2 have the same members using deep equality checking.
+         * Order is not take into account.
+         *
+         * @type T   Type of set values.
+         * @param set1   Actual set of values.
+         * @param set2   Potential expected set of values.
+         * @param message   Message to display on error.
+         */
+        sameDeepMembers<T>(set1: T[], set2: T[], message?: string): void;
+
+        /**
+         * Asserts that subset is included in superset. Order is not take into account.
+         *
+         * @type T   Type of set values.
+         * @param superset   Actual set of values.
+         * @param subset   Potential contained set of values.
+         * @param message   Message to display on error.
+         */
+        includeMembers<T>(superset: T[], subset: T[], message?: string): void;
+
+        /**
+         * Asserts that subset is included in superset using deep equality checking.
+         * Order is not take into account.
+         *
+         * @type T   Type of set values.
+         * @param superset   Actual set of values.
+         * @param subset   Potential contained set of values.
+         * @param message   Message to display on error.
+         */
+        includeDeepMembers<T>(superset: T[], subset: T[], message?: string): void;
+
+        /**
+         * Asserts that non-object, non-array value inList appears in the flat array list.
+         *
+         * @type T   Type of list values.
+         * @param inList   Value expected to be in the list.
+         * @param list   List of values.
+         * @param message   Message to display on error.
+         */
+        oneOf<T>(inList: T, list: T[], message?: string): void;
+
+        /**
+         * Asserts that a function changes the value of a property.
+         *
+         * @type T   Type of object.
+         * @param modifier   Function to run.
+         * @param object   Container object.
+         * @param property   Property of object expected to be modified.
+         * @param message   Message to display on error.
+         */
+        changes<T>(modifier: Function, object: T, property: string /* keyof T */, message?: string): void;
+
+        /**
+         * Asserts that a function does not change the value of a property.
+         *
+         * @type T   Type of object.
+         * @param modifier   Function to run.
+         * @param object   Container object.
+         * @param property   Property of object expected not to be modified.
+         * @param message   Message to display on error.
+         */
+        doesNotChange<T>(modifier: Function, object: T, property: string /* keyof T */, message?: string): void;
+
+        /**
+         * Asserts that a function increases an object property.
+         *
+         * @type T   Type of object.
+         * @param modifier   Function to run.
+         * @param object   Container object.
+         * @param property   Property of object expected to be increased.
+         * @param message   Message to display on error.
+         */
+        increases<T>(modifier: Function, object: T, property: string /* keyof T */, message?: string): void;
+
+        /**
+         * Asserts that a function does not increase an object property.
+         *
+         * @type T   Type of object.
+         * @param modifier   Function to run.
+         * @param object   Container object.
+         * @param property   Property of object expected not to be increased.
+         * @param message   Message to display on error.
+         */
+        doesNotIncrease<T>(modifier: Function, object: T, property: string /* keyof T */, message?: string): void;
+
+        /**
+         * Asserts that a function decreases an object property.
+         *
+         * @type T   Type of object.
+         * @param modifier   Function to run.
+         * @param object   Container object.
+         * @param property   Property of object expected to be decreased.
+         * @param message   Message to display on error.
+         */
+        decreases<T>(modifier: Function, object: T, property: string /* keyof T */, message?: string): void;
+
+        /**
+         * Asserts that a function does not decrease an object property.
+         *
+         * @type T   Type of object.
+         * @param modifier   Function to run.
+         * @param object   Container object.
+         * @param property   Property of object expected not to be decreased.
+         * @param message   Message to display on error.
+         */
+        doesNotDecrease<T>(modifier: Function, object: T, property: string /* keyof T */, message?: string): void;
+
+        /**
+         * Asserts if value is not a false value, and throws if it is a true value.
+         *
+         * @type T   Type of object.
+         * @param object   Actual value.
+         * @param message   Message to display on error.
+         * @remarks This is added to allow for chai to be a drop-in replacement for
+         *          Node’s assert class.
+         */
+        ifError<T>(object: T, message?: string): void;
+
+        /**
+         * Asserts that object is extensible (can have new properties added to it).
+         *
+         * @type T   Type of object
+         * @param object   Actual value.
+         * @param message   Message to display on error.
+         */
+        isExtensible<T>(object: T, message?: string): void;
+
+        /**
+         * Asserts that object is extensible (can have new properties added to it).
+         *
+         * @type T   Type of object
+         * @param object   Actual value.
+         * @param message   Message to display on error.
+         */
+        extensible<T>(object: T, message?: string): void;
+
+        /**
+         * Asserts that object is not extensible.
+         *
+         * @type T   Type of object
+         * @param object   Actual value.
+         * @param message   Message to display on error.
+         */
+        isNotExtensible<T>(object: T, message?: string): void;
+
+        /**
+         * Asserts that object is not extensible.
+         *
+         * @type T   Type of object
+         * @param object   Actual value.
+         * @param message   Message to display on error.
+         */
+        notExtensible<T>(object: T, message?: string): void;
+
+        /**
+         * Asserts that object is sealed (can have new properties added to it
+         * and its existing properties cannot be removed).
+         *
+         * @type T   Type of object
+         * @param object   Actual value.
+         * @param message   Message to display on error.
+         */
+        isSealed<T>(object: T, message?: string): void;
+
+        /**
+         * Asserts that object is sealed (can have new properties added to it
+         * and its existing properties cannot be removed).
+         *
+         * @type T   Type of object
+         * @param object   Actual value.
+         * @param message   Message to display on error.
+         */
+        sealed<T>(object: T, message?: string): void;
+
+        /**
+         * Asserts that object is not sealed.
+         *
+         * @type T   Type of object
+         * @param object   Actual value.
+         * @param message   Message to display on error.
+         */
+        isNotSealed<T>(object: T, message?: string): void;
+
+        /**
+         * Asserts that object is not sealed.
+         *
+         * @type T   Type of object
+         * @param object   Actual value.
+         * @param message   Message to display on error.
+         */
+        notSealed<T>(object: T, message?: string): void;
+
+        /**
+         * Asserts that object is frozen (cannot have new properties added to it
+         * and its existing properties cannot be removed).
+         *
+         * @type T   Type of object
+         * @param object   Actual value.
+         * @param message   Message to display on error.
+         */
+        isFrozen<T>(object: T, message?: string): void;
+
+        /**
+         * Asserts that object is frozen (cannot have new properties added to it
+         * and its existing properties cannot be removed).
+         *
+         * @type T   Type of object
+         * @param object   Actual value.
+         * @param message   Message to display on error.
+         */
+        frozen<T>(object: T, message?: string): void;
+
+        /**
+         * Asserts that object is not frozen (cannot have new properties added to it
+         * and its existing properties cannot be removed).
+         *
+         * @type T   Type of object
+         * @param object   Actual value.
+         * @param message   Message to display on error.
+         */
+        isNotFrozen<T>(object: T, message?: string): void;
+
+        /**
+         * Asserts that object is not frozen (cannot have new properties added to it
+         * and its existing properties cannot be removed).
+         *
+         * @type T   Type of object
+         * @param object   Actual value.
+         * @param message   Message to display on error.
+         */
+        notFrozen<T>(object: T, message?: string): void;
+    }
+
+    export interface Config {
+        /**
+         * Default: false
+         */
+        includeStack: boolean;
+
+        /**
+         * Default: true
+         */
+        showDiff: boolean;
+
+        /**
+         * Default: 40
+         */
+        truncateThreshold: number;
+    }
+
+    export class AssertionError {
+        constructor(message: string, _props?: any, ssf?: Function);
+        public name: string;
+        public message: string;
+        public showDiff: boolean;
+        public stack: string;
+    }
 }
 
 declare const chai: Chai.ChaiStatic;
 
 declare module 'chai' {
-	export = chai;
+    export = chai;
 }
 
 interface Object {
-	should: Chai.Assertion;
+    should: Chai.Assertion;
 }
diff --git a/packages/chai-typescript-typings/package.json b/packages/chai-typescript-typings/package.json
index f2136ffa4..db7cba863 100644
--- a/packages/chai-typescript-typings/package.json
+++ b/packages/chai-typescript-typings/package.json
@@ -1,16 +1,16 @@
 {
-	"name": "chai-typescript-typings",
-	"version": "0.0.2",
-	"description": "Typescript type definitions for chai",
-	"main": "index.d.ts",
-	"types": "index.d.ts",
-	"repository": {
-		"type": "git",
-		"url": "git+https://github.com/0xProject/0x.js.git"
-	},
-	"license": "Apache-2.0",
-	"bugs": {
-		"url": "https://github.com/0xProject/0x.js/issues"
-	},
-	"homepage": "https://github.com/0xProject/0x.js/packages/chai-typescript-typings#readme"
+    "name": "chai-typescript-typings",
+    "version": "0.0.2",
+    "description": "Typescript type definitions for chai",
+    "main": "index.d.ts",
+    "types": "index.d.ts",
+    "repository": {
+        "type": "git",
+        "url": "git+https://github.com/0xProject/0x.js.git"
+    },
+    "license": "Apache-2.0",
+    "bugs": {
+        "url": "https://github.com/0xProject/0x.js/issues"
+    },
+    "homepage": "https://github.com/0xProject/0x.js/packages/chai-typescript-typings#readme"
 }
diff --git a/packages/chai-typescript-typings/tslint.json b/packages/chai-typescript-typings/tslint.json
index ef528b22e..9a93a1f74 100644
--- a/packages/chai-typescript-typings/tslint.json
+++ b/packages/chai-typescript-typings/tslint.json
@@ -1,3 +1,3 @@
 {
-	"extends": ["tslint-config-0xproject"]
+    "extends": ["tslint-config-0xproject"]
 }
diff --git a/packages/connect/package.json b/packages/connect/package.json
index 2eff3f681..104e28803 100644
--- a/packages/connect/package.json
+++ b/packages/connect/package.json
@@ -1,64 +1,64 @@
 {
-	"name": "@0xproject/connect",
-	"version": "0.5.2",
-	"description": "A javascript library for interacting with the standard relayer api",
-	"keywords": ["connect", "0xproject", "ethereum", "tokens", "exchange"],
-	"main": "lib/src/index.js",
-	"types": "lib/src/index.d.ts",
-	"scripts": {
-		"build": "tsc",
-		"clean": "shx rm -rf _bundles lib test_temp",
-		"docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --json $JSON_FILE_PATH $PROJECT_DIR",
-		"upload_docs_json":
-			"aws s3 cp generated_docs/index.json $S3_URL --profile 0xproject --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --content-type application/json",
-		"copy_test_fixtures": "copyfiles -u 2 './test/fixtures/**/*.json' ./lib/test/fixtures",
-		"lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'",
-		"run_mocha": "mocha lib/test/**/*_test.js",
-		"test": "run-s clean build copy_test_fixtures run_mocha",
-		"test:circleci": "yarn test"
-	},
-	"repository": {
-		"type": "git",
-		"url": "https://github.com/0xProject/0x.js.git"
-	},
-	"author": "Brandon Millman",
-	"license": "Apache-2.0",
-	"engines": {
-		"node": ">=6.0.0"
-	},
-	"bugs": {
-		"url": "https://github.com/0xProject/0x.js/issues"
-	},
-	"homepage": "https://github.com/0xProject/0x.js/packages/connect/README.md",
-	"dependencies": {
-		"@0xproject/assert": "^0.0.13",
-		"@0xproject/json-schemas": "^0.7.5",
-		"@0xproject/utils": "^0.2.2",
-		"isomorphic-fetch": "^2.2.1",
-		"lodash": "^4.17.4",
-		"query-string": "^5.0.1",
-		"websocket": "^1.0.25"
-	},
-	"devDependencies": {
-		"@0xproject/tslint-config": "^0.4.4",
-		"@types/fetch-mock": "^5.12.1",
-		"@types/lodash": "^4.14.86",
-		"@types/mocha": "^2.2.42",
-		"@types/query-string": "^5.0.1",
-		"@types/websocket": "^0.0.34",
-		"chai": "^4.0.1",
-		"chai-as-promised": "^7.1.0",
-		"chai-as-promised-typescript-typings": "^0.0.6",
-		"chai-typescript-typings": "^0.0.2",
-		"copyfiles": "^1.2.0",
-		"dirty-chai": "^2.0.1",
-		"fetch-mock": "^5.13.1",
-		"mocha": "^4.0.1",
-		"npm-run-all": "^4.1.2",
-		"shx": "^0.2.2",
-		"tslint": "5.8.0",
-		"typedoc": "~0.8.0",
-		"typescript": "~2.6.1",
-		"web3-typescript-typings": "^0.9.6"
-	}
+    "name": "@0xproject/connect",
+    "version": "0.5.2",
+    "description": "A javascript library for interacting with the standard relayer api",
+    "keywords": ["connect", "0xproject", "ethereum", "tokens", "exchange"],
+    "main": "lib/src/index.js",
+    "types": "lib/src/index.d.ts",
+    "scripts": {
+        "build": "tsc",
+        "clean": "shx rm -rf _bundles lib test_temp",
+        "docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --json $JSON_FILE_PATH $PROJECT_DIR",
+        "upload_docs_json":
+            "aws s3 cp generated_docs/index.json $S3_URL --profile 0xproject --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --content-type application/json",
+        "copy_test_fixtures": "copyfiles -u 2 './test/fixtures/**/*.json' ./lib/test/fixtures",
+        "lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'",
+        "run_mocha": "mocha lib/test/**/*_test.js",
+        "test": "run-s clean build copy_test_fixtures run_mocha",
+        "test:circleci": "yarn test"
+    },
+    "repository": {
+        "type": "git",
+        "url": "https://github.com/0xProject/0x.js.git"
+    },
+    "author": "Brandon Millman",
+    "license": "Apache-2.0",
+    "engines": {
+        "node": ">=6.0.0"
+    },
+    "bugs": {
+        "url": "https://github.com/0xProject/0x.js/issues"
+    },
+    "homepage": "https://github.com/0xProject/0x.js/packages/connect/README.md",
+    "dependencies": {
+        "@0xproject/assert": "^0.0.13",
+        "@0xproject/json-schemas": "^0.7.5",
+        "@0xproject/utils": "^0.2.2",
+        "isomorphic-fetch": "^2.2.1",
+        "lodash": "^4.17.4",
+        "query-string": "^5.0.1",
+        "websocket": "^1.0.25"
+    },
+    "devDependencies": {
+        "@0xproject/tslint-config": "^0.4.4",
+        "@types/fetch-mock": "^5.12.1",
+        "@types/lodash": "^4.14.86",
+        "@types/mocha": "^2.2.42",
+        "@types/query-string": "^5.0.1",
+        "@types/websocket": "^0.0.34",
+        "chai": "^4.0.1",
+        "chai-as-promised": "^7.1.0",
+        "chai-as-promised-typescript-typings": "^0.0.6",
+        "chai-typescript-typings": "^0.0.2",
+        "copyfiles": "^1.2.0",
+        "dirty-chai": "^2.0.1",
+        "fetch-mock": "^5.13.1",
+        "mocha": "^4.0.1",
+        "npm-run-all": "^4.1.2",
+        "shx": "^0.2.2",
+        "tslint": "5.8.0",
+        "typedoc": "~0.8.0",
+        "typescript": "~2.6.1",
+        "web3-typescript-typings": "^0.9.6"
+    }
 }
diff --git a/packages/connect/src/globals.d.ts b/packages/connect/src/globals.d.ts
index d2011026b..078e189cd 100644
--- a/packages/connect/src/globals.d.ts
+++ b/packages/connect/src/globals.d.ts
@@ -1,6 +1,6 @@
 declare module 'dirty-chai';
 
 declare module '*.json' {
-	const value: any;
-	export default value;
+    const value: any;
+    export default value;
 }
diff --git a/packages/connect/src/http_client.ts b/packages/connect/src/http_client.ts
index 03c0b9702..3df77b0f0 100644
--- a/packages/connect/src/http_client.ts
+++ b/packages/connect/src/http_client.ts
@@ -6,17 +6,17 @@ import * as queryString from 'query-string';
 
 import { schemas as clientSchemas } from './schemas/schemas';
 import {
-	Client,
-	FeesRequest,
-	FeesResponse,
-	HttpRequestOptions,
-	HttpRequestType,
-	OrderbookRequest,
-	OrderbookResponse,
-	OrdersRequest,
-	SignedOrder,
-	TokenPairsItem,
-	TokenPairsRequest,
+    Client,
+    FeesRequest,
+    FeesResponse,
+    HttpRequestOptions,
+    HttpRequestType,
+    OrderbookRequest,
+    OrderbookResponse,
+    OrdersRequest,
+    SignedOrder,
+    TokenPairsItem,
+    TokenPairsRequest,
 } from './types';
 import { relayerResponseJsonParsers } from './utils/relayer_response_json_parsers';
 
@@ -26,127 +26,127 @@ const TRAILING_SLASHES_REGEX = /\/+$/;
  * that implement the standard relayer API v0
  */
 export class HttpClient implements Client {
-	private _apiEndpointUrl: string;
-	/**
-	 * Instantiates a new HttpClient instance
-	 * @param   url    The relayer API base HTTP url you would like to interact with
-	 * @return  An instance of HttpClient
-	 */
-	constructor(url: string) {
-		assert.isHttpUrl('url', url);
-		this._apiEndpointUrl = url.replace(TRAILING_SLASHES_REGEX, ''); // remove trailing slashes
-	}
-	/**
-	 * Retrieve token pair info from the API
-	 * @param   request     A TokenPairsRequest instance describing specific token information
-	 *                      to retrieve
-	 * @return  The resulting TokenPairsItems that match the request
-	 */
-	public async getTokenPairsAsync(request?: TokenPairsRequest): Promise<TokenPairsItem[]> {
-		if (!_.isUndefined(request)) {
-			assert.doesConformToSchema('request', request, clientSchemas.relayerTokenPairsRequestSchema);
-		}
-		const requestOpts = {
-			params: request,
-		};
-		const responseJson = await this._requestAsync('/token_pairs', HttpRequestType.Get, requestOpts);
-		const tokenPairs = relayerResponseJsonParsers.parseTokenPairsJson(responseJson);
-		return tokenPairs;
-	}
-	/**
-	 * Retrieve orders from the API
-	 * @param   request     An OrdersRequest instance describing specific orders to retrieve
-	 * @return  The resulting SignedOrders that match the request
-	 */
-	public async getOrdersAsync(request?: OrdersRequest): Promise<SignedOrder[]> {
-		if (!_.isUndefined(request)) {
-			assert.doesConformToSchema('request', request, clientSchemas.relayerOrdersRequestSchema);
-		}
-		const requestOpts = {
-			params: request,
-		};
-		const responseJson = await this._requestAsync(`/orders`, HttpRequestType.Get, requestOpts);
-		const orders = relayerResponseJsonParsers.parseOrdersJson(responseJson);
-		return orders;
-	}
-	/**
-	 * Retrieve a specific order from the API
-	 * @param   orderHash     An orderHash generated from the desired order
-	 * @return  The SignedOrder that matches the supplied orderHash
-	 */
-	public async getOrderAsync(orderHash: string): Promise<SignedOrder> {
-		assert.doesConformToSchema('orderHash', orderHash, schemas.orderHashSchema);
-		const responseJson = await this._requestAsync(`/order/${orderHash}`, HttpRequestType.Get);
-		const order = relayerResponseJsonParsers.parseOrderJson(responseJson);
-		return order;
-	}
-	/**
-	 * Retrieve an orderbook from the API
-	 * @param   request     An OrderbookRequest instance describing the specific orderbook to retrieve
-	 * @return  The resulting OrderbookResponse that matches the request
-	 */
-	public async getOrderbookAsync(request: OrderbookRequest): Promise<OrderbookResponse> {
-		assert.doesConformToSchema('request', request, clientSchemas.relayerOrderBookRequestSchema);
-		const requestOpts = {
-			params: request,
-		};
-		const responseJson = await this._requestAsync('/orderbook', HttpRequestType.Get, requestOpts);
-		const orderbook = relayerResponseJsonParsers.parseOrderbookResponseJson(responseJson);
-		return orderbook;
-	}
-	/**
-	 * Retrieve fee information from the API
-	 * @param   request     A FeesRequest instance describing the specific fees to retrieve
-	 * @return  The resulting FeesResponse that matches the request
-	 */
-	public async getFeesAsync(request: FeesRequest): Promise<FeesResponse> {
-		assert.doesConformToSchema('request', request, schemas.relayerApiFeesPayloadSchema);
-		const requestOpts = {
-			payload: request,
-		};
-		const responseJson = await this._requestAsync('/fees', HttpRequestType.Post, requestOpts);
-		const fees = relayerResponseJsonParsers.parseFeesResponseJson(responseJson);
-		return fees;
-	}
-	/**
-	 * Submit a signed order to the API
-	 * @param   signedOrder     A SignedOrder instance to submit
-	 */
-	public async submitOrderAsync(signedOrder: SignedOrder): Promise<void> {
-		assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
-		const requestOpts = {
-			payload: signedOrder,
-		};
-		await this._requestAsync('/order', HttpRequestType.Post, requestOpts);
-	}
-	private async _requestAsync(
-		path: string,
-		requestType: HttpRequestType,
-		requestOptions?: HttpRequestOptions,
-	): Promise<any> {
-		const params = _.get(requestOptions, 'params');
-		const payload = _.get(requestOptions, 'payload');
-		let query = '';
-		if (!_.isUndefined(params) && !_.isEmpty(params)) {
-			const stringifiedParams = queryString.stringify(params);
-			query = `?${stringifiedParams}`;
-		}
-		const url = `${this._apiEndpointUrl}${path}${query}`;
-		const headers = new Headers({
-			'content-type': 'application/json',
-		});
-		const response = await fetch(url, {
-			method: requestType,
-			body: JSON.stringify(payload),
-			headers,
-		});
-		const json = await response.json();
-		if (!response.ok) {
-			const errorString = `${response.status} - ${response.statusText}\n${requestType} ${url}\n${JSON.stringify(
-				json,
-			)}`;
-			throw Error(errorString);
-		}
-		return json;
-	}
+    private _apiEndpointUrl: string;
+    /**
+     * Instantiates a new HttpClient instance
+     * @param   url    The relayer API base HTTP url you would like to interact with
+     * @return  An instance of HttpClient
+     */
+    constructor(url: string) {
+        assert.isHttpUrl('url', url);
+        this._apiEndpointUrl = url.replace(TRAILING_SLASHES_REGEX, ''); // remove trailing slashes
+    }
+    /**
+     * Retrieve token pair info from the API
+     * @param   request     A TokenPairsRequest instance describing specific token information
+     *                      to retrieve
+     * @return  The resulting TokenPairsItems that match the request
+     */
+    public async getTokenPairsAsync(request?: TokenPairsRequest): Promise<TokenPairsItem[]> {
+        if (!_.isUndefined(request)) {
+            assert.doesConformToSchema('request', request, clientSchemas.relayerTokenPairsRequestSchema);
+        }
+        const requestOpts = {
+            params: request,
+        };
+        const responseJson = await this._requestAsync('/token_pairs', HttpRequestType.Get, requestOpts);
+        const tokenPairs = relayerResponseJsonParsers.parseTokenPairsJson(responseJson);
+        return tokenPairs;
+    }
+    /**
+     * Retrieve orders from the API
+     * @param   request     An OrdersRequest instance describing specific orders to retrieve
+     * @return  The resulting SignedOrders that match the request
+     */
+    public async getOrdersAsync(request?: OrdersRequest): Promise<SignedOrder[]> {
+        if (!_.isUndefined(request)) {
+            assert.doesConformToSchema('request', request, clientSchemas.relayerOrdersRequestSchema);
+        }
+        const requestOpts = {
+            params: request,
+        };
+        const responseJson = await this._requestAsync(`/orders`, HttpRequestType.Get, requestOpts);
+        const orders = relayerResponseJsonParsers.parseOrdersJson(responseJson);
+        return orders;
+    }
+    /**
+     * Retrieve a specific order from the API
+     * @param   orderHash     An orderHash generated from the desired order
+     * @return  The SignedOrder that matches the supplied orderHash
+     */
+    public async getOrderAsync(orderHash: string): Promise<SignedOrder> {
+        assert.doesConformToSchema('orderHash', orderHash, schemas.orderHashSchema);
+        const responseJson = await this._requestAsync(`/order/${orderHash}`, HttpRequestType.Get);
+        const order = relayerResponseJsonParsers.parseOrderJson(responseJson);
+        return order;
+    }
+    /**
+     * Retrieve an orderbook from the API
+     * @param   request     An OrderbookRequest instance describing the specific orderbook to retrieve
+     * @return  The resulting OrderbookResponse that matches the request
+     */
+    public async getOrderbookAsync(request: OrderbookRequest): Promise<OrderbookResponse> {
+        assert.doesConformToSchema('request', request, clientSchemas.relayerOrderBookRequestSchema);
+        const requestOpts = {
+            params: request,
+        };
+        const responseJson = await this._requestAsync('/orderbook', HttpRequestType.Get, requestOpts);
+        const orderbook = relayerResponseJsonParsers.parseOrderbookResponseJson(responseJson);
+        return orderbook;
+    }
+    /**
+     * Retrieve fee information from the API
+     * @param   request     A FeesRequest instance describing the specific fees to retrieve
+     * @return  The resulting FeesResponse that matches the request
+     */
+    public async getFeesAsync(request: FeesRequest): Promise<FeesResponse> {
+        assert.doesConformToSchema('request', request, schemas.relayerApiFeesPayloadSchema);
+        const requestOpts = {
+            payload: request,
+        };
+        const responseJson = await this._requestAsync('/fees', HttpRequestType.Post, requestOpts);
+        const fees = relayerResponseJsonParsers.parseFeesResponseJson(responseJson);
+        return fees;
+    }
+    /**
+     * Submit a signed order to the API
+     * @param   signedOrder     A SignedOrder instance to submit
+     */
+    public async submitOrderAsync(signedOrder: SignedOrder): Promise<void> {
+        assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
+        const requestOpts = {
+            payload: signedOrder,
+        };
+        await this._requestAsync('/order', HttpRequestType.Post, requestOpts);
+    }
+    private async _requestAsync(
+        path: string,
+        requestType: HttpRequestType,
+        requestOptions?: HttpRequestOptions,
+    ): Promise<any> {
+        const params = _.get(requestOptions, 'params');
+        const payload = _.get(requestOptions, 'payload');
+        let query = '';
+        if (!_.isUndefined(params) && !_.isEmpty(params)) {
+            const stringifiedParams = queryString.stringify(params);
+            query = `?${stringifiedParams}`;
+        }
+        const url = `${this._apiEndpointUrl}${path}${query}`;
+        const headers = new Headers({
+            'content-type': 'application/json',
+        });
+        const response = await fetch(url, {
+            method: requestType,
+            body: JSON.stringify(payload),
+            headers,
+        });
+        const json = await response.json();
+        if (!response.ok) {
+            const errorString = `${response.status} - ${response.statusText}\n${requestType} ${url}\n${JSON.stringify(
+                json,
+            )}`;
+            throw Error(errorString);
+        }
+        return json;
+    }
 }
diff --git a/packages/connect/src/index.ts b/packages/connect/src/index.ts
index d0cce9935..a492f5ae9 100644
--- a/packages/connect/src/index.ts
+++ b/packages/connect/src/index.ts
@@ -1,19 +1,19 @@
 export { HttpClient } from './http_client';
 export { WebSocketOrderbookChannel } from './ws_orderbook_channel';
 export {
-	Client,
-	ECSignature,
-	FeesRequest,
-	FeesResponse,
-	Order,
-	OrderbookChannel,
-	OrderbookChannelHandler,
-	OrderbookChannelSubscriptionOpts,
-	OrderbookRequest,
-	OrderbookResponse,
-	OrdersRequest,
-	SignedOrder,
-	TokenPairsItem,
-	TokenPairsRequest,
-	TokenTradeInfo,
+    Client,
+    ECSignature,
+    FeesRequest,
+    FeesResponse,
+    Order,
+    OrderbookChannel,
+    OrderbookChannelHandler,
+    OrderbookChannelSubscriptionOpts,
+    OrderbookRequest,
+    OrderbookResponse,
+    OrdersRequest,
+    SignedOrder,
+    TokenPairsItem,
+    TokenPairsRequest,
+    TokenTradeInfo,
 } from './types';
diff --git a/packages/connect/src/schemas/relayer_fees_request_schema.ts b/packages/connect/src/schemas/relayer_fees_request_schema.ts
index bd0b91fa3..f20e077ba 100644
--- a/packages/connect/src/schemas/relayer_fees_request_schema.ts
+++ b/packages/connect/src/schemas/relayer_fees_request_schema.ts
@@ -1,8 +1,8 @@
 export const relayerOrderBookRequestSchema = {
-	id: '/RelayerOrderBookRequest',
-	type: 'object',
-	properties: {
-		baseTokenAddress: { $ref: '/Address' },
-		quoteTokenAddress: { $ref: '/Address' },
-	},
+    id: '/RelayerOrderBookRequest',
+    type: 'object',
+    properties: {
+        baseTokenAddress: { $ref: '/Address' },
+        quoteTokenAddress: { $ref: '/Address' },
+    },
 };
diff --git a/packages/connect/src/schemas/relayer_orderbook_request_schema.ts b/packages/connect/src/schemas/relayer_orderbook_request_schema.ts
index bd0b91fa3..f20e077ba 100644
--- a/packages/connect/src/schemas/relayer_orderbook_request_schema.ts
+++ b/packages/connect/src/schemas/relayer_orderbook_request_schema.ts
@@ -1,8 +1,8 @@
 export const relayerOrderBookRequestSchema = {
-	id: '/RelayerOrderBookRequest',
-	type: 'object',
-	properties: {
-		baseTokenAddress: { $ref: '/Address' },
-		quoteTokenAddress: { $ref: '/Address' },
-	},
+    id: '/RelayerOrderBookRequest',
+    type: 'object',
+    properties: {
+        baseTokenAddress: { $ref: '/Address' },
+        quoteTokenAddress: { $ref: '/Address' },
+    },
 };
diff --git a/packages/connect/src/schemas/relayer_orders_request_schema.ts b/packages/connect/src/schemas/relayer_orders_request_schema.ts
index 0471cb104..570238dae 100644
--- a/packages/connect/src/schemas/relayer_orders_request_schema.ts
+++ b/packages/connect/src/schemas/relayer_orders_request_schema.ts
@@ -1,16 +1,16 @@
 export const relayerOrdersRequestSchema = {
-	id: '/RelayerOrdersRequest',
-	type: 'object',
-	properties: {
-		exchangeContractAddress: { $ref: '/Address' },
-		tokenAddress: { $ref: '/Address' },
-		makerTokenAddress: { $ref: '/Address' },
-		takerTokenAddress: { $ref: '/Address' },
-		tokenA: { $ref: '/Address' },
-		tokenB: { $ref: '/Address' },
-		maker: { $ref: '/Address' },
-		taker: { $ref: '/Address' },
-		trader: { $ref: '/Address' },
-		feeRecipient: { $ref: '/Address' },
-	},
+    id: '/RelayerOrdersRequest',
+    type: 'object',
+    properties: {
+        exchangeContractAddress: { $ref: '/Address' },
+        tokenAddress: { $ref: '/Address' },
+        makerTokenAddress: { $ref: '/Address' },
+        takerTokenAddress: { $ref: '/Address' },
+        tokenA: { $ref: '/Address' },
+        tokenB: { $ref: '/Address' },
+        maker: { $ref: '/Address' },
+        taker: { $ref: '/Address' },
+        trader: { $ref: '/Address' },
+        feeRecipient: { $ref: '/Address' },
+    },
 };
diff --git a/packages/connect/src/schemas/relayer_token_pairs_request_schema.ts b/packages/connect/src/schemas/relayer_token_pairs_request_schema.ts
index cb79efdb3..379232204 100644
--- a/packages/connect/src/schemas/relayer_token_pairs_request_schema.ts
+++ b/packages/connect/src/schemas/relayer_token_pairs_request_schema.ts
@@ -1,8 +1,8 @@
 export const relayerTokenPairsRequestSchema = {
-	id: '/RelayerTokenPairsRequest',
-	type: 'object',
-	properties: {
-		tokenA: { $ref: '/Address' },
-		tokenB: { $ref: '/Address' },
-	},
+    id: '/RelayerTokenPairsRequest',
+    type: 'object',
+    properties: {
+        tokenA: { $ref: '/Address' },
+        tokenB: { $ref: '/Address' },
+    },
 };
diff --git a/packages/connect/src/schemas/schemas.ts b/packages/connect/src/schemas/schemas.ts
index 2982d81ab..288d6969d 100644
--- a/packages/connect/src/schemas/schemas.ts
+++ b/packages/connect/src/schemas/schemas.ts
@@ -3,7 +3,7 @@ import { relayerOrdersRequestSchema } from './relayer_orders_request_schema';
 import { relayerTokenPairsRequestSchema } from './relayer_token_pairs_request_schema';
 
 export const schemas = {
-	relayerOrderBookRequestSchema,
-	relayerOrdersRequestSchema,
-	relayerTokenPairsRequestSchema,
+    relayerOrderBookRequestSchema,
+    relayerOrdersRequestSchema,
+    relayerTokenPairsRequestSchema,
 };
diff --git a/packages/connect/src/types.ts b/packages/connect/src/types.ts
index 5f72f6e85..edb6c77a6 100644
--- a/packages/connect/src/types.ts
+++ b/packages/connect/src/types.ts
@@ -2,45 +2,45 @@ import { BigNumber } from '@0xproject/utils';
 
 // TODO: Consolidate Order, SignedOrder and ECSignature into a shared package instead of duplicating them from 0x.js
 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;
+    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;
+    ecSignature: ECSignature;
 }
 
 /**
  * Elliptic Curve signature
  */
 export interface ECSignature {
-	v: number;
-	r: string;
-	s: string;
+    v: number;
+    r: string;
+    s: string;
 }
 
 export interface Client {
-	getTokenPairsAsync: (request?: TokenPairsRequest) => Promise<TokenPairsItem[]>;
-	getOrdersAsync: (request?: OrdersRequest) => Promise<SignedOrder[]>;
-	getOrderAsync: (orderHash: string) => Promise<SignedOrder>;
-	getOrderbookAsync: (request: OrderbookRequest) => Promise<OrderbookResponse>;
-	getFeesAsync: (request: FeesRequest) => Promise<FeesResponse>;
-	submitOrderAsync: (signedOrder: SignedOrder) => Promise<void>;
+    getTokenPairsAsync: (request?: TokenPairsRequest) => Promise<TokenPairsItem[]>;
+    getOrdersAsync: (request?: OrdersRequest) => Promise<SignedOrder[]>;
+    getOrderAsync: (orderHash: string) => Promise<SignedOrder>;
+    getOrderbookAsync: (request: OrderbookRequest) => Promise<OrderbookResponse>;
+    getFeesAsync: (request: FeesRequest) => Promise<FeesResponse>;
+    submitOrderAsync: (signedOrder: SignedOrder) => Promise<void>;
 }
 
 export interface OrderbookChannel {
-	subscribe: (subscriptionOpts: OrderbookChannelSubscriptionOpts, handler: OrderbookChannelHandler) => void;
-	close: () => void;
+    subscribe: (subscriptionOpts: OrderbookChannelSubscriptionOpts, handler: OrderbookChannelHandler) => void;
+    close: () => void;
 }
 
 /*
@@ -50,129 +50,129 @@ export interface OrderbookChannel {
  * limit: Maximum number of bids and asks in orderbook snapshot
  */
 export interface OrderbookChannelSubscriptionOpts {
-	baseTokenAddress: string;
-	quoteTokenAddress: string;
-	snapshot: boolean;
-	limit: number;
+    baseTokenAddress: string;
+    quoteTokenAddress: string;
+    snapshot: boolean;
+    limit: number;
 }
 
 export interface OrderbookChannelHandler {
-	onSnapshot: (
-		channel: OrderbookChannel,
-		subscriptionOpts: OrderbookChannelSubscriptionOpts,
-		snapshot: OrderbookResponse,
-	) => void;
-	onUpdate: (
-		channel: OrderbookChannel,
-		subscriptionOpts: OrderbookChannelSubscriptionOpts,
-		order: SignedOrder,
-	) => void;
-	onError: (channel: OrderbookChannel, subscriptionOpts: OrderbookChannelSubscriptionOpts, err: Error) => void;
-	onClose: (channel: OrderbookChannel, subscriptionOpts: OrderbookChannelSubscriptionOpts) => void;
+    onSnapshot: (
+        channel: OrderbookChannel,
+        subscriptionOpts: OrderbookChannelSubscriptionOpts,
+        snapshot: OrderbookResponse,
+    ) => void;
+    onUpdate: (
+        channel: OrderbookChannel,
+        subscriptionOpts: OrderbookChannelSubscriptionOpts,
+        order: SignedOrder,
+    ) => void;
+    onError: (channel: OrderbookChannel, subscriptionOpts: OrderbookChannelSubscriptionOpts, err: Error) => void;
+    onClose: (channel: OrderbookChannel, subscriptionOpts: OrderbookChannelSubscriptionOpts) => void;
 }
 
 export type OrderbookChannelMessage =
-	| SnapshotOrderbookChannelMessage
-	| UpdateOrderbookChannelMessage
-	| UnknownOrderbookChannelMessage;
+    | SnapshotOrderbookChannelMessage
+    | UpdateOrderbookChannelMessage
+    | UnknownOrderbookChannelMessage;
 
 export enum OrderbookChannelMessageTypes {
-	Snapshot = 'snapshot',
-	Update = 'update',
-	Unknown = 'unknown',
+    Snapshot = 'snapshot',
+    Update = 'update',
+    Unknown = 'unknown',
 }
 
 export interface SnapshotOrderbookChannelMessage {
-	type: OrderbookChannelMessageTypes.Snapshot;
-	requestId: number;
-	payload: OrderbookResponse;
+    type: OrderbookChannelMessageTypes.Snapshot;
+    requestId: number;
+    payload: OrderbookResponse;
 }
 
 export interface UpdateOrderbookChannelMessage {
-	type: OrderbookChannelMessageTypes.Update;
-	requestId: number;
-	payload: SignedOrder;
+    type: OrderbookChannelMessageTypes.Update;
+    requestId: number;
+    payload: SignedOrder;
 }
 
 export interface UnknownOrderbookChannelMessage {
-	type: OrderbookChannelMessageTypes.Unknown;
-	requestId: number;
-	payload: undefined;
+    type: OrderbookChannelMessageTypes.Unknown;
+    requestId: number;
+    payload: undefined;
 }
 
 export enum WebsocketConnectionEventType {
-	Close = 'close',
-	Error = 'error',
-	Message = 'message',
+    Close = 'close',
+    Error = 'error',
+    Message = 'message',
 }
 
 export enum WebsocketClientEventType {
-	Connect = 'connect',
-	ConnectFailed = 'connectFailed',
+    Connect = 'connect',
+    ConnectFailed = 'connectFailed',
 }
 
 export interface TokenPairsRequest {
-	tokenA?: string;
-	tokenB?: string;
+    tokenA?: string;
+    tokenB?: string;
 }
 
 export interface TokenPairsItem {
-	tokenA: TokenTradeInfo;
-	tokenB: TokenTradeInfo;
+    tokenA: TokenTradeInfo;
+    tokenB: TokenTradeInfo;
 }
 
 export interface TokenTradeInfo {
-	address: string;
-	minAmount: BigNumber;
-	maxAmount: BigNumber;
-	precision: number;
+    address: string;
+    minAmount: BigNumber;
+    maxAmount: BigNumber;
+    precision: number;
 }
 
 export interface OrdersRequest {
-	exchangeContractAddress?: string;
-	tokenAddress?: string;
-	makerTokenAddress?: string;
-	takerTokenAddress?: string;
-	maker?: string;
-	taker?: string;
-	trader?: string;
-	feeRecipient?: string;
+    exchangeContractAddress?: string;
+    tokenAddress?: string;
+    makerTokenAddress?: string;
+    takerTokenAddress?: string;
+    maker?: string;
+    taker?: string;
+    trader?: string;
+    feeRecipient?: string;
 }
 
 export interface OrderbookRequest {
-	baseTokenAddress: string;
-	quoteTokenAddress: string;
+    baseTokenAddress: string;
+    quoteTokenAddress: string;
 }
 
 export interface OrderbookResponse {
-	bids: SignedOrder[];
-	asks: SignedOrder[];
+    bids: SignedOrder[];
+    asks: SignedOrder[];
 }
 
 export interface FeesRequest {
-	exchangeContractAddress: string;
-	maker: string;
-	taker: string;
-	makerTokenAddress: string;
-	takerTokenAddress: string;
-	makerTokenAmount: BigNumber;
-	takerTokenAmount: BigNumber;
-	expirationUnixTimestampSec: BigNumber;
-	salt: BigNumber;
+    exchangeContractAddress: string;
+    maker: string;
+    taker: string;
+    makerTokenAddress: string;
+    takerTokenAddress: string;
+    makerTokenAmount: BigNumber;
+    takerTokenAmount: BigNumber;
+    expirationUnixTimestampSec: BigNumber;
+    salt: BigNumber;
 }
 
 export interface FeesResponse {
-	feeRecipient: string;
-	makerFee: BigNumber;
-	takerFee: BigNumber;
+    feeRecipient: string;
+    makerFee: BigNumber;
+    takerFee: BigNumber;
 }
 
 export interface HttpRequestOptions {
-	params?: object;
-	payload?: object;
+    params?: object;
+    payload?: object;
 }
 
 export enum HttpRequestType {
-	Get = 'GET',
-	Post = 'POST',
+    Get = 'GET',
+    Post = 'POST',
 }
diff --git a/packages/connect/src/utils/orderbook_channel_message_parser.ts b/packages/connect/src/utils/orderbook_channel_message_parser.ts
index c5dd2ee2e..9a9ca8901 100644
--- a/packages/connect/src/utils/orderbook_channel_message_parser.ts
+++ b/packages/connect/src/utils/orderbook_channel_message_parser.ts
@@ -7,31 +7,31 @@ import { OrderbookChannelMessage, OrderbookChannelMessageTypes } from '../types'
 import { relayerResponseJsonParsers } from './relayer_response_json_parsers';
 
 export const orderbookChannelMessageParser = {
-	parse(utf8Data: string): OrderbookChannelMessage {
-		const messageObj = JSON.parse(utf8Data);
-		const type: string = _.get(messageObj, 'type');
-		assert.assert(!_.isUndefined(type), `Message is missing a type parameter: ${utf8Data}`);
-		assert.isString('type', type);
-		switch (type) {
-			case OrderbookChannelMessageTypes.Snapshot: {
-				assert.doesConformToSchema('message', messageObj, schemas.relayerApiOrderbookChannelSnapshotSchema);
-				const orderbookJson = messageObj.payload;
-				const orderbook = relayerResponseJsonParsers.parseOrderbookResponseJson(orderbookJson);
-				return _.assign(messageObj, { payload: orderbook });
-			}
-			case OrderbookChannelMessageTypes.Update: {
-				assert.doesConformToSchema('message', messageObj, schemas.relayerApiOrderbookChannelUpdateSchema);
-				const orderJson = messageObj.payload;
-				const order = relayerResponseJsonParsers.parseOrderJson(orderJson);
-				return _.assign(messageObj, { payload: order });
-			}
-			default: {
-				return {
-					type: OrderbookChannelMessageTypes.Unknown,
-					requestId: 0,
-					payload: undefined,
-				};
-			}
-		}
-	},
+    parse(utf8Data: string): OrderbookChannelMessage {
+        const messageObj = JSON.parse(utf8Data);
+        const type: string = _.get(messageObj, 'type');
+        assert.assert(!_.isUndefined(type), `Message is missing a type parameter: ${utf8Data}`);
+        assert.isString('type', type);
+        switch (type) {
+            case OrderbookChannelMessageTypes.Snapshot: {
+                assert.doesConformToSchema('message', messageObj, schemas.relayerApiOrderbookChannelSnapshotSchema);
+                const orderbookJson = messageObj.payload;
+                const orderbook = relayerResponseJsonParsers.parseOrderbookResponseJson(orderbookJson);
+                return _.assign(messageObj, { payload: orderbook });
+            }
+            case OrderbookChannelMessageTypes.Update: {
+                assert.doesConformToSchema('message', messageObj, schemas.relayerApiOrderbookChannelUpdateSchema);
+                const orderJson = messageObj.payload;
+                const order = relayerResponseJsonParsers.parseOrderJson(orderJson);
+                return _.assign(messageObj, { payload: order });
+            }
+            default: {
+                return {
+                    type: OrderbookChannelMessageTypes.Unknown,
+                    requestId: 0,
+                    payload: undefined,
+                };
+            }
+        }
+    },
 };
diff --git a/packages/connect/src/utils/relayer_response_json_parsers.ts b/packages/connect/src/utils/relayer_response_json_parsers.ts
index b6c5decaf..668461bf4 100644
--- a/packages/connect/src/utils/relayer_response_json_parsers.ts
+++ b/packages/connect/src/utils/relayer_response_json_parsers.ts
@@ -7,31 +7,31 @@ import { FeesResponse, OrderbookResponse, SignedOrder, TokenPairsItem } from '..
 import { typeConverters } from './type_converters';
 
 export const relayerResponseJsonParsers = {
-	parseTokenPairsJson(json: any): TokenPairsItem[] {
-		assert.doesConformToSchema('tokenPairs', json, schemas.relayerApiTokenPairsResponseSchema);
-		return json.map((tokenPair: any) => {
-			return typeConverters.convertStringsFieldsToBigNumbers(tokenPair, [
-				'tokenA.minAmount',
-				'tokenA.maxAmount',
-				'tokenB.minAmount',
-				'tokenB.maxAmount',
-			]);
-		});
-	},
-	parseOrdersJson(json: any): SignedOrder[] {
-		assert.doesConformToSchema('orders', json, schemas.signedOrdersSchema);
-		return json.map((order: object) => typeConverters.convertOrderStringFieldsToBigNumber(order));
-	},
-	parseOrderJson(json: any): SignedOrder {
-		assert.doesConformToSchema('order', json, schemas.signedOrderSchema);
-		return typeConverters.convertOrderStringFieldsToBigNumber(json);
-	},
-	parseOrderbookResponseJson(json: any): OrderbookResponse {
-		assert.doesConformToSchema('orderBook', json, schemas.relayerApiOrderBookResponseSchema);
-		return typeConverters.convertOrderbookStringFieldsToBigNumber(json);
-	},
-	parseFeesResponseJson(json: any): FeesResponse {
-		assert.doesConformToSchema('fees', json, schemas.relayerApiFeesResponseSchema);
-		return typeConverters.convertStringsFieldsToBigNumbers(json, ['makerFee', 'takerFee']);
-	},
+    parseTokenPairsJson(json: any): TokenPairsItem[] {
+        assert.doesConformToSchema('tokenPairs', json, schemas.relayerApiTokenPairsResponseSchema);
+        return json.map((tokenPair: any) => {
+            return typeConverters.convertStringsFieldsToBigNumbers(tokenPair, [
+                'tokenA.minAmount',
+                'tokenA.maxAmount',
+                'tokenB.minAmount',
+                'tokenB.maxAmount',
+            ]);
+        });
+    },
+    parseOrdersJson(json: any): SignedOrder[] {
+        assert.doesConformToSchema('orders', json, schemas.signedOrdersSchema);
+        return json.map((order: object) => typeConverters.convertOrderStringFieldsToBigNumber(order));
+    },
+    parseOrderJson(json: any): SignedOrder {
+        assert.doesConformToSchema('order', json, schemas.signedOrderSchema);
+        return typeConverters.convertOrderStringFieldsToBigNumber(json);
+    },
+    parseOrderbookResponseJson(json: any): OrderbookResponse {
+        assert.doesConformToSchema('orderBook', json, schemas.relayerApiOrderBookResponseSchema);
+        return typeConverters.convertOrderbookStringFieldsToBigNumber(json);
+    },
+    parseFeesResponseJson(json: any): FeesResponse {
+        assert.doesConformToSchema('fees', json, schemas.relayerApiFeesResponseSchema);
+        return typeConverters.convertStringsFieldsToBigNumbers(json, ['makerFee', 'takerFee']);
+    },
 };
diff --git a/packages/connect/src/utils/type_converters.ts b/packages/connect/src/utils/type_converters.ts
index beea557c2..c1808ce8a 100644
--- a/packages/connect/src/utils/type_converters.ts
+++ b/packages/connect/src/utils/type_converters.ts
@@ -2,29 +2,29 @@ import { BigNumber } from '@0xproject/utils';
 import * as _ from 'lodash';
 
 export const typeConverters = {
-	convertOrderbookStringFieldsToBigNumber(orderbook: any): any {
-		const bids = _.get(orderbook, 'bids', []);
-		const asks = _.get(orderbook, 'asks', []);
-		return {
-			bids: bids.map((order: any) => this.convertOrderStringFieldsToBigNumber(order)),
-			asks: asks.map((order: any) => this.convertOrderStringFieldsToBigNumber(order)),
-		};
-	},
-	convertOrderStringFieldsToBigNumber(order: any): any {
-		return this.convertStringsFieldsToBigNumbers(order, [
-			'makerTokenAmount',
-			'takerTokenAmount',
-			'makerFee',
-			'takerFee',
-			'expirationUnixTimestampSec',
-			'salt',
-		]);
-	},
-	convertStringsFieldsToBigNumbers(obj: any, fields: string[]): any {
-		const result = _.assign({}, obj);
-		_.each(fields, field => {
-			_.update(result, field, (value: string) => new BigNumber(value));
-		});
-		return result;
-	},
+    convertOrderbookStringFieldsToBigNumber(orderbook: any): any {
+        const bids = _.get(orderbook, 'bids', []);
+        const asks = _.get(orderbook, 'asks', []);
+        return {
+            bids: bids.map((order: any) => this.convertOrderStringFieldsToBigNumber(order)),
+            asks: asks.map((order: any) => this.convertOrderStringFieldsToBigNumber(order)),
+        };
+    },
+    convertOrderStringFieldsToBigNumber(order: any): any {
+        return this.convertStringsFieldsToBigNumbers(order, [
+            'makerTokenAmount',
+            'takerTokenAmount',
+            'makerFee',
+            'takerFee',
+            'expirationUnixTimestampSec',
+            'salt',
+        ]);
+    },
+    convertStringsFieldsToBigNumbers(obj: any, fields: string[]): any {
+        const result = _.assign({}, obj);
+        _.each(fields, field => {
+            _.update(result, field, (value: string) => new BigNumber(value));
+        });
+        return result;
+    },
 };
diff --git a/packages/connect/src/ws_orderbook_channel.ts b/packages/connect/src/ws_orderbook_channel.ts
index bbb47c649..822a022f4 100644
--- a/packages/connect/src/ws_orderbook_channel.ts
+++ b/packages/connect/src/ws_orderbook_channel.ts
@@ -4,12 +4,12 @@ import * as _ from 'lodash';
 import * as WebSocket from 'websocket';
 
 import {
-	OrderbookChannel,
-	OrderbookChannelHandler,
-	OrderbookChannelMessageTypes,
-	OrderbookChannelSubscriptionOpts,
-	WebsocketClientEventType,
-	WebsocketConnectionEventType,
+    OrderbookChannel,
+    OrderbookChannelHandler,
+    OrderbookChannelMessageTypes,
+    OrderbookChannelSubscriptionOpts,
+    WebsocketClientEventType,
+    WebsocketConnectionEventType,
 } from './types';
 import { orderbookChannelMessageParser } from './utils/orderbook_channel_message_parser';
 
@@ -18,117 +18,117 @@ import { orderbookChannelMessageParser } from './utils/orderbook_channel_message
  * that implements the standard relayer API v0
  */
 export class WebSocketOrderbookChannel implements OrderbookChannel {
-	private _apiEndpointUrl: string;
-	private _client: WebSocket.client;
-	private _connectionIfExists?: WebSocket.connection;
-	private _subscriptionCounter = 0;
-	/**
-	 * Instantiates a new WebSocketOrderbookChannel instance
-	 * @param   url                 The relayer API base WS url you would like to interact with
-	 * @return  An instance of WebSocketOrderbookChannel
-	 */
-	constructor(url: string) {
-		assert.isUri('url', url);
-		this._apiEndpointUrl = url;
-		this._client = new WebSocket.client();
-	}
-	/**
-	 * Subscribe to orderbook snapshots and updates from the websocket
-	 * @param   subscriptionOpts     An OrderbookChannelSubscriptionOpts instance describing which
-	 *                               token pair to subscribe to
-	 * @param   handler              An OrderbookChannelHandler instance that responds to various
-	 *                               channel updates
-	 */
-	public subscribe(subscriptionOpts: OrderbookChannelSubscriptionOpts, handler: OrderbookChannelHandler): void {
-		assert.doesConformToSchema(
-			'subscriptionOpts',
-			subscriptionOpts,
-			schemas.relayerApiOrderbookChannelSubscribePayload,
-		);
-		assert.isFunction('handler.onSnapshot', _.get(handler, 'onSnapshot'));
-		assert.isFunction('handler.onUpdate', _.get(handler, 'onUpdate'));
-		assert.isFunction('handler.onError', _.get(handler, 'onError'));
-		assert.isFunction('handler.onClose', _.get(handler, 'onClose'));
-		this._subscriptionCounter += 1;
-		const subscribeMessage = {
-			type: 'subscribe',
-			channel: 'orderbook',
-			requestId: this._subscriptionCounter,
-			payload: subscriptionOpts,
-		};
-		this._getConnection((error, connection) => {
-			if (!_.isUndefined(error)) {
-				handler.onError(this, subscriptionOpts, error);
-			} else if (!_.isUndefined(connection) && connection.connected) {
-				connection.on(WebsocketConnectionEventType.Error, wsError => {
-					handler.onError(this, subscriptionOpts, wsError);
-				});
-				connection.on(WebsocketConnectionEventType.Close, () => {
-					handler.onClose(this, subscriptionOpts);
-				});
-				connection.on(WebsocketConnectionEventType.Message, message => {
-					this._handleWebSocketMessage(subscribeMessage.requestId, subscriptionOpts, message, handler);
-				});
-				connection.sendUTF(JSON.stringify(subscribeMessage));
-			}
-		});
-	}
-	/**
-	 * Close the websocket and stop receiving updates
-	 */
-	public close() {
-		if (!_.isUndefined(this._connectionIfExists)) {
-			this._connectionIfExists.close();
-		}
-	}
-	private _getConnection(callback: (error?: Error, connection?: WebSocket.connection) => void) {
-		if (!_.isUndefined(this._connectionIfExists) && this._connectionIfExists.connected) {
-			callback(undefined, this._connectionIfExists);
-		} else {
-			this._client.on(WebsocketClientEventType.Connect, connection => {
-				this._connectionIfExists = connection;
-				callback(undefined, this._connectionIfExists);
-			});
-			this._client.on(WebsocketClientEventType.ConnectFailed, error => {
-				callback(error, undefined);
-			});
-			this._client.connect(this._apiEndpointUrl);
-		}
-	}
-	private _handleWebSocketMessage(
-		requestId: number,
-		subscriptionOpts: OrderbookChannelSubscriptionOpts,
-		message: WebSocket.IMessage,
-		handler: OrderbookChannelHandler,
-	): void {
-		if (!_.isUndefined(message.utf8Data)) {
-			try {
-				const utf8Data = message.utf8Data;
-				const parserResult = orderbookChannelMessageParser.parse(utf8Data);
-				if (parserResult.requestId === requestId) {
-					switch (parserResult.type) {
-						case OrderbookChannelMessageTypes.Snapshot: {
-							handler.onSnapshot(this, subscriptionOpts, parserResult.payload);
-							break;
-						}
-						case OrderbookChannelMessageTypes.Update: {
-							handler.onUpdate(this, subscriptionOpts, parserResult.payload);
-							break;
-						}
-						default: {
-							handler.onError(
-								this,
-								subscriptionOpts,
-								new Error(`Message has missing a type parameter: ${utf8Data}`),
-							);
-						}
-					}
-				}
-			} catch (error) {
-				handler.onError(this, subscriptionOpts, error);
-			}
-		} else {
-			handler.onError(this, subscriptionOpts, new Error(`Message does not contain utf8Data`));
-		}
-	}
+    private _apiEndpointUrl: string;
+    private _client: WebSocket.client;
+    private _connectionIfExists?: WebSocket.connection;
+    private _subscriptionCounter = 0;
+    /**
+     * Instantiates a new WebSocketOrderbookChannel instance
+     * @param   url                 The relayer API base WS url you would like to interact with
+     * @return  An instance of WebSocketOrderbookChannel
+     */
+    constructor(url: string) {
+        assert.isUri('url', url);
+        this._apiEndpointUrl = url;
+        this._client = new WebSocket.client();
+    }
+    /**
+     * Subscribe to orderbook snapshots and updates from the websocket
+     * @param   subscriptionOpts     An OrderbookChannelSubscriptionOpts instance describing which
+     *                               token pair to subscribe to
+     * @param   handler              An OrderbookChannelHandler instance that responds to various
+     *                               channel updates
+     */
+    public subscribe(subscriptionOpts: OrderbookChannelSubscriptionOpts, handler: OrderbookChannelHandler): void {
+        assert.doesConformToSchema(
+            'subscriptionOpts',
+            subscriptionOpts,
+            schemas.relayerApiOrderbookChannelSubscribePayload,
+        );
+        assert.isFunction('handler.onSnapshot', _.get(handler, 'onSnapshot'));
+        assert.isFunction('handler.onUpdate', _.get(handler, 'onUpdate'));
+        assert.isFunction('handler.onError', _.get(handler, 'onError'));
+        assert.isFunction('handler.onClose', _.get(handler, 'onClose'));
+        this._subscriptionCounter += 1;
+        const subscribeMessage = {
+            type: 'subscribe',
+            channel: 'orderbook',
+            requestId: this._subscriptionCounter,
+            payload: subscriptionOpts,
+        };
+        this._getConnection((error, connection) => {
+            if (!_.isUndefined(error)) {
+                handler.onError(this, subscriptionOpts, error);
+            } else if (!_.isUndefined(connection) && connection.connected) {
+                connection.on(WebsocketConnectionEventType.Error, wsError => {
+                    handler.onError(this, subscriptionOpts, wsError);
+                });
+                connection.on(WebsocketConnectionEventType.Close, () => {
+                    handler.onClose(this, subscriptionOpts);
+                });
+                connection.on(WebsocketConnectionEventType.Message, message => {
+                    this._handleWebSocketMessage(subscribeMessage.requestId, subscriptionOpts, message, handler);
+                });
+                connection.sendUTF(JSON.stringify(subscribeMessage));
+            }
+        });
+    }
+    /**
+     * Close the websocket and stop receiving updates
+     */
+    public close() {
+        if (!_.isUndefined(this._connectionIfExists)) {
+            this._connectionIfExists.close();
+        }
+    }
+    private _getConnection(callback: (error?: Error, connection?: WebSocket.connection) => void) {
+        if (!_.isUndefined(this._connectionIfExists) && this._connectionIfExists.connected) {
+            callback(undefined, this._connectionIfExists);
+        } else {
+            this._client.on(WebsocketClientEventType.Connect, connection => {
+                this._connectionIfExists = connection;
+                callback(undefined, this._connectionIfExists);
+            });
+            this._client.on(WebsocketClientEventType.ConnectFailed, error => {
+                callback(error, undefined);
+            });
+            this._client.connect(this._apiEndpointUrl);
+        }
+    }
+    private _handleWebSocketMessage(
+        requestId: number,
+        subscriptionOpts: OrderbookChannelSubscriptionOpts,
+        message: WebSocket.IMessage,
+        handler: OrderbookChannelHandler,
+    ): void {
+        if (!_.isUndefined(message.utf8Data)) {
+            try {
+                const utf8Data = message.utf8Data;
+                const parserResult = orderbookChannelMessageParser.parse(utf8Data);
+                if (parserResult.requestId === requestId) {
+                    switch (parserResult.type) {
+                        case OrderbookChannelMessageTypes.Snapshot: {
+                            handler.onSnapshot(this, subscriptionOpts, parserResult.payload);
+                            break;
+                        }
+                        case OrderbookChannelMessageTypes.Update: {
+                            handler.onUpdate(this, subscriptionOpts, parserResult.payload);
+                            break;
+                        }
+                        default: {
+                            handler.onError(
+                                this,
+                                subscriptionOpts,
+                                new Error(`Message has missing a type parameter: ${utf8Data}`),
+                            );
+                        }
+                    }
+                }
+            } catch (error) {
+                handler.onError(this, subscriptionOpts, error);
+            }
+        } else {
+            handler.onError(this, subscriptionOpts, new Error(`Message does not contain utf8Data`));
+        }
+    }
 }
diff --git a/packages/connect/test/fixtures/standard_relayer_api/fees.json b/packages/connect/test/fixtures/standard_relayer_api/fees.json
index 9f24e93d2..483a74254 100644
--- a/packages/connect/test/fixtures/standard_relayer_api/fees.json
+++ b/packages/connect/test/fixtures/standard_relayer_api/fees.json
@@ -1,5 +1,5 @@
 {
-	"feeRecipient": "0x323b5d4c32345ced77393b3530b1eed0f346429d",
-	"makerFee": "10000000000000000",
-	"takerFee": "30000000000000000"
+    "feeRecipient": "0x323b5d4c32345ced77393b3530b1eed0f346429d",
+    "makerFee": "10000000000000000",
+    "takerFee": "30000000000000000"
 }
diff --git a/packages/connect/test/fixtures/standard_relayer_api/fees.ts b/packages/connect/test/fixtures/standard_relayer_api/fees.ts
index 03981031a..fecbaacff 100644
--- a/packages/connect/test/fixtures/standard_relayer_api/fees.ts
+++ b/packages/connect/test/fixtures/standard_relayer_api/fees.ts
@@ -3,7 +3,7 @@ import { BigNumber } from '@0xproject/utils';
 import { FeesResponse } from '../../../src/types';
 
 export const feesResponse: FeesResponse = {
-	feeRecipient: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-	makerFee: new BigNumber('10000000000000000'),
-	takerFee: new BigNumber('30000000000000000'),
+    feeRecipient: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+    makerFee: new BigNumber('10000000000000000'),
+    takerFee: new BigNumber('30000000000000000'),
 };
diff --git a/packages/connect/test/fixtures/standard_relayer_api/order/0xabc67323774bdbd24d94f977fa9ac94a50f016026fd13f42990861238897721f.json b/packages/connect/test/fixtures/standard_relayer_api/order/0xabc67323774bdbd24d94f977fa9ac94a50f016026fd13f42990861238897721f.json
index c0423bf49..e84954b0d 100644
--- a/packages/connect/test/fixtures/standard_relayer_api/order/0xabc67323774bdbd24d94f977fa9ac94a50f016026fd13f42990861238897721f.json
+++ b/packages/connect/test/fixtures/standard_relayer_api/order/0xabc67323774bdbd24d94f977fa9ac94a50f016026fd13f42990861238897721f.json
@@ -1,19 +1,19 @@
 {
-	"maker": "0x9e56625509c2f60af937f23b7b532600390e8c8b",
-	"taker": "0xa2b31dacf30a9c50ca473337c01d8a201ae33e32",
-	"makerFee": "100000000000000",
-	"takerFee": "200000000000000",
-	"makerTokenAmount": "10000000000000000",
-	"takerTokenAmount": "20000000000000000",
-	"makerTokenAddress": "0x323b5d4c32345ced77393b3530b1eed0f346429d",
-	"takerTokenAddress": "0xef7fff64389b814a946f3e92105513705ca6b990",
-	"salt": "256",
-	"feeRecipient": "0xb046140686d052fff581f63f8136cce132e857da",
-	"exchangeContractAddress": "0x12459c951127e0c374ff9105dda097662a027093",
-	"expirationUnixTimestampSec": "42",
-	"ecSignature": {
-		"v": 27,
-		"r": "0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33",
-		"s": "0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254"
-	}
+    "maker": "0x9e56625509c2f60af937f23b7b532600390e8c8b",
+    "taker": "0xa2b31dacf30a9c50ca473337c01d8a201ae33e32",
+    "makerFee": "100000000000000",
+    "takerFee": "200000000000000",
+    "makerTokenAmount": "10000000000000000",
+    "takerTokenAmount": "20000000000000000",
+    "makerTokenAddress": "0x323b5d4c32345ced77393b3530b1eed0f346429d",
+    "takerTokenAddress": "0xef7fff64389b814a946f3e92105513705ca6b990",
+    "salt": "256",
+    "feeRecipient": "0xb046140686d052fff581f63f8136cce132e857da",
+    "exchangeContractAddress": "0x12459c951127e0c374ff9105dda097662a027093",
+    "expirationUnixTimestampSec": "42",
+    "ecSignature": {
+        "v": 27,
+        "r": "0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33",
+        "s": "0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254"
+    }
 }
diff --git a/packages/connect/test/fixtures/standard_relayer_api/order/0xabc67323774bdbd24d94f977fa9ac94a50f016026fd13f42990861238897721f.ts b/packages/connect/test/fixtures/standard_relayer_api/order/0xabc67323774bdbd24d94f977fa9ac94a50f016026fd13f42990861238897721f.ts
index 459a87919..5a03a2ff6 100644
--- a/packages/connect/test/fixtures/standard_relayer_api/order/0xabc67323774bdbd24d94f977fa9ac94a50f016026fd13f42990861238897721f.ts
+++ b/packages/connect/test/fixtures/standard_relayer_api/order/0xabc67323774bdbd24d94f977fa9ac94a50f016026fd13f42990861238897721f.ts
@@ -1,21 +1,21 @@
 import { BigNumber } from '@0xproject/utils';
 
 export const orderResponse = {
-	maker: '0x9e56625509c2f60af937f23b7b532600390e8c8b',
-	taker: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
-	makerFee: new BigNumber('100000000000000'),
-	takerFee: new BigNumber('200000000000000'),
-	makerTokenAmount: new BigNumber('10000000000000000'),
-	takerTokenAmount: new BigNumber('20000000000000000'),
-	makerTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-	takerTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
-	salt: new BigNumber('256'),
-	feeRecipient: '0xb046140686d052fff581f63f8136cce132e857da',
-	exchangeContractAddress: '0x12459c951127e0c374ff9105dda097662a027093',
-	expirationUnixTimestampSec: new BigNumber('42'),
-	ecSignature: {
-		v: 27,
-		r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
-		s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
-	},
+    maker: '0x9e56625509c2f60af937f23b7b532600390e8c8b',
+    taker: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
+    makerFee: new BigNumber('100000000000000'),
+    takerFee: new BigNumber('200000000000000'),
+    makerTokenAmount: new BigNumber('10000000000000000'),
+    takerTokenAmount: new BigNumber('20000000000000000'),
+    makerTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+    takerTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
+    salt: new BigNumber('256'),
+    feeRecipient: '0xb046140686d052fff581f63f8136cce132e857da',
+    exchangeContractAddress: '0x12459c951127e0c374ff9105dda097662a027093',
+    expirationUnixTimestampSec: new BigNumber('42'),
+    ecSignature: {
+        v: 27,
+        r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
+        s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
+    },
 };
diff --git a/packages/connect/test/fixtures/standard_relayer_api/orderbook.json b/packages/connect/test/fixtures/standard_relayer_api/orderbook.json
index 569498312..825be34c2 100644
--- a/packages/connect/test/fixtures/standard_relayer_api/orderbook.json
+++ b/packages/connect/test/fixtures/standard_relayer_api/orderbook.json
@@ -1,44 +1,44 @@
 {
-	"bids": [
-		{
-			"maker": "0x9e56625509c2f60af937f23b7b532600390e8c8b",
-			"taker": "0xa2b31dacf30a9c50ca473337c01d8a201ae33e32",
-			"makerFee": "100000000000000",
-			"takerFee": "200000000000000",
-			"makerTokenAmount": "10000000000000000",
-			"takerTokenAmount": "20000000000000000",
-			"makerTokenAddress": "0x323b5d4c32345ced77393b3530b1eed0f346429d",
-			"takerTokenAddress": "0xef7fff64389b814a946f3e92105513705ca6b990",
-			"salt": "256",
-			"feeRecipient": "0xb046140686d052fff581f63f8136cce132e857da",
-			"exchangeContractAddress": "0x12459c951127e0c374ff9105dda097662a027093",
-			"expirationUnixTimestampSec": "42",
-			"ecSignature": {
-				"v": 27,
-				"r": "0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33",
-				"s": "0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254"
-			}
-		}
-	],
-	"asks": [
-		{
-			"maker": "0x9e56625509c2f60af937f23b7b532600390e8c8b",
-			"taker": "0xa2b31dacf30a9c50ca473337c01d8a201ae33e32",
-			"makerFee": "100000000000000",
-			"takerFee": "200000000000000",
-			"makerTokenAmount": "10000000000000000",
-			"takerTokenAmount": "20000000000000000",
-			"makerTokenAddress": "0x323b5d4c32345ced77393b3530b1eed0f346429d",
-			"takerTokenAddress": "0xef7fff64389b814a946f3e92105513705ca6b990",
-			"salt": "256",
-			"feeRecipient": "0xb046140686d052fff581f63f8136cce132e857da",
-			"exchangeContractAddress": "0x12459c951127e0c374ff9105dda097662a027093",
-			"expirationUnixTimestampSec": "42",
-			"ecSignature": {
-				"v": 27,
-				"r": "0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33",
-				"s": "0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254"
-			}
-		}
-	]
+    "bids": [
+        {
+            "maker": "0x9e56625509c2f60af937f23b7b532600390e8c8b",
+            "taker": "0xa2b31dacf30a9c50ca473337c01d8a201ae33e32",
+            "makerFee": "100000000000000",
+            "takerFee": "200000000000000",
+            "makerTokenAmount": "10000000000000000",
+            "takerTokenAmount": "20000000000000000",
+            "makerTokenAddress": "0x323b5d4c32345ced77393b3530b1eed0f346429d",
+            "takerTokenAddress": "0xef7fff64389b814a946f3e92105513705ca6b990",
+            "salt": "256",
+            "feeRecipient": "0xb046140686d052fff581f63f8136cce132e857da",
+            "exchangeContractAddress": "0x12459c951127e0c374ff9105dda097662a027093",
+            "expirationUnixTimestampSec": "42",
+            "ecSignature": {
+                "v": 27,
+                "r": "0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33",
+                "s": "0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254"
+            }
+        }
+    ],
+    "asks": [
+        {
+            "maker": "0x9e56625509c2f60af937f23b7b532600390e8c8b",
+            "taker": "0xa2b31dacf30a9c50ca473337c01d8a201ae33e32",
+            "makerFee": "100000000000000",
+            "takerFee": "200000000000000",
+            "makerTokenAmount": "10000000000000000",
+            "takerTokenAmount": "20000000000000000",
+            "makerTokenAddress": "0x323b5d4c32345ced77393b3530b1eed0f346429d",
+            "takerTokenAddress": "0xef7fff64389b814a946f3e92105513705ca6b990",
+            "salt": "256",
+            "feeRecipient": "0xb046140686d052fff581f63f8136cce132e857da",
+            "exchangeContractAddress": "0x12459c951127e0c374ff9105dda097662a027093",
+            "expirationUnixTimestampSec": "42",
+            "ecSignature": {
+                "v": 27,
+                "r": "0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33",
+                "s": "0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254"
+            }
+        }
+    ]
 }
diff --git a/packages/connect/test/fixtures/standard_relayer_api/orderbook.ts b/packages/connect/test/fixtures/standard_relayer_api/orderbook.ts
index 90d3d9220..6684ac2e5 100644
--- a/packages/connect/test/fixtures/standard_relayer_api/orderbook.ts
+++ b/packages/connect/test/fixtures/standard_relayer_api/orderbook.ts
@@ -1,46 +1,46 @@
 import { BigNumber } from '@0xproject/utils';
 
 export const orderbookResponse = {
-	bids: [
-		{
-			maker: '0x9e56625509c2f60af937f23b7b532600390e8c8b',
-			taker: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
-			makerFee: new BigNumber('100000000000000'),
-			takerFee: new BigNumber('200000000000000'),
-			makerTokenAmount: new BigNumber('10000000000000000'),
-			takerTokenAmount: new BigNumber('20000000000000000'),
-			makerTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-			takerTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
-			salt: new BigNumber('256'),
-			feeRecipient: '0xb046140686d052fff581f63f8136cce132e857da',
-			exchangeContractAddress: '0x12459c951127e0c374ff9105dda097662a027093',
-			expirationUnixTimestampSec: new BigNumber('42'),
-			ecSignature: {
-				v: 27,
-				r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
-				s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
-			},
-		},
-	],
-	asks: [
-		{
-			maker: '0x9e56625509c2f60af937f23b7b532600390e8c8b',
-			taker: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
-			makerFee: new BigNumber('100000000000000'),
-			takerFee: new BigNumber('200000000000000'),
-			makerTokenAmount: new BigNumber('10000000000000000'),
-			takerTokenAmount: new BigNumber('20000000000000000'),
-			makerTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-			takerTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
-			salt: new BigNumber('256'),
-			feeRecipient: '0xb046140686d052fff581f63f8136cce132e857da',
-			exchangeContractAddress: '0x12459c951127e0c374ff9105dda097662a027093',
-			expirationUnixTimestampSec: new BigNumber('42'),
-			ecSignature: {
-				v: 27,
-				r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
-				s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
-			},
-		},
-	],
+    bids: [
+        {
+            maker: '0x9e56625509c2f60af937f23b7b532600390e8c8b',
+            taker: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
+            makerFee: new BigNumber('100000000000000'),
+            takerFee: new BigNumber('200000000000000'),
+            makerTokenAmount: new BigNumber('10000000000000000'),
+            takerTokenAmount: new BigNumber('20000000000000000'),
+            makerTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+            takerTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
+            salt: new BigNumber('256'),
+            feeRecipient: '0xb046140686d052fff581f63f8136cce132e857da',
+            exchangeContractAddress: '0x12459c951127e0c374ff9105dda097662a027093',
+            expirationUnixTimestampSec: new BigNumber('42'),
+            ecSignature: {
+                v: 27,
+                r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
+                s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
+            },
+        },
+    ],
+    asks: [
+        {
+            maker: '0x9e56625509c2f60af937f23b7b532600390e8c8b',
+            taker: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
+            makerFee: new BigNumber('100000000000000'),
+            takerFee: new BigNumber('200000000000000'),
+            makerTokenAmount: new BigNumber('10000000000000000'),
+            takerTokenAmount: new BigNumber('20000000000000000'),
+            makerTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+            takerTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
+            salt: new BigNumber('256'),
+            feeRecipient: '0xb046140686d052fff581f63f8136cce132e857da',
+            exchangeContractAddress: '0x12459c951127e0c374ff9105dda097662a027093',
+            expirationUnixTimestampSec: new BigNumber('42'),
+            ecSignature: {
+                v: 27,
+                r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
+                s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
+            },
+        },
+    ],
 };
diff --git a/packages/connect/test/fixtures/standard_relayer_api/orders.json b/packages/connect/test/fixtures/standard_relayer_api/orders.json
index 97d21abd8..cfa780dc4 100644
--- a/packages/connect/test/fixtures/standard_relayer_api/orders.json
+++ b/packages/connect/test/fixtures/standard_relayer_api/orders.json
@@ -1,21 +1,21 @@
 [
-	{
-		"maker": "0x9e56625509c2f60af937f23b7b532600390e8c8b",
-		"taker": "0xa2b31dacf30a9c50ca473337c01d8a201ae33e32",
-		"makerFee": "100000000000000",
-		"takerFee": "200000000000000",
-		"makerTokenAmount": "10000000000000000",
-		"takerTokenAmount": "20000000000000000",
-		"makerTokenAddress": "0x323b5d4c32345ced77393b3530b1eed0f346429d",
-		"takerTokenAddress": "0xef7fff64389b814a946f3e92105513705ca6b990",
-		"salt": "256",
-		"feeRecipient": "0x9e56625509c2f60af937f23b7b532600390e8c8b",
-		"exchangeContractAddress": "0x9e56625509c2f60af937f23b7b532600390e8c8b",
-		"expirationUnixTimestampSec": "42",
-		"ecSignature": {
-			"v": 27,
-			"r": "0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33",
-			"s": "0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254"
-		}
-	}
+    {
+        "maker": "0x9e56625509c2f60af937f23b7b532600390e8c8b",
+        "taker": "0xa2b31dacf30a9c50ca473337c01d8a201ae33e32",
+        "makerFee": "100000000000000",
+        "takerFee": "200000000000000",
+        "makerTokenAmount": "10000000000000000",
+        "takerTokenAmount": "20000000000000000",
+        "makerTokenAddress": "0x323b5d4c32345ced77393b3530b1eed0f346429d",
+        "takerTokenAddress": "0xef7fff64389b814a946f3e92105513705ca6b990",
+        "salt": "256",
+        "feeRecipient": "0x9e56625509c2f60af937f23b7b532600390e8c8b",
+        "exchangeContractAddress": "0x9e56625509c2f60af937f23b7b532600390e8c8b",
+        "expirationUnixTimestampSec": "42",
+        "ecSignature": {
+            "v": 27,
+            "r": "0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33",
+            "s": "0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254"
+        }
+    }
 ]
diff --git a/packages/connect/test/fixtures/standard_relayer_api/orders.ts b/packages/connect/test/fixtures/standard_relayer_api/orders.ts
index 701346971..5044777bd 100644
--- a/packages/connect/test/fixtures/standard_relayer_api/orders.ts
+++ b/packages/connect/test/fixtures/standard_relayer_api/orders.ts
@@ -1,23 +1,23 @@
 import { BigNumber } from '@0xproject/utils';
 
 export const ordersResponse = [
-	{
-		maker: '0x9e56625509c2f60af937f23b7b532600390e8c8b',
-		taker: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
-		makerFee: new BigNumber('100000000000000'),
-		takerFee: new BigNumber('200000000000000'),
-		makerTokenAmount: new BigNumber('10000000000000000'),
-		takerTokenAmount: new BigNumber('20000000000000000'),
-		makerTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-		takerTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
-		salt: new BigNumber('256'),
-		feeRecipient: '0x9e56625509c2f60af937f23b7b532600390e8c8b',
-		exchangeContractAddress: '0x9e56625509c2f60af937f23b7b532600390e8c8b',
-		expirationUnixTimestampSec: new BigNumber('42'),
-		ecSignature: {
-			v: 27,
-			r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
-			s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
-		},
-	},
+    {
+        maker: '0x9e56625509c2f60af937f23b7b532600390e8c8b',
+        taker: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
+        makerFee: new BigNumber('100000000000000'),
+        takerFee: new BigNumber('200000000000000'),
+        makerTokenAmount: new BigNumber('10000000000000000'),
+        takerTokenAmount: new BigNumber('20000000000000000'),
+        makerTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+        takerTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
+        salt: new BigNumber('256'),
+        feeRecipient: '0x9e56625509c2f60af937f23b7b532600390e8c8b',
+        exchangeContractAddress: '0x9e56625509c2f60af937f23b7b532600390e8c8b',
+        expirationUnixTimestampSec: new BigNumber('42'),
+        ecSignature: {
+            v: 27,
+            r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
+            s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
+        },
+    },
 ];
diff --git a/packages/connect/test/fixtures/standard_relayer_api/token_pairs.json b/packages/connect/test/fixtures/standard_relayer_api/token_pairs.json
index 8d2ea328a..90f57a974 100644
--- a/packages/connect/test/fixtures/standard_relayer_api/token_pairs.json
+++ b/packages/connect/test/fixtures/standard_relayer_api/token_pairs.json
@@ -1,16 +1,16 @@
 [
-	{
-		"tokenA": {
-			"address": "0x323b5d4c32345ced77393b3530b1eed0f346429d",
-			"minAmount": "0",
-			"maxAmount": "10000000000000000000",
-			"precision": 5
-		},
-		"tokenB": {
-			"address": "0xef7fff64389b814a946f3e92105513705ca6b990",
-			"minAmount": "0",
-			"maxAmount": "50000000000000000000",
-			"precision": 5
-		}
-	}
+    {
+        "tokenA": {
+            "address": "0x323b5d4c32345ced77393b3530b1eed0f346429d",
+            "minAmount": "0",
+            "maxAmount": "10000000000000000000",
+            "precision": 5
+        },
+        "tokenB": {
+            "address": "0xef7fff64389b814a946f3e92105513705ca6b990",
+            "minAmount": "0",
+            "maxAmount": "50000000000000000000",
+            "precision": 5
+        }
+    }
 ]
diff --git a/packages/connect/test/fixtures/standard_relayer_api/token_pairs.ts b/packages/connect/test/fixtures/standard_relayer_api/token_pairs.ts
index 80ecb8207..f48b1e877 100644
--- a/packages/connect/test/fixtures/standard_relayer_api/token_pairs.ts
+++ b/packages/connect/test/fixtures/standard_relayer_api/token_pairs.ts
@@ -3,18 +3,18 @@ import { BigNumber } from '@0xproject/utils';
 import { TokenPairsItem } from '../../../src/types';
 
 export const tokenPairsResponse: TokenPairsItem[] = [
-	{
-		tokenA: {
-			address: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-			minAmount: new BigNumber(0),
-			maxAmount: new BigNumber('10000000000000000000'),
-			precision: 5,
-		},
-		tokenB: {
-			address: '0xef7fff64389b814a946f3e92105513705ca6b990',
-			minAmount: new BigNumber(0),
-			maxAmount: new BigNumber('50000000000000000000'),
-			precision: 5,
-		},
-	},
+    {
+        tokenA: {
+            address: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+            minAmount: new BigNumber(0),
+            maxAmount: new BigNumber('10000000000000000000'),
+            precision: 5,
+        },
+        tokenB: {
+            address: '0xef7fff64389b814a946f3e92105513705ca6b990',
+            minAmount: new BigNumber(0),
+            maxAmount: new BigNumber('50000000000000000000'),
+            precision: 5,
+        },
+    },
 ];
diff --git a/packages/connect/test/http_client_test.ts b/packages/connect/test/http_client_test.ts
index 00bde2fc6..15759d911 100644
--- a/packages/connect/test/http_client_test.ts
+++ b/packages/connect/test/http_client_test.ts
@@ -24,128 +24,128 @@ chai.use(chaiAsPromised);
 const expect = chai.expect;
 
 describe('HttpClient', () => {
-	const relayUrl = 'https://example.com';
-	const relayerClient = new HttpClient(relayUrl);
-	afterEach(() => {
-		fetchMock.restore();
-	});
-	describe('#constructor', () => {
-		it('should remove trailing slashes from api url', async () => {
-			const urlWithTrailingSlash = 'https://slash.com/';
-			const urlWithoutTrailingSlash = 'https://slash.com';
-			const client = new HttpClient(urlWithTrailingSlash);
-			const sanitizedUrl = (client as any)._apiEndpointUrl;
-			expect(sanitizedUrl).to.be.deep.equal(urlWithoutTrailingSlash);
-		});
-	});
-	describe('#getTokenPairsAsync', () => {
-		const url = `${relayUrl}/token_pairs`;
-		it('gets token pairs', async () => {
-			fetchMock.get(url, tokenPairsResponseJSON);
-			const tokenPairs = await relayerClient.getTokenPairsAsync();
-			expect(tokenPairs).to.be.deep.equal(tokenPairsResponse);
-		});
-		it('gets specific token pairs for request', async () => {
-			const tokenAddress = '0x323b5d4c32345ced77393b3530b1eed0f346429d';
-			const tokenPairsRequest = {
-				tokenA: tokenAddress,
-			};
-			const urlWithQuery = `${url}?tokenA=${tokenAddress}`;
-			fetchMock.get(urlWithQuery, tokenPairsResponseJSON);
-			const tokenPairs = await relayerClient.getTokenPairsAsync(tokenPairsRequest);
-			expect(tokenPairs).to.be.deep.equal(tokenPairsResponse);
-		});
-		it('throws an error for invalid JSON response', async () => {
-			fetchMock.get(url, { test: 'dummy' });
-			expect(relayerClient.getTokenPairsAsync()).to.be.rejected();
-		});
-	});
-	describe('#getOrdersAsync', () => {
-		const url = `${relayUrl}/orders`;
-		it('gets orders', async () => {
-			fetchMock.get(url, ordersResponseJSON);
-			const orders = await relayerClient.getOrdersAsync();
-			expect(orders).to.be.deep.equal(ordersResponse);
-		});
-		it('gets specific orders for request', async () => {
-			const tokenAddress = '0x323b5d4c32345ced77393b3530b1eed0f346429d';
-			const ordersRequest = {
-				tokenAddress,
-			};
-			const urlWithQuery = `${url}?tokenAddress=${tokenAddress}`;
-			fetchMock.get(urlWithQuery, ordersResponseJSON);
-			const orders = await relayerClient.getOrdersAsync(ordersRequest);
-			expect(orders).to.be.deep.equal(ordersResponse);
-		});
-		it('throws an error for invalid JSON response', async () => {
-			fetchMock.get(url, { test: 'dummy' });
-			expect(relayerClient.getOrdersAsync()).to.be.rejected();
-		});
-	});
-	describe('#getOrderAsync', () => {
-		const orderHash = '0xabc67323774bdbd24d94f977fa9ac94a50f016026fd13f42990861238897721f';
-		const url = `${relayUrl}/order/${orderHash}`;
-		it('gets order', async () => {
-			fetchMock.get(url, orderResponseJSON);
-			const order = await relayerClient.getOrderAsync(orderHash);
-			expect(order).to.be.deep.equal(orderResponse);
-		});
-		it('throws an error for invalid JSON response', async () => {
-			fetchMock.get(url, { test: 'dummy' });
-			expect(relayerClient.getOrderAsync(orderHash)).to.be.rejected();
-		});
-	});
-	describe('#getOrderBookAsync', () => {
-		const request = {
-			baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-			quoteTokenAddress: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
-		};
-		const url = `${relayUrl}/orderbook?baseTokenAddress=${request.baseTokenAddress}&quoteTokenAddress=${
-			request.quoteTokenAddress
-		}`;
-		it('gets order book', async () => {
-			fetchMock.get(url, orderbookJSON);
-			const orderbook = await relayerClient.getOrderbookAsync(request);
-			expect(orderbook).to.be.deep.equal(orderbookResponse);
-		});
-		it('throws an error for invalid JSON response', async () => {
-			fetchMock.get(url, { test: 'dummy' });
-			expect(relayerClient.getOrderbookAsync(request)).to.be.rejected();
-		});
-	});
-	describe('#getFeesAsync', () => {
-		const request = {
-			exchangeContractAddress: '0x12459c951127e0c374ff9105dda097662a027093',
-			maker: '0x9e56625509c2f60af937f23b7b532600390e8c8b',
-			taker: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
-			makerTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-			takerTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
-			makerTokenAmount: new BigNumber('10000000000000000000'),
-			takerTokenAmount: new BigNumber('30000000000000000000'),
-			salt: new BigNumber('256'),
-			expirationUnixTimestampSec: new BigNumber('42'),
-		};
-		const url = `${relayUrl}/fees`;
-		it('gets fees', async () => {
-			fetchMock.post(url, feesResponseJSON);
-			const fees = await relayerClient.getFeesAsync(request);
-			expect(fees).to.be.deep.equal(feesResponse);
-		});
-		it('does not mutate input', async () => {
-			fetchMock.post(url, feesResponseJSON);
-			const makerTokenAmountBefore = new BigNumber(request.makerTokenAmount);
-			const takerTokenAmountBefore = new BigNumber(request.takerTokenAmount);
-			const saltBefore = new BigNumber(request.salt);
-			const expirationUnixTimestampSecBefore = new BigNumber(request.expirationUnixTimestampSec);
-			await relayerClient.getFeesAsync(request);
-			expect(makerTokenAmountBefore).to.be.deep.equal(request.makerTokenAmount);
-			expect(takerTokenAmountBefore).to.be.deep.equal(request.takerTokenAmount);
-			expect(saltBefore).to.be.deep.equal(request.salt);
-			expect(expirationUnixTimestampSecBefore).to.be.deep.equal(request.expirationUnixTimestampSec);
-		});
-		it('throws an error for invalid JSON response', async () => {
-			fetchMock.post(url, { test: 'dummy' });
-			expect(relayerClient.getFeesAsync(request)).to.be.rejected();
-		});
-	});
+    const relayUrl = 'https://example.com';
+    const relayerClient = new HttpClient(relayUrl);
+    afterEach(() => {
+        fetchMock.restore();
+    });
+    describe('#constructor', () => {
+        it('should remove trailing slashes from api url', async () => {
+            const urlWithTrailingSlash = 'https://slash.com/';
+            const urlWithoutTrailingSlash = 'https://slash.com';
+            const client = new HttpClient(urlWithTrailingSlash);
+            const sanitizedUrl = (client as any)._apiEndpointUrl;
+            expect(sanitizedUrl).to.be.deep.equal(urlWithoutTrailingSlash);
+        });
+    });
+    describe('#getTokenPairsAsync', () => {
+        const url = `${relayUrl}/token_pairs`;
+        it('gets token pairs', async () => {
+            fetchMock.get(url, tokenPairsResponseJSON);
+            const tokenPairs = await relayerClient.getTokenPairsAsync();
+            expect(tokenPairs).to.be.deep.equal(tokenPairsResponse);
+        });
+        it('gets specific token pairs for request', async () => {
+            const tokenAddress = '0x323b5d4c32345ced77393b3530b1eed0f346429d';
+            const tokenPairsRequest = {
+                tokenA: tokenAddress,
+            };
+            const urlWithQuery = `${url}?tokenA=${tokenAddress}`;
+            fetchMock.get(urlWithQuery, tokenPairsResponseJSON);
+            const tokenPairs = await relayerClient.getTokenPairsAsync(tokenPairsRequest);
+            expect(tokenPairs).to.be.deep.equal(tokenPairsResponse);
+        });
+        it('throws an error for invalid JSON response', async () => {
+            fetchMock.get(url, { test: 'dummy' });
+            expect(relayerClient.getTokenPairsAsync()).to.be.rejected();
+        });
+    });
+    describe('#getOrdersAsync', () => {
+        const url = `${relayUrl}/orders`;
+        it('gets orders', async () => {
+            fetchMock.get(url, ordersResponseJSON);
+            const orders = await relayerClient.getOrdersAsync();
+            expect(orders).to.be.deep.equal(ordersResponse);
+        });
+        it('gets specific orders for request', async () => {
+            const tokenAddress = '0x323b5d4c32345ced77393b3530b1eed0f346429d';
+            const ordersRequest = {
+                tokenAddress,
+            };
+            const urlWithQuery = `${url}?tokenAddress=${tokenAddress}`;
+            fetchMock.get(urlWithQuery, ordersResponseJSON);
+            const orders = await relayerClient.getOrdersAsync(ordersRequest);
+            expect(orders).to.be.deep.equal(ordersResponse);
+        });
+        it('throws an error for invalid JSON response', async () => {
+            fetchMock.get(url, { test: 'dummy' });
+            expect(relayerClient.getOrdersAsync()).to.be.rejected();
+        });
+    });
+    describe('#getOrderAsync', () => {
+        const orderHash = '0xabc67323774bdbd24d94f977fa9ac94a50f016026fd13f42990861238897721f';
+        const url = `${relayUrl}/order/${orderHash}`;
+        it('gets order', async () => {
+            fetchMock.get(url, orderResponseJSON);
+            const order = await relayerClient.getOrderAsync(orderHash);
+            expect(order).to.be.deep.equal(orderResponse);
+        });
+        it('throws an error for invalid JSON response', async () => {
+            fetchMock.get(url, { test: 'dummy' });
+            expect(relayerClient.getOrderAsync(orderHash)).to.be.rejected();
+        });
+    });
+    describe('#getOrderBookAsync', () => {
+        const request = {
+            baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+            quoteTokenAddress: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
+        };
+        const url = `${relayUrl}/orderbook?baseTokenAddress=${request.baseTokenAddress}&quoteTokenAddress=${
+            request.quoteTokenAddress
+        }`;
+        it('gets order book', async () => {
+            fetchMock.get(url, orderbookJSON);
+            const orderbook = await relayerClient.getOrderbookAsync(request);
+            expect(orderbook).to.be.deep.equal(orderbookResponse);
+        });
+        it('throws an error for invalid JSON response', async () => {
+            fetchMock.get(url, { test: 'dummy' });
+            expect(relayerClient.getOrderbookAsync(request)).to.be.rejected();
+        });
+    });
+    describe('#getFeesAsync', () => {
+        const request = {
+            exchangeContractAddress: '0x12459c951127e0c374ff9105dda097662a027093',
+            maker: '0x9e56625509c2f60af937f23b7b532600390e8c8b',
+            taker: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
+            makerTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+            takerTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
+            makerTokenAmount: new BigNumber('10000000000000000000'),
+            takerTokenAmount: new BigNumber('30000000000000000000'),
+            salt: new BigNumber('256'),
+            expirationUnixTimestampSec: new BigNumber('42'),
+        };
+        const url = `${relayUrl}/fees`;
+        it('gets fees', async () => {
+            fetchMock.post(url, feesResponseJSON);
+            const fees = await relayerClient.getFeesAsync(request);
+            expect(fees).to.be.deep.equal(feesResponse);
+        });
+        it('does not mutate input', async () => {
+            fetchMock.post(url, feesResponseJSON);
+            const makerTokenAmountBefore = new BigNumber(request.makerTokenAmount);
+            const takerTokenAmountBefore = new BigNumber(request.takerTokenAmount);
+            const saltBefore = new BigNumber(request.salt);
+            const expirationUnixTimestampSecBefore = new BigNumber(request.expirationUnixTimestampSec);
+            await relayerClient.getFeesAsync(request);
+            expect(makerTokenAmountBefore).to.be.deep.equal(request.makerTokenAmount);
+            expect(takerTokenAmountBefore).to.be.deep.equal(request.takerTokenAmount);
+            expect(saltBefore).to.be.deep.equal(request.salt);
+            expect(expirationUnixTimestampSecBefore).to.be.deep.equal(request.expirationUnixTimestampSec);
+        });
+        it('throws an error for invalid JSON response', async () => {
+            fetchMock.post(url, { test: 'dummy' });
+            expect(relayerClient.getFeesAsync(request)).to.be.rejected();
+        });
+    });
 });
diff --git a/packages/connect/test/orderbook_channel_message_parsers_test.ts b/packages/connect/test/orderbook_channel_message_parsers_test.ts
index 04ca157a8..3e1f44384 100644
--- a/packages/connect/test/orderbook_channel_message_parsers_test.ts
+++ b/packages/connect/test/orderbook_channel_message_parsers_test.ts
@@ -7,13 +7,13 @@ import { orderbookChannelMessageParser } from '../src/utils/orderbook_channel_me
 import { orderResponse } from './fixtures/standard_relayer_api/order/0xabc67323774bdbd24d94f977fa9ac94a50f016026fd13f42990861238897721f';
 import { orderbookResponse } from './fixtures/standard_relayer_api/orderbook';
 import {
-	malformedSnapshotOrderbookChannelMessage,
-	snapshotOrderbookChannelMessage,
+    malformedSnapshotOrderbookChannelMessage,
+    snapshotOrderbookChannelMessage,
 } from './fixtures/standard_relayer_api/snapshot_orderbook_channel_message';
 import { unknownOrderbookChannelMessage } from './fixtures/standard_relayer_api/unknown_orderbook_channel_message';
 import {
-	malformedUpdateOrderbookChannelMessage,
-	updateOrderbookChannelMessage,
+    malformedUpdateOrderbookChannelMessage,
+    updateOrderbookChannelMessage,
 } from './fixtures/standard_relayer_api/update_orderbook_channel_message';
 
 chai.config.includeStack = true;
@@ -21,56 +21,56 @@ chai.use(dirtyChai);
 const expect = chai.expect;
 
 describe('orderbookChannelMessageParser', () => {
-	describe('#parser', () => {
-		it('parses snapshot messages', () => {
-			const snapshotMessage = orderbookChannelMessageParser.parse(snapshotOrderbookChannelMessage);
-			expect(snapshotMessage.type).to.be.equal('snapshot');
-			expect(snapshotMessage.payload).to.be.deep.equal(orderbookResponse);
-		});
-		it('parses update messages', () => {
-			const updateMessage = orderbookChannelMessageParser.parse(updateOrderbookChannelMessage);
-			expect(updateMessage.type).to.be.equal('update');
-			expect(updateMessage.payload).to.be.deep.equal(orderResponse);
-		});
-		it('returns unknown message for messages with unsupported types', () => {
-			const unknownMessage = orderbookChannelMessageParser.parse(unknownOrderbookChannelMessage);
-			expect(unknownMessage.type).to.be.equal('unknown');
-			expect(unknownMessage.payload).to.be.undefined();
-		});
-		it('throws when message does not include a type', () => {
-			const typelessMessage = `{
+    describe('#parser', () => {
+        it('parses snapshot messages', () => {
+            const snapshotMessage = orderbookChannelMessageParser.parse(snapshotOrderbookChannelMessage);
+            expect(snapshotMessage.type).to.be.equal('snapshot');
+            expect(snapshotMessage.payload).to.be.deep.equal(orderbookResponse);
+        });
+        it('parses update messages', () => {
+            const updateMessage = orderbookChannelMessageParser.parse(updateOrderbookChannelMessage);
+            expect(updateMessage.type).to.be.equal('update');
+            expect(updateMessage.payload).to.be.deep.equal(orderResponse);
+        });
+        it('returns unknown message for messages with unsupported types', () => {
+            const unknownMessage = orderbookChannelMessageParser.parse(unknownOrderbookChannelMessage);
+            expect(unknownMessage.type).to.be.equal('unknown');
+            expect(unknownMessage.payload).to.be.undefined();
+        });
+        it('throws when message does not include a type', () => {
+            const typelessMessage = `{
                 "channel": "orderbook",
                 "requestId": 1,
                 "payload": {}
             }`;
-			const badCall = () => orderbookChannelMessageParser.parse(typelessMessage);
-			expect(badCall).throws(`Message is missing a type parameter: ${typelessMessage}`);
-		});
-		it('throws when type is not a string', () => {
-			const messageWithBadType = `{
+            const badCall = () => orderbookChannelMessageParser.parse(typelessMessage);
+            expect(badCall).throws(`Message is missing a type parameter: ${typelessMessage}`);
+        });
+        it('throws when type is not a string', () => {
+            const messageWithBadType = `{
                 "type": 1,
                 "channel": "orderbook",
                 "requestId": 1,
                 "payload": {}
             }`;
-			const badCall = () => orderbookChannelMessageParser.parse(messageWithBadType);
-			expect(badCall).throws('Expected type to be of type string, encountered: 1');
-		});
-		it('throws when snapshot message has malformed payload', () => {
-			const badCall = () => orderbookChannelMessageParser.parse(malformedSnapshotOrderbookChannelMessage);
-			// tslint:disable-next-line:max-line-length
-			const errMsg =
-				'Validation errors: instance.payload requires property "bids", instance.payload requires property "asks"';
-			expect(badCall).throws(errMsg);
-		});
-		it('throws when update message has malformed payload', () => {
-			const badCall = () => orderbookChannelMessageParser.parse(malformedUpdateOrderbookChannelMessage);
-			expect(badCall).throws(/^Expected message to conform to schema/);
-		});
-		it('throws when input message is not valid JSON', () => {
-			const nonJsonString = 'h93b{sdfs9fsd f';
-			const badCall = () => orderbookChannelMessageParser.parse(nonJsonString);
-			expect(badCall).throws('Unexpected token h in JSON at position 0');
-		});
-	});
+            const badCall = () => orderbookChannelMessageParser.parse(messageWithBadType);
+            expect(badCall).throws('Expected type to be of type string, encountered: 1');
+        });
+        it('throws when snapshot message has malformed payload', () => {
+            const badCall = () => orderbookChannelMessageParser.parse(malformedSnapshotOrderbookChannelMessage);
+            // tslint:disable-next-line:max-line-length
+            const errMsg =
+                'Validation errors: instance.payload requires property "bids", instance.payload requires property "asks"';
+            expect(badCall).throws(errMsg);
+        });
+        it('throws when update message has malformed payload', () => {
+            const badCall = () => orderbookChannelMessageParser.parse(malformedUpdateOrderbookChannelMessage);
+            expect(badCall).throws(/^Expected message to conform to schema/);
+        });
+        it('throws when input message is not valid JSON', () => {
+            const nonJsonString = 'h93b{sdfs9fsd f';
+            const badCall = () => orderbookChannelMessageParser.parse(nonJsonString);
+            expect(badCall).throws('Unexpected token h in JSON at position 0');
+        });
+    });
 });
diff --git a/packages/connect/test/ws_orderbook_channel_test.ts b/packages/connect/test/ws_orderbook_channel_test.ts
index 0cd8cd12f..ce404d934 100644
--- a/packages/connect/test/ws_orderbook_channel_test.ts
+++ b/packages/connect/test/ws_orderbook_channel_test.ts
@@ -10,52 +10,52 @@ chai.use(dirtyChai);
 const expect = chai.expect;
 
 describe('WebSocketOrderbookChannel', () => {
-	const websocketUrl = 'ws://localhost:8080';
-	const orderbookChannel = new WebSocketOrderbookChannel(websocketUrl);
-	const subscriptionOpts = {
-		baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-		quoteTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
-		snapshot: true,
-		limit: 100,
-	};
-	const emptyOrderbookChannelHandler = {
-		onSnapshot: () => {
-			_.noop();
-		},
-		onUpdate: () => {
-			_.noop();
-		},
-		onError: () => {
-			_.noop();
-		},
-		onClose: () => {
-			_.noop();
-		},
-	};
-	describe('#subscribe', () => {
-		it('throws when subscriptionOpts does not conform to schema', () => {
-			const badSubscribeCall = orderbookChannel.subscribe.bind(
-				orderbookChannel,
-				{},
-				emptyOrderbookChannelHandler,
-			);
-			expect(badSubscribeCall).throws(
-				'Expected subscriptionOpts to conform to schema /RelayerApiOrderbookChannelSubscribePayload\nEncountered: {}\nValidation errors: instance requires property "baseTokenAddress", instance requires property "quoteTokenAddress"',
-			);
-		});
-		it('throws when handler has the incorrect members', () => {
-			const badSubscribeCall = orderbookChannel.subscribe.bind(orderbookChannel, subscriptionOpts, {});
-			expect(badSubscribeCall).throws(
-				'Expected handler.onSnapshot to be of type function, encountered: undefined',
-			);
-		});
-		it('does not throw when inputs are of correct types', () => {
-			const goodSubscribeCall = orderbookChannel.subscribe.bind(
-				orderbookChannel,
-				subscriptionOpts,
-				emptyOrderbookChannelHandler,
-			);
-			expect(goodSubscribeCall).to.not.throw();
-		});
-	});
+    const websocketUrl = 'ws://localhost:8080';
+    const orderbookChannel = new WebSocketOrderbookChannel(websocketUrl);
+    const subscriptionOpts = {
+        baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+        quoteTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
+        snapshot: true,
+        limit: 100,
+    };
+    const emptyOrderbookChannelHandler = {
+        onSnapshot: () => {
+            _.noop();
+        },
+        onUpdate: () => {
+            _.noop();
+        },
+        onError: () => {
+            _.noop();
+        },
+        onClose: () => {
+            _.noop();
+        },
+    };
+    describe('#subscribe', () => {
+        it('throws when subscriptionOpts does not conform to schema', () => {
+            const badSubscribeCall = orderbookChannel.subscribe.bind(
+                orderbookChannel,
+                {},
+                emptyOrderbookChannelHandler,
+            );
+            expect(badSubscribeCall).throws(
+                'Expected subscriptionOpts to conform to schema /RelayerApiOrderbookChannelSubscribePayload\nEncountered: {}\nValidation errors: instance requires property "baseTokenAddress", instance requires property "quoteTokenAddress"',
+            );
+        });
+        it('throws when handler has the incorrect members', () => {
+            const badSubscribeCall = orderbookChannel.subscribe.bind(orderbookChannel, subscriptionOpts, {});
+            expect(badSubscribeCall).throws(
+                'Expected handler.onSnapshot to be of type function, encountered: undefined',
+            );
+        });
+        it('does not throw when inputs are of correct types', () => {
+            const goodSubscribeCall = orderbookChannel.subscribe.bind(
+                orderbookChannel,
+                subscriptionOpts,
+                emptyOrderbookChannelHandler,
+            );
+            expect(goodSubscribeCall).to.not.throw();
+        });
+    });
 });
diff --git a/packages/connect/tsconfig.json b/packages/connect/tsconfig.json
index ed8210b04..3c150236e 100644
--- a/packages/connect/tsconfig.json
+++ b/packages/connect/tsconfig.json
@@ -1,12 +1,12 @@
 {
-	"extends": "../../tsconfig",
-	"compilerOptions": {
-		"outDir": "lib"
-	},
-	"include": [
-		"./src/**/*",
-		"./test/**/*",
-		"../../node_modules/chai-as-promised-typescript-typings/index.d.ts",
-		"../../node_modules/chai-typescript-typings/index.d.ts"
-	]
+    "extends": "../../tsconfig",
+    "compilerOptions": {
+        "outDir": "lib"
+    },
+    "include": [
+        "./src/**/*",
+        "./test/**/*",
+        "../../node_modules/chai-as-promised-typescript-typings/index.d.ts",
+        "../../node_modules/chai-typescript-typings/index.d.ts"
+    ]
 }
diff --git a/packages/connect/tslint.json b/packages/connect/tslint.json
index e63054bfc..ffaefe83a 100644
--- a/packages/connect/tslint.json
+++ b/packages/connect/tslint.json
@@ -1,3 +1,3 @@
 {
-	"extends": ["@0xproject/tslint-config"]
+    "extends": ["@0xproject/tslint-config"]
 }
diff --git a/packages/contracts/globals.d.ts b/packages/contracts/globals.d.ts
index 1f451cf5b..2e5827324 100644
--- a/packages/contracts/globals.d.ts
+++ b/packages/contracts/globals.d.ts
@@ -6,31 +6,31 @@ declare module 'dirty-chai';
 // disallow `namespace`, we disable tslint for the following.
 /* tslint:disable */
 declare namespace Chai {
-	interface Assertion {
-		bignumber: Assertion;
-	}
+    interface Assertion {
+        bignumber: Assertion;
+    }
 }
 /* tslint:enable */
 
 declare module '*.json' {
-	const json: any;
-	/* tslint:disable */
-	export default json;
-	/* tslint:enable */
+    const json: any;
+    /* tslint:disable */
+    export default json;
+    /* tslint:enable */
 }
 
 declare module 'solc' {
-	export function compile(sources: any, optimizerEnabled: number, findImports: (importPath: string) => any): any;
-	export function setupMethods(solcBin: any): any;
+    export function compile(sources: any, optimizerEnabled: number, findImports: (importPath: string) => any): any;
+    export function setupMethods(solcBin: any): any;
 }
 
 declare module 'web3-eth-abi' {
-	export function encodeParameters(typesArray: string[], parameters: any[]): string;
+    export function encodeParameters(typesArray: string[], parameters: any[]): string;
 }
 
 declare module 'ethereumjs-abi' {
-	const soliditySHA3: (argTypes: string[], args: any[]) => Buffer;
-	const methodID: (name: string, types: string[]) => Buffer;
+    const soliditySHA3: (argTypes: string[], args: any[]) => Buffer;
+    const methodID: (name: string, types: string[]) => Buffer;
 }
 
 // Truffle injects the following into the global scope
diff --git a/packages/contracts/globalsAugment.d.ts b/packages/contracts/globalsAugment.d.ts
index c81a74844..9b16ce2ad 100644
--- a/packages/contracts/globalsAugment.d.ts
+++ b/packages/contracts/globalsAugment.d.ts
@@ -3,17 +3,17 @@ import { BigNumber } from '@0xproject/utils';
 // 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 */
+    // 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 */
 }
diff --git a/packages/contracts/migrations/1_initial_migration.ts b/packages/contracts/migrations/1_initial_migration.ts
index 73999dac5..8661ee218 100644
--- a/packages/contracts/migrations/1_initial_migration.ts
+++ b/packages/contracts/migrations/1_initial_migration.ts
@@ -2,5 +2,5 @@ import { Artifacts } from '../util/artifacts';
 const { Migrations } = new Artifacts(artifacts);
 
 module.exports = (deployer: any) => {
-	deployer.deploy(Migrations);
+    deployer.deploy(Migrations);
 };
diff --git a/packages/contracts/migrations/2_deploy_independent_contracts.ts b/packages/contracts/migrations/2_deploy_independent_contracts.ts
index 07e2f600f..ac1752347 100644
--- a/packages/contracts/migrations/2_deploy_independent_contracts.ts
+++ b/packages/contracts/migrations/2_deploy_independent_contracts.ts
@@ -4,38 +4,38 @@ const { MultiSigWalletWithTimeLock, TokenTransferProxy, EtherToken, TokenRegistr
 
 let multiSigConfigByNetwork: MultiSigConfigByNetwork;
 try {
-	/* tslint:disable */
-	const multiSigConfig = require('./config/multisig');
-	multiSigConfigByNetwork = multiSigConfig.multiSig;
-	/* tslint:enable */
+    /* tslint:disable */
+    const multiSigConfig = require('./config/multisig');
+    multiSigConfigByNetwork = multiSigConfig.multiSig;
+    /* tslint:enable */
 } catch (e) {
-	multiSigConfigByNetwork = {};
+    multiSigConfigByNetwork = {};
 }
 
 module.exports = (deployer: any, network: string, accounts: string[]) => {
-	const defaultConfig = {
-		owners: [accounts[0], accounts[1]],
-		confirmationsRequired: 2,
-		secondsRequired: 0,
-	};
-	const config = multiSigConfigByNetwork[network] || defaultConfig;
-	if (network !== 'live') {
-		deployer
-			.deploy(MultiSigWalletWithTimeLock, config.owners, config.confirmationsRequired, config.secondsRequired)
-			.then(() => {
-				return deployer.deploy(TokenTransferProxy);
-			})
-			.then(() => {
-				return deployer.deploy(TokenRegistry);
-			})
-			.then(() => {
-				return deployer.deploy(EtherToken);
-			});
-	} else {
-		deployer.deploy([
-			[MultiSigWalletWithTimeLock, config.owners, config.confirmationsRequired, config.secondsRequired],
-			TokenTransferProxy,
-			TokenRegistry,
-		]);
-	}
+    const defaultConfig = {
+        owners: [accounts[0], accounts[1]],
+        confirmationsRequired: 2,
+        secondsRequired: 0,
+    };
+    const config = multiSigConfigByNetwork[network] || defaultConfig;
+    if (network !== 'live') {
+        deployer
+            .deploy(MultiSigWalletWithTimeLock, config.owners, config.confirmationsRequired, config.secondsRequired)
+            .then(() => {
+                return deployer.deploy(TokenTransferProxy);
+            })
+            .then(() => {
+                return deployer.deploy(TokenRegistry);
+            })
+            .then(() => {
+                return deployer.deploy(EtherToken);
+            });
+    } else {
+        deployer.deploy([
+            [MultiSigWalletWithTimeLock, config.owners, config.confirmationsRequired, config.secondsRequired],
+            TokenTransferProxy,
+            TokenRegistry,
+        ]);
+    }
 };
diff --git a/packages/contracts/migrations/3_register_tokens.ts b/packages/contracts/migrations/3_register_tokens.ts
index b36cea296..d5cf63f94 100644
--- a/packages/contracts/migrations/3_register_tokens.ts
+++ b/packages/contracts/migrations/3_register_tokens.ts
@@ -9,87 +9,87 @@ import { tokenInfo } from './config/token_info';
 const { DummyToken, EtherToken, ZRXToken, TokenRegistry } = new Artifacts(artifacts);
 
 module.exports = (deployer: any, network: string) => {
-	const tokens = network === 'live' ? tokenInfo.live : tokenInfo.development;
-	deployer
-		.then(() => {
-			return TokenRegistry.deployed();
-		})
-		.then((tokenRegistry: ContractInstance) => {
-			if (network !== 'live') {
-				const totalSupply = Math.pow(10, 18) * 1000000000;
-				return Bluebird.each(
-					tokens.map((token: Token) => DummyToken.new(token.name, token.symbol, token.decimals, totalSupply)),
-					_.noop,
-				).then((dummyTokens: ContractInstance[]) => {
-					const weth = {
-						address: EtherToken.address,
-						name: 'Ether Token',
-						symbol: 'WETH',
-						url: '',
-						decimals: 18,
-						ipfsHash: constants.NULL_BYTES,
-						swarmHash: constants.NULL_BYTES,
-					};
-					return Bluebird.each(
-						dummyTokens
-							.map((tokenContract: ContractInstance, i: number) => {
-								const token = tokens[i];
-								return tokenRegistry.addToken(
-									tokenContract.address,
-									token.name,
-									token.symbol,
-									token.decimals,
-									token.ipfsHash,
-									token.swarmHash,
-								);
-							})
-							.concat(
-								tokenRegistry.addToken(
-									weth.address,
-									weth.name,
-									weth.symbol,
-									weth.decimals,
-									weth.ipfsHash,
-									weth.swarmHash,
-								),
-							),
-						_.noop,
-					);
-				});
-			} else {
-				const zrx = {
-					address: ZRXToken.address,
-					name: '0x Protocol Token',
-					symbol: 'ZRX',
-					url: 'https://www.0xproject.com/',
-					decimals: 18,
-					ipfsHash: constants.NULL_BYTES,
-					swarmHash: constants.NULL_BYTES,
-				};
-				return Bluebird.each(
-					tokens
-						.map((token: Token) => {
-							return tokenRegistry.addToken(
-								token.address,
-								token.name,
-								token.symbol,
-								token.decimals,
-								token.ipfsHash,
-								token.swarmHash,
-							);
-						})
-						.concat(
-							tokenRegistry.addToken(
-								zrx.address,
-								zrx.name,
-								zrx.symbol,
-								zrx.decimals,
-								zrx.ipfsHash,
-								zrx.swarmHash,
-							),
-						),
-					_.noop,
-				);
-			}
-		});
+    const tokens = network === 'live' ? tokenInfo.live : tokenInfo.development;
+    deployer
+        .then(() => {
+            return TokenRegistry.deployed();
+        })
+        .then((tokenRegistry: ContractInstance) => {
+            if (network !== 'live') {
+                const totalSupply = Math.pow(10, 18) * 1000000000;
+                return Bluebird.each(
+                    tokens.map((token: Token) => DummyToken.new(token.name, token.symbol, token.decimals, totalSupply)),
+                    _.noop,
+                ).then((dummyTokens: ContractInstance[]) => {
+                    const weth = {
+                        address: EtherToken.address,
+                        name: 'Ether Token',
+                        symbol: 'WETH',
+                        url: '',
+                        decimals: 18,
+                        ipfsHash: constants.NULL_BYTES,
+                        swarmHash: constants.NULL_BYTES,
+                    };
+                    return Bluebird.each(
+                        dummyTokens
+                            .map((tokenContract: ContractInstance, i: number) => {
+                                const token = tokens[i];
+                                return tokenRegistry.addToken(
+                                    tokenContract.address,
+                                    token.name,
+                                    token.symbol,
+                                    token.decimals,
+                                    token.ipfsHash,
+                                    token.swarmHash,
+                                );
+                            })
+                            .concat(
+                                tokenRegistry.addToken(
+                                    weth.address,
+                                    weth.name,
+                                    weth.symbol,
+                                    weth.decimals,
+                                    weth.ipfsHash,
+                                    weth.swarmHash,
+                                ),
+                            ),
+                        _.noop,
+                    );
+                });
+            } else {
+                const zrx = {
+                    address: ZRXToken.address,
+                    name: '0x Protocol Token',
+                    symbol: 'ZRX',
+                    url: 'https://www.0xproject.com/',
+                    decimals: 18,
+                    ipfsHash: constants.NULL_BYTES,
+                    swarmHash: constants.NULL_BYTES,
+                };
+                return Bluebird.each(
+                    tokens
+                        .map((token: Token) => {
+                            return tokenRegistry.addToken(
+                                token.address,
+                                token.name,
+                                token.symbol,
+                                token.decimals,
+                                token.ipfsHash,
+                                token.swarmHash,
+                            );
+                        })
+                        .concat(
+                            tokenRegistry.addToken(
+                                zrx.address,
+                                zrx.name,
+                                zrx.symbol,
+                                zrx.decimals,
+                                zrx.ipfsHash,
+                                zrx.swarmHash,
+                            ),
+                        ),
+                    _.noop,
+                );
+            }
+        });
 };
diff --git a/packages/contracts/migrations/4_configure_proxy.ts b/packages/contracts/migrations/4_configure_proxy.ts
index ce34ddd32..ff3b844d6 100644
--- a/packages/contracts/migrations/4_configure_proxy.ts
+++ b/packages/contracts/migrations/4_configure_proxy.ts
@@ -4,19 +4,19 @@ const { TokenTransferProxy, Exchange, TokenRegistry } = new Artifacts(artifacts)
 
 let tokenTransferProxy: ContractInstance;
 module.exports = (deployer: any) => {
-	deployer
-		.then(async () => {
-			return Promise.all([TokenTransferProxy.deployed(), TokenRegistry.deployed()]);
-		})
-		.then((instances: ContractInstance[]) => {
-			let tokenRegistry: ContractInstance;
-			[tokenTransferProxy, tokenRegistry] = instances;
-			return tokenRegistry.getTokenAddressBySymbol('ZRX');
-		})
-		.then((ptAddress: string) => {
-			return deployer.deploy(Exchange, ptAddress, tokenTransferProxy.address);
-		})
-		.then(() => {
-			return tokenTransferProxy.addAuthorizedAddress(Exchange.address);
-		});
+    deployer
+        .then(async () => {
+            return Promise.all([TokenTransferProxy.deployed(), TokenRegistry.deployed()]);
+        })
+        .then((instances: ContractInstance[]) => {
+            let tokenRegistry: ContractInstance;
+            [tokenTransferProxy, tokenRegistry] = instances;
+            return tokenRegistry.getTokenAddressBySymbol('ZRX');
+        })
+        .then((ptAddress: string) => {
+            return deployer.deploy(Exchange, ptAddress, tokenTransferProxy.address);
+        })
+        .then(() => {
+            return tokenTransferProxy.addAuthorizedAddress(Exchange.address);
+        });
 };
diff --git a/packages/contracts/migrations/5_transfer_ownership.ts b/packages/contracts/migrations/5_transfer_ownership.ts
index 08b068e18..a27801de3 100644
--- a/packages/contracts/migrations/5_transfer_ownership.ts
+++ b/packages/contracts/migrations/5_transfer_ownership.ts
@@ -4,17 +4,17 @@ const { TokenTransferProxy, MultiSigWalletWithTimeLock, TokenRegistry } = new Ar
 
 let tokenRegistry: ContractInstance;
 module.exports = (deployer: any, network: string) => {
-	if (network !== 'development') {
-		deployer.then(async () => {
-			return Promise.all([TokenTransferProxy.deployed(), TokenRegistry.deployed()])
-				.then((instances: ContractInstance[]) => {
-					let tokenTransferProxy: ContractInstance;
-					[tokenTransferProxy, tokenRegistry] = instances;
-					return tokenTransferProxy.transferOwnership(MultiSigWalletWithTimeLock.address);
-				})
-				.then(() => {
-					return tokenRegistry.transferOwnership(MultiSigWalletWithTimeLock.address);
-				});
-		});
-	}
+    if (network !== 'development') {
+        deployer.then(async () => {
+            return Promise.all([TokenTransferProxy.deployed(), TokenRegistry.deployed()])
+                .then((instances: ContractInstance[]) => {
+                    let tokenTransferProxy: ContractInstance;
+                    [tokenTransferProxy, tokenRegistry] = instances;
+                    return tokenTransferProxy.transferOwnership(MultiSigWalletWithTimeLock.address);
+                })
+                .then(() => {
+                    return tokenRegistry.transferOwnership(MultiSigWalletWithTimeLock.address);
+                });
+        });
+    }
 };
diff --git a/packages/contracts/migrations/config/multisig_sample.ts b/packages/contracts/migrations/config/multisig_sample.ts
index 6ff5efc1c..97cdc2eae 100644
--- a/packages/contracts/migrations/config/multisig_sample.ts
+++ b/packages/contracts/migrations/config/multisig_sample.ts
@@ -2,9 +2,9 @@ import { MultiSigConfigByNetwork } from '../../util/types';
 
 // Make a copy of this file named `multisig.js` and input custom params as needed
 export const multiSig: MultiSigConfigByNetwork = {
-	kovan: {
-		owners: [],
-		confirmationsRequired: 0,
-		secondsRequired: 0,
-	},
+    kovan: {
+        owners: [],
+        confirmationsRequired: 0,
+        secondsRequired: 0,
+    },
 };
diff --git a/packages/contracts/migrations/config/token_info.ts b/packages/contracts/migrations/config/token_info.ts
index 9e211c489..6ae67175e 100644
--- a/packages/contracts/migrations/config/token_info.ts
+++ b/packages/contracts/migrations/config/token_info.ts
@@ -2,98 +2,98 @@ import { constants } from '../../util/constants';
 import { TokenInfoByNetwork } from '../../util/types';
 
 export const tokenInfo: TokenInfoByNetwork = {
-	development: [
-		{
-			name: '0x Protocol Token',
-			symbol: 'ZRX',
-			decimals: 18,
-			ipfsHash: constants.NULL_BYTES,
-			swarmHash: constants.NULL_BYTES,
-		},
-		{
-			name: 'Augur Reputation Token',
-			symbol: 'REP',
-			decimals: 18,
-			ipfsHash: constants.NULL_BYTES,
-			swarmHash: constants.NULL_BYTES,
-		},
-		{
-			name: 'Digix DAO Token',
-			symbol: 'DGD',
-			decimals: 18,
-			ipfsHash: constants.NULL_BYTES,
-			swarmHash: constants.NULL_BYTES,
-		},
-		{
-			name: 'Golem Network Token',
-			symbol: 'GNT',
-			decimals: 18,
-			ipfsHash: constants.NULL_BYTES,
-			swarmHash: constants.NULL_BYTES,
-		},
-		{
-			name: 'MakerDAO',
-			symbol: 'MKR',
-			decimals: 18,
-			ipfsHash: constants.NULL_BYTES,
-			swarmHash: constants.NULL_BYTES,
-		},
-		{
-			name: 'Melon Token',
-			symbol: 'MLN',
-			decimals: 18,
-			ipfsHash: constants.NULL_BYTES,
-			swarmHash: constants.NULL_BYTES,
-		},
-	],
-	live: [
-		{
-			address: '0xecf8f87f810ecf450940c9f60066b4a7a501d6a7',
-			name: 'ETH Wrapper Token',
-			symbol: 'WETH',
-			decimals: 18,
-			ipfsHash: constants.NULL_BYTES,
-			swarmHash: constants.NULL_BYTES,
-		},
-		{
-			address: '0x48c80f1f4d53d5951e5d5438b54cba84f29f32a5',
-			name: 'Augur Reputation Token',
-			symbol: 'REP',
-			decimals: 18,
-			ipfsHash: constants.NULL_BYTES,
-			swarmHash: constants.NULL_BYTES,
-		},
-		{
-			address: '0xe0b7927c4af23765cb51314a0e0521a9645f0e2a',
-			name: 'Digix DAO Token',
-			symbol: 'DGD',
-			decimals: 18,
-			ipfsHash: constants.NULL_BYTES,
-			swarmHash: constants.NULL_BYTES,
-		},
-		{
-			address: '0xa74476443119a942de498590fe1f2454d7d4ac0d',
-			name: 'Golem Network Token',
-			symbol: 'GNT',
-			decimals: 18,
-			ipfsHash: constants.NULL_BYTES,
-			swarmHash: constants.NULL_BYTES,
-		},
-		{
-			address: '0xc66ea802717bfb9833400264dd12c2bceaa34a6d',
-			name: 'MakerDAO',
-			symbol: 'MKR',
-			decimals: 18,
-			ipfsHash: constants.NULL_BYTES,
-			swarmHash: constants.NULL_BYTES,
-		},
-		{
-			address: '0xbeb9ef514a379b997e0798fdcc901ee474b6d9a1',
-			name: 'Melon Token',
-			symbol: 'MLN',
-			decimals: 18,
-			ipfsHash: constants.NULL_BYTES,
-			swarmHash: constants.NULL_BYTES,
-		},
-	],
+    development: [
+        {
+            name: '0x Protocol Token',
+            symbol: 'ZRX',
+            decimals: 18,
+            ipfsHash: constants.NULL_BYTES,
+            swarmHash: constants.NULL_BYTES,
+        },
+        {
+            name: 'Augur Reputation Token',
+            symbol: 'REP',
+            decimals: 18,
+            ipfsHash: constants.NULL_BYTES,
+            swarmHash: constants.NULL_BYTES,
+        },
+        {
+            name: 'Digix DAO Token',
+            symbol: 'DGD',
+            decimals: 18,
+            ipfsHash: constants.NULL_BYTES,
+            swarmHash: constants.NULL_BYTES,
+        },
+        {
+            name: 'Golem Network Token',
+            symbol: 'GNT',
+            decimals: 18,
+            ipfsHash: constants.NULL_BYTES,
+            swarmHash: constants.NULL_BYTES,
+        },
+        {
+            name: 'MakerDAO',
+            symbol: 'MKR',
+            decimals: 18,
+            ipfsHash: constants.NULL_BYTES,
+            swarmHash: constants.NULL_BYTES,
+        },
+        {
+            name: 'Melon Token',
+            symbol: 'MLN',
+            decimals: 18,
+            ipfsHash: constants.NULL_BYTES,
+            swarmHash: constants.NULL_BYTES,
+        },
+    ],
+    live: [
+        {
+            address: '0xecf8f87f810ecf450940c9f60066b4a7a501d6a7',
+            name: 'ETH Wrapper Token',
+            symbol: 'WETH',
+            decimals: 18,
+            ipfsHash: constants.NULL_BYTES,
+            swarmHash: constants.NULL_BYTES,
+        },
+        {
+            address: '0x48c80f1f4d53d5951e5d5438b54cba84f29f32a5',
+            name: 'Augur Reputation Token',
+            symbol: 'REP',
+            decimals: 18,
+            ipfsHash: constants.NULL_BYTES,
+            swarmHash: constants.NULL_BYTES,
+        },
+        {
+            address: '0xe0b7927c4af23765cb51314a0e0521a9645f0e2a',
+            name: 'Digix DAO Token',
+            symbol: 'DGD',
+            decimals: 18,
+            ipfsHash: constants.NULL_BYTES,
+            swarmHash: constants.NULL_BYTES,
+        },
+        {
+            address: '0xa74476443119a942de498590fe1f2454d7d4ac0d',
+            name: 'Golem Network Token',
+            symbol: 'GNT',
+            decimals: 18,
+            ipfsHash: constants.NULL_BYTES,
+            swarmHash: constants.NULL_BYTES,
+        },
+        {
+            address: '0xc66ea802717bfb9833400264dd12c2bceaa34a6d',
+            name: 'MakerDAO',
+            symbol: 'MKR',
+            decimals: 18,
+            ipfsHash: constants.NULL_BYTES,
+            swarmHash: constants.NULL_BYTES,
+        },
+        {
+            address: '0xbeb9ef514a379b997e0798fdcc901ee474b6d9a1',
+            name: 'Melon Token',
+            symbol: 'MLN',
+            decimals: 18,
+            ipfsHash: constants.NULL_BYTES,
+            swarmHash: constants.NULL_BYTES,
+        },
+    ],
 };
diff --git a/packages/contracts/package.json b/packages/contracts/package.json
index b361c6622..468607c16 100644
--- a/packages/contracts/package.json
+++ b/packages/contracts/package.json
@@ -1,74 +1,74 @@
 {
-	"private": true,
-	"name": "contracts",
-	"version": "2.1.6",
-	"description": "Smart contract components of 0x protocol",
-	"main": "index.js",
-	"directories": {
-		"test": "test"
-	},
-	"scripts": {
-		"build":
-			"rm -rf ./lib; copyfiles ./build/**/* ./deploy/solc/solc_bin/* ./deploy/test/fixtures/contracts/**/* ./deploy/test/fixtures/contracts/* ./lib; tsc;",
-		"test": "npm run build; truffle test",
-		"compile:comment":
-			"Yarn workspaces do not link binaries correctly so we need to reference them directly https://github.com/yarnpkg/yarn/issues/3846",
-		"compile": "node ../deployer/lib/src/cli.js compile",
-		"clean": "rm -rf ./lib",
-		"migrate": "node ../deployer/lib/src/cli.js migrate",
-		"lint": "tslint --project . 'migrations/**/*.ts' 'test/**/*.ts' 'util/**/*.ts' 'deploy/**/*.ts'",
-		"test:circleci": "yarn test"
-	},
-	"repository": {
-		"type": "git",
-		"url": "https://github.com/0xProject/0x.js.git"
-	},
-	"author": "Amir Bandeali",
-	"license": "Apache-2.0",
-	"bugs": {
-		"url": "https://github.com/0xProject/0x.js/issues"
-	},
-	"homepage": "https://github.com/0xProject/0x.js/packages/contracts/README.md",
-	"devDependencies": {
-		"@0xproject/dev-utils": "^0.0.7",
-		"@0xproject/tslint-config": "^0.4.4",
-		"@0xproject/types": "^0.1.6",
-		"@types/bluebird": "^3.5.3",
-		"@types/lodash": "^4.14.86",
-		"@types/node": "^8.0.53",
-		"@types/request-promise-native": "^1.0.2",
-		"@types/yargs": "^10.0.0",
-		"chai": "^4.0.1",
-		"chai-as-promised": "^7.1.0",
-		"chai-as-promised-typescript-typings": "^0.0.6",
-		"chai-bignumber": "^2.0.1",
-		"chai-typescript-typings": "^0.0.2",
-		"copyfiles": "^1.2.0",
-		"dirty-chai": "^2.0.1",
-		"mocha": "^4.0.1",
-		"solc": "^0.4.18",
-		"truffle": "^4.0.1",
-		"tslint": "5.8.0",
-		"types-bn": "^0.0.1",
-		"types-ethereumjs-util": "0xProject/types-ethereumjs-util",
-		"typescript": "~2.6.1",
-		"web3-typescript-typings": "^0.9.6",
-		"yargs": "^10.0.3"
-	},
-	"dependencies": {
-		"0x.js": "^0.30.2",
-		"@0xproject/deployer": "^0.0.3",
-		"@0xproject/json-schemas": "^0.7.5",
-		"@0xproject/utils": "^0.2.2",
-		"@0xproject/web3-wrapper": "^0.1.7",
-		"bluebird": "^3.5.0",
-		"bn.js": "^4.11.8",
-		"ethereumjs-abi": "^0.6.4",
-		"ethereumjs-util": "^5.1.1",
-		"isomorphic-fetch": "^2.2.1",
-		"lodash": "^4.17.4",
-		"request": "^2.81.0",
-		"web3": "^0.20.0",
-		"web3-eth-abi": "^1.0.0-beta.24"
-	}
+    "private": true,
+    "name": "contracts",
+    "version": "2.1.6",
+    "description": "Smart contract components of 0x protocol",
+    "main": "index.js",
+    "directories": {
+        "test": "test"
+    },
+    "scripts": {
+        "build":
+            "rm -rf ./lib; copyfiles ./build/**/* ./deploy/solc/solc_bin/* ./deploy/test/fixtures/contracts/**/* ./deploy/test/fixtures/contracts/* ./lib; tsc;",
+        "test": "npm run build; truffle test",
+        "compile:comment":
+            "Yarn workspaces do not link binaries correctly so we need to reference them directly https://github.com/yarnpkg/yarn/issues/3846",
+        "compile": "node ../deployer/lib/src/cli.js compile",
+        "clean": "rm -rf ./lib",
+        "migrate": "node ../deployer/lib/src/cli.js migrate",
+        "lint": "tslint --project . 'migrations/**/*.ts' 'test/**/*.ts' 'util/**/*.ts' 'deploy/**/*.ts'",
+        "test:circleci": "yarn test"
+    },
+    "repository": {
+        "type": "git",
+        "url": "https://github.com/0xProject/0x.js.git"
+    },
+    "author": "Amir Bandeali",
+    "license": "Apache-2.0",
+    "bugs": {
+        "url": "https://github.com/0xProject/0x.js/issues"
+    },
+    "homepage": "https://github.com/0xProject/0x.js/packages/contracts/README.md",
+    "devDependencies": {
+        "@0xproject/dev-utils": "^0.0.7",
+        "@0xproject/tslint-config": "^0.4.4",
+        "@0xproject/types": "^0.1.6",
+        "@types/bluebird": "^3.5.3",
+        "@types/lodash": "^4.14.86",
+        "@types/node": "^8.0.53",
+        "@types/request-promise-native": "^1.0.2",
+        "@types/yargs": "^10.0.0",
+        "chai": "^4.0.1",
+        "chai-as-promised": "^7.1.0",
+        "chai-as-promised-typescript-typings": "^0.0.6",
+        "chai-bignumber": "^2.0.1",
+        "chai-typescript-typings": "^0.0.2",
+        "copyfiles": "^1.2.0",
+        "dirty-chai": "^2.0.1",
+        "mocha": "^4.0.1",
+        "solc": "^0.4.18",
+        "truffle": "^4.0.1",
+        "tslint": "5.8.0",
+        "types-bn": "^0.0.1",
+        "types-ethereumjs-util": "0xProject/types-ethereumjs-util",
+        "typescript": "~2.6.1",
+        "web3-typescript-typings": "^0.9.6",
+        "yargs": "^10.0.3"
+    },
+    "dependencies": {
+        "0x.js": "^0.30.2",
+        "@0xproject/deployer": "^0.0.3",
+        "@0xproject/json-schemas": "^0.7.5",
+        "@0xproject/utils": "^0.2.2",
+        "@0xproject/web3-wrapper": "^0.1.7",
+        "bluebird": "^3.5.0",
+        "bn.js": "^4.11.8",
+        "ethereumjs-abi": "^0.6.4",
+        "ethereumjs-util": "^5.1.1",
+        "isomorphic-fetch": "^2.2.1",
+        "lodash": "^4.17.4",
+        "request": "^2.81.0",
+        "web3": "^0.20.0",
+        "web3-eth-abi": "^1.0.0-beta.24"
+    }
 }
diff --git a/packages/contracts/test/ts/ether_token.ts b/packages/contracts/test/ts/ether_token.ts
index c770b4001..f807cdaa3 100644
--- a/packages/contracts/test/ts/ether_token.ts
+++ b/packages/contracts/test/ts/ether_token.ts
@@ -18,107 +18,107 @@ const expect = chai.expect;
 const web3: Web3 = (global as any).web3;
 
 contract('EtherToken', (accounts: string[]) => {
-	const account = accounts[0];
-	const gasPrice = ZeroEx.toBaseUnitAmount(new BigNumber(20), 9);
-	let zeroEx: ZeroEx;
-	let etherTokenAddress: string;
-
-	before(async () => {
-		etherTokenAddress = EtherToken.address;
-		zeroEx = new ZeroEx(web3.currentProvider, {
-			gasPrice,
-			networkId: constants.TESTRPC_NETWORK_ID,
-		});
-	});
-
-	const sendTransactionAsync = promisify<string>(web3.eth.sendTransaction);
-	const getEthBalanceAsync = async (owner: string) => {
-		const balanceStr = await promisify<string>(web3.eth.getBalance)(owner);
-		const balance = new BigNumber(balanceStr);
-		return balance;
-	};
-
-	describe('deposit', () => {
-		it('should throw if caller attempts to deposit more Ether than caller balance', async () => {
-			const initEthBalance = await getEthBalanceAsync(account);
-			const ethToDeposit = initEthBalance.plus(1);
-
-			return expect(zeroEx.etherToken.depositAsync(etherTokenAddress, ethToDeposit, account)).to.be.rejectedWith(
-				ZeroExError.InsufficientEthBalanceForDeposit,
-			);
-		});
-
-		it('should convert deposited Ether to wrapped Ether tokens', async () => {
-			const initEthBalance = await getEthBalanceAsync(account);
-			const initEthTokenBalance = await zeroEx.token.getBalanceAsync(etherTokenAddress, account);
-
-			const ethToDeposit = new BigNumber(web3.toWei(1, 'ether'));
-
-			const txHash = await zeroEx.etherToken.depositAsync(etherTokenAddress, ethToDeposit, account);
-			const receipt = await zeroEx.awaitTransactionMinedAsync(txHash);
-
-			const ethSpentOnGas = gasPrice.times(receipt.gasUsed);
-			const finalEthBalance = await getEthBalanceAsync(account);
-			const finalEthTokenBalance = await zeroEx.token.getBalanceAsync(etherTokenAddress, account);
-
-			expect(finalEthBalance).to.be.bignumber.equal(initEthBalance.minus(ethToDeposit.plus(ethSpentOnGas)));
-			expect(finalEthTokenBalance).to.be.bignumber.equal(initEthTokenBalance.plus(ethToDeposit));
-		});
-	});
-
-	describe('withdraw', () => {
-		it('should throw if caller attempts to withdraw greater than caller balance', async () => {
-			const initEthTokenBalance = await zeroEx.token.getBalanceAsync(etherTokenAddress, account);
-			const ethTokensToWithdraw = initEthTokenBalance.plus(1);
-
-			return expect(
-				zeroEx.etherToken.withdrawAsync(etherTokenAddress, ethTokensToWithdraw, account),
-			).to.be.rejectedWith(ZeroExError.InsufficientWEthBalanceForWithdrawal);
-		});
-
-		it('should convert ether tokens to ether with sufficient balance', async () => {
-			const initEthTokenBalance = await zeroEx.token.getBalanceAsync(etherTokenAddress, account);
-			const initEthBalance = await getEthBalanceAsync(account);
-			const ethTokensToWithdraw = initEthTokenBalance;
-			expect(ethTokensToWithdraw).to.not.be.bignumber.equal(0);
-			const txHash = await zeroEx.etherToken.withdrawAsync(etherTokenAddress, ethTokensToWithdraw, account, {
-				gasLimit: constants.MAX_ETHERTOKEN_WITHDRAW_GAS,
-			});
-			const receipt = await zeroEx.awaitTransactionMinedAsync(txHash);
-
-			const ethSpentOnGas = gasPrice.times(receipt.gasUsed);
-			const finalEthBalance = await getEthBalanceAsync(account);
-			const finalEthTokenBalance = await zeroEx.token.getBalanceAsync(etherTokenAddress, account);
-
-			expect(finalEthBalance).to.be.bignumber.equal(
-				initEthBalance.plus(ethTokensToWithdraw.minus(ethSpentOnGas)),
-			);
-			expect(finalEthTokenBalance).to.be.bignumber.equal(initEthTokenBalance.minus(ethTokensToWithdraw));
-		});
-	});
-
-	describe('fallback', () => {
-		it('should convert sent ether to ether tokens', async () => {
-			const initEthBalance = await getEthBalanceAsync(account);
-			const initEthTokenBalance = await zeroEx.token.getBalanceAsync(etherTokenAddress, account);
-
-			const ethToDeposit = ZeroEx.toBaseUnitAmount(new BigNumber(1), 18);
-
-			const txHash = await sendTransactionAsync({
-				from: account,
-				to: etherTokenAddress,
-				value: ethToDeposit,
-				gasPrice,
-			});
-
-			const receipt = await zeroEx.awaitTransactionMinedAsync(txHash);
-
-			const ethSpentOnGas = gasPrice.times(receipt.gasUsed);
-			const finalEthBalance = await getEthBalanceAsync(account);
-			const finalEthTokenBalance = await zeroEx.token.getBalanceAsync(etherTokenAddress, account);
-
-			expect(finalEthBalance).to.be.bignumber.equal(initEthBalance.minus(ethToDeposit.plus(ethSpentOnGas)));
-			expect(finalEthTokenBalance).to.be.bignumber.equal(initEthTokenBalance.plus(ethToDeposit));
-		});
-	});
+    const account = accounts[0];
+    const gasPrice = ZeroEx.toBaseUnitAmount(new BigNumber(20), 9);
+    let zeroEx: ZeroEx;
+    let etherTokenAddress: string;
+
+    before(async () => {
+        etherTokenAddress = EtherToken.address;
+        zeroEx = new ZeroEx(web3.currentProvider, {
+            gasPrice,
+            networkId: constants.TESTRPC_NETWORK_ID,
+        });
+    });
+
+    const sendTransactionAsync = promisify<string>(web3.eth.sendTransaction);
+    const getEthBalanceAsync = async (owner: string) => {
+        const balanceStr = await promisify<string>(web3.eth.getBalance)(owner);
+        const balance = new BigNumber(balanceStr);
+        return balance;
+    };
+
+    describe('deposit', () => {
+        it('should throw if caller attempts to deposit more Ether than caller balance', async () => {
+            const initEthBalance = await getEthBalanceAsync(account);
+            const ethToDeposit = initEthBalance.plus(1);
+
+            return expect(zeroEx.etherToken.depositAsync(etherTokenAddress, ethToDeposit, account)).to.be.rejectedWith(
+                ZeroExError.InsufficientEthBalanceForDeposit,
+            );
+        });
+
+        it('should convert deposited Ether to wrapped Ether tokens', async () => {
+            const initEthBalance = await getEthBalanceAsync(account);
+            const initEthTokenBalance = await zeroEx.token.getBalanceAsync(etherTokenAddress, account);
+
+            const ethToDeposit = new BigNumber(web3.toWei(1, 'ether'));
+
+            const txHash = await zeroEx.etherToken.depositAsync(etherTokenAddress, ethToDeposit, account);
+            const receipt = await zeroEx.awaitTransactionMinedAsync(txHash);
+
+            const ethSpentOnGas = gasPrice.times(receipt.gasUsed);
+            const finalEthBalance = await getEthBalanceAsync(account);
+            const finalEthTokenBalance = await zeroEx.token.getBalanceAsync(etherTokenAddress, account);
+
+            expect(finalEthBalance).to.be.bignumber.equal(initEthBalance.minus(ethToDeposit.plus(ethSpentOnGas)));
+            expect(finalEthTokenBalance).to.be.bignumber.equal(initEthTokenBalance.plus(ethToDeposit));
+        });
+    });
+
+    describe('withdraw', () => {
+        it('should throw if caller attempts to withdraw greater than caller balance', async () => {
+            const initEthTokenBalance = await zeroEx.token.getBalanceAsync(etherTokenAddress, account);
+            const ethTokensToWithdraw = initEthTokenBalance.plus(1);
+
+            return expect(
+                zeroEx.etherToken.withdrawAsync(etherTokenAddress, ethTokensToWithdraw, account),
+            ).to.be.rejectedWith(ZeroExError.InsufficientWEthBalanceForWithdrawal);
+        });
+
+        it('should convert ether tokens to ether with sufficient balance', async () => {
+            const initEthTokenBalance = await zeroEx.token.getBalanceAsync(etherTokenAddress, account);
+            const initEthBalance = await getEthBalanceAsync(account);
+            const ethTokensToWithdraw = initEthTokenBalance;
+            expect(ethTokensToWithdraw).to.not.be.bignumber.equal(0);
+            const txHash = await zeroEx.etherToken.withdrawAsync(etherTokenAddress, ethTokensToWithdraw, account, {
+                gasLimit: constants.MAX_ETHERTOKEN_WITHDRAW_GAS,
+            });
+            const receipt = await zeroEx.awaitTransactionMinedAsync(txHash);
+
+            const ethSpentOnGas = gasPrice.times(receipt.gasUsed);
+            const finalEthBalance = await getEthBalanceAsync(account);
+            const finalEthTokenBalance = await zeroEx.token.getBalanceAsync(etherTokenAddress, account);
+
+            expect(finalEthBalance).to.be.bignumber.equal(
+                initEthBalance.plus(ethTokensToWithdraw.minus(ethSpentOnGas)),
+            );
+            expect(finalEthTokenBalance).to.be.bignumber.equal(initEthTokenBalance.minus(ethTokensToWithdraw));
+        });
+    });
+
+    describe('fallback', () => {
+        it('should convert sent ether to ether tokens', async () => {
+            const initEthBalance = await getEthBalanceAsync(account);
+            const initEthTokenBalance = await zeroEx.token.getBalanceAsync(etherTokenAddress, account);
+
+            const ethToDeposit = ZeroEx.toBaseUnitAmount(new BigNumber(1), 18);
+
+            const txHash = await sendTransactionAsync({
+                from: account,
+                to: etherTokenAddress,
+                value: ethToDeposit,
+                gasPrice,
+            });
+
+            const receipt = await zeroEx.awaitTransactionMinedAsync(txHash);
+
+            const ethSpentOnGas = gasPrice.times(receipt.gasUsed);
+            const finalEthBalance = await getEthBalanceAsync(account);
+            const finalEthTokenBalance = await zeroEx.token.getBalanceAsync(etherTokenAddress, account);
+
+            expect(finalEthBalance).to.be.bignumber.equal(initEthBalance.minus(ethToDeposit.plus(ethSpentOnGas)));
+            expect(finalEthTokenBalance).to.be.bignumber.equal(initEthTokenBalance.plus(ethToDeposit));
+        });
+    });
 });
diff --git a/packages/contracts/test/ts/exchange/core.ts b/packages/contracts/test/ts/exchange/core.ts
index 36078aaa9..770ef0c43 100644
--- a/packages/contracts/test/ts/exchange/core.ts
+++ b/packages/contracts/test/ts/exchange/core.ts
@@ -23,830 +23,830 @@ const { Exchange, TokenTransferProxy, DummyToken, TokenRegistry, MaliciousToken
 const web3: Web3 = (global as any).web3;
 
 contract('Exchange', (accounts: string[]) => {
-	const maker = accounts[0];
-	const tokenOwner = accounts[0];
-	const taker = accounts[1] || accounts[accounts.length - 1];
-	const feeRecipient = accounts[2] || accounts[accounts.length - 1];
-
-	const INITIAL_BALANCE = ZeroEx.toBaseUnitAmount(new BigNumber(10000), 18);
-	const INITIAL_ALLOWANCE = ZeroEx.toBaseUnitAmount(new BigNumber(10000), 18);
-
-	let rep: ContractInstance;
-	let dgd: ContractInstance;
-	let zrx: ContractInstance;
-	let exchange: ContractInstance;
-	let tokenRegistry: ContractInstance;
-
-	let order: Order;
-	let balances: BalancesByOwner;
-	let exWrapper: ExchangeWrapper;
-	let dmyBalances: Balances;
-	let orderFactory: OrderFactory;
-
-	let zeroEx: ZeroEx;
-
-	before(async () => {
-		[tokenRegistry, exchange] = await Promise.all([TokenRegistry.deployed(), Exchange.deployed()]);
-		exWrapper = new ExchangeWrapper(exchange);
-		zeroEx = new ZeroEx(web3.currentProvider, {
-			exchangeContractAddress: exchange.address,
-			networkId: constants.TESTRPC_NETWORK_ID,
-		});
-
-		const [repAddress, dgdAddress, zrxAddress] = await Promise.all([
-			tokenRegistry.getTokenAddressBySymbol('REP'),
-			tokenRegistry.getTokenAddressBySymbol('DGD'),
-			tokenRegistry.getTokenAddressBySymbol('ZRX'),
-		]);
-
-		const defaultOrderParams = {
-			exchangeContractAddress: Exchange.address,
-			maker,
-			feeRecipient,
-			makerToken: repAddress,
-			takerToken: dgdAddress,
-			makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
-			takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18),
-			makerFee: ZeroEx.toBaseUnitAmount(new BigNumber(1), 18),
-			takerFee: ZeroEx.toBaseUnitAmount(new BigNumber(1), 18),
-		};
-		orderFactory = new OrderFactory(defaultOrderParams);
-
-		[rep, dgd, zrx] = await Promise.all([
-			DummyToken.at(repAddress),
-			DummyToken.at(dgdAddress),
-			DummyToken.at(zrxAddress),
-		]);
-		dmyBalances = new Balances([rep, dgd, zrx], [maker, taker, feeRecipient]);
-		await Promise.all([
-			rep.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
-				from: maker,
-			}),
-			rep.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
-				from: taker,
-			}),
-			rep.setBalance(maker, INITIAL_BALANCE, { from: tokenOwner }),
-			rep.setBalance(taker, INITIAL_BALANCE, { from: tokenOwner }),
-			dgd.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
-				from: maker,
-			}),
-			dgd.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
-				from: taker,
-			}),
-			dgd.setBalance(maker, INITIAL_BALANCE, { from: tokenOwner }),
-			dgd.setBalance(taker, INITIAL_BALANCE, { from: tokenOwner }),
-			zrx.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
-				from: maker,
-			}),
-			zrx.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
-				from: taker,
-			}),
-			zrx.setBalance(maker, INITIAL_BALANCE, { from: tokenOwner }),
-			zrx.setBalance(taker, INITIAL_BALANCE, { from: tokenOwner }),
-		]);
-	});
-
-	describe('internal functions', () => {
-		it('should include transferViaTokenTransferProxy', () => {
-			expect(exchange.transferViaTokenTransferProxy).to.be.undefined();
-		});
-
-		it('should include isTransferable', () => {
-			expect(exchange.isTransferable).to.be.undefined();
-		});
-
-		it('should include getBalance', () => {
-			expect(exchange.getBalance).to.be.undefined();
-		});
-
-		it('should include getAllowance', () => {
-			expect(exchange.getAllowance).to.be.undefined();
-		});
-	});
-
-	describe('fillOrder', () => {
-		beforeEach(async () => {
-			balances = await dmyBalances.getAsync();
-			order = await orderFactory.newSignedOrderAsync();
-		});
-
-		it('should create an unfillable order', async () => {
-			order = await orderFactory.newSignedOrderAsync({
-				makerTokenAmount: new BigNumber(1001),
-				takerTokenAmount: new BigNumber(3),
-			});
-
-			const filledTakerTokenAmountBefore = await zeroEx.exchange.getFilledTakerAmountAsync(
-				order.params.orderHashHex,
-			);
-			expect(filledTakerTokenAmountBefore).to.be.bignumber.equal(0);
-
-			const fillTakerTokenAmount1 = new BigNumber(2);
-			await exWrapper.fillOrderAsync(order, taker, {
-				fillTakerTokenAmount: fillTakerTokenAmount1,
-			});
-
-			const filledTakerTokenAmountAfter1 = await zeroEx.exchange.getFilledTakerAmountAsync(
-				order.params.orderHashHex,
-			);
-			expect(filledTakerTokenAmountAfter1).to.be.bignumber.equal(fillTakerTokenAmount1);
-
-			const fillTakerTokenAmount2 = new BigNumber(1);
-			await exWrapper.fillOrderAsync(order, taker, {
-				fillTakerTokenAmount: fillTakerTokenAmount2,
-			});
-
-			const filledTakerTokenAmountAfter2 = await zeroEx.exchange.getFilledTakerAmountAsync(
-				order.params.orderHashHex,
-			);
-			expect(filledTakerTokenAmountAfter2).to.be.bignumber.equal(filledTakerTokenAmountAfter1);
-		});
-
-		it('should transfer the correct amounts when makerTokenAmount === takerTokenAmount', async () => {
-			order = await orderFactory.newSignedOrderAsync({
-				makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
-				takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
-			});
-
-			const filledTakerTokenAmountBefore = await zeroEx.exchange.getFilledTakerAmountAsync(
-				order.params.orderHashHex,
-			);
-			expect(filledTakerTokenAmountBefore).to.be.bignumber.equal(0);
-
-			const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
-			await exWrapper.fillOrderAsync(order, taker, { fillTakerTokenAmount });
-
-			const filledTakerTokenAmountAfter = await zeroEx.exchange.getFilledTakerAmountAsync(
-				order.params.orderHashHex,
-			);
-			expect(filledTakerTokenAmountAfter).to.be.bignumber.equal(fillTakerTokenAmount);
-
-			const newBalances = await dmyBalances.getAsync();
-
-			const fillMakerTokenAmount = fillTakerTokenAmount
-				.times(order.params.makerTokenAmount)
-				.dividedToIntegerBy(order.params.takerTokenAmount);
-			const paidMakerFee = order.params.makerFee
-				.times(fillMakerTokenAmount)
-				.dividedToIntegerBy(order.params.makerTokenAmount);
-			const paidTakerFee = order.params.takerFee
-				.times(fillMakerTokenAmount)
-				.dividedToIntegerBy(order.params.makerTokenAmount);
-			expect(newBalances[maker][order.params.makerToken]).to.be.bignumber.equal(
-				balances[maker][order.params.makerToken].minus(fillMakerTokenAmount),
-			);
-			expect(newBalances[maker][order.params.takerToken]).to.be.bignumber.equal(
-				balances[maker][order.params.takerToken].add(fillTakerTokenAmount),
-			);
-			expect(newBalances[maker][zrx.address]).to.be.bignumber.equal(
-				balances[maker][zrx.address].minus(paidMakerFee),
-			);
-			expect(newBalances[taker][order.params.takerToken]).to.be.bignumber.equal(
-				balances[taker][order.params.takerToken].minus(fillTakerTokenAmount),
-			);
-			expect(newBalances[taker][order.params.makerToken]).to.be.bignumber.equal(
-				balances[taker][order.params.makerToken].add(fillMakerTokenAmount),
-			);
-			expect(newBalances[taker][zrx.address]).to.be.bignumber.equal(
-				balances[taker][zrx.address].minus(paidTakerFee),
-			);
-			expect(newBalances[feeRecipient][zrx.address]).to.be.bignumber.equal(
-				balances[feeRecipient][zrx.address].add(paidMakerFee.add(paidTakerFee)),
-			);
-		});
-
-		it('should transfer the correct amounts when makerTokenAmount > takerTokenAmount', async () => {
-			order = await orderFactory.newSignedOrderAsync({
-				makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18),
-				takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
-			});
-
-			const filledTakerTokenAmountBefore = await zeroEx.exchange.getFilledTakerAmountAsync(
-				order.params.orderHashHex,
-			);
-			expect(filledTakerTokenAmountBefore).to.be.bignumber.equal(0);
-
-			const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
-			await exWrapper.fillOrderAsync(order, taker, { fillTakerTokenAmount });
-
-			const filledTakerTokenAmountAfter = await zeroEx.exchange.getFilledTakerAmountAsync(
-				order.params.orderHashHex,
-			);
-			expect(filledTakerTokenAmountAfter).to.be.bignumber.equal(fillTakerTokenAmount);
-
-			const newBalances = await dmyBalances.getAsync();
-
-			const fillMakerTokenAmount = fillTakerTokenAmount
-				.times(order.params.makerTokenAmount)
-				.dividedToIntegerBy(order.params.takerTokenAmount);
-			const paidMakerFee = order.params.makerFee
-				.times(fillMakerTokenAmount)
-				.dividedToIntegerBy(order.params.makerTokenAmount);
-			const paidTakerFee = order.params.takerFee
-				.times(fillMakerTokenAmount)
-				.dividedToIntegerBy(order.params.makerTokenAmount);
-			expect(newBalances[maker][order.params.makerToken]).to.be.bignumber.equal(
-				balances[maker][order.params.makerToken].minus(fillMakerTokenAmount),
-			);
-			expect(newBalances[maker][order.params.takerToken]).to.be.bignumber.equal(
-				balances[maker][order.params.takerToken].add(fillTakerTokenAmount),
-			);
-			expect(newBalances[maker][zrx.address]).to.be.bignumber.equal(
-				balances[maker][zrx.address].minus(paidMakerFee),
-			);
-			expect(newBalances[taker][order.params.takerToken]).to.be.bignumber.equal(
-				balances[taker][order.params.takerToken].minus(fillTakerTokenAmount),
-			);
-			expect(newBalances[taker][order.params.makerToken]).to.be.bignumber.equal(
-				balances[taker][order.params.makerToken].add(fillMakerTokenAmount),
-			);
-			expect(newBalances[taker][zrx.address]).to.be.bignumber.equal(
-				balances[taker][zrx.address].minus(paidTakerFee),
-			);
-			expect(newBalances[feeRecipient][zrx.address]).to.be.bignumber.equal(
-				balances[feeRecipient][zrx.address].add(paidMakerFee.add(paidTakerFee)),
-			);
-		});
-
-		it('should transfer the correct amounts when makerTokenAmount < takerTokenAmount', async () => {
-			order = await orderFactory.newSignedOrderAsync({
-				makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
-				takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18),
-			});
-
-			const filledTakerTokenAmountBefore = await zeroEx.exchange.getFilledTakerAmountAsync(
-				order.params.orderHashHex,
-			);
-			expect(filledTakerTokenAmountBefore).to.be.bignumber.equal(0);
-
-			const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
-			await exWrapper.fillOrderAsync(order, taker, { fillTakerTokenAmount });
-
-			const filledTakerTokenAmountAfter = await zeroEx.exchange.getFilledTakerAmountAsync(
-				order.params.orderHashHex,
-			);
-			expect(filledTakerTokenAmountAfter).to.be.bignumber.equal(fillTakerTokenAmount);
-
-			const newBalances = await dmyBalances.getAsync();
-
-			const fillMakerTokenAmount = fillTakerTokenAmount
-				.times(order.params.makerTokenAmount)
-				.dividedToIntegerBy(order.params.takerTokenAmount);
-			const paidMakerFee = order.params.makerFee
-				.times(fillMakerTokenAmount)
-				.dividedToIntegerBy(order.params.makerTokenAmount);
-			const paidTakerFee = order.params.takerFee
-				.times(fillMakerTokenAmount)
-				.dividedToIntegerBy(order.params.makerTokenAmount);
-			expect(newBalances[maker][order.params.makerToken]).to.be.bignumber.equal(
-				balances[maker][order.params.makerToken].minus(fillMakerTokenAmount),
-			);
-			expect(newBalances[maker][order.params.takerToken]).to.be.bignumber.equal(
-				balances[maker][order.params.takerToken].add(fillTakerTokenAmount),
-			);
-			expect(newBalances[maker][zrx.address]).to.be.bignumber.equal(
-				balances[maker][zrx.address].minus(paidMakerFee),
-			);
-			expect(newBalances[taker][order.params.takerToken]).to.be.bignumber.equal(
-				balances[taker][order.params.takerToken].minus(fillTakerTokenAmount),
-			);
-			expect(newBalances[taker][order.params.makerToken]).to.be.bignumber.equal(
-				balances[taker][order.params.makerToken].add(fillMakerTokenAmount),
-			);
-			expect(newBalances[taker][zrx.address]).to.be.bignumber.equal(
-				balances[taker][zrx.address].minus(paidTakerFee),
-			);
-			expect(newBalances[feeRecipient][zrx.address]).to.be.bignumber.equal(
-				balances[feeRecipient][zrx.address].add(paidMakerFee.add(paidTakerFee)),
-			);
-		});
-
-		it('should transfer the correct amounts when taker is specified and order is claimed by taker', async () => {
-			order = await orderFactory.newSignedOrderAsync({
-				taker,
-				makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
-				takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18),
-			});
-
-			const filledTakerTokenAmountBefore = await zeroEx.exchange.getFilledTakerAmountAsync(
-				order.params.orderHashHex,
-			);
-			expect(filledTakerTokenAmountBefore).to.be.bignumber.equal(0);
-
-			const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
-			await exWrapper.fillOrderAsync(order, taker, { fillTakerTokenAmount });
-
-			const filledTakerTokenAmountAfter = await zeroEx.exchange.getFilledTakerAmountAsync(
-				order.params.orderHashHex,
-			);
-			const expectedFillAmountTAfter = fillTakerTokenAmount.add(filledTakerTokenAmountBefore);
-			expect(filledTakerTokenAmountAfter).to.be.bignumber.equal(expectedFillAmountTAfter);
-
-			const newBalances = await dmyBalances.getAsync();
-
-			const fillMakerTokenAmount = fillTakerTokenAmount
-				.times(order.params.makerTokenAmount)
-				.dividedToIntegerBy(order.params.takerTokenAmount);
-			const paidMakerFee = order.params.makerFee
-				.times(fillMakerTokenAmount)
-				.dividedToIntegerBy(order.params.makerTokenAmount);
-			const paidTakerFee = order.params.takerFee
-				.times(fillMakerTokenAmount)
-				.dividedToIntegerBy(order.params.makerTokenAmount);
-			expect(newBalances[maker][order.params.makerToken]).to.be.bignumber.equal(
-				balances[maker][order.params.makerToken].minus(fillMakerTokenAmount),
-			);
-			expect(newBalances[maker][order.params.takerToken]).to.be.bignumber.equal(
-				balances[maker][order.params.takerToken].add(fillTakerTokenAmount),
-			);
-			expect(newBalances[maker][zrx.address]).to.be.bignumber.equal(
-				balances[maker][zrx.address].minus(paidMakerFee),
-			);
-			expect(newBalances[taker][order.params.takerToken]).to.be.bignumber.equal(
-				balances[taker][order.params.takerToken].minus(fillTakerTokenAmount),
-			);
-			expect(newBalances[taker][order.params.makerToken]).to.be.bignumber.equal(
-				balances[taker][order.params.makerToken].add(fillMakerTokenAmount),
-			);
-			expect(newBalances[taker][zrx.address]).to.be.bignumber.equal(
-				balances[taker][zrx.address].minus(paidTakerFee),
-			);
-			expect(newBalances[feeRecipient][zrx.address]).to.be.bignumber.equal(
-				balances[feeRecipient][zrx.address].add(paidMakerFee.add(paidTakerFee)),
-			);
-		});
-
-		it('should fill remaining value if fillTakerTokenAmount > remaining takerTokenAmount', async () => {
-			const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
-			await exWrapper.fillOrderAsync(order, taker, { fillTakerTokenAmount });
-
-			const res = await exWrapper.fillOrderAsync(order, taker, {
-				fillTakerTokenAmount: order.params.takerTokenAmount,
-			});
-
-			expect(res.logs[0].args.filledTakerTokenAmount).to.be.bignumber.equal(
-				order.params.takerTokenAmount.minus(fillTakerTokenAmount),
-			);
-			const newBalances = await dmyBalances.getAsync();
-
-			expect(newBalances[maker][order.params.makerToken]).to.be.bignumber.equal(
-				balances[maker][order.params.makerToken].minus(order.params.makerTokenAmount),
-			);
-			expect(newBalances[maker][order.params.takerToken]).to.be.bignumber.equal(
-				balances[maker][order.params.takerToken].add(order.params.takerTokenAmount),
-			);
-			expect(newBalances[maker][zrx.address]).to.be.bignumber.equal(
-				balances[maker][zrx.address].minus(order.params.makerFee),
-			);
-			expect(newBalances[taker][order.params.takerToken]).to.be.bignumber.equal(
-				balances[taker][order.params.takerToken].minus(order.params.takerTokenAmount),
-			);
-			expect(newBalances[taker][order.params.makerToken]).to.be.bignumber.equal(
-				balances[taker][order.params.makerToken].add(order.params.makerTokenAmount),
-			);
-			expect(newBalances[taker][zrx.address]).to.be.bignumber.equal(
-				balances[taker][zrx.address].minus(order.params.takerFee),
-			);
-			expect(newBalances[feeRecipient][zrx.address]).to.be.bignumber.equal(
-				balances[feeRecipient][zrx.address].add(order.params.makerFee.add(order.params.takerFee)),
-			);
-		});
-
-		it('should log 1 event with the correct arguments when order has a feeRecipient', async () => {
-			const divisor = 2;
-			const res = await exWrapper.fillOrderAsync(order, taker, {
-				fillTakerTokenAmount: order.params.takerTokenAmount.div(divisor),
-			});
-			expect(res.logs).to.have.length(1);
-
-			const logArgs = res.logs[0].args;
-			const expectedFilledMakerTokenAmount = order.params.makerTokenAmount.div(divisor);
-			const expectedFilledTakerTokenAmount = order.params.takerTokenAmount.div(divisor);
-			const expectedFeeMPaid = order.params.makerFee.div(divisor);
-			const expectedFeeTPaid = order.params.takerFee.div(divisor);
-			const tokensHashBuff = crypto.solSHA3([order.params.makerToken, order.params.takerToken]);
-			const expectedTokens = ethUtil.bufferToHex(tokensHashBuff);
-
-			expect(order.params.maker).to.be.equal(logArgs.maker);
-			expect(taker).to.be.equal(logArgs.taker);
-			expect(order.params.feeRecipient).to.be.equal(logArgs.feeRecipient);
-			expect(order.params.makerToken).to.be.equal(logArgs.makerToken);
-			expect(order.params.takerToken).to.be.equal(logArgs.takerToken);
-			expect(expectedFilledMakerTokenAmount).to.be.bignumber.equal(logArgs.filledMakerTokenAmount);
-			expect(expectedFilledTakerTokenAmount).to.be.bignumber.equal(logArgs.filledTakerTokenAmount);
-			expect(expectedFeeMPaid).to.be.bignumber.equal(logArgs.paidMakerFee);
-			expect(expectedFeeTPaid).to.be.bignumber.equal(logArgs.paidTakerFee);
-			expect(expectedTokens).to.be.equal(logArgs.tokens);
-			expect(order.params.orderHashHex).to.be.equal(logArgs.orderHash);
-		});
-
-		it('should log 1 event with the correct arguments when order has no feeRecipient', async () => {
-			order = await orderFactory.newSignedOrderAsync({
-				feeRecipient: ZeroEx.NULL_ADDRESS,
-			});
-			const divisor = 2;
-			const res = await exWrapper.fillOrderAsync(order, taker, {
-				fillTakerTokenAmount: order.params.takerTokenAmount.div(divisor),
-			});
-			expect(res.logs).to.have.length(1);
-
-			const logArgs = res.logs[0].args;
-			const expectedFilledMakerTokenAmount = order.params.makerTokenAmount.div(divisor);
-			const expectedFilledTakerTokenAmount = order.params.takerTokenAmount.div(divisor);
-			const expectedFeeMPaid = new BigNumber(0);
-			const expectedFeeTPaid = new BigNumber(0);
-			const tokensHashBuff = crypto.solSHA3([order.params.makerToken, order.params.takerToken]);
-			const expectedTokens = ethUtil.bufferToHex(tokensHashBuff);
-
-			expect(order.params.maker).to.be.equal(logArgs.maker);
-			expect(taker).to.be.equal(logArgs.taker);
-			expect(order.params.feeRecipient).to.be.equal(logArgs.feeRecipient);
-			expect(order.params.makerToken).to.be.equal(logArgs.makerToken);
-			expect(order.params.takerToken).to.be.equal(logArgs.takerToken);
-			expect(expectedFilledMakerTokenAmount).to.be.bignumber.equal(logArgs.filledMakerTokenAmount);
-			expect(expectedFilledTakerTokenAmount).to.be.bignumber.equal(logArgs.filledTakerTokenAmount);
-			expect(expectedFeeMPaid).to.be.bignumber.equal(logArgs.paidMakerFee);
-			expect(expectedFeeTPaid).to.be.bignumber.equal(logArgs.paidTakerFee);
-			expect(expectedTokens).to.be.equal(logArgs.tokens);
-			expect(order.params.orderHashHex).to.be.equal(logArgs.orderHash);
-		});
-
-		it('should throw when taker is specified and order is claimed by other', async () => {
-			order = await orderFactory.newSignedOrderAsync({
-				taker: feeRecipient,
-				makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
-				takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18),
-			});
-
-			return expect(exWrapper.fillOrderAsync(order, taker)).to.be.rejectedWith(constants.REVERT);
-		});
-
-		it('should throw if signature is invalid', async () => {
-			order = await orderFactory.newSignedOrderAsync({
-				makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(10), 18),
-			});
-
-			order.params.r = ethUtil.bufferToHex(ethUtil.sha3('invalidR'));
-			order.params.s = ethUtil.bufferToHex(ethUtil.sha3('invalidS'));
-			return expect(exWrapper.fillOrderAsync(order, taker)).to.be.rejectedWith(constants.REVERT);
-		});
-
-		it('should throw if makerTokenAmount is 0', async () => {
-			order = await orderFactory.newSignedOrderAsync({
-				makerTokenAmount: new BigNumber(0),
-			});
-
-			return expect(exWrapper.fillOrderAsync(order, taker)).to.be.rejectedWith(constants.REVERT);
-		});
-
-		it('should throw if takerTokenAmount is 0', async () => {
-			order = await orderFactory.newSignedOrderAsync({
-				takerTokenAmount: new BigNumber(0),
-			});
-
-			return expect(exWrapper.fillOrderAsync(order, taker)).to.be.rejectedWith(constants.REVERT);
-		});
-
-		it('should throw if fillTakerTokenAmount is 0', async () => {
-			order = await orderFactory.newSignedOrderAsync();
-
-			return expect(
-				exWrapper.fillOrderAsync(order, taker, {
-					fillTakerTokenAmount: new BigNumber(0),
-				}),
-			).to.be.rejectedWith(constants.REVERT);
-		});
-
-		it('should not change balances if maker balances are too low to fill order and \
+    const maker = accounts[0];
+    const tokenOwner = accounts[0];
+    const taker = accounts[1] || accounts[accounts.length - 1];
+    const feeRecipient = accounts[2] || accounts[accounts.length - 1];
+
+    const INITIAL_BALANCE = ZeroEx.toBaseUnitAmount(new BigNumber(10000), 18);
+    const INITIAL_ALLOWANCE = ZeroEx.toBaseUnitAmount(new BigNumber(10000), 18);
+
+    let rep: ContractInstance;
+    let dgd: ContractInstance;
+    let zrx: ContractInstance;
+    let exchange: ContractInstance;
+    let tokenRegistry: ContractInstance;
+
+    let order: Order;
+    let balances: BalancesByOwner;
+    let exWrapper: ExchangeWrapper;
+    let dmyBalances: Balances;
+    let orderFactory: OrderFactory;
+
+    let zeroEx: ZeroEx;
+
+    before(async () => {
+        [tokenRegistry, exchange] = await Promise.all([TokenRegistry.deployed(), Exchange.deployed()]);
+        exWrapper = new ExchangeWrapper(exchange);
+        zeroEx = new ZeroEx(web3.currentProvider, {
+            exchangeContractAddress: exchange.address,
+            networkId: constants.TESTRPC_NETWORK_ID,
+        });
+
+        const [repAddress, dgdAddress, zrxAddress] = await Promise.all([
+            tokenRegistry.getTokenAddressBySymbol('REP'),
+            tokenRegistry.getTokenAddressBySymbol('DGD'),
+            tokenRegistry.getTokenAddressBySymbol('ZRX'),
+        ]);
+
+        const defaultOrderParams = {
+            exchangeContractAddress: Exchange.address,
+            maker,
+            feeRecipient,
+            makerToken: repAddress,
+            takerToken: dgdAddress,
+            makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
+            takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18),
+            makerFee: ZeroEx.toBaseUnitAmount(new BigNumber(1), 18),
+            takerFee: ZeroEx.toBaseUnitAmount(new BigNumber(1), 18),
+        };
+        orderFactory = new OrderFactory(defaultOrderParams);
+
+        [rep, dgd, zrx] = await Promise.all([
+            DummyToken.at(repAddress),
+            DummyToken.at(dgdAddress),
+            DummyToken.at(zrxAddress),
+        ]);
+        dmyBalances = new Balances([rep, dgd, zrx], [maker, taker, feeRecipient]);
+        await Promise.all([
+            rep.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
+                from: maker,
+            }),
+            rep.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
+                from: taker,
+            }),
+            rep.setBalance(maker, INITIAL_BALANCE, { from: tokenOwner }),
+            rep.setBalance(taker, INITIAL_BALANCE, { from: tokenOwner }),
+            dgd.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
+                from: maker,
+            }),
+            dgd.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
+                from: taker,
+            }),
+            dgd.setBalance(maker, INITIAL_BALANCE, { from: tokenOwner }),
+            dgd.setBalance(taker, INITIAL_BALANCE, { from: tokenOwner }),
+            zrx.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
+                from: maker,
+            }),
+            zrx.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
+                from: taker,
+            }),
+            zrx.setBalance(maker, INITIAL_BALANCE, { from: tokenOwner }),
+            zrx.setBalance(taker, INITIAL_BALANCE, { from: tokenOwner }),
+        ]);
+    });
+
+    describe('internal functions', () => {
+        it('should include transferViaTokenTransferProxy', () => {
+            expect(exchange.transferViaTokenTransferProxy).to.be.undefined();
+        });
+
+        it('should include isTransferable', () => {
+            expect(exchange.isTransferable).to.be.undefined();
+        });
+
+        it('should include getBalance', () => {
+            expect(exchange.getBalance).to.be.undefined();
+        });
+
+        it('should include getAllowance', () => {
+            expect(exchange.getAllowance).to.be.undefined();
+        });
+    });
+
+    describe('fillOrder', () => {
+        beforeEach(async () => {
+            balances = await dmyBalances.getAsync();
+            order = await orderFactory.newSignedOrderAsync();
+        });
+
+        it('should create an unfillable order', async () => {
+            order = await orderFactory.newSignedOrderAsync({
+                makerTokenAmount: new BigNumber(1001),
+                takerTokenAmount: new BigNumber(3),
+            });
+
+            const filledTakerTokenAmountBefore = await zeroEx.exchange.getFilledTakerAmountAsync(
+                order.params.orderHashHex,
+            );
+            expect(filledTakerTokenAmountBefore).to.be.bignumber.equal(0);
+
+            const fillTakerTokenAmount1 = new BigNumber(2);
+            await exWrapper.fillOrderAsync(order, taker, {
+                fillTakerTokenAmount: fillTakerTokenAmount1,
+            });
+
+            const filledTakerTokenAmountAfter1 = await zeroEx.exchange.getFilledTakerAmountAsync(
+                order.params.orderHashHex,
+            );
+            expect(filledTakerTokenAmountAfter1).to.be.bignumber.equal(fillTakerTokenAmount1);
+
+            const fillTakerTokenAmount2 = new BigNumber(1);
+            await exWrapper.fillOrderAsync(order, taker, {
+                fillTakerTokenAmount: fillTakerTokenAmount2,
+            });
+
+            const filledTakerTokenAmountAfter2 = await zeroEx.exchange.getFilledTakerAmountAsync(
+                order.params.orderHashHex,
+            );
+            expect(filledTakerTokenAmountAfter2).to.be.bignumber.equal(filledTakerTokenAmountAfter1);
+        });
+
+        it('should transfer the correct amounts when makerTokenAmount === takerTokenAmount', async () => {
+            order = await orderFactory.newSignedOrderAsync({
+                makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
+                takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
+            });
+
+            const filledTakerTokenAmountBefore = await zeroEx.exchange.getFilledTakerAmountAsync(
+                order.params.orderHashHex,
+            );
+            expect(filledTakerTokenAmountBefore).to.be.bignumber.equal(0);
+
+            const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
+            await exWrapper.fillOrderAsync(order, taker, { fillTakerTokenAmount });
+
+            const filledTakerTokenAmountAfter = await zeroEx.exchange.getFilledTakerAmountAsync(
+                order.params.orderHashHex,
+            );
+            expect(filledTakerTokenAmountAfter).to.be.bignumber.equal(fillTakerTokenAmount);
+
+            const newBalances = await dmyBalances.getAsync();
+
+            const fillMakerTokenAmount = fillTakerTokenAmount
+                .times(order.params.makerTokenAmount)
+                .dividedToIntegerBy(order.params.takerTokenAmount);
+            const paidMakerFee = order.params.makerFee
+                .times(fillMakerTokenAmount)
+                .dividedToIntegerBy(order.params.makerTokenAmount);
+            const paidTakerFee = order.params.takerFee
+                .times(fillMakerTokenAmount)
+                .dividedToIntegerBy(order.params.makerTokenAmount);
+            expect(newBalances[maker][order.params.makerToken]).to.be.bignumber.equal(
+                balances[maker][order.params.makerToken].minus(fillMakerTokenAmount),
+            );
+            expect(newBalances[maker][order.params.takerToken]).to.be.bignumber.equal(
+                balances[maker][order.params.takerToken].add(fillTakerTokenAmount),
+            );
+            expect(newBalances[maker][zrx.address]).to.be.bignumber.equal(
+                balances[maker][zrx.address].minus(paidMakerFee),
+            );
+            expect(newBalances[taker][order.params.takerToken]).to.be.bignumber.equal(
+                balances[taker][order.params.takerToken].minus(fillTakerTokenAmount),
+            );
+            expect(newBalances[taker][order.params.makerToken]).to.be.bignumber.equal(
+                balances[taker][order.params.makerToken].add(fillMakerTokenAmount),
+            );
+            expect(newBalances[taker][zrx.address]).to.be.bignumber.equal(
+                balances[taker][zrx.address].minus(paidTakerFee),
+            );
+            expect(newBalances[feeRecipient][zrx.address]).to.be.bignumber.equal(
+                balances[feeRecipient][zrx.address].add(paidMakerFee.add(paidTakerFee)),
+            );
+        });
+
+        it('should transfer the correct amounts when makerTokenAmount > takerTokenAmount', async () => {
+            order = await orderFactory.newSignedOrderAsync({
+                makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18),
+                takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
+            });
+
+            const filledTakerTokenAmountBefore = await zeroEx.exchange.getFilledTakerAmountAsync(
+                order.params.orderHashHex,
+            );
+            expect(filledTakerTokenAmountBefore).to.be.bignumber.equal(0);
+
+            const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
+            await exWrapper.fillOrderAsync(order, taker, { fillTakerTokenAmount });
+
+            const filledTakerTokenAmountAfter = await zeroEx.exchange.getFilledTakerAmountAsync(
+                order.params.orderHashHex,
+            );
+            expect(filledTakerTokenAmountAfter).to.be.bignumber.equal(fillTakerTokenAmount);
+
+            const newBalances = await dmyBalances.getAsync();
+
+            const fillMakerTokenAmount = fillTakerTokenAmount
+                .times(order.params.makerTokenAmount)
+                .dividedToIntegerBy(order.params.takerTokenAmount);
+            const paidMakerFee = order.params.makerFee
+                .times(fillMakerTokenAmount)
+                .dividedToIntegerBy(order.params.makerTokenAmount);
+            const paidTakerFee = order.params.takerFee
+                .times(fillMakerTokenAmount)
+                .dividedToIntegerBy(order.params.makerTokenAmount);
+            expect(newBalances[maker][order.params.makerToken]).to.be.bignumber.equal(
+                balances[maker][order.params.makerToken].minus(fillMakerTokenAmount),
+            );
+            expect(newBalances[maker][order.params.takerToken]).to.be.bignumber.equal(
+                balances[maker][order.params.takerToken].add(fillTakerTokenAmount),
+            );
+            expect(newBalances[maker][zrx.address]).to.be.bignumber.equal(
+                balances[maker][zrx.address].minus(paidMakerFee),
+            );
+            expect(newBalances[taker][order.params.takerToken]).to.be.bignumber.equal(
+                balances[taker][order.params.takerToken].minus(fillTakerTokenAmount),
+            );
+            expect(newBalances[taker][order.params.makerToken]).to.be.bignumber.equal(
+                balances[taker][order.params.makerToken].add(fillMakerTokenAmount),
+            );
+            expect(newBalances[taker][zrx.address]).to.be.bignumber.equal(
+                balances[taker][zrx.address].minus(paidTakerFee),
+            );
+            expect(newBalances[feeRecipient][zrx.address]).to.be.bignumber.equal(
+                balances[feeRecipient][zrx.address].add(paidMakerFee.add(paidTakerFee)),
+            );
+        });
+
+        it('should transfer the correct amounts when makerTokenAmount < takerTokenAmount', async () => {
+            order = await orderFactory.newSignedOrderAsync({
+                makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
+                takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18),
+            });
+
+            const filledTakerTokenAmountBefore = await zeroEx.exchange.getFilledTakerAmountAsync(
+                order.params.orderHashHex,
+            );
+            expect(filledTakerTokenAmountBefore).to.be.bignumber.equal(0);
+
+            const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
+            await exWrapper.fillOrderAsync(order, taker, { fillTakerTokenAmount });
+
+            const filledTakerTokenAmountAfter = await zeroEx.exchange.getFilledTakerAmountAsync(
+                order.params.orderHashHex,
+            );
+            expect(filledTakerTokenAmountAfter).to.be.bignumber.equal(fillTakerTokenAmount);
+
+            const newBalances = await dmyBalances.getAsync();
+
+            const fillMakerTokenAmount = fillTakerTokenAmount
+                .times(order.params.makerTokenAmount)
+                .dividedToIntegerBy(order.params.takerTokenAmount);
+            const paidMakerFee = order.params.makerFee
+                .times(fillMakerTokenAmount)
+                .dividedToIntegerBy(order.params.makerTokenAmount);
+            const paidTakerFee = order.params.takerFee
+                .times(fillMakerTokenAmount)
+                .dividedToIntegerBy(order.params.makerTokenAmount);
+            expect(newBalances[maker][order.params.makerToken]).to.be.bignumber.equal(
+                balances[maker][order.params.makerToken].minus(fillMakerTokenAmount),
+            );
+            expect(newBalances[maker][order.params.takerToken]).to.be.bignumber.equal(
+                balances[maker][order.params.takerToken].add(fillTakerTokenAmount),
+            );
+            expect(newBalances[maker][zrx.address]).to.be.bignumber.equal(
+                balances[maker][zrx.address].minus(paidMakerFee),
+            );
+            expect(newBalances[taker][order.params.takerToken]).to.be.bignumber.equal(
+                balances[taker][order.params.takerToken].minus(fillTakerTokenAmount),
+            );
+            expect(newBalances[taker][order.params.makerToken]).to.be.bignumber.equal(
+                balances[taker][order.params.makerToken].add(fillMakerTokenAmount),
+            );
+            expect(newBalances[taker][zrx.address]).to.be.bignumber.equal(
+                balances[taker][zrx.address].minus(paidTakerFee),
+            );
+            expect(newBalances[feeRecipient][zrx.address]).to.be.bignumber.equal(
+                balances[feeRecipient][zrx.address].add(paidMakerFee.add(paidTakerFee)),
+            );
+        });
+
+        it('should transfer the correct amounts when taker is specified and order is claimed by taker', async () => {
+            order = await orderFactory.newSignedOrderAsync({
+                taker,
+                makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
+                takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18),
+            });
+
+            const filledTakerTokenAmountBefore = await zeroEx.exchange.getFilledTakerAmountAsync(
+                order.params.orderHashHex,
+            );
+            expect(filledTakerTokenAmountBefore).to.be.bignumber.equal(0);
+
+            const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
+            await exWrapper.fillOrderAsync(order, taker, { fillTakerTokenAmount });
+
+            const filledTakerTokenAmountAfter = await zeroEx.exchange.getFilledTakerAmountAsync(
+                order.params.orderHashHex,
+            );
+            const expectedFillAmountTAfter = fillTakerTokenAmount.add(filledTakerTokenAmountBefore);
+            expect(filledTakerTokenAmountAfter).to.be.bignumber.equal(expectedFillAmountTAfter);
+
+            const newBalances = await dmyBalances.getAsync();
+
+            const fillMakerTokenAmount = fillTakerTokenAmount
+                .times(order.params.makerTokenAmount)
+                .dividedToIntegerBy(order.params.takerTokenAmount);
+            const paidMakerFee = order.params.makerFee
+                .times(fillMakerTokenAmount)
+                .dividedToIntegerBy(order.params.makerTokenAmount);
+            const paidTakerFee = order.params.takerFee
+                .times(fillMakerTokenAmount)
+                .dividedToIntegerBy(order.params.makerTokenAmount);
+            expect(newBalances[maker][order.params.makerToken]).to.be.bignumber.equal(
+                balances[maker][order.params.makerToken].minus(fillMakerTokenAmount),
+            );
+            expect(newBalances[maker][order.params.takerToken]).to.be.bignumber.equal(
+                balances[maker][order.params.takerToken].add(fillTakerTokenAmount),
+            );
+            expect(newBalances[maker][zrx.address]).to.be.bignumber.equal(
+                balances[maker][zrx.address].minus(paidMakerFee),
+            );
+            expect(newBalances[taker][order.params.takerToken]).to.be.bignumber.equal(
+                balances[taker][order.params.takerToken].minus(fillTakerTokenAmount),
+            );
+            expect(newBalances[taker][order.params.makerToken]).to.be.bignumber.equal(
+                balances[taker][order.params.makerToken].add(fillMakerTokenAmount),
+            );
+            expect(newBalances[taker][zrx.address]).to.be.bignumber.equal(
+                balances[taker][zrx.address].minus(paidTakerFee),
+            );
+            expect(newBalances[feeRecipient][zrx.address]).to.be.bignumber.equal(
+                balances[feeRecipient][zrx.address].add(paidMakerFee.add(paidTakerFee)),
+            );
+        });
+
+        it('should fill remaining value if fillTakerTokenAmount > remaining takerTokenAmount', async () => {
+            const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
+            await exWrapper.fillOrderAsync(order, taker, { fillTakerTokenAmount });
+
+            const res = await exWrapper.fillOrderAsync(order, taker, {
+                fillTakerTokenAmount: order.params.takerTokenAmount,
+            });
+
+            expect(res.logs[0].args.filledTakerTokenAmount).to.be.bignumber.equal(
+                order.params.takerTokenAmount.minus(fillTakerTokenAmount),
+            );
+            const newBalances = await dmyBalances.getAsync();
+
+            expect(newBalances[maker][order.params.makerToken]).to.be.bignumber.equal(
+                balances[maker][order.params.makerToken].minus(order.params.makerTokenAmount),
+            );
+            expect(newBalances[maker][order.params.takerToken]).to.be.bignumber.equal(
+                balances[maker][order.params.takerToken].add(order.params.takerTokenAmount),
+            );
+            expect(newBalances[maker][zrx.address]).to.be.bignumber.equal(
+                balances[maker][zrx.address].minus(order.params.makerFee),
+            );
+            expect(newBalances[taker][order.params.takerToken]).to.be.bignumber.equal(
+                balances[taker][order.params.takerToken].minus(order.params.takerTokenAmount),
+            );
+            expect(newBalances[taker][order.params.makerToken]).to.be.bignumber.equal(
+                balances[taker][order.params.makerToken].add(order.params.makerTokenAmount),
+            );
+            expect(newBalances[taker][zrx.address]).to.be.bignumber.equal(
+                balances[taker][zrx.address].minus(order.params.takerFee),
+            );
+            expect(newBalances[feeRecipient][zrx.address]).to.be.bignumber.equal(
+                balances[feeRecipient][zrx.address].add(order.params.makerFee.add(order.params.takerFee)),
+            );
+        });
+
+        it('should log 1 event with the correct arguments when order has a feeRecipient', async () => {
+            const divisor = 2;
+            const res = await exWrapper.fillOrderAsync(order, taker, {
+                fillTakerTokenAmount: order.params.takerTokenAmount.div(divisor),
+            });
+            expect(res.logs).to.have.length(1);
+
+            const logArgs = res.logs[0].args;
+            const expectedFilledMakerTokenAmount = order.params.makerTokenAmount.div(divisor);
+            const expectedFilledTakerTokenAmount = order.params.takerTokenAmount.div(divisor);
+            const expectedFeeMPaid = order.params.makerFee.div(divisor);
+            const expectedFeeTPaid = order.params.takerFee.div(divisor);
+            const tokensHashBuff = crypto.solSHA3([order.params.makerToken, order.params.takerToken]);
+            const expectedTokens = ethUtil.bufferToHex(tokensHashBuff);
+
+            expect(order.params.maker).to.be.equal(logArgs.maker);
+            expect(taker).to.be.equal(logArgs.taker);
+            expect(order.params.feeRecipient).to.be.equal(logArgs.feeRecipient);
+            expect(order.params.makerToken).to.be.equal(logArgs.makerToken);
+            expect(order.params.takerToken).to.be.equal(logArgs.takerToken);
+            expect(expectedFilledMakerTokenAmount).to.be.bignumber.equal(logArgs.filledMakerTokenAmount);
+            expect(expectedFilledTakerTokenAmount).to.be.bignumber.equal(logArgs.filledTakerTokenAmount);
+            expect(expectedFeeMPaid).to.be.bignumber.equal(logArgs.paidMakerFee);
+            expect(expectedFeeTPaid).to.be.bignumber.equal(logArgs.paidTakerFee);
+            expect(expectedTokens).to.be.equal(logArgs.tokens);
+            expect(order.params.orderHashHex).to.be.equal(logArgs.orderHash);
+        });
+
+        it('should log 1 event with the correct arguments when order has no feeRecipient', async () => {
+            order = await orderFactory.newSignedOrderAsync({
+                feeRecipient: ZeroEx.NULL_ADDRESS,
+            });
+            const divisor = 2;
+            const res = await exWrapper.fillOrderAsync(order, taker, {
+                fillTakerTokenAmount: order.params.takerTokenAmount.div(divisor),
+            });
+            expect(res.logs).to.have.length(1);
+
+            const logArgs = res.logs[0].args;
+            const expectedFilledMakerTokenAmount = order.params.makerTokenAmount.div(divisor);
+            const expectedFilledTakerTokenAmount = order.params.takerTokenAmount.div(divisor);
+            const expectedFeeMPaid = new BigNumber(0);
+            const expectedFeeTPaid = new BigNumber(0);
+            const tokensHashBuff = crypto.solSHA3([order.params.makerToken, order.params.takerToken]);
+            const expectedTokens = ethUtil.bufferToHex(tokensHashBuff);
+
+            expect(order.params.maker).to.be.equal(logArgs.maker);
+            expect(taker).to.be.equal(logArgs.taker);
+            expect(order.params.feeRecipient).to.be.equal(logArgs.feeRecipient);
+            expect(order.params.makerToken).to.be.equal(logArgs.makerToken);
+            expect(order.params.takerToken).to.be.equal(logArgs.takerToken);
+            expect(expectedFilledMakerTokenAmount).to.be.bignumber.equal(logArgs.filledMakerTokenAmount);
+            expect(expectedFilledTakerTokenAmount).to.be.bignumber.equal(logArgs.filledTakerTokenAmount);
+            expect(expectedFeeMPaid).to.be.bignumber.equal(logArgs.paidMakerFee);
+            expect(expectedFeeTPaid).to.be.bignumber.equal(logArgs.paidTakerFee);
+            expect(expectedTokens).to.be.equal(logArgs.tokens);
+            expect(order.params.orderHashHex).to.be.equal(logArgs.orderHash);
+        });
+
+        it('should throw when taker is specified and order is claimed by other', async () => {
+            order = await orderFactory.newSignedOrderAsync({
+                taker: feeRecipient,
+                makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
+                takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18),
+            });
+
+            return expect(exWrapper.fillOrderAsync(order, taker)).to.be.rejectedWith(constants.REVERT);
+        });
+
+        it('should throw if signature is invalid', async () => {
+            order = await orderFactory.newSignedOrderAsync({
+                makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(10), 18),
+            });
+
+            order.params.r = ethUtil.bufferToHex(ethUtil.sha3('invalidR'));
+            order.params.s = ethUtil.bufferToHex(ethUtil.sha3('invalidS'));
+            return expect(exWrapper.fillOrderAsync(order, taker)).to.be.rejectedWith(constants.REVERT);
+        });
+
+        it('should throw if makerTokenAmount is 0', async () => {
+            order = await orderFactory.newSignedOrderAsync({
+                makerTokenAmount: new BigNumber(0),
+            });
+
+            return expect(exWrapper.fillOrderAsync(order, taker)).to.be.rejectedWith(constants.REVERT);
+        });
+
+        it('should throw if takerTokenAmount is 0', async () => {
+            order = await orderFactory.newSignedOrderAsync({
+                takerTokenAmount: new BigNumber(0),
+            });
+
+            return expect(exWrapper.fillOrderAsync(order, taker)).to.be.rejectedWith(constants.REVERT);
+        });
+
+        it('should throw if fillTakerTokenAmount is 0', async () => {
+            order = await orderFactory.newSignedOrderAsync();
+
+            return expect(
+                exWrapper.fillOrderAsync(order, taker, {
+                    fillTakerTokenAmount: new BigNumber(0),
+                }),
+            ).to.be.rejectedWith(constants.REVERT);
+        });
+
+        it('should not change balances if maker balances are too low to fill order and \
                 shouldThrowOnInsufficientBalanceOrAllowance = false', async () => {
-			order = await orderFactory.newSignedOrderAsync({
-				makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100000), 18),
-			});
+            order = await orderFactory.newSignedOrderAsync({
+                makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100000), 18),
+            });
 
-			await exWrapper.fillOrderAsync(order, taker);
-			const newBalances = await dmyBalances.getAsync();
-			expect(newBalances).to.be.deep.equal(balances);
-		});
+            await exWrapper.fillOrderAsync(order, taker);
+            const newBalances = await dmyBalances.getAsync();
+            expect(newBalances).to.be.deep.equal(balances);
+        });
 
-		it('should throw if maker balances are too low to fill order and \
+        it('should throw if maker balances are too low to fill order and \
                 shouldThrowOnInsufficientBalanceOrAllowance = true', async () => {
-			order = await orderFactory.newSignedOrderAsync({
-				makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100000), 18),
-			});
-
-			return expect(
-				exWrapper.fillOrderAsync(order, taker, {
-					shouldThrowOnInsufficientBalanceOrAllowance: true,
-				}),
-			).to.be.rejectedWith(constants.REVERT);
-		});
-
-		it('should not change balances if taker balances are too low to fill order and \
+            order = await orderFactory.newSignedOrderAsync({
+                makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100000), 18),
+            });
+
+            return expect(
+                exWrapper.fillOrderAsync(order, taker, {
+                    shouldThrowOnInsufficientBalanceOrAllowance: true,
+                }),
+            ).to.be.rejectedWith(constants.REVERT);
+        });
+
+        it('should not change balances if taker balances are too low to fill order and \
                 shouldThrowOnInsufficientBalanceOrAllowance = false', async () => {
-			order = await orderFactory.newSignedOrderAsync({
-				takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100000), 18),
-			});
+            order = await orderFactory.newSignedOrderAsync({
+                takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100000), 18),
+            });
 
-			await exWrapper.fillOrderAsync(order, taker);
-			const newBalances = await dmyBalances.getAsync();
-			expect(newBalances).to.be.deep.equal(balances);
-		});
+            await exWrapper.fillOrderAsync(order, taker);
+            const newBalances = await dmyBalances.getAsync();
+            expect(newBalances).to.be.deep.equal(balances);
+        });
 
-		it('should throw if taker balances are too low to fill order and \
+        it('should throw if taker balances are too low to fill order and \
                 shouldThrowOnInsufficientBalanceOrAllowance = true', async () => {
-			order = await orderFactory.newSignedOrderAsync({
-				takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100000), 18),
-			});
-
-			return expect(
-				exWrapper.fillOrderAsync(order, taker, {
-					shouldThrowOnInsufficientBalanceOrAllowance: true,
-				}),
-			).to.be.rejectedWith(constants.REVERT);
-		});
-
-		it('should not change balances if maker allowances are too low to fill order and \
+            order = await orderFactory.newSignedOrderAsync({
+                takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100000), 18),
+            });
+
+            return expect(
+                exWrapper.fillOrderAsync(order, taker, {
+                    shouldThrowOnInsufficientBalanceOrAllowance: true,
+                }),
+            ).to.be.rejectedWith(constants.REVERT);
+        });
+
+        it('should not change balances if maker allowances are too low to fill order and \
                 shouldThrowOnInsufficientBalanceOrAllowance = false', async () => {
-			await rep.approve(TokenTransferProxy.address, 0, { from: maker });
-			await exWrapper.fillOrderAsync(order, taker);
-			await rep.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
-				from: maker,
-			});
+            await rep.approve(TokenTransferProxy.address, 0, { from: maker });
+            await exWrapper.fillOrderAsync(order, taker);
+            await rep.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
+                from: maker,
+            });
 
-			const newBalances = await dmyBalances.getAsync();
-			expect(newBalances).to.be.deep.equal(balances);
-		});
+            const newBalances = await dmyBalances.getAsync();
+            expect(newBalances).to.be.deep.equal(balances);
+        });
 
-		it('should throw if maker allowances are too low to fill order and \
+        it('should throw if maker allowances are too low to fill order and \
                 shouldThrowOnInsufficientBalanceOrAllowance = true', async () => {
-			await rep.approve(TokenTransferProxy.address, 0, { from: maker });
-			expect(
-				exWrapper.fillOrderAsync(order, taker, {
-					shouldThrowOnInsufficientBalanceOrAllowance: true,
-				}),
-			).to.be.rejectedWith(constants.REVERT);
-			await rep.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
-				from: maker,
-			});
-		});
-
-		it('should not change balances if taker allowances are too low to fill order and \
+            await rep.approve(TokenTransferProxy.address, 0, { from: maker });
+            expect(
+                exWrapper.fillOrderAsync(order, taker, {
+                    shouldThrowOnInsufficientBalanceOrAllowance: true,
+                }),
+            ).to.be.rejectedWith(constants.REVERT);
+            await rep.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
+                from: maker,
+            });
+        });
+
+        it('should not change balances if taker allowances are too low to fill order and \
                 shouldThrowOnInsufficientBalanceOrAllowance = false', async () => {
-			await dgd.approve(TokenTransferProxy.address, 0, { from: taker });
-			await exWrapper.fillOrderAsync(order, taker);
-			await dgd.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
-				from: taker,
-			});
+            await dgd.approve(TokenTransferProxy.address, 0, { from: taker });
+            await exWrapper.fillOrderAsync(order, taker);
+            await dgd.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
+                from: taker,
+            });
 
-			const newBalances = await dmyBalances.getAsync();
-			expect(newBalances).to.be.deep.equal(balances);
-		});
+            const newBalances = await dmyBalances.getAsync();
+            expect(newBalances).to.be.deep.equal(balances);
+        });
 
-		it('should throw if taker allowances are too low to fill order and \
+        it('should throw if taker allowances are too low to fill order and \
                 shouldThrowOnInsufficientBalanceOrAllowance = true', async () => {
-			await dgd.approve(TokenTransferProxy.address, 0, { from: taker });
-			expect(
-				exWrapper.fillOrderAsync(order, taker, {
-					shouldThrowOnInsufficientBalanceOrAllowance: true,
-				}),
-			).to.be.rejectedWith(constants.REVERT);
-			await dgd.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
-				from: taker,
-			});
-		});
-
-		it('should not change balances if makerToken is ZRX, makerTokenAmount + makerFee > maker balance, \
+            await dgd.approve(TokenTransferProxy.address, 0, { from: taker });
+            expect(
+                exWrapper.fillOrderAsync(order, taker, {
+                    shouldThrowOnInsufficientBalanceOrAllowance: true,
+                }),
+            ).to.be.rejectedWith(constants.REVERT);
+            await dgd.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
+                from: taker,
+            });
+        });
+
+        it('should not change balances if makerToken is ZRX, makerTokenAmount + makerFee > maker balance, \
                 and shouldThrowOnInsufficientBalanceOrAllowance = false', async () => {
-			const makerZRXBalance = new BigNumber(balances[maker][zrx.address]);
-			order = await orderFactory.newSignedOrderAsync({
-				makerToken: zrx.address,
-				makerTokenAmount: makerZRXBalance,
-				makerFee: new BigNumber(1),
-			});
-			await exWrapper.fillOrderAsync(order, taker);
-			const newBalances = await dmyBalances.getAsync();
-			expect(newBalances).to.be.deep.equal(balances);
-		});
-
-		it('should not change balances if makerToken is ZRX, makerTokenAmount + makerFee > maker allowance, \
+            const makerZRXBalance = new BigNumber(balances[maker][zrx.address]);
+            order = await orderFactory.newSignedOrderAsync({
+                makerToken: zrx.address,
+                makerTokenAmount: makerZRXBalance,
+                makerFee: new BigNumber(1),
+            });
+            await exWrapper.fillOrderAsync(order, taker);
+            const newBalances = await dmyBalances.getAsync();
+            expect(newBalances).to.be.deep.equal(balances);
+        });
+
+        it('should not change balances if makerToken is ZRX, makerTokenAmount + makerFee > maker allowance, \
                 and shouldThrowOnInsufficientBalanceOrAllowance = false', async () => {
-			const makerZRXAllowance = await zrx.allowance(maker, TokenTransferProxy.address);
-			order = await orderFactory.newSignedOrderAsync({
-				makerToken: zrx.address,
-				makerTokenAmount: new BigNumber(makerZRXAllowance),
-				makerFee: new BigNumber(1),
-			});
-			await exWrapper.fillOrderAsync(order, taker);
-			const newBalances = await dmyBalances.getAsync();
-			expect(newBalances).to.be.deep.equal(balances);
-		});
-
-		it('should not change balances if takerToken is ZRX, takerTokenAmount + takerFee > taker balance, \
+            const makerZRXAllowance = await zrx.allowance(maker, TokenTransferProxy.address);
+            order = await orderFactory.newSignedOrderAsync({
+                makerToken: zrx.address,
+                makerTokenAmount: new BigNumber(makerZRXAllowance),
+                makerFee: new BigNumber(1),
+            });
+            await exWrapper.fillOrderAsync(order, taker);
+            const newBalances = await dmyBalances.getAsync();
+            expect(newBalances).to.be.deep.equal(balances);
+        });
+
+        it('should not change balances if takerToken is ZRX, takerTokenAmount + takerFee > taker balance, \
                 and shouldThrowOnInsufficientBalanceOrAllowance = false', async () => {
-			const takerZRXBalance = new BigNumber(balances[taker][zrx.address]);
-			order = await orderFactory.newSignedOrderAsync({
-				takerToken: zrx.address,
-				takerTokenAmount: takerZRXBalance,
-				takerFee: new BigNumber(1),
-			});
-			await exWrapper.fillOrderAsync(order, taker);
-			const newBalances = await dmyBalances.getAsync();
-			expect(newBalances).to.be.deep.equal(balances);
-		});
-
-		it('should not change balances if takerToken is ZRX, takerTokenAmount + takerFee > taker allowance, \
+            const takerZRXBalance = new BigNumber(balances[taker][zrx.address]);
+            order = await orderFactory.newSignedOrderAsync({
+                takerToken: zrx.address,
+                takerTokenAmount: takerZRXBalance,
+                takerFee: new BigNumber(1),
+            });
+            await exWrapper.fillOrderAsync(order, taker);
+            const newBalances = await dmyBalances.getAsync();
+            expect(newBalances).to.be.deep.equal(balances);
+        });
+
+        it('should not change balances if takerToken is ZRX, takerTokenAmount + takerFee > taker allowance, \
                 and shouldThrowOnInsufficientBalanceOrAllowance = false', async () => {
-			const takerZRXAllowance = await zrx.allowance(taker, TokenTransferProxy.address);
-			order = await orderFactory.newSignedOrderAsync({
-				takerToken: zrx.address,
-				takerTokenAmount: new BigNumber(takerZRXAllowance),
-				takerFee: new BigNumber(1),
-			});
-			await exWrapper.fillOrderAsync(order, taker);
-			const newBalances = await dmyBalances.getAsync();
-			expect(newBalances).to.be.deep.equal(balances);
-		});
-
-		it('should throw if getBalance or getAllowance attempts to change state and \
+            const takerZRXAllowance = await zrx.allowance(taker, TokenTransferProxy.address);
+            order = await orderFactory.newSignedOrderAsync({
+                takerToken: zrx.address,
+                takerTokenAmount: new BigNumber(takerZRXAllowance),
+                takerFee: new BigNumber(1),
+            });
+            await exWrapper.fillOrderAsync(order, taker);
+            const newBalances = await dmyBalances.getAsync();
+            expect(newBalances).to.be.deep.equal(balances);
+        });
+
+        it('should throw if getBalance or getAllowance attempts to change state and \
                 shouldThrowOnInsufficientBalanceOrAllowance = false', async () => {
-			const maliciousToken = await MaliciousToken.new();
-			await maliciousToken.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, { from: taker });
-
-			order = await orderFactory.newSignedOrderAsync({
-				takerToken: maliciousToken.address,
-			});
-
-			return expect(
-				exWrapper.fillOrderAsync(order, taker, {
-					shouldThrowOnInsufficientBalanceOrAllowance: false,
-				}),
-			).to.be.rejectedWith(constants.REVERT);
-		});
-
-		it('should not change balances if an order is expired', async () => {
-			order = await orderFactory.newSignedOrderAsync({
-				expirationTimestampInSec: new BigNumber(Math.floor((Date.now() - 10000) / 1000)),
-			});
-			await exWrapper.fillOrderAsync(order, taker);
-
-			const newBalances = await dmyBalances.getAsync();
-			expect(newBalances).to.be.deep.equal(balances);
-		});
-
-		it('should log an error event if an order is expired', async () => {
-			order = await orderFactory.newSignedOrderAsync({
-				expirationTimestampInSec: new BigNumber(Math.floor((Date.now() - 10000) / 1000)),
-			});
-
-			const res = await exWrapper.fillOrderAsync(order, taker);
-			expect(res.logs).to.have.length(1);
-			const errCode = res.logs[0].args.errorId.toNumber();
-			expect(errCode).to.be.equal(ExchangeContractErrs.ERROR_ORDER_EXPIRED);
-		});
-
-		it('should log an error event if no value is filled', async () => {
-			await exWrapper.fillOrderAsync(order, taker);
-
-			const res = await exWrapper.fillOrderAsync(order, taker);
-			expect(res.logs).to.have.length(1);
-			const errCode = res.logs[0].args.errorId.toNumber();
-			expect(errCode).to.be.equal(ExchangeContractErrs.ERROR_ORDER_FULLY_FILLED_OR_CANCELLED);
-		});
-	});
-
-	describe('cancelOrder', () => {
-		beforeEach(async () => {
-			balances = await dmyBalances.getAsync();
-			order = await orderFactory.newSignedOrderAsync();
-		});
-
-		it('should throw if not sent by maker', async () => {
-			return expect(exWrapper.cancelOrderAsync(order, taker)).to.be.rejectedWith(constants.REVERT);
-		});
-
-		it('should throw if makerTokenAmount is 0', async () => {
-			order = await orderFactory.newSignedOrderAsync({
-				makerTokenAmount: new BigNumber(0),
-			});
-
-			return expect(exWrapper.cancelOrderAsync(order, maker)).to.be.rejectedWith(constants.REVERT);
-		});
-
-		it('should throw if takerTokenAmount is 0', async () => {
-			order = await orderFactory.newSignedOrderAsync({
-				takerTokenAmount: new BigNumber(0),
-			});
-
-			return expect(exWrapper.cancelOrderAsync(order, maker)).to.be.rejectedWith(constants.REVERT);
-		});
-
-		it('should throw if cancelTakerTokenAmount is 0', async () => {
-			order = await orderFactory.newSignedOrderAsync();
-
-			return expect(
-				exWrapper.cancelOrderAsync(order, maker, {
-					cancelTakerTokenAmount: new BigNumber(0),
-				}),
-			).to.be.rejectedWith(constants.REVERT);
-		});
-
-		it('should be able to cancel a full order', async () => {
-			await exWrapper.cancelOrderAsync(order, maker);
-			await exWrapper.fillOrderAsync(order, taker, {
-				fillTakerTokenAmount: order.params.takerTokenAmount.div(2),
-			});
-
-			const newBalances = await dmyBalances.getAsync();
-			expect(newBalances).to.be.deep.equal(balances);
-		});
-
-		it('should be able to cancel part of an order', async () => {
-			const cancelTakerTokenAmount = order.params.takerTokenAmount.div(2);
-			await exWrapper.cancelOrderAsync(order, maker, {
-				cancelTakerTokenAmount,
-			});
-
-			const res = await exWrapper.fillOrderAsync(order, taker, {
-				fillTakerTokenAmount: order.params.takerTokenAmount,
-			});
-			expect(res.logs[0].args.filledTakerTokenAmount).to.be.bignumber.equal(
-				order.params.takerTokenAmount.minus(cancelTakerTokenAmount),
-			);
-
-			const newBalances = await dmyBalances.getAsync();
-			const cancelMakerTokenAmount = cancelTakerTokenAmount
-				.times(order.params.makerTokenAmount)
-				.dividedToIntegerBy(order.params.takerTokenAmount);
-			const paidMakerFee = order.params.makerFee
-				.times(cancelMakerTokenAmount)
-				.dividedToIntegerBy(order.params.makerTokenAmount);
-			const paidTakerFee = order.params.takerFee
-				.times(cancelMakerTokenAmount)
-				.dividedToIntegerBy(order.params.makerTokenAmount);
-			expect(newBalances[maker][order.params.makerToken]).to.be.bignumber.equal(
-				balances[maker][order.params.makerToken].minus(cancelMakerTokenAmount),
-			);
-			expect(newBalances[maker][order.params.takerToken]).to.be.bignumber.equal(
-				balances[maker][order.params.takerToken].add(cancelTakerTokenAmount),
-			);
-			expect(newBalances[maker][zrx.address]).to.be.bignumber.equal(
-				balances[maker][zrx.address].minus(paidMakerFee),
-			);
-			expect(newBalances[taker][order.params.takerToken]).to.be.bignumber.equal(
-				balances[taker][order.params.takerToken].minus(cancelTakerTokenAmount),
-			);
-			expect(newBalances[taker][order.params.makerToken]).to.be.bignumber.equal(
-				balances[taker][order.params.makerToken].add(cancelMakerTokenAmount),
-			);
-			expect(newBalances[taker][zrx.address]).to.be.bignumber.equal(
-				balances[taker][zrx.address].minus(paidTakerFee),
-			);
-			expect(newBalances[feeRecipient][zrx.address]).to.be.bignumber.equal(
-				balances[feeRecipient][zrx.address].add(paidMakerFee.add(paidTakerFee)),
-			);
-		});
-
-		it('should log 1 event with correct arguments', async () => {
-			const divisor = 2;
-			const res = await exWrapper.cancelOrderAsync(order, maker, {
-				cancelTakerTokenAmount: order.params.takerTokenAmount.div(divisor),
-			});
-			expect(res.logs).to.have.length(1);
-
-			const logArgs = res.logs[0].args;
-			const expectedCancelledMakerTokenAmount = order.params.makerTokenAmount.div(divisor);
-			const expectedCancelledTakerTokenAmount = order.params.takerTokenAmount.div(divisor);
-			const tokensHashBuff = crypto.solSHA3([order.params.makerToken, order.params.takerToken]);
-			const expectedTokens = ethUtil.bufferToHex(tokensHashBuff);
-
-			expect(order.params.maker).to.be.equal(logArgs.maker);
-			expect(order.params.feeRecipient).to.be.equal(logArgs.feeRecipient);
-			expect(order.params.makerToken).to.be.equal(logArgs.makerToken);
-			expect(order.params.takerToken).to.be.equal(logArgs.takerToken);
-			expect(expectedCancelledMakerTokenAmount).to.be.bignumber.equal(logArgs.cancelledMakerTokenAmount);
-			expect(expectedCancelledTakerTokenAmount).to.be.bignumber.equal(logArgs.cancelledTakerTokenAmount);
-			expect(expectedTokens).to.be.equal(logArgs.tokens);
-			expect(order.params.orderHashHex).to.be.equal(logArgs.orderHash);
-		});
-
-		it('should not log events if no value is cancelled', async () => {
-			await exWrapper.cancelOrderAsync(order, maker);
-
-			const res = await exWrapper.cancelOrderAsync(order, maker);
-			expect(res.logs).to.have.length(1);
-			const errCode = res.logs[0].args.errorId.toNumber();
-			expect(errCode).to.be.equal(ExchangeContractErrs.ERROR_ORDER_FULLY_FILLED_OR_CANCELLED);
-		});
-
-		it('should not log events if order is expired', async () => {
-			order = await orderFactory.newSignedOrderAsync({
-				expirationTimestampInSec: new BigNumber(Math.floor((Date.now() - 10000) / 1000)),
-			});
-
-			const res = await exWrapper.cancelOrderAsync(order, maker);
-			expect(res.logs).to.have.length(1);
-			const errCode = res.logs[0].args.errorId.toNumber();
-			expect(errCode).to.be.equal(ExchangeContractErrs.ERROR_ORDER_EXPIRED);
-		});
-	});
+            const maliciousToken = await MaliciousToken.new();
+            await maliciousToken.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, { from: taker });
+
+            order = await orderFactory.newSignedOrderAsync({
+                takerToken: maliciousToken.address,
+            });
+
+            return expect(
+                exWrapper.fillOrderAsync(order, taker, {
+                    shouldThrowOnInsufficientBalanceOrAllowance: false,
+                }),
+            ).to.be.rejectedWith(constants.REVERT);
+        });
+
+        it('should not change balances if an order is expired', async () => {
+            order = await orderFactory.newSignedOrderAsync({
+                expirationTimestampInSec: new BigNumber(Math.floor((Date.now() - 10000) / 1000)),
+            });
+            await exWrapper.fillOrderAsync(order, taker);
+
+            const newBalances = await dmyBalances.getAsync();
+            expect(newBalances).to.be.deep.equal(balances);
+        });
+
+        it('should log an error event if an order is expired', async () => {
+            order = await orderFactory.newSignedOrderAsync({
+                expirationTimestampInSec: new BigNumber(Math.floor((Date.now() - 10000) / 1000)),
+            });
+
+            const res = await exWrapper.fillOrderAsync(order, taker);
+            expect(res.logs).to.have.length(1);
+            const errCode = res.logs[0].args.errorId.toNumber();
+            expect(errCode).to.be.equal(ExchangeContractErrs.ERROR_ORDER_EXPIRED);
+        });
+
+        it('should log an error event if no value is filled', async () => {
+            await exWrapper.fillOrderAsync(order, taker);
+
+            const res = await exWrapper.fillOrderAsync(order, taker);
+            expect(res.logs).to.have.length(1);
+            const errCode = res.logs[0].args.errorId.toNumber();
+            expect(errCode).to.be.equal(ExchangeContractErrs.ERROR_ORDER_FULLY_FILLED_OR_CANCELLED);
+        });
+    });
+
+    describe('cancelOrder', () => {
+        beforeEach(async () => {
+            balances = await dmyBalances.getAsync();
+            order = await orderFactory.newSignedOrderAsync();
+        });
+
+        it('should throw if not sent by maker', async () => {
+            return expect(exWrapper.cancelOrderAsync(order, taker)).to.be.rejectedWith(constants.REVERT);
+        });
+
+        it('should throw if makerTokenAmount is 0', async () => {
+            order = await orderFactory.newSignedOrderAsync({
+                makerTokenAmount: new BigNumber(0),
+            });
+
+            return expect(exWrapper.cancelOrderAsync(order, maker)).to.be.rejectedWith(constants.REVERT);
+        });
+
+        it('should throw if takerTokenAmount is 0', async () => {
+            order = await orderFactory.newSignedOrderAsync({
+                takerTokenAmount: new BigNumber(0),
+            });
+
+            return expect(exWrapper.cancelOrderAsync(order, maker)).to.be.rejectedWith(constants.REVERT);
+        });
+
+        it('should throw if cancelTakerTokenAmount is 0', async () => {
+            order = await orderFactory.newSignedOrderAsync();
+
+            return expect(
+                exWrapper.cancelOrderAsync(order, maker, {
+                    cancelTakerTokenAmount: new BigNumber(0),
+                }),
+            ).to.be.rejectedWith(constants.REVERT);
+        });
+
+        it('should be able to cancel a full order', async () => {
+            await exWrapper.cancelOrderAsync(order, maker);
+            await exWrapper.fillOrderAsync(order, taker, {
+                fillTakerTokenAmount: order.params.takerTokenAmount.div(2),
+            });
+
+            const newBalances = await dmyBalances.getAsync();
+            expect(newBalances).to.be.deep.equal(balances);
+        });
+
+        it('should be able to cancel part of an order', async () => {
+            const cancelTakerTokenAmount = order.params.takerTokenAmount.div(2);
+            await exWrapper.cancelOrderAsync(order, maker, {
+                cancelTakerTokenAmount,
+            });
+
+            const res = await exWrapper.fillOrderAsync(order, taker, {
+                fillTakerTokenAmount: order.params.takerTokenAmount,
+            });
+            expect(res.logs[0].args.filledTakerTokenAmount).to.be.bignumber.equal(
+                order.params.takerTokenAmount.minus(cancelTakerTokenAmount),
+            );
+
+            const newBalances = await dmyBalances.getAsync();
+            const cancelMakerTokenAmount = cancelTakerTokenAmount
+                .times(order.params.makerTokenAmount)
+                .dividedToIntegerBy(order.params.takerTokenAmount);
+            const paidMakerFee = order.params.makerFee
+                .times(cancelMakerTokenAmount)
+                .dividedToIntegerBy(order.params.makerTokenAmount);
+            const paidTakerFee = order.params.takerFee
+                .times(cancelMakerTokenAmount)
+                .dividedToIntegerBy(order.params.makerTokenAmount);
+            expect(newBalances[maker][order.params.makerToken]).to.be.bignumber.equal(
+                balances[maker][order.params.makerToken].minus(cancelMakerTokenAmount),
+            );
+            expect(newBalances[maker][order.params.takerToken]).to.be.bignumber.equal(
+                balances[maker][order.params.takerToken].add(cancelTakerTokenAmount),
+            );
+            expect(newBalances[maker][zrx.address]).to.be.bignumber.equal(
+                balances[maker][zrx.address].minus(paidMakerFee),
+            );
+            expect(newBalances[taker][order.params.takerToken]).to.be.bignumber.equal(
+                balances[taker][order.params.takerToken].minus(cancelTakerTokenAmount),
+            );
+            expect(newBalances[taker][order.params.makerToken]).to.be.bignumber.equal(
+                balances[taker][order.params.makerToken].add(cancelMakerTokenAmount),
+            );
+            expect(newBalances[taker][zrx.address]).to.be.bignumber.equal(
+                balances[taker][zrx.address].minus(paidTakerFee),
+            );
+            expect(newBalances[feeRecipient][zrx.address]).to.be.bignumber.equal(
+                balances[feeRecipient][zrx.address].add(paidMakerFee.add(paidTakerFee)),
+            );
+        });
+
+        it('should log 1 event with correct arguments', async () => {
+            const divisor = 2;
+            const res = await exWrapper.cancelOrderAsync(order, maker, {
+                cancelTakerTokenAmount: order.params.takerTokenAmount.div(divisor),
+            });
+            expect(res.logs).to.have.length(1);
+
+            const logArgs = res.logs[0].args;
+            const expectedCancelledMakerTokenAmount = order.params.makerTokenAmount.div(divisor);
+            const expectedCancelledTakerTokenAmount = order.params.takerTokenAmount.div(divisor);
+            const tokensHashBuff = crypto.solSHA3([order.params.makerToken, order.params.takerToken]);
+            const expectedTokens = ethUtil.bufferToHex(tokensHashBuff);
+
+            expect(order.params.maker).to.be.equal(logArgs.maker);
+            expect(order.params.feeRecipient).to.be.equal(logArgs.feeRecipient);
+            expect(order.params.makerToken).to.be.equal(logArgs.makerToken);
+            expect(order.params.takerToken).to.be.equal(logArgs.takerToken);
+            expect(expectedCancelledMakerTokenAmount).to.be.bignumber.equal(logArgs.cancelledMakerTokenAmount);
+            expect(expectedCancelledTakerTokenAmount).to.be.bignumber.equal(logArgs.cancelledTakerTokenAmount);
+            expect(expectedTokens).to.be.equal(logArgs.tokens);
+            expect(order.params.orderHashHex).to.be.equal(logArgs.orderHash);
+        });
+
+        it('should not log events if no value is cancelled', async () => {
+            await exWrapper.cancelOrderAsync(order, maker);
+
+            const res = await exWrapper.cancelOrderAsync(order, maker);
+            expect(res.logs).to.have.length(1);
+            const errCode = res.logs[0].args.errorId.toNumber();
+            expect(errCode).to.be.equal(ExchangeContractErrs.ERROR_ORDER_FULLY_FILLED_OR_CANCELLED);
+        });
+
+        it('should not log events if order is expired', async () => {
+            order = await orderFactory.newSignedOrderAsync({
+                expirationTimestampInSec: new BigNumber(Math.floor((Date.now() - 10000) / 1000)),
+            });
+
+            const res = await exWrapper.cancelOrderAsync(order, maker);
+            expect(res.logs).to.have.length(1);
+            const errCode = res.logs[0].args.errorId.toNumber();
+            expect(errCode).to.be.equal(ExchangeContractErrs.ERROR_ORDER_EXPIRED);
+        });
+    });
 }); // tslint:disable-line:max-file-line-count
diff --git a/packages/contracts/test/ts/exchange/helpers.ts b/packages/contracts/test/ts/exchange/helpers.ts
index 993b4c7d5..95f68e419 100644
--- a/packages/contracts/test/ts/exchange/helpers.ts
+++ b/packages/contracts/test/ts/exchange/helpers.ts
@@ -15,153 +15,153 @@ const expect = chai.expect;
 const { Exchange, TokenRegistry } = new Artifacts(artifacts);
 
 contract('Exchange', (accounts: string[]) => {
-	const maker = accounts[0];
-	const feeRecipient = accounts[1] || accounts[accounts.length - 1];
-
-	let order: Order;
-	let exchangeWrapper: ExchangeWrapper;
-	let orderFactory: OrderFactory;
-
-	before(async () => {
-		const [tokenRegistry, exchange] = await Promise.all([TokenRegistry.deployed(), Exchange.deployed()]);
-		exchangeWrapper = new ExchangeWrapper(exchange);
-		const [repAddress, dgdAddress] = await Promise.all([
-			tokenRegistry.getTokenAddressBySymbol('REP'),
-			tokenRegistry.getTokenAddressBySymbol('DGD'),
-		]);
-		const defaultOrderParams = {
-			exchangeContractAddress: Exchange.address,
-			maker,
-			feeRecipient,
-			makerToken: repAddress,
-			takerToken: dgdAddress,
-			makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
-			takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18),
-			makerFee: ZeroEx.toBaseUnitAmount(new BigNumber(1), 18),
-			takerFee: ZeroEx.toBaseUnitAmount(new BigNumber(1), 18),
-		};
-		orderFactory = new OrderFactory(defaultOrderParams);
-	});
-
-	beforeEach(async () => {
-		order = await orderFactory.newSignedOrderAsync();
-	});
-
-	describe('getOrderHash', () => {
-		it('should output the correct orderHash', async () => {
-			const orderHashHex = await exchangeWrapper.getOrderHashAsync(order);
-			expect(order.params.orderHashHex).to.be.equal(orderHashHex);
-		});
-	});
-
-	describe('isValidSignature', () => {
-		beforeEach(async () => {
-			order = await orderFactory.newSignedOrderAsync();
-		});
-
-		it('should return true with a valid signature', async () => {
-			const success = await exchangeWrapper.isValidSignatureAsync(order);
-			const isValidSignature = order.isValidSignature();
-			expect(isValidSignature).to.be.true();
-			expect(success).to.be.true();
-		});
-
-		it('should return false with an invalid signature', async () => {
-			order.params.r = ethUtil.bufferToHex(ethUtil.sha3('invalidR'));
-			order.params.s = ethUtil.bufferToHex(ethUtil.sha3('invalidS'));
-			const success = await exchangeWrapper.isValidSignatureAsync(order);
-			expect(order.isValidSignature()).to.be.false();
-			expect(success).to.be.false();
-		});
-	});
-
-	describe('isRoundingError', () => {
-		it('should return false if there is a rounding error of 0.1%', async () => {
-			const numerator = new BigNumber(20);
-			const denominator = new BigNumber(999);
-			const target = new BigNumber(50);
-			// rounding error = ((20*50/999) - floor(20*50/999)) / (20*50/999) = 0.1%
-			const isRoundingError = await exchangeWrapper.isRoundingErrorAsync(numerator, denominator, target);
-			expect(isRoundingError).to.be.false();
-		});
-
-		it('should return false if there is a rounding of 0.09%', async () => {
-			const numerator = new BigNumber(20);
-			const denominator = new BigNumber(9991);
-			const target = new BigNumber(500);
-			// rounding error = ((20*500/9991) - floor(20*500/9991)) / (20*500/9991) = 0.09%
-			const isRoundingError = await exchangeWrapper.isRoundingErrorAsync(numerator, denominator, target);
-			expect(isRoundingError).to.be.false();
-		});
-
-		it('should return true if there is a rounding error of 0.11%', async () => {
-			const numerator = new BigNumber(20);
-			const denominator = new BigNumber(9989);
-			const target = new BigNumber(500);
-			// rounding error = ((20*500/9989) - floor(20*500/9989)) / (20*500/9989) = 0.011%
-			const isRoundingError = await exchangeWrapper.isRoundingErrorAsync(numerator, denominator, target);
-			expect(isRoundingError).to.be.true();
-		});
-
-		it('should return true if there is a rounding error > 0.1%', async () => {
-			const numerator = new BigNumber(3);
-			const denominator = new BigNumber(7);
-			const target = new BigNumber(10);
-			// rounding error = ((3*10/7) - floor(3*10/7)) / (3*10/7) = 6.67%
-			const isRoundingError = await exchangeWrapper.isRoundingErrorAsync(numerator, denominator, target);
-			expect(isRoundingError).to.be.true();
-		});
-
-		it('should return false when there is no rounding error', async () => {
-			const numerator = new BigNumber(1);
-			const denominator = new BigNumber(2);
-			const target = new BigNumber(10);
-
-			const isRoundingError = await exchangeWrapper.isRoundingErrorAsync(numerator, denominator, target);
-			expect(isRoundingError).to.be.false();
-		});
-
-		it('should return false when there is rounding error <= 0.1%', async () => {
-			// randomly generated numbers
-			const numerator = new BigNumber(76564);
-			const denominator = new BigNumber(676373677);
-			const target = new BigNumber(105762562);
-			// rounding error = ((76564*105762562/676373677) - floor(76564*105762562/676373677)) /
-			// (76564*105762562/676373677) = 0.0007%
-			const isRoundingError = await exchangeWrapper.isRoundingErrorAsync(numerator, denominator, target);
-			expect(isRoundingError).to.be.false();
-		});
-	});
-
-	describe('getPartialAmount', () => {
-		it('should return the numerator/denominator*target', async () => {
-			const numerator = new BigNumber(1);
-			const denominator = new BigNumber(2);
-			const target = new BigNumber(10);
-
-			const partialAmount = await exchangeWrapper.getPartialAmountAsync(numerator, denominator, target);
-			const expectedPartialAmount = 5;
-			expect(partialAmount).to.be.bignumber.equal(expectedPartialAmount);
-		});
-
-		it('should round down', async () => {
-			const numerator = new BigNumber(2);
-			const denominator = new BigNumber(3);
-			const target = new BigNumber(10);
-
-			const partialAmount = await exchangeWrapper.getPartialAmountAsync(numerator, denominator, target);
-			const expectedPartialAmount = 6;
-			expect(partialAmount).to.be.bignumber.equal(expectedPartialAmount);
-		});
-
-		it('should round .5 down', async () => {
-			const numerator = new BigNumber(1);
-			const denominator = new BigNumber(20);
-			const target = new BigNumber(10);
-
-			const partialAmount = await exchangeWrapper.getPartialAmountAsync(numerator, denominator, target);
-			const expectedPartialAmount = 0;
-			expect(partialAmount).to.be.bignumber.equal(expectedPartialAmount);
-		});
-	});
+    const maker = accounts[0];
+    const feeRecipient = accounts[1] || accounts[accounts.length - 1];
+
+    let order: Order;
+    let exchangeWrapper: ExchangeWrapper;
+    let orderFactory: OrderFactory;
+
+    before(async () => {
+        const [tokenRegistry, exchange] = await Promise.all([TokenRegistry.deployed(), Exchange.deployed()]);
+        exchangeWrapper = new ExchangeWrapper(exchange);
+        const [repAddress, dgdAddress] = await Promise.all([
+            tokenRegistry.getTokenAddressBySymbol('REP'),
+            tokenRegistry.getTokenAddressBySymbol('DGD'),
+        ]);
+        const defaultOrderParams = {
+            exchangeContractAddress: Exchange.address,
+            maker,
+            feeRecipient,
+            makerToken: repAddress,
+            takerToken: dgdAddress,
+            makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
+            takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18),
+            makerFee: ZeroEx.toBaseUnitAmount(new BigNumber(1), 18),
+            takerFee: ZeroEx.toBaseUnitAmount(new BigNumber(1), 18),
+        };
+        orderFactory = new OrderFactory(defaultOrderParams);
+    });
+
+    beforeEach(async () => {
+        order = await orderFactory.newSignedOrderAsync();
+    });
+
+    describe('getOrderHash', () => {
+        it('should output the correct orderHash', async () => {
+            const orderHashHex = await exchangeWrapper.getOrderHashAsync(order);
+            expect(order.params.orderHashHex).to.be.equal(orderHashHex);
+        });
+    });
+
+    describe('isValidSignature', () => {
+        beforeEach(async () => {
+            order = await orderFactory.newSignedOrderAsync();
+        });
+
+        it('should return true with a valid signature', async () => {
+            const success = await exchangeWrapper.isValidSignatureAsync(order);
+            const isValidSignature = order.isValidSignature();
+            expect(isValidSignature).to.be.true();
+            expect(success).to.be.true();
+        });
+
+        it('should return false with an invalid signature', async () => {
+            order.params.r = ethUtil.bufferToHex(ethUtil.sha3('invalidR'));
+            order.params.s = ethUtil.bufferToHex(ethUtil.sha3('invalidS'));
+            const success = await exchangeWrapper.isValidSignatureAsync(order);
+            expect(order.isValidSignature()).to.be.false();
+            expect(success).to.be.false();
+        });
+    });
+
+    describe('isRoundingError', () => {
+        it('should return false if there is a rounding error of 0.1%', async () => {
+            const numerator = new BigNumber(20);
+            const denominator = new BigNumber(999);
+            const target = new BigNumber(50);
+            // rounding error = ((20*50/999) - floor(20*50/999)) / (20*50/999) = 0.1%
+            const isRoundingError = await exchangeWrapper.isRoundingErrorAsync(numerator, denominator, target);
+            expect(isRoundingError).to.be.false();
+        });
+
+        it('should return false if there is a rounding of 0.09%', async () => {
+            const numerator = new BigNumber(20);
+            const denominator = new BigNumber(9991);
+            const target = new BigNumber(500);
+            // rounding error = ((20*500/9991) - floor(20*500/9991)) / (20*500/9991) = 0.09%
+            const isRoundingError = await exchangeWrapper.isRoundingErrorAsync(numerator, denominator, target);
+            expect(isRoundingError).to.be.false();
+        });
+
+        it('should return true if there is a rounding error of 0.11%', async () => {
+            const numerator = new BigNumber(20);
+            const denominator = new BigNumber(9989);
+            const target = new BigNumber(500);
+            // rounding error = ((20*500/9989) - floor(20*500/9989)) / (20*500/9989) = 0.011%
+            const isRoundingError = await exchangeWrapper.isRoundingErrorAsync(numerator, denominator, target);
+            expect(isRoundingError).to.be.true();
+        });
+
+        it('should return true if there is a rounding error > 0.1%', async () => {
+            const numerator = new BigNumber(3);
+            const denominator = new BigNumber(7);
+            const target = new BigNumber(10);
+            // rounding error = ((3*10/7) - floor(3*10/7)) / (3*10/7) = 6.67%
+            const isRoundingError = await exchangeWrapper.isRoundingErrorAsync(numerator, denominator, target);
+            expect(isRoundingError).to.be.true();
+        });
+
+        it('should return false when there is no rounding error', async () => {
+            const numerator = new BigNumber(1);
+            const denominator = new BigNumber(2);
+            const target = new BigNumber(10);
+
+            const isRoundingError = await exchangeWrapper.isRoundingErrorAsync(numerator, denominator, target);
+            expect(isRoundingError).to.be.false();
+        });
+
+        it('should return false when there is rounding error <= 0.1%', async () => {
+            // randomly generated numbers
+            const numerator = new BigNumber(76564);
+            const denominator = new BigNumber(676373677);
+            const target = new BigNumber(105762562);
+            // rounding error = ((76564*105762562/676373677) - floor(76564*105762562/676373677)) /
+            // (76564*105762562/676373677) = 0.0007%
+            const isRoundingError = await exchangeWrapper.isRoundingErrorAsync(numerator, denominator, target);
+            expect(isRoundingError).to.be.false();
+        });
+    });
+
+    describe('getPartialAmount', () => {
+        it('should return the numerator/denominator*target', async () => {
+            const numerator = new BigNumber(1);
+            const denominator = new BigNumber(2);
+            const target = new BigNumber(10);
+
+            const partialAmount = await exchangeWrapper.getPartialAmountAsync(numerator, denominator, target);
+            const expectedPartialAmount = 5;
+            expect(partialAmount).to.be.bignumber.equal(expectedPartialAmount);
+        });
+
+        it('should round down', async () => {
+            const numerator = new BigNumber(2);
+            const denominator = new BigNumber(3);
+            const target = new BigNumber(10);
+
+            const partialAmount = await exchangeWrapper.getPartialAmountAsync(numerator, denominator, target);
+            const expectedPartialAmount = 6;
+            expect(partialAmount).to.be.bignumber.equal(expectedPartialAmount);
+        });
+
+        it('should round .5 down', async () => {
+            const numerator = new BigNumber(1);
+            const denominator = new BigNumber(20);
+            const target = new BigNumber(10);
+
+            const partialAmount = await exchangeWrapper.getPartialAmountAsync(numerator, denominator, target);
+            const expectedPartialAmount = 0;
+            expect(partialAmount).to.be.bignumber.equal(expectedPartialAmount);
+        });
+    });
 });
diff --git a/packages/contracts/test/ts/exchange/wrapper.ts b/packages/contracts/test/ts/exchange/wrapper.ts
index e0243fc1b..e69e08bcf 100644
--- a/packages/contracts/test/ts/exchange/wrapper.ts
+++ b/packages/contracts/test/ts/exchange/wrapper.ts
@@ -17,332 +17,332 @@ const expect = chai.expect;
 const { Exchange, TokenTransferProxy, DummyToken, TokenRegistry } = new Artifacts(artifacts);
 
 contract('Exchange', (accounts: string[]) => {
-	const maker = accounts[0];
-	const tokenOwner = accounts[0];
-	const taker = accounts[1] || accounts[accounts.length - 1];
-	const feeRecipient = accounts[2] || accounts[accounts.length - 1];
-
-	const INIT_BAL = ZeroEx.toBaseUnitAmount(new BigNumber(10000), 18);
-	const INIT_ALLOW = ZeroEx.toBaseUnitAmount(new BigNumber(10000), 18);
-
-	let rep: ContractInstance;
-	let dgd: ContractInstance;
-	let zrx: ContractInstance;
-	let exchange: ContractInstance;
-	let tokenRegistry: ContractInstance;
-
-	let balances: BalancesByOwner;
-
-	let exWrapper: ExchangeWrapper;
-	let dmyBalances: Balances;
-	let orderFactory: OrderFactory;
-
-	before(async () => {
-		[tokenRegistry, exchange] = await Promise.all([TokenRegistry.deployed(), Exchange.deployed()]);
-		exWrapper = new ExchangeWrapper(exchange);
-		const [repAddress, dgdAddress, zrxAddress] = await Promise.all([
-			tokenRegistry.getTokenAddressBySymbol('REP'),
-			tokenRegistry.getTokenAddressBySymbol('DGD'),
-			tokenRegistry.getTokenAddressBySymbol('ZRX'),
-		]);
-
-		const defaultOrderParams = {
-			exchangeContractAddress: Exchange.address,
-			maker,
-			feeRecipient,
-			makerToken: repAddress,
-			takerToken: dgdAddress,
-			makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
-			takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18),
-			makerFee: ZeroEx.toBaseUnitAmount(new BigNumber(1), 18),
-			takerFee: ZeroEx.toBaseUnitAmount(new BigNumber(1), 18),
-		};
-		orderFactory = new OrderFactory(defaultOrderParams);
-
-		[rep, dgd, zrx] = await Promise.all([
-			DummyToken.at(repAddress),
-			DummyToken.at(dgdAddress),
-			DummyToken.at(zrxAddress),
-		]);
-		dmyBalances = new Balances([rep, dgd, zrx], [maker, taker, feeRecipient]);
-		await Promise.all([
-			rep.approve(TokenTransferProxy.address, INIT_ALLOW, { from: maker }),
-			rep.approve(TokenTransferProxy.address, INIT_ALLOW, { from: taker }),
-			rep.setBalance(maker, INIT_BAL, { from: tokenOwner }),
-			rep.setBalance(taker, INIT_BAL, { from: tokenOwner }),
-			dgd.approve(TokenTransferProxy.address, INIT_ALLOW, { from: maker }),
-			dgd.approve(TokenTransferProxy.address, INIT_ALLOW, { from: taker }),
-			dgd.setBalance(maker, INIT_BAL, { from: tokenOwner }),
-			dgd.setBalance(taker, INIT_BAL, { from: tokenOwner }),
-			zrx.approve(TokenTransferProxy.address, INIT_ALLOW, { from: maker }),
-			zrx.approve(TokenTransferProxy.address, INIT_ALLOW, { from: taker }),
-			zrx.setBalance(maker, INIT_BAL, { from: tokenOwner }),
-			zrx.setBalance(taker, INIT_BAL, { from: tokenOwner }),
-		]);
-	});
-
-	describe('fillOrKillOrder', () => {
-		beforeEach(async () => {
-			balances = await dmyBalances.getAsync();
-		});
-
-		it('should transfer the correct amounts', async () => {
-			const order = await orderFactory.newSignedOrderAsync({
-				makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
-				takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18),
-			});
-			const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
-			await exWrapper.fillOrKillOrderAsync(order, taker, {
-				fillTakerTokenAmount,
-			});
-
-			const newBalances = await dmyBalances.getAsync();
-
-			const fillMakerTokenAmount = fillTakerTokenAmount
-				.times(order.params.makerTokenAmount)
-				.dividedToIntegerBy(order.params.takerTokenAmount);
-			const makerFee = order.params.makerFee
-				.times(fillMakerTokenAmount)
-				.dividedToIntegerBy(order.params.makerTokenAmount);
-			const takerFee = order.params.takerFee
-				.times(fillMakerTokenAmount)
-				.dividedToIntegerBy(order.params.makerTokenAmount);
-			expect(newBalances[maker][order.params.makerToken]).to.be.bignumber.equal(
-				balances[maker][order.params.makerToken].minus(fillMakerTokenAmount),
-			);
-			expect(newBalances[maker][order.params.takerToken]).to.be.bignumber.equal(
-				balances[maker][order.params.takerToken].add(fillTakerTokenAmount),
-			);
-			expect(newBalances[maker][zrx.address]).to.be.bignumber.equal(balances[maker][zrx.address].minus(makerFee));
-			expect(newBalances[taker][order.params.takerToken]).to.be.bignumber.equal(
-				balances[taker][order.params.takerToken].minus(fillTakerTokenAmount),
-			);
-			expect(newBalances[taker][order.params.makerToken]).to.be.bignumber.equal(
-				balances[taker][order.params.makerToken].add(fillMakerTokenAmount),
-			);
-			expect(newBalances[taker][zrx.address]).to.be.bignumber.equal(balances[taker][zrx.address].minus(takerFee));
-			expect(newBalances[feeRecipient][zrx.address]).to.be.bignumber.equal(
-				balances[feeRecipient][zrx.address].add(makerFee.add(takerFee)),
-			);
-		});
-
-		it('should throw if an order is expired', async () => {
-			const order = await orderFactory.newSignedOrderAsync({
-				expirationTimestampInSec: new BigNumber(Math.floor((Date.now() - 10000) / 1000)),
-			});
-
-			return expect(exWrapper.fillOrKillOrderAsync(order, taker)).to.be.rejectedWith(constants.REVERT);
-		});
-
-		it('should throw if entire fillTakerTokenAmount not filled', async () => {
-			const order = await orderFactory.newSignedOrderAsync();
-
-			const from = taker;
-			await exWrapper.fillOrderAsync(order, from, {
-				fillTakerTokenAmount: order.params.takerTokenAmount.div(2),
-			});
-
-			return expect(exWrapper.fillOrKillOrderAsync(order, taker)).to.be.rejectedWith(constants.REVERT);
-		});
-	});
-
-	describe('batch functions', () => {
-		let orders: Order[];
-		beforeEach(async () => {
-			orders = await Promise.all([
-				orderFactory.newSignedOrderAsync(),
-				orderFactory.newSignedOrderAsync(),
-				orderFactory.newSignedOrderAsync(),
-			]);
-			balances = await dmyBalances.getAsync();
-		});
-
-		describe('batchFillOrders', () => {
-			it('should transfer the correct amounts', async () => {
-				const fillTakerTokenAmounts: BigNumber[] = [];
-				const makerToken = rep.address;
-				const takerToken = dgd.address;
-				orders.forEach(order => {
-					const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
-					const fillMakerTokenAmount = fillTakerTokenAmount
-						.times(order.params.makerTokenAmount)
-						.dividedToIntegerBy(order.params.takerTokenAmount);
-					const makerFee = order.params.makerFee
-						.times(fillMakerTokenAmount)
-						.dividedToIntegerBy(order.params.makerTokenAmount);
-					const takerFee = order.params.takerFee
-						.times(fillMakerTokenAmount)
-						.dividedToIntegerBy(order.params.makerTokenAmount);
-					fillTakerTokenAmounts.push(fillTakerTokenAmount);
-					balances[maker][makerToken] = balances[maker][makerToken].minus(fillMakerTokenAmount);
-					balances[maker][takerToken] = balances[maker][takerToken].add(fillTakerTokenAmount);
-					balances[maker][zrx.address] = balances[maker][zrx.address].minus(makerFee);
-					balances[taker][makerToken] = balances[taker][makerToken].add(fillMakerTokenAmount);
-					balances[taker][takerToken] = balances[taker][takerToken].minus(fillTakerTokenAmount);
-					balances[taker][zrx.address] = balances[taker][zrx.address].minus(takerFee);
-					balances[feeRecipient][zrx.address] = balances[feeRecipient][zrx.address].add(
-						makerFee.add(takerFee),
-					);
-				});
-
-				await exWrapper.batchFillOrdersAsync(orders, taker, {
-					fillTakerTokenAmounts,
-				});
-
-				const newBalances = await dmyBalances.getAsync();
-				expect(newBalances).to.be.deep.equal(balances);
-			});
-		});
-
-		describe('batchFillOrKillOrders', () => {
-			it('should transfer the correct amounts', async () => {
-				const fillTakerTokenAmounts: BigNumber[] = [];
-				const makerToken = rep.address;
-				const takerToken = dgd.address;
-				orders.forEach(order => {
-					const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
-					const fillMakerTokenAmount = fillTakerTokenAmount
-						.times(order.params.makerTokenAmount)
-						.dividedToIntegerBy(order.params.takerTokenAmount);
-					const makerFee = order.params.makerFee
-						.times(fillMakerTokenAmount)
-						.dividedToIntegerBy(order.params.makerTokenAmount);
-					const takerFee = order.params.takerFee
-						.times(fillMakerTokenAmount)
-						.dividedToIntegerBy(order.params.makerTokenAmount);
-					fillTakerTokenAmounts.push(fillTakerTokenAmount);
-					balances[maker][makerToken] = balances[maker][makerToken].minus(fillMakerTokenAmount);
-					balances[maker][takerToken] = balances[maker][takerToken].add(fillTakerTokenAmount);
-					balances[maker][zrx.address] = balances[maker][zrx.address].minus(makerFee);
-					balances[taker][makerToken] = balances[taker][makerToken].add(fillMakerTokenAmount);
-					balances[taker][takerToken] = balances[taker][takerToken].minus(fillTakerTokenAmount);
-					balances[taker][zrx.address] = balances[taker][zrx.address].minus(takerFee);
-					balances[feeRecipient][zrx.address] = balances[feeRecipient][zrx.address].add(
-						makerFee.add(takerFee),
-					);
-				});
-
-				await exWrapper.batchFillOrKillOrdersAsync(orders, taker, {
-					fillTakerTokenAmounts,
-				});
-
-				const newBalances = await dmyBalances.getAsync();
-				expect(newBalances).to.be.deep.equal(balances);
-			});
-
-			it('should throw if a single order does not fill the expected amount', async () => {
-				const fillTakerTokenAmounts: BigNumber[] = [];
-				orders.forEach(order => {
-					const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
-					fillTakerTokenAmounts.push(fillTakerTokenAmount);
-				});
-
-				await exWrapper.fillOrKillOrderAsync(orders[0], taker);
-
-				return expect(
-					exWrapper.batchFillOrKillOrdersAsync(orders, taker, {
-						fillTakerTokenAmounts,
-					}),
-				).to.be.rejectedWith(constants.REVERT);
-			});
-		});
-
-		describe('fillOrdersUpTo', () => {
-			it('should stop when the entire fillTakerTokenAmount is filled', async () => {
-				const fillTakerTokenAmount = orders[0].params.takerTokenAmount.plus(
-					orders[1].params.takerTokenAmount.div(2),
-				);
-				await exWrapper.fillOrdersUpToAsync(orders, taker, {
-					fillTakerTokenAmount,
-				});
-
-				const newBalances = await dmyBalances.getAsync();
-
-				const fillMakerTokenAmount = orders[0].params.makerTokenAmount.add(
-					orders[1].params.makerTokenAmount.dividedToIntegerBy(2),
-				);
-				const makerFee = orders[0].params.makerFee.add(orders[1].params.makerFee.dividedToIntegerBy(2));
-				const takerFee = orders[0].params.takerFee.add(orders[1].params.takerFee.dividedToIntegerBy(2));
-				expect(newBalances[maker][orders[0].params.makerToken]).to.be.bignumber.equal(
-					balances[maker][orders[0].params.makerToken].minus(fillMakerTokenAmount),
-				);
-				expect(newBalances[maker][orders[0].params.takerToken]).to.be.bignumber.equal(
-					balances[maker][orders[0].params.takerToken].add(fillTakerTokenAmount),
-				);
-				expect(newBalances[maker][zrx.address]).to.be.bignumber.equal(
-					balances[maker][zrx.address].minus(makerFee),
-				);
-				expect(newBalances[taker][orders[0].params.takerToken]).to.be.bignumber.equal(
-					balances[taker][orders[0].params.takerToken].minus(fillTakerTokenAmount),
-				);
-				expect(newBalances[taker][orders[0].params.makerToken]).to.be.bignumber.equal(
-					balances[taker][orders[0].params.makerToken].add(fillMakerTokenAmount),
-				);
-				expect(newBalances[taker][zrx.address]).to.be.bignumber.equal(
-					balances[taker][zrx.address].minus(takerFee),
-				);
-				expect(newBalances[feeRecipient][zrx.address]).to.be.bignumber.equal(
-					balances[feeRecipient][zrx.address].add(makerFee.add(takerFee)),
-				);
-			});
-
-			it('should fill all orders if cannot fill entire fillTakerTokenAmount', async () => {
-				const fillTakerTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(100000), 18);
-				orders.forEach(order => {
-					balances[maker][order.params.makerToken] = balances[maker][order.params.makerToken].minus(
-						order.params.makerTokenAmount,
-					);
-					balances[maker][order.params.takerToken] = balances[maker][order.params.takerToken].add(
-						order.params.takerTokenAmount,
-					);
-					balances[maker][zrx.address] = balances[maker][zrx.address].minus(order.params.makerFee);
-					balances[taker][order.params.makerToken] = balances[taker][order.params.makerToken].add(
-						order.params.makerTokenAmount,
-					);
-					balances[taker][order.params.takerToken] = balances[taker][order.params.takerToken].minus(
-						order.params.takerTokenAmount,
-					);
-					balances[taker][zrx.address] = balances[taker][zrx.address].minus(order.params.takerFee);
-					balances[feeRecipient][zrx.address] = balances[feeRecipient][zrx.address].add(
-						order.params.makerFee.add(order.params.takerFee),
-					);
-				});
-				await exWrapper.fillOrdersUpToAsync(orders, taker, {
-					fillTakerTokenAmount,
-				});
-
-				const newBalances = await dmyBalances.getAsync();
-				expect(newBalances).to.be.deep.equal(balances);
-			});
-
-			it('should throw when an order does not use the same takerToken', async () => {
-				orders = await Promise.all([
-					orderFactory.newSignedOrderAsync(),
-					orderFactory.newSignedOrderAsync({ takerToken: zrx.address }),
-					orderFactory.newSignedOrderAsync(),
-				]);
-
-				return expect(
-					exWrapper.fillOrdersUpToAsync(orders, taker, {
-						fillTakerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(1000), 18),
-					}),
-				).to.be.rejectedWith(constants.REVERT);
-			});
-		});
-
-		describe('batchCancelOrders', () => {
-			it('should be able to cancel multiple orders', async () => {
-				const cancelTakerTokenAmounts = _.map(orders, order => order.params.takerTokenAmount);
-				await exWrapper.batchCancelOrdersAsync(orders, maker, {
-					cancelTakerTokenAmounts,
-				});
-
-				await exWrapper.batchFillOrdersAsync(orders, taker, {
-					fillTakerTokenAmounts: cancelTakerTokenAmounts,
-				});
-				const newBalances = await dmyBalances.getAsync();
-				expect(balances).to.be.deep.equal(newBalances);
-			});
-		});
-	});
+    const maker = accounts[0];
+    const tokenOwner = accounts[0];
+    const taker = accounts[1] || accounts[accounts.length - 1];
+    const feeRecipient = accounts[2] || accounts[accounts.length - 1];
+
+    const INIT_BAL = ZeroEx.toBaseUnitAmount(new BigNumber(10000), 18);
+    const INIT_ALLOW = ZeroEx.toBaseUnitAmount(new BigNumber(10000), 18);
+
+    let rep: ContractInstance;
+    let dgd: ContractInstance;
+    let zrx: ContractInstance;
+    let exchange: ContractInstance;
+    let tokenRegistry: ContractInstance;
+
+    let balances: BalancesByOwner;
+
+    let exWrapper: ExchangeWrapper;
+    let dmyBalances: Balances;
+    let orderFactory: OrderFactory;
+
+    before(async () => {
+        [tokenRegistry, exchange] = await Promise.all([TokenRegistry.deployed(), Exchange.deployed()]);
+        exWrapper = new ExchangeWrapper(exchange);
+        const [repAddress, dgdAddress, zrxAddress] = await Promise.all([
+            tokenRegistry.getTokenAddressBySymbol('REP'),
+            tokenRegistry.getTokenAddressBySymbol('DGD'),
+            tokenRegistry.getTokenAddressBySymbol('ZRX'),
+        ]);
+
+        const defaultOrderParams = {
+            exchangeContractAddress: Exchange.address,
+            maker,
+            feeRecipient,
+            makerToken: repAddress,
+            takerToken: dgdAddress,
+            makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
+            takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18),
+            makerFee: ZeroEx.toBaseUnitAmount(new BigNumber(1), 18),
+            takerFee: ZeroEx.toBaseUnitAmount(new BigNumber(1), 18),
+        };
+        orderFactory = new OrderFactory(defaultOrderParams);
+
+        [rep, dgd, zrx] = await Promise.all([
+            DummyToken.at(repAddress),
+            DummyToken.at(dgdAddress),
+            DummyToken.at(zrxAddress),
+        ]);
+        dmyBalances = new Balances([rep, dgd, zrx], [maker, taker, feeRecipient]);
+        await Promise.all([
+            rep.approve(TokenTransferProxy.address, INIT_ALLOW, { from: maker }),
+            rep.approve(TokenTransferProxy.address, INIT_ALLOW, { from: taker }),
+            rep.setBalance(maker, INIT_BAL, { from: tokenOwner }),
+            rep.setBalance(taker, INIT_BAL, { from: tokenOwner }),
+            dgd.approve(TokenTransferProxy.address, INIT_ALLOW, { from: maker }),
+            dgd.approve(TokenTransferProxy.address, INIT_ALLOW, { from: taker }),
+            dgd.setBalance(maker, INIT_BAL, { from: tokenOwner }),
+            dgd.setBalance(taker, INIT_BAL, { from: tokenOwner }),
+            zrx.approve(TokenTransferProxy.address, INIT_ALLOW, { from: maker }),
+            zrx.approve(TokenTransferProxy.address, INIT_ALLOW, { from: taker }),
+            zrx.setBalance(maker, INIT_BAL, { from: tokenOwner }),
+            zrx.setBalance(taker, INIT_BAL, { from: tokenOwner }),
+        ]);
+    });
+
+    describe('fillOrKillOrder', () => {
+        beforeEach(async () => {
+            balances = await dmyBalances.getAsync();
+        });
+
+        it('should transfer the correct amounts', async () => {
+            const order = await orderFactory.newSignedOrderAsync({
+                makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
+                takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18),
+            });
+            const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
+            await exWrapper.fillOrKillOrderAsync(order, taker, {
+                fillTakerTokenAmount,
+            });
+
+            const newBalances = await dmyBalances.getAsync();
+
+            const fillMakerTokenAmount = fillTakerTokenAmount
+                .times(order.params.makerTokenAmount)
+                .dividedToIntegerBy(order.params.takerTokenAmount);
+            const makerFee = order.params.makerFee
+                .times(fillMakerTokenAmount)
+                .dividedToIntegerBy(order.params.makerTokenAmount);
+            const takerFee = order.params.takerFee
+                .times(fillMakerTokenAmount)
+                .dividedToIntegerBy(order.params.makerTokenAmount);
+            expect(newBalances[maker][order.params.makerToken]).to.be.bignumber.equal(
+                balances[maker][order.params.makerToken].minus(fillMakerTokenAmount),
+            );
+            expect(newBalances[maker][order.params.takerToken]).to.be.bignumber.equal(
+                balances[maker][order.params.takerToken].add(fillTakerTokenAmount),
+            );
+            expect(newBalances[maker][zrx.address]).to.be.bignumber.equal(balances[maker][zrx.address].minus(makerFee));
+            expect(newBalances[taker][order.params.takerToken]).to.be.bignumber.equal(
+                balances[taker][order.params.takerToken].minus(fillTakerTokenAmount),
+            );
+            expect(newBalances[taker][order.params.makerToken]).to.be.bignumber.equal(
+                balances[taker][order.params.makerToken].add(fillMakerTokenAmount),
+            );
+            expect(newBalances[taker][zrx.address]).to.be.bignumber.equal(balances[taker][zrx.address].minus(takerFee));
+            expect(newBalances[feeRecipient][zrx.address]).to.be.bignumber.equal(
+                balances[feeRecipient][zrx.address].add(makerFee.add(takerFee)),
+            );
+        });
+
+        it('should throw if an order is expired', async () => {
+            const order = await orderFactory.newSignedOrderAsync({
+                expirationTimestampInSec: new BigNumber(Math.floor((Date.now() - 10000) / 1000)),
+            });
+
+            return expect(exWrapper.fillOrKillOrderAsync(order, taker)).to.be.rejectedWith(constants.REVERT);
+        });
+
+        it('should throw if entire fillTakerTokenAmount not filled', async () => {
+            const order = await orderFactory.newSignedOrderAsync();
+
+            const from = taker;
+            await exWrapper.fillOrderAsync(order, from, {
+                fillTakerTokenAmount: order.params.takerTokenAmount.div(2),
+            });
+
+            return expect(exWrapper.fillOrKillOrderAsync(order, taker)).to.be.rejectedWith(constants.REVERT);
+        });
+    });
+
+    describe('batch functions', () => {
+        let orders: Order[];
+        beforeEach(async () => {
+            orders = await Promise.all([
+                orderFactory.newSignedOrderAsync(),
+                orderFactory.newSignedOrderAsync(),
+                orderFactory.newSignedOrderAsync(),
+            ]);
+            balances = await dmyBalances.getAsync();
+        });
+
+        describe('batchFillOrders', () => {
+            it('should transfer the correct amounts', async () => {
+                const fillTakerTokenAmounts: BigNumber[] = [];
+                const makerToken = rep.address;
+                const takerToken = dgd.address;
+                orders.forEach(order => {
+                    const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
+                    const fillMakerTokenAmount = fillTakerTokenAmount
+                        .times(order.params.makerTokenAmount)
+                        .dividedToIntegerBy(order.params.takerTokenAmount);
+                    const makerFee = order.params.makerFee
+                        .times(fillMakerTokenAmount)
+                        .dividedToIntegerBy(order.params.makerTokenAmount);
+                    const takerFee = order.params.takerFee
+                        .times(fillMakerTokenAmount)
+                        .dividedToIntegerBy(order.params.makerTokenAmount);
+                    fillTakerTokenAmounts.push(fillTakerTokenAmount);
+                    balances[maker][makerToken] = balances[maker][makerToken].minus(fillMakerTokenAmount);
+                    balances[maker][takerToken] = balances[maker][takerToken].add(fillTakerTokenAmount);
+                    balances[maker][zrx.address] = balances[maker][zrx.address].minus(makerFee);
+                    balances[taker][makerToken] = balances[taker][makerToken].add(fillMakerTokenAmount);
+                    balances[taker][takerToken] = balances[taker][takerToken].minus(fillTakerTokenAmount);
+                    balances[taker][zrx.address] = balances[taker][zrx.address].minus(takerFee);
+                    balances[feeRecipient][zrx.address] = balances[feeRecipient][zrx.address].add(
+                        makerFee.add(takerFee),
+                    );
+                });
+
+                await exWrapper.batchFillOrdersAsync(orders, taker, {
+                    fillTakerTokenAmounts,
+                });
+
+                const newBalances = await dmyBalances.getAsync();
+                expect(newBalances).to.be.deep.equal(balances);
+            });
+        });
+
+        describe('batchFillOrKillOrders', () => {
+            it('should transfer the correct amounts', async () => {
+                const fillTakerTokenAmounts: BigNumber[] = [];
+                const makerToken = rep.address;
+                const takerToken = dgd.address;
+                orders.forEach(order => {
+                    const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
+                    const fillMakerTokenAmount = fillTakerTokenAmount
+                        .times(order.params.makerTokenAmount)
+                        .dividedToIntegerBy(order.params.takerTokenAmount);
+                    const makerFee = order.params.makerFee
+                        .times(fillMakerTokenAmount)
+                        .dividedToIntegerBy(order.params.makerTokenAmount);
+                    const takerFee = order.params.takerFee
+                        .times(fillMakerTokenAmount)
+                        .dividedToIntegerBy(order.params.makerTokenAmount);
+                    fillTakerTokenAmounts.push(fillTakerTokenAmount);
+                    balances[maker][makerToken] = balances[maker][makerToken].minus(fillMakerTokenAmount);
+                    balances[maker][takerToken] = balances[maker][takerToken].add(fillTakerTokenAmount);
+                    balances[maker][zrx.address] = balances[maker][zrx.address].minus(makerFee);
+                    balances[taker][makerToken] = balances[taker][makerToken].add(fillMakerTokenAmount);
+                    balances[taker][takerToken] = balances[taker][takerToken].minus(fillTakerTokenAmount);
+                    balances[taker][zrx.address] = balances[taker][zrx.address].minus(takerFee);
+                    balances[feeRecipient][zrx.address] = balances[feeRecipient][zrx.address].add(
+                        makerFee.add(takerFee),
+                    );
+                });
+
+                await exWrapper.batchFillOrKillOrdersAsync(orders, taker, {
+                    fillTakerTokenAmounts,
+                });
+
+                const newBalances = await dmyBalances.getAsync();
+                expect(newBalances).to.be.deep.equal(balances);
+            });
+
+            it('should throw if a single order does not fill the expected amount', async () => {
+                const fillTakerTokenAmounts: BigNumber[] = [];
+                orders.forEach(order => {
+                    const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
+                    fillTakerTokenAmounts.push(fillTakerTokenAmount);
+                });
+
+                await exWrapper.fillOrKillOrderAsync(orders[0], taker);
+
+                return expect(
+                    exWrapper.batchFillOrKillOrdersAsync(orders, taker, {
+                        fillTakerTokenAmounts,
+                    }),
+                ).to.be.rejectedWith(constants.REVERT);
+            });
+        });
+
+        describe('fillOrdersUpTo', () => {
+            it('should stop when the entire fillTakerTokenAmount is filled', async () => {
+                const fillTakerTokenAmount = orders[0].params.takerTokenAmount.plus(
+                    orders[1].params.takerTokenAmount.div(2),
+                );
+                await exWrapper.fillOrdersUpToAsync(orders, taker, {
+                    fillTakerTokenAmount,
+                });
+
+                const newBalances = await dmyBalances.getAsync();
+
+                const fillMakerTokenAmount = orders[0].params.makerTokenAmount.add(
+                    orders[1].params.makerTokenAmount.dividedToIntegerBy(2),
+                );
+                const makerFee = orders[0].params.makerFee.add(orders[1].params.makerFee.dividedToIntegerBy(2));
+                const takerFee = orders[0].params.takerFee.add(orders[1].params.takerFee.dividedToIntegerBy(2));
+                expect(newBalances[maker][orders[0].params.makerToken]).to.be.bignumber.equal(
+                    balances[maker][orders[0].params.makerToken].minus(fillMakerTokenAmount),
+                );
+                expect(newBalances[maker][orders[0].params.takerToken]).to.be.bignumber.equal(
+                    balances[maker][orders[0].params.takerToken].add(fillTakerTokenAmount),
+                );
+                expect(newBalances[maker][zrx.address]).to.be.bignumber.equal(
+                    balances[maker][zrx.address].minus(makerFee),
+                );
+                expect(newBalances[taker][orders[0].params.takerToken]).to.be.bignumber.equal(
+                    balances[taker][orders[0].params.takerToken].minus(fillTakerTokenAmount),
+                );
+                expect(newBalances[taker][orders[0].params.makerToken]).to.be.bignumber.equal(
+                    balances[taker][orders[0].params.makerToken].add(fillMakerTokenAmount),
+                );
+                expect(newBalances[taker][zrx.address]).to.be.bignumber.equal(
+                    balances[taker][zrx.address].minus(takerFee),
+                );
+                expect(newBalances[feeRecipient][zrx.address]).to.be.bignumber.equal(
+                    balances[feeRecipient][zrx.address].add(makerFee.add(takerFee)),
+                );
+            });
+
+            it('should fill all orders if cannot fill entire fillTakerTokenAmount', async () => {
+                const fillTakerTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(100000), 18);
+                orders.forEach(order => {
+                    balances[maker][order.params.makerToken] = balances[maker][order.params.makerToken].minus(
+                        order.params.makerTokenAmount,
+                    );
+                    balances[maker][order.params.takerToken] = balances[maker][order.params.takerToken].add(
+                        order.params.takerTokenAmount,
+                    );
+                    balances[maker][zrx.address] = balances[maker][zrx.address].minus(order.params.makerFee);
+                    balances[taker][order.params.makerToken] = balances[taker][order.params.makerToken].add(
+                        order.params.makerTokenAmount,
+                    );
+                    balances[taker][order.params.takerToken] = balances[taker][order.params.takerToken].minus(
+                        order.params.takerTokenAmount,
+                    );
+                    balances[taker][zrx.address] = balances[taker][zrx.address].minus(order.params.takerFee);
+                    balances[feeRecipient][zrx.address] = balances[feeRecipient][zrx.address].add(
+                        order.params.makerFee.add(order.params.takerFee),
+                    );
+                });
+                await exWrapper.fillOrdersUpToAsync(orders, taker, {
+                    fillTakerTokenAmount,
+                });
+
+                const newBalances = await dmyBalances.getAsync();
+                expect(newBalances).to.be.deep.equal(balances);
+            });
+
+            it('should throw when an order does not use the same takerToken', async () => {
+                orders = await Promise.all([
+                    orderFactory.newSignedOrderAsync(),
+                    orderFactory.newSignedOrderAsync({ takerToken: zrx.address }),
+                    orderFactory.newSignedOrderAsync(),
+                ]);
+
+                return expect(
+                    exWrapper.fillOrdersUpToAsync(orders, taker, {
+                        fillTakerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(1000), 18),
+                    }),
+                ).to.be.rejectedWith(constants.REVERT);
+            });
+        });
+
+        describe('batchCancelOrders', () => {
+            it('should be able to cancel multiple orders', async () => {
+                const cancelTakerTokenAmounts = _.map(orders, order => order.params.takerTokenAmount);
+                await exWrapper.batchCancelOrdersAsync(orders, maker, {
+                    cancelTakerTokenAmounts,
+                });
+
+                await exWrapper.batchFillOrdersAsync(orders, taker, {
+                    fillTakerTokenAmounts: cancelTakerTokenAmounts,
+                });
+                const newBalances = await dmyBalances.getAsync();
+                expect(balances).to.be.deep.equal(newBalances);
+            });
+        });
+    });
 });
diff --git a/packages/contracts/test/ts/multi_sig_with_time_lock.ts b/packages/contracts/test/ts/multi_sig_with_time_lock.ts
index fa2028437..ea939a758 100644
--- a/packages/contracts/test/ts/multi_sig_with_time_lock.ts
+++ b/packages/contracts/test/ts/multi_sig_with_time_lock.ts
@@ -23,93 +23,93 @@ const expect = chai.expect;
 const web3: Web3 = (global as any).web3;
 
 contract('MultiSigWalletWithTimeLock', (accounts: string[]) => {
-	const owners = [accounts[0], accounts[1]];
-	const SECONDS_TIME_LOCKED = 10000;
-
-	let multiSig: ContractInstance;
-	let multiSigWrapper: MultiSigWrapper;
-	let txId: number;
-	let initialSecondsTimeLocked: number;
-	let rpc: RPC;
-
-	before(async () => {
-		multiSig = await MultiSigWalletWithTimeLock.deployed();
-		multiSigWrapper = new MultiSigWrapper(multiSig);
-
-		const secondsTimeLocked = await multiSig.secondsTimeLocked.call();
-		initialSecondsTimeLocked = secondsTimeLocked.toNumber();
-		const rpcUrl = `http://${truffleConf.networks.development.host}:${truffleConf.networks.development.port}`;
-		rpc = new RPC(rpcUrl);
-	});
-
-	describe('changeTimeLock', () => {
-		it('should throw when not called by wallet', async () => {
-			return expect(multiSig.changeTimeLock(SECONDS_TIME_LOCKED, { from: owners[0] })).to.be.rejectedWith(
-				constants.REVERT,
-			);
-		});
-
-		it('should throw without enough confirmations', async () => {
-			const destination = multiSig.address;
-			const from = owners[0];
-			const dataParams = {
-				name: 'changeTimeLock',
-				abi: MULTI_SIG_ABI,
-				args: [SECONDS_TIME_LOCKED],
-			};
-			const subRes = await multiSigWrapper.submitTransactionAsync(destination, from, dataParams);
-
-			txId = subRes.logs[0].args.transactionId.toNumber();
-			return expect(multiSig.executeTransaction(txId)).to.be.rejectedWith(constants.REVERT);
-		});
-
-		it('should set confirmation time with enough confirmations', async () => {
-			const res = await multiSig.confirmTransaction(txId, { from: owners[1] });
-			expect(res.logs).to.have.length(2);
-			const blockNum = await promisify<number>(web3.eth.getBlockNumber)();
-			const blockInfo = await promisify<Web3.BlockWithoutTransactionData>(web3.eth.getBlock)(blockNum);
-			const timestamp = new BigNumber(blockInfo.timestamp);
-			const confirmationTimeBigNum = new BigNumber(await multiSig.confirmationTimes.call(txId));
-
-			expect(timestamp).to.be.bignumber.equal(confirmationTimeBigNum);
-		});
-
-		it('should be executable with enough confirmations and secondsTimeLocked of 0', async () => {
-			expect(initialSecondsTimeLocked).to.be.equal(0);
-
-			const res = await multiSig.executeTransaction(txId);
-			expect(res.logs).to.have.length(2);
-
-			const secondsTimeLocked = new BigNumber(await multiSig.secondsTimeLocked.call());
-			expect(secondsTimeLocked).to.be.bignumber.equal(SECONDS_TIME_LOCKED);
-		});
-
-		const newSecondsTimeLocked = 0;
-		it('should throw if it has enough confirmations but is not past the time lock', async () => {
-			const destination = multiSig.address;
-			const from = owners[0];
-			const dataParams = {
-				name: 'changeTimeLock',
-				abi: MULTI_SIG_ABI,
-				args: [newSecondsTimeLocked],
-			};
-			const subRes = await multiSigWrapper.submitTransactionAsync(destination, from, dataParams);
-
-			txId = subRes.logs[0].args.transactionId.toNumber();
-			const confRes = await multiSig.confirmTransaction(txId, {
-				from: owners[1],
-			});
-			expect(confRes.logs).to.have.length(2);
-
-			return expect(multiSig.executeTransaction(txId)).to.be.rejectedWith(constants.REVERT);
-		});
-
-		it('should execute if it has enough confirmations and is past the time lock', async () => {
-			await rpc.increaseTimeAsync(SECONDS_TIME_LOCKED);
-			await multiSig.executeTransaction(txId);
-
-			const secondsTimeLocked = new BigNumber(await multiSig.secondsTimeLocked.call());
-			expect(secondsTimeLocked).to.be.bignumber.equal(newSecondsTimeLocked);
-		});
-	});
+    const owners = [accounts[0], accounts[1]];
+    const SECONDS_TIME_LOCKED = 10000;
+
+    let multiSig: ContractInstance;
+    let multiSigWrapper: MultiSigWrapper;
+    let txId: number;
+    let initialSecondsTimeLocked: number;
+    let rpc: RPC;
+
+    before(async () => {
+        multiSig = await MultiSigWalletWithTimeLock.deployed();
+        multiSigWrapper = new MultiSigWrapper(multiSig);
+
+        const secondsTimeLocked = await multiSig.secondsTimeLocked.call();
+        initialSecondsTimeLocked = secondsTimeLocked.toNumber();
+        const rpcUrl = `http://${truffleConf.networks.development.host}:${truffleConf.networks.development.port}`;
+        rpc = new RPC(rpcUrl);
+    });
+
+    describe('changeTimeLock', () => {
+        it('should throw when not called by wallet', async () => {
+            return expect(multiSig.changeTimeLock(SECONDS_TIME_LOCKED, { from: owners[0] })).to.be.rejectedWith(
+                constants.REVERT,
+            );
+        });
+
+        it('should throw without enough confirmations', async () => {
+            const destination = multiSig.address;
+            const from = owners[0];
+            const dataParams = {
+                name: 'changeTimeLock',
+                abi: MULTI_SIG_ABI,
+                args: [SECONDS_TIME_LOCKED],
+            };
+            const subRes = await multiSigWrapper.submitTransactionAsync(destination, from, dataParams);
+
+            txId = subRes.logs[0].args.transactionId.toNumber();
+            return expect(multiSig.executeTransaction(txId)).to.be.rejectedWith(constants.REVERT);
+        });
+
+        it('should set confirmation time with enough confirmations', async () => {
+            const res = await multiSig.confirmTransaction(txId, { from: owners[1] });
+            expect(res.logs).to.have.length(2);
+            const blockNum = await promisify<number>(web3.eth.getBlockNumber)();
+            const blockInfo = await promisify<Web3.BlockWithoutTransactionData>(web3.eth.getBlock)(blockNum);
+            const timestamp = new BigNumber(blockInfo.timestamp);
+            const confirmationTimeBigNum = new BigNumber(await multiSig.confirmationTimes.call(txId));
+
+            expect(timestamp).to.be.bignumber.equal(confirmationTimeBigNum);
+        });
+
+        it('should be executable with enough confirmations and secondsTimeLocked of 0', async () => {
+            expect(initialSecondsTimeLocked).to.be.equal(0);
+
+            const res = await multiSig.executeTransaction(txId);
+            expect(res.logs).to.have.length(2);
+
+            const secondsTimeLocked = new BigNumber(await multiSig.secondsTimeLocked.call());
+            expect(secondsTimeLocked).to.be.bignumber.equal(SECONDS_TIME_LOCKED);
+        });
+
+        const newSecondsTimeLocked = 0;
+        it('should throw if it has enough confirmations but is not past the time lock', async () => {
+            const destination = multiSig.address;
+            const from = owners[0];
+            const dataParams = {
+                name: 'changeTimeLock',
+                abi: MULTI_SIG_ABI,
+                args: [newSecondsTimeLocked],
+            };
+            const subRes = await multiSigWrapper.submitTransactionAsync(destination, from, dataParams);
+
+            txId = subRes.logs[0].args.transactionId.toNumber();
+            const confRes = await multiSig.confirmTransaction(txId, {
+                from: owners[1],
+            });
+            expect(confRes.logs).to.have.length(2);
+
+            return expect(multiSig.executeTransaction(txId)).to.be.rejectedWith(constants.REVERT);
+        });
+
+        it('should execute if it has enough confirmations and is past the time lock', async () => {
+            await rpc.increaseTimeAsync(SECONDS_TIME_LOCKED);
+            await multiSig.executeTransaction(txId);
+
+            const secondsTimeLocked = new BigNumber(await multiSig.secondsTimeLocked.call());
+            expect(secondsTimeLocked).to.be.bignumber.equal(newSecondsTimeLocked);
+        });
+    });
 });
diff --git a/packages/contracts/test/ts/multi_sig_with_time_lock_except_remove_auth_addr.ts b/packages/contracts/test/ts/multi_sig_with_time_lock_except_remove_auth_addr.ts
index 9211cb1b6..62aa625fe 100644
--- a/packages/contracts/test/ts/multi_sig_with_time_lock_except_remove_auth_addr.ts
+++ b/packages/contracts/test/ts/multi_sig_with_time_lock_except_remove_auth_addr.ts
@@ -15,136 +15,136 @@ chaiSetup.configure();
 const expect = chai.expect;
 
 contract('MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress', (accounts: string[]) => {
-	const owners = [accounts[0], accounts[1]];
-	const requiredApprovals = 2;
-	const SECONDS_TIME_LOCKED = 1000000;
-
-	// initialize fake addresses
-	const authorizedAddress = `0x${crypto
-		.solSHA3([accounts[0]])
-		.slice(0, 20)
-		.toString('hex')}`;
-	const unauthorizedAddress = `0x${crypto
-		.solSHA3([accounts[1]])
-		.slice(0, 20)
-		.toString('hex')}`;
-
-	let tokenTransferProxy: ContractInstance;
-	let multiSig: ContractInstance;
-	let multiSigWrapper: MultiSigWrapper;
-
-	let validDestination: string;
-
-	beforeEach(async () => {
-		const initialOwner = accounts[0];
-		tokenTransferProxy = await TokenTransferProxy.new({ from: initialOwner });
-		await tokenTransferProxy.addAuthorizedAddress(authorizedAddress, {
-			from: initialOwner,
-		});
-		multiSig = await MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress.new(
-			owners,
-			requiredApprovals,
-			SECONDS_TIME_LOCKED,
-			tokenTransferProxy.address,
-		);
-		await tokenTransferProxy.transferOwnership(multiSig.address, {
-			from: initialOwner,
-		});
-		multiSigWrapper = new MultiSigWrapper(multiSig);
-		validDestination = tokenTransferProxy.address;
-	});
-
-	describe('isFunctionRemoveAuthorizedAddress', () => {
-		it('should throw if data is not for removeAuthorizedAddress', async () => {
-			const data = MultiSigWrapper.encodeFnArgs('addAuthorizedAddress', PROXY_ABI, [owners[0]]);
-			return expect(multiSig.isFunctionRemoveAuthorizedAddress.call(data)).to.be.rejectedWith(constants.REVERT);
-		});
-
-		it('should return true if data is for removeAuthorizedAddress', async () => {
-			const data = MultiSigWrapper.encodeFnArgs('removeAuthorizedAddress', PROXY_ABI, [owners[0]]);
-			const isFunctionRemoveAuthorizedAddress = await multiSig.isFunctionRemoveAuthorizedAddress.call(data);
-			expect(isFunctionRemoveAuthorizedAddress).to.be.true();
-		});
-	});
-
-	describe('executeRemoveAuthorizedAddress', () => {
-		it('should throw without the required confirmations', async () => {
-			const dataParams: TransactionDataParams = {
-				name: 'removeAuthorizedAddress',
-				abi: PROXY_ABI,
-				args: [authorizedAddress],
-			};
-			const res = await multiSigWrapper.submitTransactionAsync(validDestination, owners[0], dataParams);
-			const txId = res.logs[0].args.transactionId.toString();
-
-			return expect(multiSig.executeRemoveAuthorizedAddress(txId)).to.be.rejectedWith(constants.REVERT);
-		});
-
-		it('should throw if tx destination is not the tokenTransferProxy', async () => {
-			const invalidTokenTransferProxy = await TokenTransferProxy.new();
-			const invalidDestination = invalidTokenTransferProxy.address;
-			const dataParams: TransactionDataParams = {
-				name: 'removeAuthorizedAddress',
-				abi: PROXY_ABI,
-				args: [authorizedAddress],
-			};
-			const res = await multiSigWrapper.submitTransactionAsync(invalidDestination, owners[0], dataParams);
-			const txId = res.logs[0].args.transactionId.toString();
-			await multiSig.confirmTransaction(txId, { from: owners[1] });
-			const isConfirmed = await multiSig.isConfirmed.call(txId);
-			expect(isConfirmed).to.be.true();
-
-			return expect(multiSig.executeRemoveAuthorizedAddress(txId)).to.be.rejectedWith(constants.REVERT);
-		});
-
-		it('should throw if tx data is not for removeAuthorizedAddress', async () => {
-			const dataParams: TransactionDataParams = {
-				name: 'addAuthorizedAddress',
-				abi: PROXY_ABI,
-				args: [unauthorizedAddress],
-			};
-			const res = await multiSigWrapper.submitTransactionAsync(validDestination, owners[0], dataParams);
-			const txId = res.logs[0].args.transactionId.toString();
-			await multiSig.confirmTransaction(txId, { from: owners[1] });
-			const isConfirmed = await multiSig.isConfirmed.call(txId);
-			expect(isConfirmed).to.be.true();
-
-			return expect(multiSig.executeRemoveAuthorizedAddress(txId)).to.be.rejectedWith(constants.REVERT);
-		});
-
-		it('should execute removeAuthorizedAddress for valid tokenTransferProxy if fully confirmed', async () => {
-			const dataParams: TransactionDataParams = {
-				name: 'removeAuthorizedAddress',
-				abi: PROXY_ABI,
-				args: [authorizedAddress],
-			};
-			const res = await multiSigWrapper.submitTransactionAsync(validDestination, owners[0], dataParams);
-			const txId = res.logs[0].args.transactionId.toString();
-			await multiSig.confirmTransaction(txId, { from: owners[1] });
-			const isConfirmed = await multiSig.isConfirmed.call(txId);
-			expect(isConfirmed).to.be.true();
-			await multiSig.executeRemoveAuthorizedAddress(txId);
-
-			const isAuthorized = await tokenTransferProxy.authorized.call(authorizedAddress);
-			expect(isAuthorized).to.be.false();
-		});
-
-		it('should throw if already executed', async () => {
-			const dataParams: TransactionDataParams = {
-				name: 'removeAuthorizedAddress',
-				abi: PROXY_ABI,
-				args: [authorizedAddress],
-			};
-			const res = await multiSigWrapper.submitTransactionAsync(validDestination, owners[0], dataParams);
-			const txId = res.logs[0].args.transactionId.toString();
-			await multiSig.confirmTransaction(txId, { from: owners[1] });
-			const isConfirmed = await multiSig.isConfirmed.call(txId);
-			expect(isConfirmed).to.be.true();
-			await multiSig.executeRemoveAuthorizedAddress(txId);
-			const tx = await multiSig.transactions.call(txId);
-			const isExecuted = tx[3];
-			expect(isExecuted).to.be.true();
-			return expect(multiSig.executeRemoveAuthorizedAddress(txId)).to.be.rejectedWith(constants.REVERT);
-		});
-	});
+    const owners = [accounts[0], accounts[1]];
+    const requiredApprovals = 2;
+    const SECONDS_TIME_LOCKED = 1000000;
+
+    // initialize fake addresses
+    const authorizedAddress = `0x${crypto
+        .solSHA3([accounts[0]])
+        .slice(0, 20)
+        .toString('hex')}`;
+    const unauthorizedAddress = `0x${crypto
+        .solSHA3([accounts[1]])
+        .slice(0, 20)
+        .toString('hex')}`;
+
+    let tokenTransferProxy: ContractInstance;
+    let multiSig: ContractInstance;
+    let multiSigWrapper: MultiSigWrapper;
+
+    let validDestination: string;
+
+    beforeEach(async () => {
+        const initialOwner = accounts[0];
+        tokenTransferProxy = await TokenTransferProxy.new({ from: initialOwner });
+        await tokenTransferProxy.addAuthorizedAddress(authorizedAddress, {
+            from: initialOwner,
+        });
+        multiSig = await MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress.new(
+            owners,
+            requiredApprovals,
+            SECONDS_TIME_LOCKED,
+            tokenTransferProxy.address,
+        );
+        await tokenTransferProxy.transferOwnership(multiSig.address, {
+            from: initialOwner,
+        });
+        multiSigWrapper = new MultiSigWrapper(multiSig);
+        validDestination = tokenTransferProxy.address;
+    });
+
+    describe('isFunctionRemoveAuthorizedAddress', () => {
+        it('should throw if data is not for removeAuthorizedAddress', async () => {
+            const data = MultiSigWrapper.encodeFnArgs('addAuthorizedAddress', PROXY_ABI, [owners[0]]);
+            return expect(multiSig.isFunctionRemoveAuthorizedAddress.call(data)).to.be.rejectedWith(constants.REVERT);
+        });
+
+        it('should return true if data is for removeAuthorizedAddress', async () => {
+            const data = MultiSigWrapper.encodeFnArgs('removeAuthorizedAddress', PROXY_ABI, [owners[0]]);
+            const isFunctionRemoveAuthorizedAddress = await multiSig.isFunctionRemoveAuthorizedAddress.call(data);
+            expect(isFunctionRemoveAuthorizedAddress).to.be.true();
+        });
+    });
+
+    describe('executeRemoveAuthorizedAddress', () => {
+        it('should throw without the required confirmations', async () => {
+            const dataParams: TransactionDataParams = {
+                name: 'removeAuthorizedAddress',
+                abi: PROXY_ABI,
+                args: [authorizedAddress],
+            };
+            const res = await multiSigWrapper.submitTransactionAsync(validDestination, owners[0], dataParams);
+            const txId = res.logs[0].args.transactionId.toString();
+
+            return expect(multiSig.executeRemoveAuthorizedAddress(txId)).to.be.rejectedWith(constants.REVERT);
+        });
+
+        it('should throw if tx destination is not the tokenTransferProxy', async () => {
+            const invalidTokenTransferProxy = await TokenTransferProxy.new();
+            const invalidDestination = invalidTokenTransferProxy.address;
+            const dataParams: TransactionDataParams = {
+                name: 'removeAuthorizedAddress',
+                abi: PROXY_ABI,
+                args: [authorizedAddress],
+            };
+            const res = await multiSigWrapper.submitTransactionAsync(invalidDestination, owners[0], dataParams);
+            const txId = res.logs[0].args.transactionId.toString();
+            await multiSig.confirmTransaction(txId, { from: owners[1] });
+            const isConfirmed = await multiSig.isConfirmed.call(txId);
+            expect(isConfirmed).to.be.true();
+
+            return expect(multiSig.executeRemoveAuthorizedAddress(txId)).to.be.rejectedWith(constants.REVERT);
+        });
+
+        it('should throw if tx data is not for removeAuthorizedAddress', async () => {
+            const dataParams: TransactionDataParams = {
+                name: 'addAuthorizedAddress',
+                abi: PROXY_ABI,
+                args: [unauthorizedAddress],
+            };
+            const res = await multiSigWrapper.submitTransactionAsync(validDestination, owners[0], dataParams);
+            const txId = res.logs[0].args.transactionId.toString();
+            await multiSig.confirmTransaction(txId, { from: owners[1] });
+            const isConfirmed = await multiSig.isConfirmed.call(txId);
+            expect(isConfirmed).to.be.true();
+
+            return expect(multiSig.executeRemoveAuthorizedAddress(txId)).to.be.rejectedWith(constants.REVERT);
+        });
+
+        it('should execute removeAuthorizedAddress for valid tokenTransferProxy if fully confirmed', async () => {
+            const dataParams: TransactionDataParams = {
+                name: 'removeAuthorizedAddress',
+                abi: PROXY_ABI,
+                args: [authorizedAddress],
+            };
+            const res = await multiSigWrapper.submitTransactionAsync(validDestination, owners[0], dataParams);
+            const txId = res.logs[0].args.transactionId.toString();
+            await multiSig.confirmTransaction(txId, { from: owners[1] });
+            const isConfirmed = await multiSig.isConfirmed.call(txId);
+            expect(isConfirmed).to.be.true();
+            await multiSig.executeRemoveAuthorizedAddress(txId);
+
+            const isAuthorized = await tokenTransferProxy.authorized.call(authorizedAddress);
+            expect(isAuthorized).to.be.false();
+        });
+
+        it('should throw if already executed', async () => {
+            const dataParams: TransactionDataParams = {
+                name: 'removeAuthorizedAddress',
+                abi: PROXY_ABI,
+                args: [authorizedAddress],
+            };
+            const res = await multiSigWrapper.submitTransactionAsync(validDestination, owners[0], dataParams);
+            const txId = res.logs[0].args.transactionId.toString();
+            await multiSig.confirmTransaction(txId, { from: owners[1] });
+            const isConfirmed = await multiSig.isConfirmed.call(txId);
+            expect(isConfirmed).to.be.true();
+            await multiSig.executeRemoveAuthorizedAddress(txId);
+            const tx = await multiSig.transactions.call(txId);
+            const isExecuted = tx[3];
+            expect(isExecuted).to.be.true();
+            return expect(multiSig.executeRemoveAuthorizedAddress(txId)).to.be.rejectedWith(constants.REVERT);
+        });
+    });
 });
diff --git a/packages/contracts/test/ts/token_registry.ts b/packages/contracts/test/ts/token_registry.ts
index fadb276da..d1c551565 100644
--- a/packages/contracts/test/ts/token_registry.ts
+++ b/packages/contracts/test/ts/token_registry.ts
@@ -15,220 +15,220 @@ chaiSetup.configure();
 const expect = chai.expect;
 
 contract('TokenRegistry', (accounts: string[]) => {
-	const owner = accounts[0];
-	const notOwner = accounts[1];
-
-	const tokenAddress1 = `0x${ethUtil.setLength(ethUtil.toBuffer('0x1'), 20, false).toString('hex')}`;
-	const tokenAddress2 = `0x${ethUtil.setLength(ethUtil.toBuffer('0x2'), 20, false).toString('hex')}`;
-
-	const token1 = {
-		address: tokenAddress1,
-		name: 'testToken1',
-		symbol: 'TT1',
-		decimals: 18,
-		ipfsHash: `0x${ethUtil.sha3('ipfs1').toString('hex')}`,
-		swarmHash: `0x${ethUtil.sha3('swarm1').toString('hex')}`,
-	};
-
-	const token2 = {
-		address: tokenAddress2,
-		name: 'testToken2',
-		symbol: 'TT2',
-		decimals: 18,
-		ipfsHash: `0x${ethUtil.sha3('ipfs2').toString('hex')}`,
-		swarmHash: `0x${ethUtil.sha3('swarm2').toString('hex')}`,
-	};
-
-	const nullToken = {
-		address: ZeroEx.NULL_ADDRESS,
-		name: '',
-		symbol: '',
-		decimals: 0,
-		ipfsHash: constants.NULL_BYTES,
-		swarmHash: constants.NULL_BYTES,
-	};
-
-	let tokenReg: ContractInstance;
-	let tokenRegWrapper: TokenRegWrapper;
-
-	beforeEach(async () => {
-		tokenReg = await TokenRegistry.new();
-		tokenRegWrapper = new TokenRegWrapper(tokenReg);
-	});
-
-	describe('addToken', () => {
-		it('should throw when not called by owner', async () => {
-			return expect(tokenRegWrapper.addTokenAsync(token1, notOwner)).to.be.rejectedWith(constants.REVERT);
-		});
-
-		it('should add token metadata when called by owner', async () => {
-			await tokenRegWrapper.addTokenAsync(token1, owner);
-			const tokenData = await tokenRegWrapper.getTokenMetaDataAsync(token1.address);
-			expect(tokenData).to.be.deep.equal(token1);
-		});
-
-		it('should throw if token already exists', async () => {
-			await tokenRegWrapper.addTokenAsync(token1, owner);
-
-			return expect(tokenRegWrapper.addTokenAsync(token1, owner)).to.be.rejectedWith(constants.REVERT);
-		});
-
-		it('should throw if token address is null', async () => {
-			return expect(tokenRegWrapper.addTokenAsync(nullToken, owner)).to.be.rejectedWith(constants.REVERT);
-		});
-
-		it('should throw if name already exists', async () => {
-			await tokenRegWrapper.addTokenAsync(token1, owner);
-			const duplicateNameToken = _.assign({}, token2, { name: token1.name });
-
-			return expect(tokenRegWrapper.addTokenAsync(duplicateNameToken, owner)).to.be.rejectedWith(
-				constants.REVERT,
-			);
-		});
-
-		it('should throw if symbol already exists', async () => {
-			await tokenRegWrapper.addTokenAsync(token1, owner);
-			const duplicateSymbolToken = _.assign({}, token2, {
-				symbol: token1.symbol,
-			});
-
-			return expect(tokenRegWrapper.addTokenAsync(duplicateSymbolToken, owner)).to.be.rejectedWith(
-				constants.REVERT,
-			);
-		});
-	});
-
-	describe('after addToken', () => {
-		beforeEach(async () => {
-			await tokenRegWrapper.addTokenAsync(token1, owner);
-		});
-
-		describe('getTokenByName', () => {
-			it('should return token metadata when given the token name', async () => {
-				const tokenData = await tokenRegWrapper.getTokenByNameAsync(token1.name);
-				expect(tokenData).to.be.deep.equal(token1);
-			});
-		});
-
-		describe('getTokenBySymbol', () => {
-			it('should return token metadata when given the token symbol', async () => {
-				const tokenData = await tokenRegWrapper.getTokenBySymbolAsync(token1.symbol);
-				expect(tokenData).to.be.deep.equal(token1);
-			});
-		});
-
-		describe('setTokenName', () => {
-			it('should throw when not called by owner', async () => {
-				return expect(
-					tokenReg.setTokenName(token1.address, token2.name, { from: notOwner }),
-				).to.be.rejectedWith(constants.REVERT);
-			});
-
-			it('should change the token name when called by owner', async () => {
-				const res = await tokenReg.setTokenName(token1.address, token2.name, {
-					from: owner,
-				});
-				expect(res.logs).to.have.length(1);
-				const [newData, oldData] = await Promise.all([
-					tokenRegWrapper.getTokenByNameAsync(token2.name),
-					tokenRegWrapper.getTokenByNameAsync(token1.name),
-				]);
-
-				const expectedNewData = _.assign({}, token1, { name: token2.name });
-				const expectedOldData = nullToken;
-				expect(newData).to.be.deep.equal(expectedNewData);
-				expect(oldData).to.be.deep.equal(expectedOldData);
-			});
-
-			it('should throw if the name already exists', async () => {
-				await tokenRegWrapper.addTokenAsync(token2, owner);
-
-				return expect(tokenReg.setTokenName(token1.address, token2.name, { from: owner })).to.be.rejectedWith(
-					constants.REVERT,
-				);
-			});
-
-			it('should throw if token does not exist', async () => {
-				return expect(
-					tokenReg.setTokenName(nullToken.address, token2.name, { from: owner }),
-				).to.be.rejectedWith(constants.REVERT);
-			});
-		});
-
-		describe('setTokenSymbol', () => {
-			it('should throw when not called by owner', async () => {
-				return expect(
-					tokenReg.setTokenSymbol(token1.address, token2.symbol, {
-						from: notOwner,
-					}),
-				).to.be.rejectedWith(constants.REVERT);
-			});
-
-			it('should change the token symbol when called by owner', async () => {
-				const res = await tokenReg.setTokenSymbol(token1.address, token2.symbol, { from: owner });
-				expect(res.logs).to.have.length(1);
-				const [newData, oldData] = await Promise.all([
-					tokenRegWrapper.getTokenBySymbolAsync(token2.symbol),
-					tokenRegWrapper.getTokenBySymbolAsync(token1.symbol),
-				]);
-
-				const expectedNewData = _.assign({}, token1, { symbol: token2.symbol });
-				const expectedOldData = nullToken;
-				expect(newData).to.be.deep.equal(expectedNewData);
-				expect(oldData).to.be.deep.equal(expectedOldData);
-			});
-
-			it('should throw if the symbol already exists', async () => {
-				await tokenRegWrapper.addTokenAsync(token2, owner);
-
-				return expect(
-					tokenReg.setTokenSymbol(token1.address, token2.symbol, {
-						from: owner,
-					}),
-				).to.be.rejectedWith(constants.REVERT);
-			});
-
-			it('should throw if token does not exist', async () => {
-				return expect(
-					tokenReg.setTokenSymbol(nullToken.address, token2.symbol, {
-						from: owner,
-					}),
-				).to.be.rejectedWith(constants.REVERT);
-			});
-		});
-
-		describe('removeToken', () => {
-			it('should throw if not called by owner', async () => {
-				const index = 0;
-				return expect(tokenReg.removeToken(token1.address, index, { from: notOwner })).to.be.rejectedWith(
-					constants.REVERT,
-				);
-			});
-
-			it('should remove token metadata when called by owner', async () => {
-				const index = 0;
-				const res = await tokenReg.removeToken(token1.address, index, {
-					from: owner,
-				});
-				expect(res.logs).to.have.length(1);
-				const tokenData = await tokenRegWrapper.getTokenMetaDataAsync(token1.address);
-				expect(tokenData).to.be.deep.equal(nullToken);
-			});
-
-			it('should throw if token does not exist', async () => {
-				const index = 0;
-				return expect(tokenReg.removeToken(nullToken.address, index, { from: owner })).to.be.rejectedWith(
-					constants.REVERT,
-				);
-			});
-
-			it('should throw if token at given index does not match address', async () => {
-				await tokenRegWrapper.addTokenAsync(token2, owner);
-				const incorrectIndex = 0;
-				return expect(tokenReg.removeToken(token2.address, incorrectIndex, { from: owner })).to.be.rejectedWith(
-					constants.REVERT,
-				);
-			});
-		});
-	});
+    const owner = accounts[0];
+    const notOwner = accounts[1];
+
+    const tokenAddress1 = `0x${ethUtil.setLength(ethUtil.toBuffer('0x1'), 20, false).toString('hex')}`;
+    const tokenAddress2 = `0x${ethUtil.setLength(ethUtil.toBuffer('0x2'), 20, false).toString('hex')}`;
+
+    const token1 = {
+        address: tokenAddress1,
+        name: 'testToken1',
+        symbol: 'TT1',
+        decimals: 18,
+        ipfsHash: `0x${ethUtil.sha3('ipfs1').toString('hex')}`,
+        swarmHash: `0x${ethUtil.sha3('swarm1').toString('hex')}`,
+    };
+
+    const token2 = {
+        address: tokenAddress2,
+        name: 'testToken2',
+        symbol: 'TT2',
+        decimals: 18,
+        ipfsHash: `0x${ethUtil.sha3('ipfs2').toString('hex')}`,
+        swarmHash: `0x${ethUtil.sha3('swarm2').toString('hex')}`,
+    };
+
+    const nullToken = {
+        address: ZeroEx.NULL_ADDRESS,
+        name: '',
+        symbol: '',
+        decimals: 0,
+        ipfsHash: constants.NULL_BYTES,
+        swarmHash: constants.NULL_BYTES,
+    };
+
+    let tokenReg: ContractInstance;
+    let tokenRegWrapper: TokenRegWrapper;
+
+    beforeEach(async () => {
+        tokenReg = await TokenRegistry.new();
+        tokenRegWrapper = new TokenRegWrapper(tokenReg);
+    });
+
+    describe('addToken', () => {
+        it('should throw when not called by owner', async () => {
+            return expect(tokenRegWrapper.addTokenAsync(token1, notOwner)).to.be.rejectedWith(constants.REVERT);
+        });
+
+        it('should add token metadata when called by owner', async () => {
+            await tokenRegWrapper.addTokenAsync(token1, owner);
+            const tokenData = await tokenRegWrapper.getTokenMetaDataAsync(token1.address);
+            expect(tokenData).to.be.deep.equal(token1);
+        });
+
+        it('should throw if token already exists', async () => {
+            await tokenRegWrapper.addTokenAsync(token1, owner);
+
+            return expect(tokenRegWrapper.addTokenAsync(token1, owner)).to.be.rejectedWith(constants.REVERT);
+        });
+
+        it('should throw if token address is null', async () => {
+            return expect(tokenRegWrapper.addTokenAsync(nullToken, owner)).to.be.rejectedWith(constants.REVERT);
+        });
+
+        it('should throw if name already exists', async () => {
+            await tokenRegWrapper.addTokenAsync(token1, owner);
+            const duplicateNameToken = _.assign({}, token2, { name: token1.name });
+
+            return expect(tokenRegWrapper.addTokenAsync(duplicateNameToken, owner)).to.be.rejectedWith(
+                constants.REVERT,
+            );
+        });
+
+        it('should throw if symbol already exists', async () => {
+            await tokenRegWrapper.addTokenAsync(token1, owner);
+            const duplicateSymbolToken = _.assign({}, token2, {
+                symbol: token1.symbol,
+            });
+
+            return expect(tokenRegWrapper.addTokenAsync(duplicateSymbolToken, owner)).to.be.rejectedWith(
+                constants.REVERT,
+            );
+        });
+    });
+
+    describe('after addToken', () => {
+        beforeEach(async () => {
+            await tokenRegWrapper.addTokenAsync(token1, owner);
+        });
+
+        describe('getTokenByName', () => {
+            it('should return token metadata when given the token name', async () => {
+                const tokenData = await tokenRegWrapper.getTokenByNameAsync(token1.name);
+                expect(tokenData).to.be.deep.equal(token1);
+            });
+        });
+
+        describe('getTokenBySymbol', () => {
+            it('should return token metadata when given the token symbol', async () => {
+                const tokenData = await tokenRegWrapper.getTokenBySymbolAsync(token1.symbol);
+                expect(tokenData).to.be.deep.equal(token1);
+            });
+        });
+
+        describe('setTokenName', () => {
+            it('should throw when not called by owner', async () => {
+                return expect(
+                    tokenReg.setTokenName(token1.address, token2.name, { from: notOwner }),
+                ).to.be.rejectedWith(constants.REVERT);
+            });
+
+            it('should change the token name when called by owner', async () => {
+                const res = await tokenReg.setTokenName(token1.address, token2.name, {
+                    from: owner,
+                });
+                expect(res.logs).to.have.length(1);
+                const [newData, oldData] = await Promise.all([
+                    tokenRegWrapper.getTokenByNameAsync(token2.name),
+                    tokenRegWrapper.getTokenByNameAsync(token1.name),
+                ]);
+
+                const expectedNewData = _.assign({}, token1, { name: token2.name });
+                const expectedOldData = nullToken;
+                expect(newData).to.be.deep.equal(expectedNewData);
+                expect(oldData).to.be.deep.equal(expectedOldData);
+            });
+
+            it('should throw if the name already exists', async () => {
+                await tokenRegWrapper.addTokenAsync(token2, owner);
+
+                return expect(tokenReg.setTokenName(token1.address, token2.name, { from: owner })).to.be.rejectedWith(
+                    constants.REVERT,
+                );
+            });
+
+            it('should throw if token does not exist', async () => {
+                return expect(
+                    tokenReg.setTokenName(nullToken.address, token2.name, { from: owner }),
+                ).to.be.rejectedWith(constants.REVERT);
+            });
+        });
+
+        describe('setTokenSymbol', () => {
+            it('should throw when not called by owner', async () => {
+                return expect(
+                    tokenReg.setTokenSymbol(token1.address, token2.symbol, {
+                        from: notOwner,
+                    }),
+                ).to.be.rejectedWith(constants.REVERT);
+            });
+
+            it('should change the token symbol when called by owner', async () => {
+                const res = await tokenReg.setTokenSymbol(token1.address, token2.symbol, { from: owner });
+                expect(res.logs).to.have.length(1);
+                const [newData, oldData] = await Promise.all([
+                    tokenRegWrapper.getTokenBySymbolAsync(token2.symbol),
+                    tokenRegWrapper.getTokenBySymbolAsync(token1.symbol),
+                ]);
+
+                const expectedNewData = _.assign({}, token1, { symbol: token2.symbol });
+                const expectedOldData = nullToken;
+                expect(newData).to.be.deep.equal(expectedNewData);
+                expect(oldData).to.be.deep.equal(expectedOldData);
+            });
+
+            it('should throw if the symbol already exists', async () => {
+                await tokenRegWrapper.addTokenAsync(token2, owner);
+
+                return expect(
+                    tokenReg.setTokenSymbol(token1.address, token2.symbol, {
+                        from: owner,
+                    }),
+                ).to.be.rejectedWith(constants.REVERT);
+            });
+
+            it('should throw if token does not exist', async () => {
+                return expect(
+                    tokenReg.setTokenSymbol(nullToken.address, token2.symbol, {
+                        from: owner,
+                    }),
+                ).to.be.rejectedWith(constants.REVERT);
+            });
+        });
+
+        describe('removeToken', () => {
+            it('should throw if not called by owner', async () => {
+                const index = 0;
+                return expect(tokenReg.removeToken(token1.address, index, { from: notOwner })).to.be.rejectedWith(
+                    constants.REVERT,
+                );
+            });
+
+            it('should remove token metadata when called by owner', async () => {
+                const index = 0;
+                const res = await tokenReg.removeToken(token1.address, index, {
+                    from: owner,
+                });
+                expect(res.logs).to.have.length(1);
+                const tokenData = await tokenRegWrapper.getTokenMetaDataAsync(token1.address);
+                expect(tokenData).to.be.deep.equal(nullToken);
+            });
+
+            it('should throw if token does not exist', async () => {
+                const index = 0;
+                return expect(tokenReg.removeToken(nullToken.address, index, { from: owner })).to.be.rejectedWith(
+                    constants.REVERT,
+                );
+            });
+
+            it('should throw if token at given index does not match address', async () => {
+                await tokenRegWrapper.addTokenAsync(token2, owner);
+                const incorrectIndex = 0;
+                return expect(tokenReg.removeToken(token2.address, incorrectIndex, { from: owner })).to.be.rejectedWith(
+                    constants.REVERT,
+                );
+            });
+        });
+    });
 });
diff --git a/packages/contracts/test/ts/token_transfer_proxy/auth.ts b/packages/contracts/test/ts/token_transfer_proxy/auth.ts
index 69a6c0ada..9ae0a8fc3 100644
--- a/packages/contracts/test/ts/token_transfer_proxy/auth.ts
+++ b/packages/contracts/test/ts/token_transfer_proxy/auth.ts
@@ -9,91 +9,91 @@ const expect = chai.expect;
 const TokenTransferProxy = artifacts.require('./db/TokenTransferProxy.sol');
 
 contract('TokenTransferProxy', (accounts: string[]) => {
-	const owner = accounts[0];
-	const notOwner = accounts[1];
+    const owner = accounts[0];
+    const notOwner = accounts[1];
 
-	let tokenTransferProxy: ContractInstance;
-	let authorized: string;
-	let notAuthorized = owner;
+    let tokenTransferProxy: ContractInstance;
+    let authorized: string;
+    let notAuthorized = owner;
 
-	before(async () => {
-		tokenTransferProxy = await TokenTransferProxy.deployed();
-	});
+    before(async () => {
+        tokenTransferProxy = await TokenTransferProxy.deployed();
+    });
 
-	describe('addAuthorizedAddress', () => {
-		it('should throw if not called by owner', async () => {
-			return expect(tokenTransferProxy.addAuthorizedAddress(notOwner, { from: notOwner })).to.be.rejectedWith(
-				constants.REVERT,
-			);
-		});
+    describe('addAuthorizedAddress', () => {
+        it('should throw if not called by owner', async () => {
+            return expect(tokenTransferProxy.addAuthorizedAddress(notOwner, { from: notOwner })).to.be.rejectedWith(
+                constants.REVERT,
+            );
+        });
 
-		it('should allow owner to add an authorized address', async () => {
-			await tokenTransferProxy.addAuthorizedAddress(notAuthorized, {
-				from: owner,
-			});
-			authorized = notAuthorized;
-			notAuthorized = null;
-			const isAuthorized = await tokenTransferProxy.authorized.call(authorized);
-			expect(isAuthorized).to.be.true();
-		});
+        it('should allow owner to add an authorized address', async () => {
+            await tokenTransferProxy.addAuthorizedAddress(notAuthorized, {
+                from: owner,
+            });
+            authorized = notAuthorized;
+            notAuthorized = null;
+            const isAuthorized = await tokenTransferProxy.authorized.call(authorized);
+            expect(isAuthorized).to.be.true();
+        });
 
-		it('should throw if owner attempts to authorize a duplicate address', async () => {
-			return expect(tokenTransferProxy.addAuthorizedAddress(authorized, { from: owner })).to.be.rejectedWith(
-				constants.REVERT,
-			);
-		});
-	});
+        it('should throw if owner attempts to authorize a duplicate address', async () => {
+            return expect(tokenTransferProxy.addAuthorizedAddress(authorized, { from: owner })).to.be.rejectedWith(
+                constants.REVERT,
+            );
+        });
+    });
 
-	describe('removeAuthorizedAddress', () => {
-		it('should throw if not called by owner', async () => {
-			return expect(
-				tokenTransferProxy.removeAuthorizedAddress(authorized, {
-					from: notOwner,
-				}),
-			).to.be.rejectedWith(constants.REVERT);
-		});
+    describe('removeAuthorizedAddress', () => {
+        it('should throw if not called by owner', async () => {
+            return expect(
+                tokenTransferProxy.removeAuthorizedAddress(authorized, {
+                    from: notOwner,
+                }),
+            ).to.be.rejectedWith(constants.REVERT);
+        });
 
-		it('should allow owner to remove an authorized address', async () => {
-			await tokenTransferProxy.removeAuthorizedAddress(authorized, {
-				from: owner,
-			});
-			notAuthorized = authorized;
-			authorized = null;
+        it('should allow owner to remove an authorized address', async () => {
+            await tokenTransferProxy.removeAuthorizedAddress(authorized, {
+                from: owner,
+            });
+            notAuthorized = authorized;
+            authorized = null;
 
-			const isAuthorized = await tokenTransferProxy.authorized.call(notAuthorized);
-			expect(isAuthorized).to.be.false();
-		});
+            const isAuthorized = await tokenTransferProxy.authorized.call(notAuthorized);
+            expect(isAuthorized).to.be.false();
+        });
 
-		it('should throw if owner attempts to remove an address that is not authorized', async () => {
-			return expect(
-				tokenTransferProxy.removeAuthorizedAddress(notAuthorized, {
-					from: owner,
-				}),
-			).to.be.rejectedWith(constants.REVERT);
-		});
-	});
+        it('should throw if owner attempts to remove an address that is not authorized', async () => {
+            return expect(
+                tokenTransferProxy.removeAuthorizedAddress(notAuthorized, {
+                    from: owner,
+                }),
+            ).to.be.rejectedWith(constants.REVERT);
+        });
+    });
 
-	describe('getAuthorizedAddresses', () => {
-		it('should return all authorized addresses', async () => {
-			const initial = await tokenTransferProxy.getAuthorizedAddresses();
-			expect(initial).to.have.length(1);
-			await tokenTransferProxy.addAuthorizedAddress(notAuthorized, {
-				from: owner,
-			});
+    describe('getAuthorizedAddresses', () => {
+        it('should return all authorized addresses', async () => {
+            const initial = await tokenTransferProxy.getAuthorizedAddresses();
+            expect(initial).to.have.length(1);
+            await tokenTransferProxy.addAuthorizedAddress(notAuthorized, {
+                from: owner,
+            });
 
-			authorized = notAuthorized;
-			notAuthorized = null;
-			const afterAdd = await tokenTransferProxy.getAuthorizedAddresses();
-			expect(afterAdd).to.have.length(2);
-			expect(afterAdd).to.include(authorized);
+            authorized = notAuthorized;
+            notAuthorized = null;
+            const afterAdd = await tokenTransferProxy.getAuthorizedAddresses();
+            expect(afterAdd).to.have.length(2);
+            expect(afterAdd).to.include(authorized);
 
-			await tokenTransferProxy.removeAuthorizedAddress(authorized, {
-				from: owner,
-			});
-			notAuthorized = authorized;
-			authorized = null;
-			const afterRemove = await tokenTransferProxy.getAuthorizedAddresses();
-			expect(afterRemove).to.have.length(1);
-		});
-	});
+            await tokenTransferProxy.removeAuthorizedAddress(authorized, {
+                from: owner,
+            });
+            notAuthorized = authorized;
+            authorized = null;
+            const afterRemove = await tokenTransferProxy.getAuthorizedAddresses();
+            expect(afterRemove).to.have.length(1);
+        });
+    });
 });
diff --git a/packages/contracts/test/ts/token_transfer_proxy/transfer_from.ts b/packages/contracts/test/ts/token_transfer_proxy/transfer_from.ts
index 847256598..e1aff6dae 100644
--- a/packages/contracts/test/ts/token_transfer_proxy/transfer_from.ts
+++ b/packages/contracts/test/ts/token_transfer_proxy/transfer_from.ts
@@ -11,63 +11,63 @@ const expect = chai.expect;
 const { TokenTransferProxy, DummyToken, TokenRegistry } = new Artifacts(artifacts);
 
 contract('TokenTransferProxy', (accounts: string[]) => {
-	const INIT_BAL = 100000000;
-	const INIT_ALLOW = 100000000;
+    const INIT_BAL = 100000000;
+    const INIT_ALLOW = 100000000;
 
-	const owner = accounts[0];
-	const notAuthorized = owner;
+    const owner = accounts[0];
+    const notAuthorized = owner;
 
-	let tokenTransferProxy: ContractInstance;
-	let tokenRegistry: ContractInstance;
-	let rep: ContractInstance;
-	let dmyBalances: Balances;
+    let tokenTransferProxy: ContractInstance;
+    let tokenRegistry: ContractInstance;
+    let rep: ContractInstance;
+    let dmyBalances: Balances;
 
-	before(async () => {
-		[tokenTransferProxy, tokenRegistry] = await Promise.all([
-			TokenTransferProxy.deployed(),
-			TokenRegistry.deployed(),
-		]);
-		const repAddress = await tokenRegistry.getTokenAddressBySymbol('REP');
-		rep = DummyToken.at(repAddress);
+    before(async () => {
+        [tokenTransferProxy, tokenRegistry] = await Promise.all([
+            TokenTransferProxy.deployed(),
+            TokenRegistry.deployed(),
+        ]);
+        const repAddress = await tokenRegistry.getTokenAddressBySymbol('REP');
+        rep = DummyToken.at(repAddress);
 
-		dmyBalances = new Balances([rep], [accounts[0], accounts[1]]);
-		await Promise.all([
-			rep.approve(TokenTransferProxy.address, INIT_ALLOW, {
-				from: accounts[0],
-			}),
-			rep.setBalance(accounts[0], INIT_BAL, { from: owner }),
-			rep.approve(TokenTransferProxy.address, INIT_ALLOW, {
-				from: accounts[1],
-			}),
-			rep.setBalance(accounts[1], INIT_BAL, { from: owner }),
-		]);
-	});
+        dmyBalances = new Balances([rep], [accounts[0], accounts[1]]);
+        await Promise.all([
+            rep.approve(TokenTransferProxy.address, INIT_ALLOW, {
+                from: accounts[0],
+            }),
+            rep.setBalance(accounts[0], INIT_BAL, { from: owner }),
+            rep.approve(TokenTransferProxy.address, INIT_ALLOW, {
+                from: accounts[1],
+            }),
+            rep.setBalance(accounts[1], INIT_BAL, { from: owner }),
+        ]);
+    });
 
-	describe('transferFrom', () => {
-		it('should throw when called by an unauthorized address', async () => {
-			expect(
-				tokenTransferProxy.transferFrom(rep.address, accounts[0], accounts[1], 1000, { from: notAuthorized }),
-			).to.be.rejectedWith(constants.REVERT);
-		});
+    describe('transferFrom', () => {
+        it('should throw when called by an unauthorized address', async () => {
+            expect(
+                tokenTransferProxy.transferFrom(rep.address, accounts[0], accounts[1], 1000, { from: notAuthorized }),
+            ).to.be.rejectedWith(constants.REVERT);
+        });
 
-		it('should allow an authorized address to transfer', async () => {
-			const balances = await dmyBalances.getAsync();
+        it('should allow an authorized address to transfer', async () => {
+            const balances = await dmyBalances.getAsync();
 
-			await tokenTransferProxy.addAuthorizedAddress(notAuthorized, {
-				from: owner,
-			});
-			const transferAmt = 10000;
-			await tokenTransferProxy.transferFrom(rep.address, accounts[0], accounts[1], transferAmt, {
-				from: notAuthorized,
-			});
+            await tokenTransferProxy.addAuthorizedAddress(notAuthorized, {
+                from: owner,
+            });
+            const transferAmt = 10000;
+            await tokenTransferProxy.transferFrom(rep.address, accounts[0], accounts[1], transferAmt, {
+                from: notAuthorized,
+            });
 
-			const newBalances = await dmyBalances.getAsync();
-			expect(newBalances[accounts[0]][rep.address]).to.be.bignumber.equal(
-				balances[accounts[0]][rep.address].minus(transferAmt),
-			);
-			expect(newBalances[accounts[1]][rep.address]).to.be.bignumber.equal(
-				balances[accounts[1]][rep.address].add(transferAmt),
-			);
-		});
-	});
+            const newBalances = await dmyBalances.getAsync();
+            expect(newBalances[accounts[0]][rep.address]).to.be.bignumber.equal(
+                balances[accounts[0]][rep.address].minus(transferAmt),
+            );
+            expect(newBalances[accounts[1]][rep.address]).to.be.bignumber.equal(
+                balances[accounts[1]][rep.address].add(transferAmt),
+            );
+        });
+    });
 });
diff --git a/packages/contracts/test/ts/unlimited_allowance_token.ts b/packages/contracts/test/ts/unlimited_allowance_token.ts
index f2e070fbb..c90a52095 100644
--- a/packages/contracts/test/ts/unlimited_allowance_token.ts
+++ b/packages/contracts/test/ts/unlimited_allowance_token.ts
@@ -15,113 +15,113 @@ chaiSetup.configure();
 const expect = chai.expect;
 
 contract('UnlimitedAllowanceToken', (accounts: string[]) => {
-	const config = {
-		networkId: constants.TESTRPC_NETWORK_ID,
-	};
-	const zeroEx = new ZeroEx(web3.currentProvider, config);
-	const owner = accounts[0];
-	const spender = accounts[1];
-
-	const MAX_MINT_VALUE = new BigNumber(100000000000000000000);
-	let tokenAddress: string;
-	let token: ContractInstance;
-
-	beforeEach(async () => {
-		token = await DummyToken.new({ from: owner });
-		await token.mint(MAX_MINT_VALUE, { from: owner });
-		tokenAddress = token.address;
-	});
-
-	describe('transfer', () => {
-		it('should transfer balance from sender to receiver', async () => {
-			const receiver = spender;
-			const initOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
-			const amountToTransfer = new BigNumber(1);
-			await zeroEx.token.transferAsync(tokenAddress, owner, receiver, amountToTransfer);
-			const finalOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
-			const finalReceiverBalance = await zeroEx.token.getBalanceAsync(tokenAddress, receiver);
-
-			const expectedFinalOwnerBalance = initOwnerBalance.minus(amountToTransfer);
-			const expectedFinalReceiverBalance = amountToTransfer;
-			expect(finalOwnerBalance).to.be.bignumber.equal(expectedFinalOwnerBalance);
-			expect(finalReceiverBalance).to.be.bignumber.equal(expectedFinalReceiverBalance);
-		});
-
-		it('should return true on a 0 value transfer', async () => {
-			const didReturnTrue = await token.transfer.call(spender, 0, {
-				from: owner,
-			});
-			expect(didReturnTrue).to.be.true();
-		});
-	});
-
-	describe('transferFrom', () => {
-		it('should return false if owner has insufficient balance', async () => {
-			const ownerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
-			const amountToTransfer = ownerBalance.plus(1);
-			await zeroEx.token.setAllowanceAsync(tokenAddress, owner, spender, amountToTransfer);
-			const didReturnTrue = await token.transferFrom.call(owner, spender, amountToTransfer, { from: spender });
-			expect(didReturnTrue).to.be.false();
-		});
-
-		it('should return false if spender has insufficient allowance', async () => {
-			const ownerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
-			const amountToTransfer = ownerBalance;
-
-			const spenderAllowance = await zeroEx.token.getAllowanceAsync(tokenAddress, owner, spender);
-			const spenderAllowanceIsInsufficient = spenderAllowance.cmp(amountToTransfer) < 0;
-			expect(spenderAllowanceIsInsufficient).to.be.true();
-
-			const didReturnTrue = await token.transferFrom.call(owner, spender, amountToTransfer, { from: spender });
-			expect(didReturnTrue).to.be.false();
-		});
-
-		it('should return true on a 0 value transfer', async () => {
-			const amountToTransfer = 0;
-			const didReturnTrue = await token.transferFrom.call(owner, spender, amountToTransfer, { from: spender });
-			expect(didReturnTrue).to.be.true();
-		});
-
-		it('should not modify spender allowance if spender allowance is 2^256 - 1', async () => {
-			const initOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
-			const amountToTransfer = initOwnerBalance;
-			const initSpenderAllowance = zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS;
-			await zeroEx.token.setAllowanceAsync(tokenAddress, owner, spender, initSpenderAllowance);
-			await zeroEx.token.transferFromAsync(tokenAddress, owner, spender, spender, amountToTransfer, {
-				gasLimit: constants.MAX_TOKEN_TRANSFERFROM_GAS,
-			});
-
-			const newSpenderAllowance = await zeroEx.token.getAllowanceAsync(tokenAddress, owner, spender);
-			expect(initSpenderAllowance).to.be.bignumber.equal(newSpenderAllowance);
-		});
-
-		it('should transfer the correct balances if spender has sufficient allowance', async () => {
-			const initOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
-			const amountToTransfer = initOwnerBalance;
-			const initSpenderAllowance = initOwnerBalance;
-			await zeroEx.token.setAllowanceAsync(tokenAddress, owner, spender, initSpenderAllowance);
-			await zeroEx.token.transferFromAsync(tokenAddress, owner, spender, spender, amountToTransfer, {
-				gasLimit: constants.MAX_TOKEN_TRANSFERFROM_GAS,
-			});
-
-			const newOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
-			const newSpenderBalance = await zeroEx.token.getBalanceAsync(tokenAddress, spender);
-
-			expect(newOwnerBalance).to.be.bignumber.equal(0);
-			expect(newSpenderBalance).to.be.bignumber.equal(initOwnerBalance);
-		});
-
-		it('should modify allowance if spender has sufficient allowance less than 2^256 - 1', async () => {
-			const initOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
-			const amountToTransfer = initOwnerBalance;
-			const initSpenderAllowance = initOwnerBalance;
-			await zeroEx.token.setAllowanceAsync(tokenAddress, owner, spender, initSpenderAllowance);
-			await zeroEx.token.transferFromAsync(tokenAddress, owner, spender, spender, amountToTransfer, {
-				gasLimit: constants.MAX_TOKEN_TRANSFERFROM_GAS,
-			});
-
-			const newSpenderAllowance = await zeroEx.token.getAllowanceAsync(tokenAddress, owner, spender);
-			expect(newSpenderAllowance).to.be.bignumber.equal(0);
-		});
-	});
+    const config = {
+        networkId: constants.TESTRPC_NETWORK_ID,
+    };
+    const zeroEx = new ZeroEx(web3.currentProvider, config);
+    const owner = accounts[0];
+    const spender = accounts[1];
+
+    const MAX_MINT_VALUE = new BigNumber(100000000000000000000);
+    let tokenAddress: string;
+    let token: ContractInstance;
+
+    beforeEach(async () => {
+        token = await DummyToken.new({ from: owner });
+        await token.mint(MAX_MINT_VALUE, { from: owner });
+        tokenAddress = token.address;
+    });
+
+    describe('transfer', () => {
+        it('should transfer balance from sender to receiver', async () => {
+            const receiver = spender;
+            const initOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
+            const amountToTransfer = new BigNumber(1);
+            await zeroEx.token.transferAsync(tokenAddress, owner, receiver, amountToTransfer);
+            const finalOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
+            const finalReceiverBalance = await zeroEx.token.getBalanceAsync(tokenAddress, receiver);
+
+            const expectedFinalOwnerBalance = initOwnerBalance.minus(amountToTransfer);
+            const expectedFinalReceiverBalance = amountToTransfer;
+            expect(finalOwnerBalance).to.be.bignumber.equal(expectedFinalOwnerBalance);
+            expect(finalReceiverBalance).to.be.bignumber.equal(expectedFinalReceiverBalance);
+        });
+
+        it('should return true on a 0 value transfer', async () => {
+            const didReturnTrue = await token.transfer.call(spender, 0, {
+                from: owner,
+            });
+            expect(didReturnTrue).to.be.true();
+        });
+    });
+
+    describe('transferFrom', () => {
+        it('should return false if owner has insufficient balance', async () => {
+            const ownerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
+            const amountToTransfer = ownerBalance.plus(1);
+            await zeroEx.token.setAllowanceAsync(tokenAddress, owner, spender, amountToTransfer);
+            const didReturnTrue = await token.transferFrom.call(owner, spender, amountToTransfer, { from: spender });
+            expect(didReturnTrue).to.be.false();
+        });
+
+        it('should return false if spender has insufficient allowance', async () => {
+            const ownerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
+            const amountToTransfer = ownerBalance;
+
+            const spenderAllowance = await zeroEx.token.getAllowanceAsync(tokenAddress, owner, spender);
+            const spenderAllowanceIsInsufficient = spenderAllowance.cmp(amountToTransfer) < 0;
+            expect(spenderAllowanceIsInsufficient).to.be.true();
+
+            const didReturnTrue = await token.transferFrom.call(owner, spender, amountToTransfer, { from: spender });
+            expect(didReturnTrue).to.be.false();
+        });
+
+        it('should return true on a 0 value transfer', async () => {
+            const amountToTransfer = 0;
+            const didReturnTrue = await token.transferFrom.call(owner, spender, amountToTransfer, { from: spender });
+            expect(didReturnTrue).to.be.true();
+        });
+
+        it('should not modify spender allowance if spender allowance is 2^256 - 1', async () => {
+            const initOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
+            const amountToTransfer = initOwnerBalance;
+            const initSpenderAllowance = zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS;
+            await zeroEx.token.setAllowanceAsync(tokenAddress, owner, spender, initSpenderAllowance);
+            await zeroEx.token.transferFromAsync(tokenAddress, owner, spender, spender, amountToTransfer, {
+                gasLimit: constants.MAX_TOKEN_TRANSFERFROM_GAS,
+            });
+
+            const newSpenderAllowance = await zeroEx.token.getAllowanceAsync(tokenAddress, owner, spender);
+            expect(initSpenderAllowance).to.be.bignumber.equal(newSpenderAllowance);
+        });
+
+        it('should transfer the correct balances if spender has sufficient allowance', async () => {
+            const initOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
+            const amountToTransfer = initOwnerBalance;
+            const initSpenderAllowance = initOwnerBalance;
+            await zeroEx.token.setAllowanceAsync(tokenAddress, owner, spender, initSpenderAllowance);
+            await zeroEx.token.transferFromAsync(tokenAddress, owner, spender, spender, amountToTransfer, {
+                gasLimit: constants.MAX_TOKEN_TRANSFERFROM_GAS,
+            });
+
+            const newOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
+            const newSpenderBalance = await zeroEx.token.getBalanceAsync(tokenAddress, spender);
+
+            expect(newOwnerBalance).to.be.bignumber.equal(0);
+            expect(newSpenderBalance).to.be.bignumber.equal(initOwnerBalance);
+        });
+
+        it('should modify allowance if spender has sufficient allowance less than 2^256 - 1', async () => {
+            const initOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
+            const amountToTransfer = initOwnerBalance;
+            const initSpenderAllowance = initOwnerBalance;
+            await zeroEx.token.setAllowanceAsync(tokenAddress, owner, spender, initSpenderAllowance);
+            await zeroEx.token.transferFromAsync(tokenAddress, owner, spender, spender, amountToTransfer, {
+                gasLimit: constants.MAX_TOKEN_TRANSFERFROM_GAS,
+            });
+
+            const newSpenderAllowance = await zeroEx.token.getAllowanceAsync(tokenAddress, owner, spender);
+            expect(newSpenderAllowance).to.be.bignumber.equal(0);
+        });
+    });
 });
diff --git a/packages/contracts/test/ts/unlimited_allowance_token_v2.ts b/packages/contracts/test/ts/unlimited_allowance_token_v2.ts
index 4f2ab2e1e..1b29a02ba 100644
--- a/packages/contracts/test/ts/unlimited_allowance_token_v2.ts
+++ b/packages/contracts/test/ts/unlimited_allowance_token_v2.ts
@@ -15,127 +15,127 @@ chaiSetup.configure();
 const expect = chai.expect;
 
 contract('UnlimitedAllowanceTokenV2', (accounts: string[]) => {
-	const config = {
-		networkId: constants.TESTRPC_NETWORK_ID,
-	};
-	const zeroEx = new ZeroEx(web3.currentProvider, config);
-	const owner = accounts[0];
-	const spender = accounts[1];
-
-	const MAX_MINT_VALUE = new BigNumber(100000000000000000000);
-	let tokenAddress: string;
-	let token: ContractInstance;
-
-	beforeEach(async () => {
-		token = await DummyTokenV2.new({ from: owner });
-		await token.mint(MAX_MINT_VALUE, { from: owner });
-		tokenAddress = token.address;
-	});
-
-	describe('transfer', () => {
-		it('should throw if owner has insufficient balance', async () => {
-			const ownerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
-			const amountToTransfer = ownerBalance.plus(1);
-			return expect(token.transfer.call(spender, amountToTransfer, { from: owner })).to.be.rejectedWith(
-				constants.REVERT,
-			);
-		});
-
-		it('should transfer balance from sender to receiver', async () => {
-			const receiver = spender;
-			const initOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
-			const amountToTransfer = new BigNumber(1);
-			await zeroEx.token.transferAsync(tokenAddress, owner, receiver, amountToTransfer);
-			const finalOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
-			const finalReceiverBalance = await zeroEx.token.getBalanceAsync(tokenAddress, receiver);
-
-			const expectedFinalOwnerBalance = initOwnerBalance.minus(amountToTransfer);
-			const expectedFinalReceiverBalance = amountToTransfer;
-			expect(finalOwnerBalance).to.be.bignumber.equal(expectedFinalOwnerBalance);
-			expect(finalReceiverBalance).to.be.bignumber.equal(expectedFinalReceiverBalance);
-		});
-
-		it('should return true on a 0 value transfer', async () => {
-			const didReturnTrue = await token.transfer.call(spender, 0, {
-				from: owner,
-			});
-			expect(didReturnTrue).to.be.true();
-		});
-	});
-
-	describe('transferFrom', () => {
-		it('should throw if owner has insufficient balance', async () => {
-			const ownerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
-			const amountToTransfer = ownerBalance.plus(1);
-			await zeroEx.token.setAllowanceAsync(tokenAddress, owner, spender, amountToTransfer);
-			return expect(
-				token.transferFrom.call(owner, spender, amountToTransfer, {
-					from: spender,
-				}),
-			).to.be.rejectedWith(constants.REVERT);
-		});
-
-		it('should throw if spender has insufficient allowance', async () => {
-			const ownerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
-			const amountToTransfer = ownerBalance;
-
-			const spenderAllowance = await zeroEx.token.getAllowanceAsync(tokenAddress, owner, spender);
-			const spenderAllowanceIsInsufficient = spenderAllowance.cmp(amountToTransfer) < 0;
-			expect(spenderAllowanceIsInsufficient).to.be.true();
-
-			return expect(
-				token.transferFrom.call(owner, spender, amountToTransfer, {
-					from: spender,
-				}),
-			).to.be.rejectedWith(constants.REVERT);
-		});
-
-		it('should return true on a 0 value transfer', async () => {
-			const amountToTransfer = 0;
-			const didReturnTrue = await token.transferFrom.call(owner, spender, amountToTransfer, { from: spender });
-			expect(didReturnTrue).to.be.true();
-		});
-
-		it('should not modify spender allowance if spender allowance is 2^256 - 1', async () => {
-			const initOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
-			const amountToTransfer = initOwnerBalance;
-			const initSpenderAllowance = zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS;
-			await zeroEx.token.setAllowanceAsync(tokenAddress, owner, spender, initSpenderAllowance);
-			await zeroEx.token.transferFromAsync(tokenAddress, owner, spender, spender, amountToTransfer, {
-				gasLimit: constants.MAX_TOKEN_TRANSFERFROM_GAS,
-			});
-
-			const newSpenderAllowance = await zeroEx.token.getAllowanceAsync(tokenAddress, owner, spender);
-			expect(initSpenderAllowance).to.be.bignumber.equal(newSpenderAllowance);
-		});
-
-		it('should transfer the correct balances if spender has sufficient allowance', async () => {
-			const initOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
-			const amountToTransfer = initOwnerBalance;
-			const initSpenderAllowance = initOwnerBalance;
-			await zeroEx.token.setAllowanceAsync(tokenAddress, owner, spender, initSpenderAllowance);
-			await zeroEx.token.transferFromAsync(tokenAddress, owner, spender, spender, amountToTransfer, {
-				gasLimit: constants.MAX_TOKEN_TRANSFERFROM_GAS,
-			});
-
-			const newOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
-			const newSpenderBalance = await zeroEx.token.getBalanceAsync(tokenAddress, spender);
-
-			expect(newOwnerBalance).to.be.bignumber.equal(0);
-			expect(newSpenderBalance).to.be.bignumber.equal(initOwnerBalance);
-		});
-
-		it('should modify allowance if spender has sufficient allowance less than 2^256 - 1', async () => {
-			const initOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
-			const amountToTransfer = initOwnerBalance;
-			const initSpenderAllowance = initOwnerBalance;
-			await zeroEx.token.setAllowanceAsync(tokenAddress, owner, spender, initSpenderAllowance);
-			await zeroEx.token.transferFromAsync(tokenAddress, owner, spender, spender, amountToTransfer, {
-				gasLimit: constants.MAX_TOKEN_TRANSFERFROM_GAS,
-			});
-
-			const newSpenderAllowance = await zeroEx.token.getAllowanceAsync(tokenAddress, owner, spender);
-			expect(newSpenderAllowance).to.be.bignumber.equal(0);
-		});
-	});
+    const config = {
+        networkId: constants.TESTRPC_NETWORK_ID,
+    };
+    const zeroEx = new ZeroEx(web3.currentProvider, config);
+    const owner = accounts[0];
+    const spender = accounts[1];
+
+    const MAX_MINT_VALUE = new BigNumber(100000000000000000000);
+    let tokenAddress: string;
+    let token: ContractInstance;
+
+    beforeEach(async () => {
+        token = await DummyTokenV2.new({ from: owner });
+        await token.mint(MAX_MINT_VALUE, { from: owner });
+        tokenAddress = token.address;
+    });
+
+    describe('transfer', () => {
+        it('should throw if owner has insufficient balance', async () => {
+            const ownerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
+            const amountToTransfer = ownerBalance.plus(1);
+            return expect(token.transfer.call(spender, amountToTransfer, { from: owner })).to.be.rejectedWith(
+                constants.REVERT,
+            );
+        });
+
+        it('should transfer balance from sender to receiver', async () => {
+            const receiver = spender;
+            const initOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
+            const amountToTransfer = new BigNumber(1);
+            await zeroEx.token.transferAsync(tokenAddress, owner, receiver, amountToTransfer);
+            const finalOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
+            const finalReceiverBalance = await zeroEx.token.getBalanceAsync(tokenAddress, receiver);
+
+            const expectedFinalOwnerBalance = initOwnerBalance.minus(amountToTransfer);
+            const expectedFinalReceiverBalance = amountToTransfer;
+            expect(finalOwnerBalance).to.be.bignumber.equal(expectedFinalOwnerBalance);
+            expect(finalReceiverBalance).to.be.bignumber.equal(expectedFinalReceiverBalance);
+        });
+
+        it('should return true on a 0 value transfer', async () => {
+            const didReturnTrue = await token.transfer.call(spender, 0, {
+                from: owner,
+            });
+            expect(didReturnTrue).to.be.true();
+        });
+    });
+
+    describe('transferFrom', () => {
+        it('should throw if owner has insufficient balance', async () => {
+            const ownerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
+            const amountToTransfer = ownerBalance.plus(1);
+            await zeroEx.token.setAllowanceAsync(tokenAddress, owner, spender, amountToTransfer);
+            return expect(
+                token.transferFrom.call(owner, spender, amountToTransfer, {
+                    from: spender,
+                }),
+            ).to.be.rejectedWith(constants.REVERT);
+        });
+
+        it('should throw if spender has insufficient allowance', async () => {
+            const ownerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
+            const amountToTransfer = ownerBalance;
+
+            const spenderAllowance = await zeroEx.token.getAllowanceAsync(tokenAddress, owner, spender);
+            const spenderAllowanceIsInsufficient = spenderAllowance.cmp(amountToTransfer) < 0;
+            expect(spenderAllowanceIsInsufficient).to.be.true();
+
+            return expect(
+                token.transferFrom.call(owner, spender, amountToTransfer, {
+                    from: spender,
+                }),
+            ).to.be.rejectedWith(constants.REVERT);
+        });
+
+        it('should return true on a 0 value transfer', async () => {
+            const amountToTransfer = 0;
+            const didReturnTrue = await token.transferFrom.call(owner, spender, amountToTransfer, { from: spender });
+            expect(didReturnTrue).to.be.true();
+        });
+
+        it('should not modify spender allowance if spender allowance is 2^256 - 1', async () => {
+            const initOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
+            const amountToTransfer = initOwnerBalance;
+            const initSpenderAllowance = zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS;
+            await zeroEx.token.setAllowanceAsync(tokenAddress, owner, spender, initSpenderAllowance);
+            await zeroEx.token.transferFromAsync(tokenAddress, owner, spender, spender, amountToTransfer, {
+                gasLimit: constants.MAX_TOKEN_TRANSFERFROM_GAS,
+            });
+
+            const newSpenderAllowance = await zeroEx.token.getAllowanceAsync(tokenAddress, owner, spender);
+            expect(initSpenderAllowance).to.be.bignumber.equal(newSpenderAllowance);
+        });
+
+        it('should transfer the correct balances if spender has sufficient allowance', async () => {
+            const initOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
+            const amountToTransfer = initOwnerBalance;
+            const initSpenderAllowance = initOwnerBalance;
+            await zeroEx.token.setAllowanceAsync(tokenAddress, owner, spender, initSpenderAllowance);
+            await zeroEx.token.transferFromAsync(tokenAddress, owner, spender, spender, amountToTransfer, {
+                gasLimit: constants.MAX_TOKEN_TRANSFERFROM_GAS,
+            });
+
+            const newOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
+            const newSpenderBalance = await zeroEx.token.getBalanceAsync(tokenAddress, spender);
+
+            expect(newOwnerBalance).to.be.bignumber.equal(0);
+            expect(newSpenderBalance).to.be.bignumber.equal(initOwnerBalance);
+        });
+
+        it('should modify allowance if spender has sufficient allowance less than 2^256 - 1', async () => {
+            const initOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
+            const amountToTransfer = initOwnerBalance;
+            const initSpenderAllowance = initOwnerBalance;
+            await zeroEx.token.setAllowanceAsync(tokenAddress, owner, spender, initSpenderAllowance);
+            await zeroEx.token.transferFromAsync(tokenAddress, owner, spender, spender, amountToTransfer, {
+                gasLimit: constants.MAX_TOKEN_TRANSFERFROM_GAS,
+            });
+
+            const newSpenderAllowance = await zeroEx.token.getAllowanceAsync(tokenAddress, owner, spender);
+            expect(newSpenderAllowance).to.be.bignumber.equal(0);
+        });
+    });
 });
diff --git a/packages/contracts/test/ts/utils/chai_setup.ts b/packages/contracts/test/ts/utils/chai_setup.ts
index e156b5f7c..078edd309 100644
--- a/packages/contracts/test/ts/utils/chai_setup.ts
+++ b/packages/contracts/test/ts/utils/chai_setup.ts
@@ -4,10 +4,10 @@ import ChaiBigNumber = require('chai-bignumber');
 import * as dirtyChai from 'dirty-chai';
 
 export const chaiSetup = {
-	configure() {
-		chai.config.includeStack = true;
-		chai.use(ChaiBigNumber());
-		chai.use(dirtyChai);
-		chai.use(chaiAsPromised);
-	},
+    configure() {
+        chai.config.includeStack = true;
+        chai.use(ChaiBigNumber());
+        chai.use(dirtyChai);
+        chai.use(chaiAsPromised);
+    },
 };
diff --git a/packages/contracts/test/ts/zrx_token.ts b/packages/contracts/test/ts/zrx_token.ts
index a0b11cdb6..766c94c2a 100644
--- a/packages/contracts/test/ts/zrx_token.ts
+++ b/packages/contracts/test/ts/zrx_token.ts
@@ -15,161 +15,161 @@ const { Exchange, ZRXToken } = new Artifacts(artifacts);
 const web3: Web3 = (global as any).web3;
 
 contract('ZRXToken', (accounts: string[]) => {
-	const owner = accounts[0];
-	const spender = accounts[1];
-	let zeroEx: ZeroEx;
-
-	let MAX_UINT: BigNumber;
-
-	let zrx: ContractInstance;
-	let zrxAddress: string;
-
-	beforeEach(async () => {
-		zeroEx = new ZeroEx(web3.currentProvider, {
-			exchangeContractAddress: Exchange.address,
-			networkId: constants.TESTRPC_NETWORK_ID,
-		});
-		zrx = await ZRXToken.new();
-		zrxAddress = zrx.address;
-		MAX_UINT = zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS;
-	});
-
-	describe('constants', () => {
-		it('should have 18 decimals', async () => {
-			const decimals = new BigNumber(await zrx.decimals.call());
-			const expectedDecimals = 18;
-			expect(decimals).to.be.bignumber.equal(expectedDecimals);
-		});
-
-		it('should have a total supply of 1 billion tokens', async () => {
-			const totalSupply = new BigNumber(await zrx.totalSupply.call());
-			const expectedTotalSupply = 1000000000;
-			expect(ZeroEx.toUnitAmount(totalSupply, 18)).to.be.bignumber.equal(expectedTotalSupply);
-		});
-
-		it('should be named 0x Protocol Token', async () => {
-			const name = await zrx.name.call();
-			const expectedName = '0x Protocol Token';
-			expect(name).to.be.equal(expectedName);
-		});
-
-		it('should have the symbol ZRX', async () => {
-			const symbol = await zrx.symbol.call();
-			const expectedSymbol = 'ZRX';
-			expect(symbol).to.be.equal(expectedSymbol);
-		});
-	});
-
-	describe('constructor', () => {
-		it('should initialize owner balance to totalSupply', async () => {
-			const ownerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner);
-			const totalSupply = new BigNumber(await zrx.totalSupply.call());
-			expect(totalSupply).to.be.bignumber.equal(ownerBalance);
-		});
-	});
-
-	describe('transfer', () => {
-		it('should transfer balance from sender to receiver', async () => {
-			const receiver = spender;
-			const initOwnerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner);
-			const amountToTransfer = new BigNumber(1);
-			const txHash = await zeroEx.token.transferAsync(zrxAddress, owner, receiver, amountToTransfer);
-			await zeroEx.awaitTransactionMinedAsync(txHash);
-			const finalOwnerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner);
-			const finalReceiverBalance = await zeroEx.token.getBalanceAsync(zrxAddress, receiver);
-
-			const expectedFinalOwnerBalance = initOwnerBalance.minus(amountToTransfer);
-			const expectedFinalReceiverBalance = amountToTransfer;
-			expect(finalOwnerBalance).to.be.bignumber.equal(expectedFinalOwnerBalance);
-			expect(finalReceiverBalance).to.be.bignumber.equal(expectedFinalReceiverBalance);
-		});
-
-		it('should return true on a 0 value transfer', async () => {
-			const didReturnTrue = await zrx.transfer.call(spender, 0, {
-				from: owner,
-			});
-			expect(didReturnTrue).to.be.true();
-		});
-	});
-
-	describe('transferFrom', () => {
-		it('should return false if owner has insufficient balance', async () => {
-			const ownerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner);
-			const amountToTransfer = ownerBalance.plus(1);
-			const txHash = await zeroEx.token.setAllowanceAsync(zrxAddress, owner, spender, amountToTransfer, {
-				gasLimit: constants.MAX_TOKEN_APPROVE_GAS,
-			});
-			await zeroEx.awaitTransactionMinedAsync(txHash);
-			const didReturnTrue = await zrx.transferFrom.call(owner, spender, amountToTransfer, { from: spender });
-			expect(didReturnTrue).to.be.false();
-		});
-
-		it('should return false if spender has insufficient allowance', async () => {
-			const ownerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner);
-			const amountToTransfer = ownerBalance;
-
-			const spenderAllowance = await zeroEx.token.getAllowanceAsync(zrxAddress, owner, spender);
-			const spenderAllowanceIsInsufficient = spenderAllowance.cmp(amountToTransfer) < 0;
-			expect(spenderAllowanceIsInsufficient).to.be.true();
-
-			const didReturnTrue = await zrx.transferFrom.call(owner, spender, amountToTransfer, { from: spender });
-			expect(didReturnTrue).to.be.false();
-		});
-
-		it('should return true on a 0 value transfer', async () => {
-			const amountToTransfer = 0;
-			const didReturnTrue = await zrx.transferFrom.call(owner, spender, amountToTransfer, { from: spender });
-			expect(didReturnTrue).to.be.true();
-		});
-
-		it('should not modify spender allowance if spender allowance is 2^256 - 1', async () => {
-			const initOwnerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner);
-			const amountToTransfer = initOwnerBalance;
-			const initSpenderAllowance = MAX_UINT;
-			let txHash = await zeroEx.token.setAllowanceAsync(zrxAddress, owner, spender, initSpenderAllowance, {
-				gasLimit: constants.MAX_TOKEN_APPROVE_GAS,
-			});
-			await zeroEx.awaitTransactionMinedAsync(txHash);
-			txHash = await zeroEx.token.transferFromAsync(zrxAddress, owner, spender, spender, amountToTransfer, {
-				gasLimit: constants.MAX_TOKEN_TRANSFERFROM_GAS,
-			});
-			await zeroEx.awaitTransactionMinedAsync(txHash);
-
-			const newSpenderAllowance = await zeroEx.token.getAllowanceAsync(zrxAddress, owner, spender);
-			expect(initSpenderAllowance).to.be.bignumber.equal(newSpenderAllowance);
-		});
-
-		it('should transfer the correct balances if spender has sufficient allowance', async () => {
-			const initOwnerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner);
-			const initSpenderBalance = await zeroEx.token.getBalanceAsync(zrxAddress, spender);
-			const amountToTransfer = initOwnerBalance;
-			const initSpenderAllowance = initOwnerBalance;
-			let txHash = await zeroEx.token.setAllowanceAsync(zrxAddress, owner, spender, initSpenderAllowance);
-			await zeroEx.awaitTransactionMinedAsync(txHash);
-			txHash = await zeroEx.token.transferFromAsync(zrxAddress, owner, spender, spender, amountToTransfer, {
-				gasLimit: constants.MAX_TOKEN_TRANSFERFROM_GAS,
-			});
-			await zeroEx.awaitTransactionMinedAsync(txHash);
-
-			const newOwnerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner);
-			const newSpenderBalance = await zeroEx.token.getBalanceAsync(zrxAddress, spender);
-
-			expect(newOwnerBalance).to.be.bignumber.equal(0);
-			expect(newSpenderBalance).to.be.bignumber.equal(initSpenderBalance.plus(initOwnerBalance));
-		});
-
-		it('should modify allowance if spender has sufficient allowance less than 2^256 - 1', async () => {
-			const initOwnerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner);
-			const amountToTransfer = initOwnerBalance;
-			let txHash = await zeroEx.token.setAllowanceAsync(zrxAddress, owner, spender, amountToTransfer);
-			await zeroEx.awaitTransactionMinedAsync(txHash);
-			txHash = await zeroEx.token.transferFromAsync(zrxAddress, owner, spender, spender, amountToTransfer, {
-				gasLimit: constants.MAX_TOKEN_TRANSFERFROM_GAS,
-			});
-			await zeroEx.awaitTransactionMinedAsync(txHash);
-
-			const newSpenderAllowance = await zeroEx.token.getAllowanceAsync(zrxAddress, owner, spender);
-			expect(newSpenderAllowance).to.be.bignumber.equal(0);
-		});
-	});
+    const owner = accounts[0];
+    const spender = accounts[1];
+    let zeroEx: ZeroEx;
+
+    let MAX_UINT: BigNumber;
+
+    let zrx: ContractInstance;
+    let zrxAddress: string;
+
+    beforeEach(async () => {
+        zeroEx = new ZeroEx(web3.currentProvider, {
+            exchangeContractAddress: Exchange.address,
+            networkId: constants.TESTRPC_NETWORK_ID,
+        });
+        zrx = await ZRXToken.new();
+        zrxAddress = zrx.address;
+        MAX_UINT = zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS;
+    });
+
+    describe('constants', () => {
+        it('should have 18 decimals', async () => {
+            const decimals = new BigNumber(await zrx.decimals.call());
+            const expectedDecimals = 18;
+            expect(decimals).to.be.bignumber.equal(expectedDecimals);
+        });
+
+        it('should have a total supply of 1 billion tokens', async () => {
+            const totalSupply = new BigNumber(await zrx.totalSupply.call());
+            const expectedTotalSupply = 1000000000;
+            expect(ZeroEx.toUnitAmount(totalSupply, 18)).to.be.bignumber.equal(expectedTotalSupply);
+        });
+
+        it('should be named 0x Protocol Token', async () => {
+            const name = await zrx.name.call();
+            const expectedName = '0x Protocol Token';
+            expect(name).to.be.equal(expectedName);
+        });
+
+        it('should have the symbol ZRX', async () => {
+            const symbol = await zrx.symbol.call();
+            const expectedSymbol = 'ZRX';
+            expect(symbol).to.be.equal(expectedSymbol);
+        });
+    });
+
+    describe('constructor', () => {
+        it('should initialize owner balance to totalSupply', async () => {
+            const ownerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner);
+            const totalSupply = new BigNumber(await zrx.totalSupply.call());
+            expect(totalSupply).to.be.bignumber.equal(ownerBalance);
+        });
+    });
+
+    describe('transfer', () => {
+        it('should transfer balance from sender to receiver', async () => {
+            const receiver = spender;
+            const initOwnerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner);
+            const amountToTransfer = new BigNumber(1);
+            const txHash = await zeroEx.token.transferAsync(zrxAddress, owner, receiver, amountToTransfer);
+            await zeroEx.awaitTransactionMinedAsync(txHash);
+            const finalOwnerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner);
+            const finalReceiverBalance = await zeroEx.token.getBalanceAsync(zrxAddress, receiver);
+
+            const expectedFinalOwnerBalance = initOwnerBalance.minus(amountToTransfer);
+            const expectedFinalReceiverBalance = amountToTransfer;
+            expect(finalOwnerBalance).to.be.bignumber.equal(expectedFinalOwnerBalance);
+            expect(finalReceiverBalance).to.be.bignumber.equal(expectedFinalReceiverBalance);
+        });
+
+        it('should return true on a 0 value transfer', async () => {
+            const didReturnTrue = await zrx.transfer.call(spender, 0, {
+                from: owner,
+            });
+            expect(didReturnTrue).to.be.true();
+        });
+    });
+
+    describe('transferFrom', () => {
+        it('should return false if owner has insufficient balance', async () => {
+            const ownerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner);
+            const amountToTransfer = ownerBalance.plus(1);
+            const txHash = await zeroEx.token.setAllowanceAsync(zrxAddress, owner, spender, amountToTransfer, {
+                gasLimit: constants.MAX_TOKEN_APPROVE_GAS,
+            });
+            await zeroEx.awaitTransactionMinedAsync(txHash);
+            const didReturnTrue = await zrx.transferFrom.call(owner, spender, amountToTransfer, { from: spender });
+            expect(didReturnTrue).to.be.false();
+        });
+
+        it('should return false if spender has insufficient allowance', async () => {
+            const ownerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner);
+            const amountToTransfer = ownerBalance;
+
+            const spenderAllowance = await zeroEx.token.getAllowanceAsync(zrxAddress, owner, spender);
+            const spenderAllowanceIsInsufficient = spenderAllowance.cmp(amountToTransfer) < 0;
+            expect(spenderAllowanceIsInsufficient).to.be.true();
+
+            const didReturnTrue = await zrx.transferFrom.call(owner, spender, amountToTransfer, { from: spender });
+            expect(didReturnTrue).to.be.false();
+        });
+
+        it('should return true on a 0 value transfer', async () => {
+            const amountToTransfer = 0;
+            const didReturnTrue = await zrx.transferFrom.call(owner, spender, amountToTransfer, { from: spender });
+            expect(didReturnTrue).to.be.true();
+        });
+
+        it('should not modify spender allowance if spender allowance is 2^256 - 1', async () => {
+            const initOwnerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner);
+            const amountToTransfer = initOwnerBalance;
+            const initSpenderAllowance = MAX_UINT;
+            let txHash = await zeroEx.token.setAllowanceAsync(zrxAddress, owner, spender, initSpenderAllowance, {
+                gasLimit: constants.MAX_TOKEN_APPROVE_GAS,
+            });
+            await zeroEx.awaitTransactionMinedAsync(txHash);
+            txHash = await zeroEx.token.transferFromAsync(zrxAddress, owner, spender, spender, amountToTransfer, {
+                gasLimit: constants.MAX_TOKEN_TRANSFERFROM_GAS,
+            });
+            await zeroEx.awaitTransactionMinedAsync(txHash);
+
+            const newSpenderAllowance = await zeroEx.token.getAllowanceAsync(zrxAddress, owner, spender);
+            expect(initSpenderAllowance).to.be.bignumber.equal(newSpenderAllowance);
+        });
+
+        it('should transfer the correct balances if spender has sufficient allowance', async () => {
+            const initOwnerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner);
+            const initSpenderBalance = await zeroEx.token.getBalanceAsync(zrxAddress, spender);
+            const amountToTransfer = initOwnerBalance;
+            const initSpenderAllowance = initOwnerBalance;
+            let txHash = await zeroEx.token.setAllowanceAsync(zrxAddress, owner, spender, initSpenderAllowance);
+            await zeroEx.awaitTransactionMinedAsync(txHash);
+            txHash = await zeroEx.token.transferFromAsync(zrxAddress, owner, spender, spender, amountToTransfer, {
+                gasLimit: constants.MAX_TOKEN_TRANSFERFROM_GAS,
+            });
+            await zeroEx.awaitTransactionMinedAsync(txHash);
+
+            const newOwnerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner);
+            const newSpenderBalance = await zeroEx.token.getBalanceAsync(zrxAddress, spender);
+
+            expect(newOwnerBalance).to.be.bignumber.equal(0);
+            expect(newSpenderBalance).to.be.bignumber.equal(initSpenderBalance.plus(initOwnerBalance));
+        });
+
+        it('should modify allowance if spender has sufficient allowance less than 2^256 - 1', async () => {
+            const initOwnerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner);
+            const amountToTransfer = initOwnerBalance;
+            let txHash = await zeroEx.token.setAllowanceAsync(zrxAddress, owner, spender, amountToTransfer);
+            await zeroEx.awaitTransactionMinedAsync(txHash);
+            txHash = await zeroEx.token.transferFromAsync(zrxAddress, owner, spender, spender, amountToTransfer, {
+                gasLimit: constants.MAX_TOKEN_TRANSFERFROM_GAS,
+            });
+            await zeroEx.awaitTransactionMinedAsync(txHash);
+
+            const newSpenderAllowance = await zeroEx.token.getAllowanceAsync(zrxAddress, owner, spender);
+            expect(newSpenderAllowance).to.be.bignumber.equal(0);
+        });
+    });
 });
diff --git a/packages/contracts/tsconfig.json b/packages/contracts/tsconfig.json
index e88b3c3f0..38008a542 100644
--- a/packages/contracts/tsconfig.json
+++ b/packages/contracts/tsconfig.json
@@ -1,25 +1,25 @@
 {
-	"extends": "../../tsconfig",
-	"compilerOptions": {
-		"outDir": "lib",
-		"baseUrl": ".",
-		"declaration": false,
-		"strictNullChecks": false,
-		"strictFunctionTypes": false,
-		"allowJs": true
-	},
-	"include": [
-		"../../node_modules/types-ethereumjs-util/index.d.ts",
-		"../../node_modules/chai-typescript-typings/index.d.ts",
-		"../../node_modules/web3-typescript-typings/index.d.ts",
-		"../../node_modules/chai-as-promised-typescript-typings/index.d.ts",
-		"../../node_modules/types-ethereumjs-util/index.d.ts",
-		"../../node_modules/types-bn/index.d.ts",
-		"./globals.d.ts",
-		"./util/**/*",
-		"./test/**/*",
-		"./migrations/**/*",
-		"./deploy/**/*"
-	],
-	"exclude": ["./deploy/solc/solc_bin"]
+    "extends": "../../tsconfig",
+    "compilerOptions": {
+        "outDir": "lib",
+        "baseUrl": ".",
+        "declaration": false,
+        "strictNullChecks": false,
+        "strictFunctionTypes": false,
+        "allowJs": true
+    },
+    "include": [
+        "../../node_modules/types-ethereumjs-util/index.d.ts",
+        "../../node_modules/chai-typescript-typings/index.d.ts",
+        "../../node_modules/web3-typescript-typings/index.d.ts",
+        "../../node_modules/chai-as-promised-typescript-typings/index.d.ts",
+        "../../node_modules/types-ethereumjs-util/index.d.ts",
+        "../../node_modules/types-bn/index.d.ts",
+        "./globals.d.ts",
+        "./util/**/*",
+        "./test/**/*",
+        "./migrations/**/*",
+        "./deploy/**/*"
+    ],
+    "exclude": ["./deploy/solc/solc_bin"]
 }
diff --git a/packages/contracts/tslint.json b/packages/contracts/tslint.json
index e63054bfc..ffaefe83a 100644
--- a/packages/contracts/tslint.json
+++ b/packages/contracts/tslint.json
@@ -1,3 +1,3 @@
 {
-	"extends": ["@0xproject/tslint-config"]
+    "extends": ["@0xproject/tslint-config"]
 }
diff --git a/packages/contracts/util/artifacts.ts b/packages/contracts/util/artifacts.ts
index ab9518d41..ecb18cbce 100644
--- a/packages/contracts/util/artifacts.ts
+++ b/packages/contracts/util/artifacts.ts
@@ -1,28 +1,28 @@
 export class Artifacts {
-	public Migrations: any;
-	public TokenTransferProxy: any;
-	public TokenRegistry: any;
-	public MultiSigWalletWithTimeLock: any;
-	public Exchange: any;
-	public ZRXToken: any;
-	public DummyToken: any;
-	public DummyTokenV2: any;
-	public EtherToken: any;
-	public MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress: any;
-	public MaliciousToken: any;
-	constructor(artifacts: any) {
-		this.Migrations = artifacts.require('Migrations');
-		this.TokenTransferProxy = artifacts.require('TokenTransferProxy');
-		this.TokenRegistry = artifacts.require('TokenRegistry');
-		this.MultiSigWalletWithTimeLock = artifacts.require('MultiSigWalletWithTimeLock');
-		this.Exchange = artifacts.require('Exchange');
-		this.ZRXToken = artifacts.require('ZRXToken');
-		this.DummyToken = artifacts.require('DummyToken');
-		this.DummyTokenV2 = artifacts.require('DummyToken_v2');
-		this.EtherToken = artifacts.require('WETH9');
-		this.MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress = artifacts.require(
-			'MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress',
-		);
-		this.MaliciousToken = artifacts.require('MaliciousToken');
-	}
+    public Migrations: any;
+    public TokenTransferProxy: any;
+    public TokenRegistry: any;
+    public MultiSigWalletWithTimeLock: any;
+    public Exchange: any;
+    public ZRXToken: any;
+    public DummyToken: any;
+    public DummyTokenV2: any;
+    public EtherToken: any;
+    public MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress: any;
+    public MaliciousToken: any;
+    constructor(artifacts: any) {
+        this.Migrations = artifacts.require('Migrations');
+        this.TokenTransferProxy = artifacts.require('TokenTransferProxy');
+        this.TokenRegistry = artifacts.require('TokenRegistry');
+        this.MultiSigWalletWithTimeLock = artifacts.require('MultiSigWalletWithTimeLock');
+        this.Exchange = artifacts.require('Exchange');
+        this.ZRXToken = artifacts.require('ZRXToken');
+        this.DummyToken = artifacts.require('DummyToken');
+        this.DummyTokenV2 = artifacts.require('DummyToken_v2');
+        this.EtherToken = artifacts.require('WETH9');
+        this.MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress = artifacts.require(
+            'MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress',
+        );
+        this.MaliciousToken = artifacts.require('MaliciousToken');
+    }
 }
diff --git a/packages/contracts/util/balances.ts b/packages/contracts/util/balances.ts
index f8c103670..6a1659ab1 100644
--- a/packages/contracts/util/balances.ts
+++ b/packages/contracts/util/balances.ts
@@ -4,24 +4,24 @@ import * as _ from 'lodash';
 import { BalancesByOwner, ContractInstance } from './types';
 
 export class Balances {
-	private _tokenContractInstances: ContractInstance[];
-	private _ownerAddresses: string[];
-	constructor(tokenContractInstances: ContractInstance[], ownerAddresses: string[]) {
-		this._tokenContractInstances = tokenContractInstances;
-		this._ownerAddresses = ownerAddresses;
-	}
-	public async getAsync(): Promise<BalancesByOwner> {
-		const balancesByOwner: BalancesByOwner = {};
-		for (const tokenContractInstance of this._tokenContractInstances) {
-			for (const ownerAddress of this._ownerAddresses) {
-				let balance = await tokenContractInstance.balanceOf(ownerAddress);
-				balance = new BigNumber(balance);
-				if (_.isUndefined(balancesByOwner[ownerAddress])) {
-					balancesByOwner[ownerAddress] = {};
-				}
-				balancesByOwner[ownerAddress][tokenContractInstance.address] = balance;
-			}
-		}
-		return balancesByOwner;
-	}
+    private _tokenContractInstances: ContractInstance[];
+    private _ownerAddresses: string[];
+    constructor(tokenContractInstances: ContractInstance[], ownerAddresses: string[]) {
+        this._tokenContractInstances = tokenContractInstances;
+        this._ownerAddresses = ownerAddresses;
+    }
+    public async getAsync(): Promise<BalancesByOwner> {
+        const balancesByOwner: BalancesByOwner = {};
+        for (const tokenContractInstance of this._tokenContractInstances) {
+            for (const ownerAddress of this._ownerAddresses) {
+                let balance = await tokenContractInstance.balanceOf(ownerAddress);
+                balance = new BigNumber(balance);
+                if (_.isUndefined(balancesByOwner[ownerAddress])) {
+                    balancesByOwner[ownerAddress] = {};
+                }
+                balancesByOwner[ownerAddress][tokenContractInstance.address] = balance;
+            }
+        }
+        return balancesByOwner;
+    }
 }
diff --git a/packages/contracts/util/constants.ts b/packages/contracts/util/constants.ts
index 85fd31be3..e61b2f802 100644
--- a/packages/contracts/util/constants.ts
+++ b/packages/contracts/util/constants.ts
@@ -1,9 +1,9 @@
 export const constants = {
-	NULL_BYTES: '0x',
-	INVALID_OPCODE: 'invalid opcode',
-	REVERT: 'revert',
-	TESTRPC_NETWORK_ID: 50,
-	MAX_ETHERTOKEN_WITHDRAW_GAS: 43000,
-	MAX_TOKEN_TRANSFERFROM_GAS: 80000,
-	MAX_TOKEN_APPROVE_GAS: 60000,
+    NULL_BYTES: '0x',
+    INVALID_OPCODE: 'invalid opcode',
+    REVERT: 'revert',
+    TESTRPC_NETWORK_ID: 50,
+    MAX_ETHERTOKEN_WITHDRAW_GAS: 43000,
+    MAX_TOKEN_TRANSFERFROM_GAS: 80000,
+    MAX_TOKEN_APPROVE_GAS: 60000,
 };
diff --git a/packages/contracts/util/crypto.ts b/packages/contracts/util/crypto.ts
index 29bbf206a..9173df643 100644
--- a/packages/contracts/util/crypto.ts
+++ b/packages/contracts/util/crypto.ts
@@ -4,7 +4,7 @@ import ethUtil = require('ethereumjs-util');
 import * as _ from 'lodash';
 
 export const crypto = {
-	/*
+    /*
    * We convert types from JS to Solidity as follows:
    * BigNumber -> uint256
    * number -> uint8
@@ -12,26 +12,26 @@ export const crypto = {
    * boolean -> bool
    * valid Ethereum address -> address
    */
-	solSHA3(args: any[]): Buffer {
-		const argTypes: string[] = [];
-		_.each(args, (arg, i) => {
-			const isNumber = _.isFinite(arg);
-			if (isNumber) {
-				argTypes.push('uint8');
-			} else if (arg.isBigNumber) {
-				argTypes.push('uint256');
-				args[i] = new BN(arg.toString(10), 10);
-			} else if (ethUtil.isValidAddress(arg)) {
-				argTypes.push('address');
-			} else if (_.isString(arg)) {
-				argTypes.push('string');
-			} else if (_.isBoolean(arg)) {
-				argTypes.push('bool');
-			} else {
-				throw new Error(`Unable to guess arg type: ${arg}`);
-			}
-		});
-		const hash = ABI.soliditySHA3(argTypes, args);
-		return hash;
-	},
+    solSHA3(args: any[]): Buffer {
+        const argTypes: string[] = [];
+        _.each(args, (arg, i) => {
+            const isNumber = _.isFinite(arg);
+            if (isNumber) {
+                argTypes.push('uint8');
+            } else if (arg.isBigNumber) {
+                argTypes.push('uint256');
+                args[i] = new BN(arg.toString(10), 10);
+            } else if (ethUtil.isValidAddress(arg)) {
+                argTypes.push('address');
+            } else if (_.isString(arg)) {
+                argTypes.push('string');
+            } else if (_.isBoolean(arg)) {
+                argTypes.push('bool');
+            } else {
+                throw new Error(`Unable to guess arg type: ${arg}`);
+            }
+        });
+        const hash = ABI.soliditySHA3(argTypes, args);
+        return hash;
+    },
 };
diff --git a/packages/contracts/util/exchange_wrapper.ts b/packages/contracts/util/exchange_wrapper.ts
index 3a3c44aae..ca79f92c4 100644
--- a/packages/contracts/util/exchange_wrapper.ts
+++ b/packages/contracts/util/exchange_wrapper.ts
@@ -6,186 +6,186 @@ import { Order } from './order';
 import { ContractInstance } from './types';
 
 export class ExchangeWrapper {
-	private _exchange: ContractInstance;
-	constructor(exchangeContractInstance: ContractInstance) {
-		this._exchange = exchangeContractInstance;
-	}
-	public async fillOrderAsync(
-		order: Order,
-		from: string,
-		opts: {
-			fillTakerTokenAmount?: BigNumber;
-			shouldThrowOnInsufficientBalanceOrAllowance?: boolean;
-		} = {},
-	) {
-		const shouldThrowOnInsufficientBalanceOrAllowance = !!opts.shouldThrowOnInsufficientBalanceOrAllowance;
-		const params = order.createFill(shouldThrowOnInsufficientBalanceOrAllowance, opts.fillTakerTokenAmount);
-		const tx = await this._exchange.fillOrder(
-			params.orderAddresses,
-			params.orderValues,
-			params.fillTakerTokenAmount,
-			params.shouldThrowOnInsufficientBalanceOrAllowance,
-			params.v,
-			params.r,
-			params.s,
-			{ from },
-		);
-		_.each(tx.logs, log => wrapLogBigNumbers(log));
-		return tx;
-	}
-	public async cancelOrderAsync(order: Order, from: string, opts: { cancelTakerTokenAmount?: BigNumber } = {}) {
-		const params = order.createCancel(opts.cancelTakerTokenAmount);
-		const tx = await this._exchange.cancelOrder(
-			params.orderAddresses,
-			params.orderValues,
-			params.cancelTakerTokenAmount,
-			{ from },
-		);
-		_.each(tx.logs, log => wrapLogBigNumbers(log));
-		return tx;
-	}
-	public async fillOrKillOrderAsync(order: Order, from: string, opts: { fillTakerTokenAmount?: BigNumber } = {}) {
-		const shouldThrowOnInsufficientBalanceOrAllowance = true;
-		const params = order.createFill(shouldThrowOnInsufficientBalanceOrAllowance, opts.fillTakerTokenAmount);
-		const tx = await this._exchange.fillOrKillOrder(
-			params.orderAddresses,
-			params.orderValues,
-			params.fillTakerTokenAmount,
-			params.v,
-			params.r,
-			params.s,
-			{ from },
-		);
-		_.each(tx.logs, log => wrapLogBigNumbers(log));
-		return tx;
-	}
-	public async batchFillOrdersAsync(
-		orders: Order[],
-		from: string,
-		opts: {
-			fillTakerTokenAmounts?: BigNumber[];
-			shouldThrowOnInsufficientBalanceOrAllowance?: boolean;
-		} = {},
-	) {
-		const shouldThrowOnInsufficientBalanceOrAllowance = !!opts.shouldThrowOnInsufficientBalanceOrAllowance;
-		const params = formatters.createBatchFill(
-			orders,
-			shouldThrowOnInsufficientBalanceOrAllowance,
-			opts.fillTakerTokenAmounts,
-		);
-		const tx = await this._exchange.batchFillOrders(
-			params.orderAddresses,
-			params.orderValues,
-			params.fillTakerTokenAmounts,
-			params.shouldThrowOnInsufficientBalanceOrAllowance,
-			params.v,
-			params.r,
-			params.s,
-			{ from },
-		);
-		_.each(tx.logs, log => wrapLogBigNumbers(log));
-		return tx;
-	}
-	public async batchFillOrKillOrdersAsync(
-		orders: Order[],
-		from: string,
-		opts: { fillTakerTokenAmounts?: BigNumber[] } = {},
-	) {
-		const params = formatters.createBatchFill(orders, undefined, opts.fillTakerTokenAmounts);
-		const tx = await this._exchange.batchFillOrKillOrders(
-			params.orderAddresses,
-			params.orderValues,
-			params.fillTakerTokenAmounts,
-			params.v,
-			params.r,
-			params.s,
-			{ from },
-		);
-		_.each(tx.logs, log => wrapLogBigNumbers(log));
-		return tx;
-	}
-	public async fillOrdersUpToAsync(
-		orders: Order[],
-		from: string,
-		opts: {
-			fillTakerTokenAmount?: BigNumber;
-			shouldThrowOnInsufficientBalanceOrAllowance?: boolean;
-		} = {},
-	) {
-		const shouldThrowOnInsufficientBalanceOrAllowance = !!opts.shouldThrowOnInsufficientBalanceOrAllowance;
-		const params = formatters.createFillUpTo(
-			orders,
-			shouldThrowOnInsufficientBalanceOrAllowance,
-			opts.fillTakerTokenAmount,
-		);
-		const tx = await this._exchange.fillOrdersUpTo(
-			params.orderAddresses,
-			params.orderValues,
-			params.fillTakerTokenAmount,
-			params.shouldThrowOnInsufficientBalanceOrAllowance,
-			params.v,
-			params.r,
-			params.s,
-			{ from },
-		);
-		_.each(tx.logs, log => wrapLogBigNumbers(log));
-		return tx;
-	}
-	public async batchCancelOrdersAsync(
-		orders: Order[],
-		from: string,
-		opts: { cancelTakerTokenAmounts?: BigNumber[] } = {},
-	) {
-		const params = formatters.createBatchCancel(orders, opts.cancelTakerTokenAmounts);
-		const tx = await this._exchange.batchCancelOrders(
-			params.orderAddresses,
-			params.orderValues,
-			params.cancelTakerTokenAmounts,
-			{ from },
-		);
-		_.each(tx.logs, log => wrapLogBigNumbers(log));
-		return tx;
-	}
-	public async getOrderHashAsync(order: Order): Promise<string> {
-		const shouldThrowOnInsufficientBalanceOrAllowance = false;
-		const params = order.createFill(shouldThrowOnInsufficientBalanceOrAllowance);
-		const orderHash = await this._exchange.getOrderHash(params.orderAddresses, params.orderValues);
-		return orderHash;
-	}
-	public async isValidSignatureAsync(order: Order): Promise<boolean> {
-		const isValidSignature = await this._exchange.isValidSignature(
-			order.params.maker,
-			order.params.orderHashHex,
-			order.params.v,
-			order.params.r,
-			order.params.s,
-		);
-		return isValidSignature;
-	}
-	public async isRoundingErrorAsync(
-		numerator: BigNumber,
-		denominator: BigNumber,
-		target: BigNumber,
-	): Promise<boolean> {
-		const isRoundingError = await this._exchange.isRoundingError(numerator, denominator, target);
-		return isRoundingError;
-	}
-	public async getPartialAmountAsync(
-		numerator: BigNumber,
-		denominator: BigNumber,
-		target: BigNumber,
-	): Promise<BigNumber> {
-		const partialAmount = new BigNumber(await this._exchange.getPartialAmount(numerator, denominator, target));
-		return partialAmount;
-	}
+    private _exchange: ContractInstance;
+    constructor(exchangeContractInstance: ContractInstance) {
+        this._exchange = exchangeContractInstance;
+    }
+    public async fillOrderAsync(
+        order: Order,
+        from: string,
+        opts: {
+            fillTakerTokenAmount?: BigNumber;
+            shouldThrowOnInsufficientBalanceOrAllowance?: boolean;
+        } = {},
+    ) {
+        const shouldThrowOnInsufficientBalanceOrAllowance = !!opts.shouldThrowOnInsufficientBalanceOrAllowance;
+        const params = order.createFill(shouldThrowOnInsufficientBalanceOrAllowance, opts.fillTakerTokenAmount);
+        const tx = await this._exchange.fillOrder(
+            params.orderAddresses,
+            params.orderValues,
+            params.fillTakerTokenAmount,
+            params.shouldThrowOnInsufficientBalanceOrAllowance,
+            params.v,
+            params.r,
+            params.s,
+            { from },
+        );
+        _.each(tx.logs, log => wrapLogBigNumbers(log));
+        return tx;
+    }
+    public async cancelOrderAsync(order: Order, from: string, opts: { cancelTakerTokenAmount?: BigNumber } = {}) {
+        const params = order.createCancel(opts.cancelTakerTokenAmount);
+        const tx = await this._exchange.cancelOrder(
+            params.orderAddresses,
+            params.orderValues,
+            params.cancelTakerTokenAmount,
+            { from },
+        );
+        _.each(tx.logs, log => wrapLogBigNumbers(log));
+        return tx;
+    }
+    public async fillOrKillOrderAsync(order: Order, from: string, opts: { fillTakerTokenAmount?: BigNumber } = {}) {
+        const shouldThrowOnInsufficientBalanceOrAllowance = true;
+        const params = order.createFill(shouldThrowOnInsufficientBalanceOrAllowance, opts.fillTakerTokenAmount);
+        const tx = await this._exchange.fillOrKillOrder(
+            params.orderAddresses,
+            params.orderValues,
+            params.fillTakerTokenAmount,
+            params.v,
+            params.r,
+            params.s,
+            { from },
+        );
+        _.each(tx.logs, log => wrapLogBigNumbers(log));
+        return tx;
+    }
+    public async batchFillOrdersAsync(
+        orders: Order[],
+        from: string,
+        opts: {
+            fillTakerTokenAmounts?: BigNumber[];
+            shouldThrowOnInsufficientBalanceOrAllowance?: boolean;
+        } = {},
+    ) {
+        const shouldThrowOnInsufficientBalanceOrAllowance = !!opts.shouldThrowOnInsufficientBalanceOrAllowance;
+        const params = formatters.createBatchFill(
+            orders,
+            shouldThrowOnInsufficientBalanceOrAllowance,
+            opts.fillTakerTokenAmounts,
+        );
+        const tx = await this._exchange.batchFillOrders(
+            params.orderAddresses,
+            params.orderValues,
+            params.fillTakerTokenAmounts,
+            params.shouldThrowOnInsufficientBalanceOrAllowance,
+            params.v,
+            params.r,
+            params.s,
+            { from },
+        );
+        _.each(tx.logs, log => wrapLogBigNumbers(log));
+        return tx;
+    }
+    public async batchFillOrKillOrdersAsync(
+        orders: Order[],
+        from: string,
+        opts: { fillTakerTokenAmounts?: BigNumber[] } = {},
+    ) {
+        const params = formatters.createBatchFill(orders, undefined, opts.fillTakerTokenAmounts);
+        const tx = await this._exchange.batchFillOrKillOrders(
+            params.orderAddresses,
+            params.orderValues,
+            params.fillTakerTokenAmounts,
+            params.v,
+            params.r,
+            params.s,
+            { from },
+        );
+        _.each(tx.logs, log => wrapLogBigNumbers(log));
+        return tx;
+    }
+    public async fillOrdersUpToAsync(
+        orders: Order[],
+        from: string,
+        opts: {
+            fillTakerTokenAmount?: BigNumber;
+            shouldThrowOnInsufficientBalanceOrAllowance?: boolean;
+        } = {},
+    ) {
+        const shouldThrowOnInsufficientBalanceOrAllowance = !!opts.shouldThrowOnInsufficientBalanceOrAllowance;
+        const params = formatters.createFillUpTo(
+            orders,
+            shouldThrowOnInsufficientBalanceOrAllowance,
+            opts.fillTakerTokenAmount,
+        );
+        const tx = await this._exchange.fillOrdersUpTo(
+            params.orderAddresses,
+            params.orderValues,
+            params.fillTakerTokenAmount,
+            params.shouldThrowOnInsufficientBalanceOrAllowance,
+            params.v,
+            params.r,
+            params.s,
+            { from },
+        );
+        _.each(tx.logs, log => wrapLogBigNumbers(log));
+        return tx;
+    }
+    public async batchCancelOrdersAsync(
+        orders: Order[],
+        from: string,
+        opts: { cancelTakerTokenAmounts?: BigNumber[] } = {},
+    ) {
+        const params = formatters.createBatchCancel(orders, opts.cancelTakerTokenAmounts);
+        const tx = await this._exchange.batchCancelOrders(
+            params.orderAddresses,
+            params.orderValues,
+            params.cancelTakerTokenAmounts,
+            { from },
+        );
+        _.each(tx.logs, log => wrapLogBigNumbers(log));
+        return tx;
+    }
+    public async getOrderHashAsync(order: Order): Promise<string> {
+        const shouldThrowOnInsufficientBalanceOrAllowance = false;
+        const params = order.createFill(shouldThrowOnInsufficientBalanceOrAllowance);
+        const orderHash = await this._exchange.getOrderHash(params.orderAddresses, params.orderValues);
+        return orderHash;
+    }
+    public async isValidSignatureAsync(order: Order): Promise<boolean> {
+        const isValidSignature = await this._exchange.isValidSignature(
+            order.params.maker,
+            order.params.orderHashHex,
+            order.params.v,
+            order.params.r,
+            order.params.s,
+        );
+        return isValidSignature;
+    }
+    public async isRoundingErrorAsync(
+        numerator: BigNumber,
+        denominator: BigNumber,
+        target: BigNumber,
+    ): Promise<boolean> {
+        const isRoundingError = await this._exchange.isRoundingError(numerator, denominator, target);
+        return isRoundingError;
+    }
+    public async getPartialAmountAsync(
+        numerator: BigNumber,
+        denominator: BigNumber,
+        target: BigNumber,
+    ): Promise<BigNumber> {
+        const partialAmount = new BigNumber(await this._exchange.getPartialAmount(numerator, denominator, target));
+        return partialAmount;
+    }
 }
 
 function wrapLogBigNumbers(log: any): any {
-	const argNames = _.keys(log.args);
-	for (const argName of argNames) {
-		const isWeb3BigNumber = _.startsWith(log.args[argName].constructor.toString(), 'function BigNumber(');
-		if (isWeb3BigNumber) {
-			log.args[argName] = new BigNumber(log.args[argName]);
-		}
-	}
+    const argNames = _.keys(log.args);
+    for (const argName of argNames) {
+        const isWeb3BigNumber = _.startsWith(log.args[argName].constructor.toString(), 'function BigNumber(');
+        if (isWeb3BigNumber) {
+            log.args[argName] = new BigNumber(log.args[argName]);
+        }
+    }
 }
diff --git a/packages/contracts/util/formatters.ts b/packages/contracts/util/formatters.ts
index c452b8e79..0d0ef6df4 100644
--- a/packages/contracts/util/formatters.ts
+++ b/packages/contracts/util/formatters.ts
@@ -5,107 +5,107 @@ import { Order } from './order';
 import { BatchCancelOrders, BatchFillOrders, FillOrdersUpTo } from './types';
 
 export const formatters = {
-	createBatchFill(
-		orders: Order[],
-		shouldThrowOnInsufficientBalanceOrAllowance: boolean,
-		fillTakerTokenAmounts: BigNumber[] = [],
-	) {
-		const batchFill: BatchFillOrders = {
-			orderAddresses: [],
-			orderValues: [],
-			fillTakerTokenAmounts,
-			shouldThrowOnInsufficientBalanceOrAllowance,
-			v: [],
-			r: [],
-			s: [],
-		};
-		_.forEach(orders, order => {
-			batchFill.orderAddresses.push([
-				order.params.maker,
-				order.params.taker,
-				order.params.makerToken,
-				order.params.takerToken,
-				order.params.feeRecipient,
-			]);
-			batchFill.orderValues.push([
-				order.params.makerTokenAmount,
-				order.params.takerTokenAmount,
-				order.params.makerFee,
-				order.params.takerFee,
-				order.params.expirationTimestampInSec,
-				order.params.salt,
-			]);
-			batchFill.v.push(order.params.v);
-			batchFill.r.push(order.params.r);
-			batchFill.s.push(order.params.s);
-			if (fillTakerTokenAmounts.length < orders.length) {
-				batchFill.fillTakerTokenAmounts.push(order.params.takerTokenAmount);
-			}
-		});
-		return batchFill;
-	},
-	createFillUpTo(
-		orders: Order[],
-		shouldThrowOnInsufficientBalanceOrAllowance: boolean,
-		fillTakerTokenAmount: BigNumber,
-	) {
-		const fillUpTo: FillOrdersUpTo = {
-			orderAddresses: [],
-			orderValues: [],
-			fillTakerTokenAmount,
-			shouldThrowOnInsufficientBalanceOrAllowance,
-			v: [],
-			r: [],
-			s: [],
-		};
-		orders.forEach(order => {
-			fillUpTo.orderAddresses.push([
-				order.params.maker,
-				order.params.taker,
-				order.params.makerToken,
-				order.params.takerToken,
-				order.params.feeRecipient,
-			]);
-			fillUpTo.orderValues.push([
-				order.params.makerTokenAmount,
-				order.params.takerTokenAmount,
-				order.params.makerFee,
-				order.params.takerFee,
-				order.params.expirationTimestampInSec,
-				order.params.salt,
-			]);
-			fillUpTo.v.push(order.params.v);
-			fillUpTo.r.push(order.params.r);
-			fillUpTo.s.push(order.params.s);
-		});
-		return fillUpTo;
-	},
-	createBatchCancel(orders: Order[], cancelTakerTokenAmounts: BigNumber[] = []) {
-		const batchCancel: BatchCancelOrders = {
-			orderAddresses: [],
-			orderValues: [],
-			cancelTakerTokenAmounts,
-		};
-		orders.forEach(order => {
-			batchCancel.orderAddresses.push([
-				order.params.maker,
-				order.params.taker,
-				order.params.makerToken,
-				order.params.takerToken,
-				order.params.feeRecipient,
-			]);
-			batchCancel.orderValues.push([
-				order.params.makerTokenAmount,
-				order.params.takerTokenAmount,
-				order.params.makerFee,
-				order.params.takerFee,
-				order.params.expirationTimestampInSec,
-				order.params.salt,
-			]);
-			if (cancelTakerTokenAmounts.length < orders.length) {
-				batchCancel.cancelTakerTokenAmounts.push(order.params.takerTokenAmount);
-			}
-		});
-		return batchCancel;
-	},
+    createBatchFill(
+        orders: Order[],
+        shouldThrowOnInsufficientBalanceOrAllowance: boolean,
+        fillTakerTokenAmounts: BigNumber[] = [],
+    ) {
+        const batchFill: BatchFillOrders = {
+            orderAddresses: [],
+            orderValues: [],
+            fillTakerTokenAmounts,
+            shouldThrowOnInsufficientBalanceOrAllowance,
+            v: [],
+            r: [],
+            s: [],
+        };
+        _.forEach(orders, order => {
+            batchFill.orderAddresses.push([
+                order.params.maker,
+                order.params.taker,
+                order.params.makerToken,
+                order.params.takerToken,
+                order.params.feeRecipient,
+            ]);
+            batchFill.orderValues.push([
+                order.params.makerTokenAmount,
+                order.params.takerTokenAmount,
+                order.params.makerFee,
+                order.params.takerFee,
+                order.params.expirationTimestampInSec,
+                order.params.salt,
+            ]);
+            batchFill.v.push(order.params.v);
+            batchFill.r.push(order.params.r);
+            batchFill.s.push(order.params.s);
+            if (fillTakerTokenAmounts.length < orders.length) {
+                batchFill.fillTakerTokenAmounts.push(order.params.takerTokenAmount);
+            }
+        });
+        return batchFill;
+    },
+    createFillUpTo(
+        orders: Order[],
+        shouldThrowOnInsufficientBalanceOrAllowance: boolean,
+        fillTakerTokenAmount: BigNumber,
+    ) {
+        const fillUpTo: FillOrdersUpTo = {
+            orderAddresses: [],
+            orderValues: [],
+            fillTakerTokenAmount,
+            shouldThrowOnInsufficientBalanceOrAllowance,
+            v: [],
+            r: [],
+            s: [],
+        };
+        orders.forEach(order => {
+            fillUpTo.orderAddresses.push([
+                order.params.maker,
+                order.params.taker,
+                order.params.makerToken,
+                order.params.takerToken,
+                order.params.feeRecipient,
+            ]);
+            fillUpTo.orderValues.push([
+                order.params.makerTokenAmount,
+                order.params.takerTokenAmount,
+                order.params.makerFee,
+                order.params.takerFee,
+                order.params.expirationTimestampInSec,
+                order.params.salt,
+            ]);
+            fillUpTo.v.push(order.params.v);
+            fillUpTo.r.push(order.params.r);
+            fillUpTo.s.push(order.params.s);
+        });
+        return fillUpTo;
+    },
+    createBatchCancel(orders: Order[], cancelTakerTokenAmounts: BigNumber[] = []) {
+        const batchCancel: BatchCancelOrders = {
+            orderAddresses: [],
+            orderValues: [],
+            cancelTakerTokenAmounts,
+        };
+        orders.forEach(order => {
+            batchCancel.orderAddresses.push([
+                order.params.maker,
+                order.params.taker,
+                order.params.makerToken,
+                order.params.takerToken,
+                order.params.feeRecipient,
+            ]);
+            batchCancel.orderValues.push([
+                order.params.makerTokenAmount,
+                order.params.takerTokenAmount,
+                order.params.makerFee,
+                order.params.takerFee,
+                order.params.expirationTimestampInSec,
+                order.params.salt,
+            ]);
+            if (cancelTakerTokenAmounts.length < orders.length) {
+                batchCancel.cancelTakerTokenAmounts.push(order.params.takerTokenAmount);
+            }
+        });
+        return batchCancel;
+    },
 };
diff --git a/packages/contracts/util/multi_sig_wrapper.ts b/packages/contracts/util/multi_sig_wrapper.ts
index ca9f07ce5..0e2e671ec 100644
--- a/packages/contracts/util/multi_sig_wrapper.ts
+++ b/packages/contracts/util/multi_sig_wrapper.ts
@@ -6,34 +6,34 @@ import * as Web3 from 'web3';
 import { ContractInstance, TransactionDataParams } from './types';
 
 export class MultiSigWrapper {
-	private _multiSig: ContractInstance;
-	public static encodeFnArgs(name: string, abi: Web3.AbiDefinition[], args: any[]) {
-		const abiEntity = _.find(abi, { name }) as Web3.MethodAbi;
-		if (_.isUndefined(abiEntity)) {
-			throw new Error(`Did not find abi entry for name: ${name}`);
-		}
-		const types = _.map(abiEntity.inputs, input => input.type);
-		const funcSig = ethUtil.bufferToHex(ABI.methodID(name, types));
-		const argsData = _.map(args, arg => {
-			const target = _.isBoolean(arg) ? +arg : arg;
-			const targetBuff = ethUtil.toBuffer(target);
-			return ethUtil.setLengthLeft(targetBuff, 32).toString('hex');
-		});
-		return funcSig + argsData.join('');
-	}
-	constructor(multiSigContractInstance: ContractInstance) {
-		this._multiSig = multiSigContractInstance;
-	}
-	public async submitTransactionAsync(
-		destination: string,
-		from: string,
-		dataParams: TransactionDataParams,
-		value: number = 0,
-	) {
-		const { name, abi, args = [] } = dataParams;
-		const encoded = MultiSigWrapper.encodeFnArgs(name, abi, args);
-		return this._multiSig.submitTransaction(destination, value, encoded, {
-			from,
-		});
-	}
+    private _multiSig: ContractInstance;
+    public static encodeFnArgs(name: string, abi: Web3.AbiDefinition[], args: any[]) {
+        const abiEntity = _.find(abi, { name }) as Web3.MethodAbi;
+        if (_.isUndefined(abiEntity)) {
+            throw new Error(`Did not find abi entry for name: ${name}`);
+        }
+        const types = _.map(abiEntity.inputs, input => input.type);
+        const funcSig = ethUtil.bufferToHex(ABI.methodID(name, types));
+        const argsData = _.map(args, arg => {
+            const target = _.isBoolean(arg) ? +arg : arg;
+            const targetBuff = ethUtil.toBuffer(target);
+            return ethUtil.setLengthLeft(targetBuff, 32).toString('hex');
+        });
+        return funcSig + argsData.join('');
+    }
+    constructor(multiSigContractInstance: ContractInstance) {
+        this._multiSig = multiSigContractInstance;
+    }
+    public async submitTransactionAsync(
+        destination: string,
+        from: string,
+        dataParams: TransactionDataParams,
+        value: number = 0,
+    ) {
+        const { name, abi, args = [] } = dataParams;
+        const encoded = MultiSigWrapper.encodeFnArgs(name, abi, args);
+        return this._multiSig.submitTransaction(destination, value, encoded, {
+            from,
+        });
+    }
 }
diff --git a/packages/contracts/util/order.ts b/packages/contracts/util/order.ts
index 31194c03e..e202d485b 100644
--- a/packages/contracts/util/order.ts
+++ b/packages/contracts/util/order.ts
@@ -11,98 +11,98 @@ import { OrderParams } from './types';
 const web3: Web3 = (global as any).web3;
 
 export class Order {
-	public params: OrderParams;
-	constructor(params: OrderParams) {
-		this.params = params;
-	}
-	public isValidSignature() {
-		const { v, r, s } = this.params;
-		if (_.isUndefined(v) || _.isUndefined(r) || _.isUndefined(s)) {
-			throw new Error('Cannot call isValidSignature on unsigned order');
-		}
-		const orderHash = this._getOrderHash();
-		const msgHash = ethUtil.hashPersonalMessage(ethUtil.toBuffer(orderHash));
-		try {
-			const pubKey = ethUtil.ecrecover(msgHash, v, ethUtil.toBuffer(r), ethUtil.toBuffer(s));
-			const recoveredAddress = ethUtil.bufferToHex(ethUtil.pubToAddress(pubKey));
-			return recoveredAddress === this.params.maker;
-		} catch (err) {
-			return false;
-		}
-	}
-	public async signAsync() {
-		const orderHash = this._getOrderHash();
-		const signature = await promisify<string>(web3.eth.sign)(this.params.maker, orderHash);
-		const { v, r, s } = ethUtil.fromRpcSig(signature);
-		this.params = _.assign(this.params, {
-			orderHashHex: orderHash,
-			v,
-			r: ethUtil.bufferToHex(r),
-			s: ethUtil.bufferToHex(s),
-		});
-	}
-	public createFill(shouldThrowOnInsufficientBalanceOrAllowance?: boolean, fillTakerTokenAmount?: BigNumber) {
-		const fill = {
-			orderAddresses: [
-				this.params.maker,
-				this.params.taker,
-				this.params.makerToken,
-				this.params.takerToken,
-				this.params.feeRecipient,
-			],
-			orderValues: [
-				this.params.makerTokenAmount,
-				this.params.takerTokenAmount,
-				this.params.makerFee,
-				this.params.takerFee,
-				this.params.expirationTimestampInSec,
-				this.params.salt,
-			],
-			fillTakerTokenAmount: fillTakerTokenAmount || this.params.takerTokenAmount,
-			shouldThrowOnInsufficientBalanceOrAllowance: !!shouldThrowOnInsufficientBalanceOrAllowance,
-			v: this.params.v,
-			r: this.params.r,
-			s: this.params.s,
-		};
-		return fill;
-	}
-	public createCancel(cancelTakerTokenAmount?: BigNumber) {
-		const cancel = {
-			orderAddresses: [
-				this.params.maker,
-				this.params.taker,
-				this.params.makerToken,
-				this.params.takerToken,
-				this.params.feeRecipient,
-			],
-			orderValues: [
-				this.params.makerTokenAmount,
-				this.params.takerTokenAmount,
-				this.params.makerFee,
-				this.params.takerFee,
-				this.params.expirationTimestampInSec,
-				this.params.salt,
-			],
-			cancelTakerTokenAmount: cancelTakerTokenAmount || this.params.takerTokenAmount,
-		};
-		return cancel;
-	}
-	private _getOrderHash(): string {
-		const orderHash = crypto.solSHA3([
-			this.params.exchangeContractAddress,
-			this.params.maker,
-			this.params.taker,
-			this.params.makerToken,
-			this.params.takerToken,
-			this.params.feeRecipient,
-			this.params.makerTokenAmount,
-			this.params.takerTokenAmount,
-			this.params.makerFee,
-			this.params.takerFee,
-			this.params.expirationTimestampInSec,
-			this.params.salt,
-		]);
-		const orderHashHex = ethUtil.bufferToHex(orderHash);
-		return orderHashHex;
-	}
+    public params: OrderParams;
+    constructor(params: OrderParams) {
+        this.params = params;
+    }
+    public isValidSignature() {
+        const { v, r, s } = this.params;
+        if (_.isUndefined(v) || _.isUndefined(r) || _.isUndefined(s)) {
+            throw new Error('Cannot call isValidSignature on unsigned order');
+        }
+        const orderHash = this._getOrderHash();
+        const msgHash = ethUtil.hashPersonalMessage(ethUtil.toBuffer(orderHash));
+        try {
+            const pubKey = ethUtil.ecrecover(msgHash, v, ethUtil.toBuffer(r), ethUtil.toBuffer(s));
+            const recoveredAddress = ethUtil.bufferToHex(ethUtil.pubToAddress(pubKey));
+            return recoveredAddress === this.params.maker;
+        } catch (err) {
+            return false;
+        }
+    }
+    public async signAsync() {
+        const orderHash = this._getOrderHash();
+        const signature = await promisify<string>(web3.eth.sign)(this.params.maker, orderHash);
+        const { v, r, s } = ethUtil.fromRpcSig(signature);
+        this.params = _.assign(this.params, {
+            orderHashHex: orderHash,
+            v,
+            r: ethUtil.bufferToHex(r),
+            s: ethUtil.bufferToHex(s),
+        });
+    }
+    public createFill(shouldThrowOnInsufficientBalanceOrAllowance?: boolean, fillTakerTokenAmount?: BigNumber) {
+        const fill = {
+            orderAddresses: [
+                this.params.maker,
+                this.params.taker,
+                this.params.makerToken,
+                this.params.takerToken,
+                this.params.feeRecipient,
+            ],
+            orderValues: [
+                this.params.makerTokenAmount,
+                this.params.takerTokenAmount,
+                this.params.makerFee,
+                this.params.takerFee,
+                this.params.expirationTimestampInSec,
+                this.params.salt,
+            ],
+            fillTakerTokenAmount: fillTakerTokenAmount || this.params.takerTokenAmount,
+            shouldThrowOnInsufficientBalanceOrAllowance: !!shouldThrowOnInsufficientBalanceOrAllowance,
+            v: this.params.v,
+            r: this.params.r,
+            s: this.params.s,
+        };
+        return fill;
+    }
+    public createCancel(cancelTakerTokenAmount?: BigNumber) {
+        const cancel = {
+            orderAddresses: [
+                this.params.maker,
+                this.params.taker,
+                this.params.makerToken,
+                this.params.takerToken,
+                this.params.feeRecipient,
+            ],
+            orderValues: [
+                this.params.makerTokenAmount,
+                this.params.takerTokenAmount,
+                this.params.makerFee,
+                this.params.takerFee,
+                this.params.expirationTimestampInSec,
+                this.params.salt,
+            ],
+            cancelTakerTokenAmount: cancelTakerTokenAmount || this.params.takerTokenAmount,
+        };
+        return cancel;
+    }
+    private _getOrderHash(): string {
+        const orderHash = crypto.solSHA3([
+            this.params.exchangeContractAddress,
+            this.params.maker,
+            this.params.taker,
+            this.params.makerToken,
+            this.params.takerToken,
+            this.params.feeRecipient,
+            this.params.makerTokenAmount,
+            this.params.takerTokenAmount,
+            this.params.makerFee,
+            this.params.takerFee,
+            this.params.expirationTimestampInSec,
+            this.params.salt,
+        ]);
+        const orderHashHex = ethUtil.bufferToHex(orderHash);
+        return orderHashHex;
+    }
 }
diff --git a/packages/contracts/util/order_factory.ts b/packages/contracts/util/order_factory.ts
index 55034655b..a45877de0 100644
--- a/packages/contracts/util/order_factory.ts
+++ b/packages/contracts/util/order_factory.ts
@@ -6,24 +6,24 @@ import { Order } from './order';
 import { DefaultOrderParams, OptionalOrderParams, OrderParams } from './types';
 
 export class OrderFactory {
-	private _defaultOrderParams: DefaultOrderParams;
-	constructor(defaultOrderParams: DefaultOrderParams) {
-		this._defaultOrderParams = defaultOrderParams;
-	}
-	public async newSignedOrderAsync(customOrderParams: OptionalOrderParams = {}) {
-		const randomExpiration = new BigNumber(Math.floor((Date.now() + Math.random() * 100000000000) / 1000));
-		const orderParams: OrderParams = _.assign(
-			{},
-			{
-				expirationTimestampInSec: randomExpiration,
-				salt: ZeroEx.generatePseudoRandomSalt(),
-				taker: ZeroEx.NULL_ADDRESS,
-			},
-			this._defaultOrderParams,
-			customOrderParams,
-		);
-		const order = new Order(orderParams);
-		await order.signAsync();
-		return order;
-	}
+    private _defaultOrderParams: DefaultOrderParams;
+    constructor(defaultOrderParams: DefaultOrderParams) {
+        this._defaultOrderParams = defaultOrderParams;
+    }
+    public async newSignedOrderAsync(customOrderParams: OptionalOrderParams = {}) {
+        const randomExpiration = new BigNumber(Math.floor((Date.now() + Math.random() * 100000000000) / 1000));
+        const orderParams: OrderParams = _.assign(
+            {},
+            {
+                expirationTimestampInSec: randomExpiration,
+                salt: ZeroEx.generatePseudoRandomSalt(),
+                taker: ZeroEx.NULL_ADDRESS,
+            },
+            this._defaultOrderParams,
+            customOrderParams,
+        );
+        const order = new Order(orderParams);
+        await order.signAsync();
+        return order;
+    }
 }
diff --git a/packages/contracts/util/token_registry_wrapper.ts b/packages/contracts/util/token_registry_wrapper.ts
index d1983db7c..07a577dea 100644
--- a/packages/contracts/util/token_registry_wrapper.ts
+++ b/packages/contracts/util/token_registry_wrapper.ts
@@ -1,56 +1,56 @@
 import { ContractInstance, Token } from './types';
 
 export class TokenRegWrapper {
-	private _tokenReg: ContractInstance;
-	constructor(tokenRegContractInstance: ContractInstance) {
-		this._tokenReg = tokenRegContractInstance;
-	}
-	public addTokenAsync(token: Token, from: string) {
-		const tx = this._tokenReg.addToken(
-			token.address,
-			token.name,
-			token.symbol,
-			token.decimals,
-			token.ipfsHash,
-			token.swarmHash,
-			{ from },
-		);
-		return tx;
-	}
-	public async getTokenMetaDataAsync(tokenAddress: string) {
-		const data = await this._tokenReg.getTokenMetaData(tokenAddress);
-		const token: Token = {
-			address: data[0],
-			name: data[1],
-			symbol: data[2],
-			decimals: data[3].toNumber(),
-			ipfsHash: data[4],
-			swarmHash: data[5],
-		};
-		return token;
-	}
-	public async getTokenByNameAsync(tokenName: string) {
-		const data = await this._tokenReg.getTokenByName(tokenName);
-		const token: Token = {
-			address: data[0],
-			name: data[1],
-			symbol: data[2],
-			decimals: data[3].toNumber(),
-			ipfsHash: data[4],
-			swarmHash: data[5],
-		};
-		return token;
-	}
-	public async getTokenBySymbolAsync(tokenSymbol: string) {
-		const data = await this._tokenReg.getTokenBySymbol(tokenSymbol);
-		const token: Token = {
-			address: data[0],
-			name: data[1],
-			symbol: data[2],
-			decimals: data[3].toNumber(),
-			ipfsHash: data[4],
-			swarmHash: data[5],
-		};
-		return token;
-	}
+    private _tokenReg: ContractInstance;
+    constructor(tokenRegContractInstance: ContractInstance) {
+        this._tokenReg = tokenRegContractInstance;
+    }
+    public addTokenAsync(token: Token, from: string) {
+        const tx = this._tokenReg.addToken(
+            token.address,
+            token.name,
+            token.symbol,
+            token.decimals,
+            token.ipfsHash,
+            token.swarmHash,
+            { from },
+        );
+        return tx;
+    }
+    public async getTokenMetaDataAsync(tokenAddress: string) {
+        const data = await this._tokenReg.getTokenMetaData(tokenAddress);
+        const token: Token = {
+            address: data[0],
+            name: data[1],
+            symbol: data[2],
+            decimals: data[3].toNumber(),
+            ipfsHash: data[4],
+            swarmHash: data[5],
+        };
+        return token;
+    }
+    public async getTokenByNameAsync(tokenName: string) {
+        const data = await this._tokenReg.getTokenByName(tokenName);
+        const token: Token = {
+            address: data[0],
+            name: data[1],
+            symbol: data[2],
+            decimals: data[3].toNumber(),
+            ipfsHash: data[4],
+            swarmHash: data[5],
+        };
+        return token;
+    }
+    public async getTokenBySymbolAsync(tokenSymbol: string) {
+        const data = await this._tokenReg.getTokenBySymbol(tokenSymbol);
+        const token: Token = {
+            address: data[0],
+            name: data[1],
+            symbol: data[2],
+            decimals: data[3].toNumber(),
+            ipfsHash: data[4],
+            swarmHash: data[5],
+        };
+        return token;
+    }
 }
diff --git a/packages/contracts/util/types.ts b/packages/contracts/util/types.ts
index 675f3f17d..e511ca9f4 100644
--- a/packages/contracts/util/types.ts
+++ b/packages/contracts/util/types.ts
@@ -2,118 +2,118 @@ import { BigNumber } from '@0xproject/utils';
 import * as Web3 from 'web3';
 
 export interface BalancesByOwner {
-	[ownerAddress: string]: {
-		[tokenAddress: string]: BigNumber;
-	};
+    [ownerAddress: string]: {
+        [tokenAddress: string]: BigNumber;
+    };
 }
 
 export interface BatchFillOrders {
-	orderAddresses: string[][];
-	orderValues: BigNumber[][];
-	fillTakerTokenAmounts: BigNumber[];
-	shouldThrowOnInsufficientBalanceOrAllowance: boolean;
-	v: number[];
-	r: string[];
-	s: string[];
+    orderAddresses: string[][];
+    orderValues: BigNumber[][];
+    fillTakerTokenAmounts: BigNumber[];
+    shouldThrowOnInsufficientBalanceOrAllowance: boolean;
+    v: number[];
+    r: string[];
+    s: string[];
 }
 
 export interface FillOrdersUpTo {
-	orderAddresses: string[][];
-	orderValues: BigNumber[][];
-	fillTakerTokenAmount: BigNumber;
-	shouldThrowOnInsufficientBalanceOrAllowance: boolean;
-	v: number[];
-	r: string[];
-	s: string[];
+    orderAddresses: string[][];
+    orderValues: BigNumber[][];
+    fillTakerTokenAmount: BigNumber;
+    shouldThrowOnInsufficientBalanceOrAllowance: boolean;
+    v: number[];
+    r: string[];
+    s: string[];
 }
 
 export interface BatchCancelOrders {
-	orderAddresses: string[][];
-	orderValues: BigNumber[][];
-	cancelTakerTokenAmounts: BigNumber[];
+    orderAddresses: string[][];
+    orderValues: BigNumber[][];
+    cancelTakerTokenAmounts: BigNumber[];
 }
 
 export interface DefaultOrderParams {
-	exchangeContractAddress: string;
-	maker: string;
-	feeRecipient: string;
-	makerToken: string;
-	takerToken: string;
-	makerTokenAmount: BigNumber;
-	takerTokenAmount: BigNumber;
-	makerFee: BigNumber;
-	takerFee: BigNumber;
+    exchangeContractAddress: string;
+    maker: string;
+    feeRecipient: string;
+    makerToken: string;
+    takerToken: string;
+    makerTokenAmount: BigNumber;
+    takerTokenAmount: BigNumber;
+    makerFee: BigNumber;
+    takerFee: BigNumber;
 }
 
 export interface OptionalOrderParams {
-	exchangeContractAddress?: string;
-	maker?: string;
-	taker?: string;
-	feeRecipient?: string;
-	makerToken?: string;
-	takerToken?: string;
-	makerTokenAmount?: BigNumber;
-	takerTokenAmount?: BigNumber;
-	makerFee?: BigNumber;
-	takerFee?: BigNumber;
-	expirationTimestampInSec?: BigNumber;
+    exchangeContractAddress?: string;
+    maker?: string;
+    taker?: string;
+    feeRecipient?: string;
+    makerToken?: string;
+    takerToken?: string;
+    makerTokenAmount?: BigNumber;
+    takerTokenAmount?: BigNumber;
+    makerFee?: BigNumber;
+    takerFee?: BigNumber;
+    expirationTimestampInSec?: BigNumber;
 }
 
 export interface OrderParams {
-	exchangeContractAddress: string;
-	maker: string;
-	taker: string;
-	feeRecipient: string;
-	makerToken: string;
-	takerToken: string;
-	makerTokenAmount: BigNumber;
-	takerTokenAmount: BigNumber;
-	makerFee: BigNumber;
-	takerFee: BigNumber;
-	expirationTimestampInSec: BigNumber;
-	salt: BigNumber;
-	orderHashHex?: string;
-	v?: number;
-	r?: string;
-	s?: string;
+    exchangeContractAddress: string;
+    maker: string;
+    taker: string;
+    feeRecipient: string;
+    makerToken: string;
+    takerToken: string;
+    makerTokenAmount: BigNumber;
+    takerTokenAmount: BigNumber;
+    makerFee: BigNumber;
+    takerFee: BigNumber;
+    expirationTimestampInSec: BigNumber;
+    salt: BigNumber;
+    orderHashHex?: string;
+    v?: number;
+    r?: string;
+    s?: string;
 }
 
 export interface TransactionDataParams {
-	name: string;
-	abi: Web3.AbiDefinition[];
-	args: any[];
+    name: string;
+    abi: Web3.AbiDefinition[];
+    args: any[];
 }
 
 export interface MultiSigConfig {
-	owners: string[];
-	confirmationsRequired: number;
-	secondsRequired: number;
+    owners: string[];
+    confirmationsRequired: number;
+    secondsRequired: number;
 }
 
 export interface MultiSigConfigByNetwork {
-	[networkName: string]: MultiSigConfig;
+    [networkName: string]: MultiSigConfig;
 }
 
 export interface Token {
-	address?: string;
-	name: string;
-	symbol: string;
-	decimals: number;
-	ipfsHash: string;
-	swarmHash: string;
+    address?: string;
+    name: string;
+    symbol: string;
+    decimals: number;
+    ipfsHash: string;
+    swarmHash: string;
 }
 
 export interface TokenInfoByNetwork {
-	development: Token[];
-	live: Token[];
+    development: Token[];
+    live: Token[];
 }
 
 // Named type aliases to improve readability
 export type ContractInstance = any;
 
 export enum ExchangeContractErrs {
-	ERROR_ORDER_EXPIRED,
-	ERROR_ORDER_FULLY_FILLED_OR_CANCELLED,
-	ERROR_ROUNDING_ERROR_TOO_LARGE,
-	ERROR_INSUFFICIENT_BALANCE_OR_ALLOWANCE,
+    ERROR_ORDER_EXPIRED,
+    ERROR_ORDER_FULLY_FILLED_OR_CANCELLED,
+    ERROR_ROUNDING_ERROR_TOO_LARGE,
+    ERROR_INSUFFICIENT_BALANCE_OR_ALLOWANCE,
 }
diff --git a/packages/deployer/package.json b/packages/deployer/package.json
index f78f49497..423d3bad8 100644
--- a/packages/deployer/package.json
+++ b/packages/deployer/package.json
@@ -1,43 +1,43 @@
 {
-	"name": "@0xproject/deployer",
-	"version": "0.0.3",
-	"description": "Smart contract deployer of 0x protocol",
-	"main": "lib/src/cli.js",
-	"scripts": {
-		"build": "yarn clean && copyfiles 'test/fixtures/contracts/**/*' src/solc/solc_bin/* ./lib && tsc",
-		"test": "npm run build; mocha lib/test/*_test.js",
-		"compile": "npm run build; node lib/src/cli.js compile",
-		"clean": "rm -rf ./lib",
-		"migrate": "npm run build; node lib/src/cli.js migrate",
-		"lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'",
-		"test:circleci": "yarn test"
-	},
-	"bin": {
-		"0x-deployer": "lib/src/cli.js"
-	},
-	"repository": {
-		"type": "git",
-		"url": "https://github.com/0xProject/0x.js.git"
-	},
-	"author": "Amir Bandeali",
-	"license": "Apache-2.0",
-	"bugs": {
-		"url": "https://github.com/0xProject/0x.js/issues"
-	},
-	"homepage": "https://github.com/0xProject/0x.js/packages/deployer/README.md",
-	"devDependencies": {
-		"copyfiles": "^1.2.0",
-		"types-bn": "^0.0.1",
-		"typescript": "~2.6.1",
-		"web3-typescript-typings": "^0.9.6"
-	},
-	"dependencies": {
-		"@0xproject/utils": "^0.1.3",
-		"@0xproject/web3-wrapper": "^0.1.7",
-		"lodash": "^4.17.4",
-		"solc": "^0.4.18",
-		"web3": "^0.20.0",
-		"web3-eth-abi": "^1.0.0-beta.24",
-		"yargs": "^10.0.3"
-	}
+    "name": "@0xproject/deployer",
+    "version": "0.0.3",
+    "description": "Smart contract deployer of 0x protocol",
+    "main": "lib/src/cli.js",
+    "scripts": {
+        "build": "yarn clean && copyfiles 'test/fixtures/contracts/**/*' src/solc/solc_bin/* ./lib && tsc",
+        "test": "npm run build; mocha lib/test/*_test.js",
+        "compile": "npm run build; node lib/src/cli.js compile",
+        "clean": "rm -rf ./lib",
+        "migrate": "npm run build; node lib/src/cli.js migrate",
+        "lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'",
+        "test:circleci": "yarn test"
+    },
+    "bin": {
+        "0x-deployer": "lib/src/cli.js"
+    },
+    "repository": {
+        "type": "git",
+        "url": "https://github.com/0xProject/0x.js.git"
+    },
+    "author": "Amir Bandeali",
+    "license": "Apache-2.0",
+    "bugs": {
+        "url": "https://github.com/0xProject/0x.js/issues"
+    },
+    "homepage": "https://github.com/0xProject/0x.js/packages/deployer/README.md",
+    "devDependencies": {
+        "copyfiles": "^1.2.0",
+        "types-bn": "^0.0.1",
+        "typescript": "~2.6.1",
+        "web3-typescript-typings": "^0.9.6"
+    },
+    "dependencies": {
+        "@0xproject/utils": "^0.1.3",
+        "@0xproject/web3-wrapper": "^0.1.7",
+        "lodash": "^4.17.4",
+        "solc": "^0.4.18",
+        "web3": "^0.20.0",
+        "web3-eth-abi": "^1.0.0-beta.24",
+        "yargs": "^10.0.3"
+    }
 }
diff --git a/packages/deployer/src/cli.ts b/packages/deployer/src/cli.ts
index f4241b1cc..decb37fdc 100644
--- a/packages/deployer/src/cli.ts
+++ b/packages/deployer/src/cli.ts
@@ -20,13 +20,13 @@ const DEFAULT_GAS_PRICE = (10 ** 9 * 2).toString();
  * @param argv Instance of process.argv provided by yargs.
  */
 async function onCompileCommand(argv: CliOptions): Promise<void> {
-	const opts: CompilerOptions = {
-		contractsDir: argv.contractsDir,
-		networkId: argv.networkId,
-		optimizerEnabled: argv.shouldOptimize ? 1 : 0,
-		artifactsDir: argv.artifactsDir,
-	};
-	await commands.compileAsync(opts);
+    const opts: CompilerOptions = {
+        contractsDir: argv.contractsDir,
+        networkId: argv.networkId,
+        optimizerEnabled: argv.shouldOptimize ? 1 : 0,
+        artifactsDir: argv.artifactsDir,
+    };
+    await commands.compileAsync(opts);
 }
 /**
  * Compiles all contracts and runs migration script with options passed in through CLI.
@@ -34,123 +34,123 @@ async function onCompileCommand(argv: CliOptions): Promise<void> {
  * @param argv Instance of process.argv provided by yargs.
  */
 async function onMigrateCommand(argv: CliOptions): Promise<void> {
-	const url = `http://localhost:${argv.jsonrpcPort}`;
-	const web3Provider = new Web3.providers.HttpProvider(url);
-	const web3Wrapper = new Web3Wrapper(web3Provider);
-	const networkId = await web3Wrapper.getNetworkIdAsync();
-	const compilerOpts: CompilerOptions = {
-		contractsDir: argv.contractsDir,
-		networkId,
-		optimizerEnabled: argv.shouldOptimize ? 1 : 0,
-		artifactsDir: argv.artifactsDir,
-	};
-	await commands.compileAsync(compilerOpts);
+    const url = `http://localhost:${argv.jsonrpcPort}`;
+    const web3Provider = new Web3.providers.HttpProvider(url);
+    const web3Wrapper = new Web3Wrapper(web3Provider);
+    const networkId = await web3Wrapper.getNetworkIdAsync();
+    const compilerOpts: CompilerOptions = {
+        contractsDir: argv.contractsDir,
+        networkId,
+        optimizerEnabled: argv.shouldOptimize ? 1 : 0,
+        artifactsDir: argv.artifactsDir,
+    };
+    await commands.compileAsync(compilerOpts);
 
-	const defaults = {
-		gasPrice: new BigNumber(argv.gasPrice),
-		from: argv.account,
-	};
-	const deployerOpts = {
-		artifactsDir: argv.artifactsDir,
-		jsonrpcPort: argv.jsonrpcPort,
-		networkId,
-		defaults,
-	};
-	await commands.migrateAsync(deployerOpts);
+    const defaults = {
+        gasPrice: new BigNumber(argv.gasPrice),
+        from: argv.account,
+    };
+    const deployerOpts = {
+        artifactsDir: argv.artifactsDir,
+        jsonrpcPort: argv.jsonrpcPort,
+        networkId,
+        defaults,
+    };
+    await commands.migrateAsync(deployerOpts);
 }
 /**
  * Deploys a single contract with provided name and args.
  * @param argv Instance of process.argv provided by yargs.
  */
 async function onDeployCommand(argv: CliOptions): Promise<void> {
-	const url = `http://localhost:${argv.jsonrpcPort}`;
-	const web3Provider = new Web3.providers.HttpProvider(url);
-	const web3Wrapper = new Web3Wrapper(web3Provider);
-	const networkId = await web3Wrapper.getNetworkIdAsync();
-	const compilerOpts: CompilerOptions = {
-		contractsDir: argv.contractsDir,
-		networkId,
-		optimizerEnabled: argv.shouldOptimize ? 1 : 0,
-		artifactsDir: argv.artifactsDir,
-	};
-	await commands.compileAsync(compilerOpts);
+    const url = `http://localhost:${argv.jsonrpcPort}`;
+    const web3Provider = new Web3.providers.HttpProvider(url);
+    const web3Wrapper = new Web3Wrapper(web3Provider);
+    const networkId = await web3Wrapper.getNetworkIdAsync();
+    const compilerOpts: CompilerOptions = {
+        contractsDir: argv.contractsDir,
+        networkId,
+        optimizerEnabled: argv.shouldOptimize ? 1 : 0,
+        artifactsDir: argv.artifactsDir,
+    };
+    await commands.compileAsync(compilerOpts);
 
-	const defaults = {
-		gasPrice: new BigNumber(argv.gasPrice),
-		from: argv.account,
-	};
-	const deployerOpts: DeployerOptions = {
-		artifactsDir: argv.artifactsDir,
-		jsonrpcPort: argv.jsonrpcPort,
-		networkId,
-		defaults,
-	};
-	const deployerArgsString = argv.args;
-	const deployerArgs = deployerArgsString.split(',');
-	await commands.deployAsync(argv.contract, deployerArgs, deployerOpts);
+    const defaults = {
+        gasPrice: new BigNumber(argv.gasPrice),
+        from: argv.account,
+    };
+    const deployerOpts: DeployerOptions = {
+        artifactsDir: argv.artifactsDir,
+        jsonrpcPort: argv.jsonrpcPort,
+        networkId,
+        defaults,
+    };
+    const deployerArgsString = argv.args;
+    const deployerArgs = deployerArgsString.split(',');
+    await commands.deployAsync(argv.contract, deployerArgs, deployerOpts);
 }
 /**
  * Provides extra required options for deploy command.
  * @param yargsInstance yargs instance provided in builder function callback.
  */
 function deployCommandBuilder(yargsInstance: any) {
-	return yargsInstance
-		.option('contract', {
-			type: 'string',
-			description: 'name of contract to deploy, exluding .sol extension',
-		})
-		.option('args', {
-			type: 'string',
-			description: 'comma separated list of constructor args to deploy contract with',
-		})
-		.demandOption(['contract', 'args'])
-		.help().argv;
+    return yargsInstance
+        .option('contract', {
+            type: 'string',
+            description: 'name of contract to deploy, exluding .sol extension',
+        })
+        .option('args', {
+            type: 'string',
+            description: 'comma separated list of constructor args to deploy contract with',
+        })
+        .demandOption(['contract', 'args'])
+        .help().argv;
 }
 
 (() => {
-	const identityCommandBuilder = _.identity;
-	return yargs
-		.option('contracts-dir', {
-			type: 'string',
-			default: DEFAULT_CONTRACTS_DIR,
-			description: 'path of contracts directory to compile',
-		})
-		.option('network-id', {
-			type: 'number',
-			default: DEFAULT_NETWORK_ID,
-			description: 'mainnet=1, kovan=42, testrpc=50',
-		})
-		.option('should-optimize', {
-			type: 'boolean',
-			default: DEFAULT_OPTIMIZER_ENABLED,
-			description: 'enable optimizer',
-		})
-		.option('artifacts-dir', {
-			type: 'string',
-			default: DEFAULT_ARTIFACTS_DIR,
-			description: 'path to write contracts artifacts to',
-		})
-		.option('jsonrpc-port', {
-			type: 'number',
-			default: DEFAULT_JSONRPC_PORT,
-			description: 'port connected to JSON RPC',
-		})
-		.option('gas-price', {
-			type: 'string',
-			default: DEFAULT_GAS_PRICE,
-			description: 'gasPrice to be used for transactions',
-		})
-		.option('account', {
-			type: 'string',
-			description: 'account to use for deploying contracts',
-		})
-		.command('compile', 'compile contracts', identityCommandBuilder, onCompileCommand)
-		.command(
-			'migrate',
-			'compile and deploy contracts using migration scripts',
-			identityCommandBuilder,
-			onMigrateCommand,
-		)
-		.command('deploy', 'deploy a single contract with provided arguments', deployCommandBuilder, onDeployCommand)
-		.help().argv;
+    const identityCommandBuilder = _.identity;
+    return yargs
+        .option('contracts-dir', {
+            type: 'string',
+            default: DEFAULT_CONTRACTS_DIR,
+            description: 'path of contracts directory to compile',
+        })
+        .option('network-id', {
+            type: 'number',
+            default: DEFAULT_NETWORK_ID,
+            description: 'mainnet=1, kovan=42, testrpc=50',
+        })
+        .option('should-optimize', {
+            type: 'boolean',
+            default: DEFAULT_OPTIMIZER_ENABLED,
+            description: 'enable optimizer',
+        })
+        .option('artifacts-dir', {
+            type: 'string',
+            default: DEFAULT_ARTIFACTS_DIR,
+            description: 'path to write contracts artifacts to',
+        })
+        .option('jsonrpc-port', {
+            type: 'number',
+            default: DEFAULT_JSONRPC_PORT,
+            description: 'port connected to JSON RPC',
+        })
+        .option('gas-price', {
+            type: 'string',
+            default: DEFAULT_GAS_PRICE,
+            description: 'gasPrice to be used for transactions',
+        })
+        .option('account', {
+            type: 'string',
+            description: 'account to use for deploying contracts',
+        })
+        .command('compile', 'compile contracts', identityCommandBuilder, onCompileCommand)
+        .command(
+            'migrate',
+            'compile and deploy contracts using migration scripts',
+            identityCommandBuilder,
+            onMigrateCommand,
+        )
+        .command('deploy', 'deploy a single contract with provided arguments', deployCommandBuilder, onDeployCommand)
+        .help().argv;
 })();
diff --git a/packages/deployer/src/commands.ts b/packages/deployer/src/commands.ts
index 63e75685e..2acef8e8f 100644
--- a/packages/deployer/src/commands.ts
+++ b/packages/deployer/src/commands.ts
@@ -4,16 +4,16 @@ import { Deployer } from './deployer';
 import { CompilerOptions, DeployerOptions } from './utils/types';
 
 export const commands = {
-	async compileAsync(opts: CompilerOptions): Promise<void> {
-		const compiler = new Compiler(opts);
-		await compiler.compileAllAsync();
-	},
-	async migrateAsync(opts: DeployerOptions): Promise<void> {
-		const deployer = new Deployer(opts);
-		await migrator.runMigrationsAsync(deployer);
-	},
-	async deployAsync(contractName: string, args: any[], opts: DeployerOptions): Promise<void> {
-		const deployer = new Deployer(opts);
-		await deployer.deployAndSaveAsync(contractName, args);
-	},
+    async compileAsync(opts: CompilerOptions): Promise<void> {
+        const compiler = new Compiler(opts);
+        await compiler.compileAllAsync();
+    },
+    async migrateAsync(opts: DeployerOptions): Promise<void> {
+        const deployer = new Deployer(opts);
+        await migrator.runMigrationsAsync(deployer);
+    },
+    async deployAsync(contractName: string, args: any[], opts: DeployerOptions): Promise<void> {
+        const deployer = new Deployer(opts);
+        await deployer.deployAndSaveAsync(contractName, args);
+    },
 };
diff --git a/packages/deployer/src/compiler.ts b/packages/deployer/src/compiler.ts
index bc003149c..63db6c865 100644
--- a/packages/deployer/src/compiler.ts
+++ b/packages/deployer/src/compiler.ts
@@ -7,245 +7,245 @@ import * as Web3 from 'web3';
 import { binPaths } from './solc/bin_paths';
 import { fsWrapper } from './utils/fs_wrapper';
 import {
-	CompilerOptions,
-	ContractArtifact,
-	ContractData,
-	ContractNetworks,
-	ContractSources,
-	ImportContents,
+    CompilerOptions,
+    ContractArtifact,
+    ContractData,
+    ContractNetworks,
+    ContractSources,
+    ImportContents,
 } from './utils/types';
 import { utils } from './utils/utils';
 
 const SOLIDITY_FILE_EXTENSION = '.sol';
 
 export class Compiler {
-	private _contractsDir: string;
-	private _networkId: number;
-	private _optimizerEnabled: number;
-	private _artifactsDir: string;
-	private _contractSourcesIfExists?: ContractSources;
-	private _solcErrors: Set<string>;
-	/**
-	 * Recursively retrieves Solidity source code from directory.
-	 * @param  dirPath Directory to search.
-	 * @return Mapping of contract name to contract source.
-	 */
-	private static async _getContractSourcesAsync(dirPath: string): Promise<ContractSources> {
-		let dirContents: string[] = [];
-		try {
-			dirContents = await fsWrapper.readdirAsync(dirPath);
-		} catch (err) {
-			throw new Error(`No directory found at ${dirPath}`);
-		}
-		let sources: ContractSources = {};
-		for (const name of dirContents) {
-			const contentPath = `${dirPath}/${name}`;
-			if (path.extname(name) === SOLIDITY_FILE_EXTENSION) {
-				try {
-					const opts = {
-						encoding: 'utf8',
-					};
-					sources[name] = await fsWrapper.readFileAsync(contentPath, opts);
-					utils.consoleLog(`Reading ${name} source...`);
-				} catch (err) {
-					utils.consoleLog(`Could not find file at ${contentPath}`);
-				}
-			} else {
-				try {
-					const nestedSources = await Compiler._getContractSourcesAsync(contentPath);
-					sources = {
-						...sources,
-						...nestedSources,
-					};
-				} catch (err) {
-					utils.consoleLog(`${contentPath} is not a directory or ${SOLIDITY_FILE_EXTENSION} file`);
-				}
-			}
-		}
-		return sources;
-	}
-	/**
-	 * Searches Solidity source code for compiler version.
-	 * @param  source Source code of contract.
-	 * @return Solc compiler version.
-	 */
-	private static _parseSolidityVersion(source: string): string {
-		const solcVersionMatch = source.match(/(?:solidity\s\^?)([0-9]{1,2}[.][0-9]{1,2}[.][0-9]{1,2})/);
-		if (_.isNull(solcVersionMatch)) {
-			throw new Error('Could not find Solidity version in source');
-		}
-		const solcVersion = solcVersionMatch[1];
-		return solcVersion;
-	}
-	/**
-	 * Normalizes the path found in the error message.
-	 * Example: converts 'base/Token.sol:6:46: Warning: Unused local variable'
-	 *          to 'Token.sol:6:46: Warning: Unused local variable'
-	 * This is used to prevent logging the same error multiple times.
-	 * @param  errMsg An error message from the compiled output.
-	 * @return The error message with directories truncated from the contract path.
-	 */
-	private static _getNormalizedErrMsg(errMsg: string): string {
-		const errPathMatch = errMsg.match(/(.*\.sol)/);
-		if (_.isNull(errPathMatch)) {
-			throw new Error('Could not find a path in error message');
-		}
-		const errPath = errPathMatch[0];
-		const baseContract = path.basename(errPath);
-		const normalizedErrMsg = errMsg.replace(errPath, baseContract);
-		return normalizedErrMsg;
-	}
-	/**
-	 * Instantiates a new instance of the Compiler class.
-	 * @param opts Options specifying directories, network, and optimization settings.
-	 * @return An instance of the Compiler class.
-	 */
-	constructor(opts: CompilerOptions) {
-		this._contractsDir = opts.contractsDir;
-		this._networkId = opts.networkId;
-		this._optimizerEnabled = opts.optimizerEnabled;
-		this._artifactsDir = opts.artifactsDir;
-		this._solcErrors = new Set();
-	}
-	/**
-	 * Compiles all Solidity files found in contractsDir and writes JSON artifacts to artifactsDir.
-	 */
-	public async compileAllAsync(): Promise<void> {
-		await this._createArtifactsDirIfDoesNotExistAsync();
-		this._contractSourcesIfExists = await Compiler._getContractSourcesAsync(this._contractsDir);
-		const contractBaseNames = _.keys(this._contractSourcesIfExists);
-		const compiledContractPromises = _.map(contractBaseNames, async (contractBaseName: string): Promise<void> => {
-			return this._compileContractAsync(contractBaseName);
-		});
-		await Promise.all(compiledContractPromises);
+    private _contractsDir: string;
+    private _networkId: number;
+    private _optimizerEnabled: number;
+    private _artifactsDir: string;
+    private _contractSourcesIfExists?: ContractSources;
+    private _solcErrors: Set<string>;
+    /**
+     * Recursively retrieves Solidity source code from directory.
+     * @param  dirPath Directory to search.
+     * @return Mapping of contract name to contract source.
+     */
+    private static async _getContractSourcesAsync(dirPath: string): Promise<ContractSources> {
+        let dirContents: string[] = [];
+        try {
+            dirContents = await fsWrapper.readdirAsync(dirPath);
+        } catch (err) {
+            throw new Error(`No directory found at ${dirPath}`);
+        }
+        let sources: ContractSources = {};
+        for (const name of dirContents) {
+            const contentPath = `${dirPath}/${name}`;
+            if (path.extname(name) === SOLIDITY_FILE_EXTENSION) {
+                try {
+                    const opts = {
+                        encoding: 'utf8',
+                    };
+                    sources[name] = await fsWrapper.readFileAsync(contentPath, opts);
+                    utils.consoleLog(`Reading ${name} source...`);
+                } catch (err) {
+                    utils.consoleLog(`Could not find file at ${contentPath}`);
+                }
+            } else {
+                try {
+                    const nestedSources = await Compiler._getContractSourcesAsync(contentPath);
+                    sources = {
+                        ...sources,
+                        ...nestedSources,
+                    };
+                } catch (err) {
+                    utils.consoleLog(`${contentPath} is not a directory or ${SOLIDITY_FILE_EXTENSION} file`);
+                }
+            }
+        }
+        return sources;
+    }
+    /**
+     * Searches Solidity source code for compiler version.
+     * @param  source Source code of contract.
+     * @return Solc compiler version.
+     */
+    private static _parseSolidityVersion(source: string): string {
+        const solcVersionMatch = source.match(/(?:solidity\s\^?)([0-9]{1,2}[.][0-9]{1,2}[.][0-9]{1,2})/);
+        if (_.isNull(solcVersionMatch)) {
+            throw new Error('Could not find Solidity version in source');
+        }
+        const solcVersion = solcVersionMatch[1];
+        return solcVersion;
+    }
+    /**
+     * Normalizes the path found in the error message.
+     * Example: converts 'base/Token.sol:6:46: Warning: Unused local variable'
+     *          to 'Token.sol:6:46: Warning: Unused local variable'
+     * This is used to prevent logging the same error multiple times.
+     * @param  errMsg An error message from the compiled output.
+     * @return The error message with directories truncated from the contract path.
+     */
+    private static _getNormalizedErrMsg(errMsg: string): string {
+        const errPathMatch = errMsg.match(/(.*\.sol)/);
+        if (_.isNull(errPathMatch)) {
+            throw new Error('Could not find a path in error message');
+        }
+        const errPath = errPathMatch[0];
+        const baseContract = path.basename(errPath);
+        const normalizedErrMsg = errMsg.replace(errPath, baseContract);
+        return normalizedErrMsg;
+    }
+    /**
+     * Instantiates a new instance of the Compiler class.
+     * @param opts Options specifying directories, network, and optimization settings.
+     * @return An instance of the Compiler class.
+     */
+    constructor(opts: CompilerOptions) {
+        this._contractsDir = opts.contractsDir;
+        this._networkId = opts.networkId;
+        this._optimizerEnabled = opts.optimizerEnabled;
+        this._artifactsDir = opts.artifactsDir;
+        this._solcErrors = new Set();
+    }
+    /**
+     * Compiles all Solidity files found in contractsDir and writes JSON artifacts to artifactsDir.
+     */
+    public async compileAllAsync(): Promise<void> {
+        await this._createArtifactsDirIfDoesNotExistAsync();
+        this._contractSourcesIfExists = await Compiler._getContractSourcesAsync(this._contractsDir);
+        const contractBaseNames = _.keys(this._contractSourcesIfExists);
+        const compiledContractPromises = _.map(contractBaseNames, async (contractBaseName: string): Promise<void> => {
+            return this._compileContractAsync(contractBaseName);
+        });
+        await Promise.all(compiledContractPromises);
 
-		this._solcErrors.forEach(errMsg => {
-			utils.consoleLog(errMsg);
-		});
-	}
-	/**
-	 * Compiles contract and saves artifact to artifactsDir.
-	 * @param contractBaseName Name of contract with '.sol' extension.
-	 */
-	private async _compileContractAsync(contractBaseName: string): Promise<void> {
-		if (_.isUndefined(this._contractSourcesIfExists)) {
-			throw new Error('Contract sources not yet initialized');
-		}
+        this._solcErrors.forEach(errMsg => {
+            utils.consoleLog(errMsg);
+        });
+    }
+    /**
+     * Compiles contract and saves artifact to artifactsDir.
+     * @param contractBaseName Name of contract with '.sol' extension.
+     */
+    private async _compileContractAsync(contractBaseName: string): Promise<void> {
+        if (_.isUndefined(this._contractSourcesIfExists)) {
+            throw new Error('Contract sources not yet initialized');
+        }
 
-		const source = this._contractSourcesIfExists[contractBaseName];
-		const contractName = path.basename(contractBaseName, SOLIDITY_FILE_EXTENSION);
-		const currentArtifactPath = `${this._artifactsDir}/${contractName}.json`;
-		const sourceHash = `0x${ethUtil.sha3(source).toString('hex')}`;
+        const source = this._contractSourcesIfExists[contractBaseName];
+        const contractName = path.basename(contractBaseName, SOLIDITY_FILE_EXTENSION);
+        const currentArtifactPath = `${this._artifactsDir}/${contractName}.json`;
+        const sourceHash = `0x${ethUtil.sha3(source).toString('hex')}`;
 
-		let currentArtifactString: string;
-		let currentArtifact: ContractArtifact;
-		let oldNetworks: ContractNetworks;
-		let shouldCompile: boolean;
-		try {
-			const opts = {
-				encoding: 'utf8',
-			};
-			currentArtifactString = await fsWrapper.readFileAsync(currentArtifactPath, opts);
-			currentArtifact = JSON.parse(currentArtifactString);
-			oldNetworks = currentArtifact.networks;
-			const oldNetwork: ContractData = oldNetworks[this._networkId];
-			shouldCompile =
-				_.isUndefined(oldNetwork) ||
-				oldNetwork.keccak256 !== sourceHash ||
-				oldNetwork.optimizer_enabled !== this._optimizerEnabled;
-		} catch (err) {
-			shouldCompile = true;
-		}
+        let currentArtifactString: string;
+        let currentArtifact: ContractArtifact;
+        let oldNetworks: ContractNetworks;
+        let shouldCompile: boolean;
+        try {
+            const opts = {
+                encoding: 'utf8',
+            };
+            currentArtifactString = await fsWrapper.readFileAsync(currentArtifactPath, opts);
+            currentArtifact = JSON.parse(currentArtifactString);
+            oldNetworks = currentArtifact.networks;
+            const oldNetwork: ContractData = oldNetworks[this._networkId];
+            shouldCompile =
+                _.isUndefined(oldNetwork) ||
+                oldNetwork.keccak256 !== sourceHash ||
+                oldNetwork.optimizer_enabled !== this._optimizerEnabled;
+        } catch (err) {
+            shouldCompile = true;
+        }
 
-		if (!shouldCompile) {
-			return;
-		}
+        if (!shouldCompile) {
+            return;
+        }
 
-		const input = {
-			[contractBaseName]: source,
-		};
-		const solcVersion = Compiler._parseSolidityVersion(source);
-		const fullSolcVersion = binPaths[solcVersion];
-		const solcBinPath = `./solc/solc_bin/${fullSolcVersion}`;
-		const solcBin = require(solcBinPath);
-		const solcInstance = solc.setupMethods(solcBin);
+        const input = {
+            [contractBaseName]: source,
+        };
+        const solcVersion = Compiler._parseSolidityVersion(source);
+        const fullSolcVersion = binPaths[solcVersion];
+        const solcBinPath = `./solc/solc_bin/${fullSolcVersion}`;
+        const solcBin = require(solcBinPath);
+        const solcInstance = solc.setupMethods(solcBin);
 
-		utils.consoleLog(`Compiling ${contractBaseName}...`);
-		const sourcesToCompile = {
-			sources: input,
-		};
-		const compiled = solcInstance.compile(
-			sourcesToCompile,
-			this._optimizerEnabled,
-			this._findImportsIfSourcesExist.bind(this),
-		);
+        utils.consoleLog(`Compiling ${contractBaseName}...`);
+        const sourcesToCompile = {
+            sources: input,
+        };
+        const compiled = solcInstance.compile(
+            sourcesToCompile,
+            this._optimizerEnabled,
+            this._findImportsIfSourcesExist.bind(this),
+        );
 
-		if (!_.isUndefined(compiled.errors)) {
-			_.each(compiled.errors, errMsg => {
-				const normalizedErrMsg = Compiler._getNormalizedErrMsg(errMsg);
-				this._solcErrors.add(normalizedErrMsg);
-			});
-		}
+        if (!_.isUndefined(compiled.errors)) {
+            _.each(compiled.errors, errMsg => {
+                const normalizedErrMsg = Compiler._getNormalizedErrMsg(errMsg);
+                this._solcErrors.add(normalizedErrMsg);
+            });
+        }
 
-		const contractIdentifier = `${contractBaseName}:${contractName}`;
-		const abi: Web3.ContractAbi = JSON.parse(compiled.contracts[contractIdentifier].interface);
-		const unlinked_binary = `0x${compiled.contracts[contractIdentifier].bytecode}`;
-		const updated_at = Date.now();
-		const contractData: ContractData = {
-			solc_version: solcVersion,
-			keccak256: sourceHash,
-			optimizer_enabled: this._optimizerEnabled,
-			abi,
-			unlinked_binary,
-			updated_at,
-		};
+        const contractIdentifier = `${contractBaseName}:${contractName}`;
+        const abi: Web3.ContractAbi = JSON.parse(compiled.contracts[contractIdentifier].interface);
+        const unlinked_binary = `0x${compiled.contracts[contractIdentifier].bytecode}`;
+        const updated_at = Date.now();
+        const contractData: ContractData = {
+            solc_version: solcVersion,
+            keccak256: sourceHash,
+            optimizer_enabled: this._optimizerEnabled,
+            abi,
+            unlinked_binary,
+            updated_at,
+        };
 
-		let newArtifact: ContractArtifact;
-		if (!_.isUndefined(currentArtifactString)) {
-			newArtifact = {
-				...currentArtifact,
-				networks: {
-					...oldNetworks,
-					[this._networkId]: contractData,
-				},
-			};
-		} else {
-			newArtifact = {
-				contract_name: contractName,
-				networks: {
-					[this._networkId]: contractData,
-				},
-			};
-		}
+        let newArtifact: ContractArtifact;
+        if (!_.isUndefined(currentArtifactString)) {
+            newArtifact = {
+                ...currentArtifact,
+                networks: {
+                    ...oldNetworks,
+                    [this._networkId]: contractData,
+                },
+            };
+        } else {
+            newArtifact = {
+                contract_name: contractName,
+                networks: {
+                    [this._networkId]: contractData,
+                },
+            };
+        }
 
-		const artifactString = utils.stringifyWithFormatting(newArtifact);
-		await fsWrapper.writeFileAsync(currentArtifactPath, artifactString);
-		utils.consoleLog(`${contractBaseName} artifact saved!`);
-	}
-	/**
-	 * Callback to resolve dependencies with `solc.compile`.
-	 * Throws error if contractSources not yet initialized.
-	 * @param  importPath Path to an imported dependency.
-	 * @return Import contents object containing source code of dependency.
-	 */
-	private _findImportsIfSourcesExist(importPath: string): ImportContents {
-		if (_.isUndefined(this._contractSourcesIfExists)) {
-			throw new Error('Contract sources not yet initialized');
-		}
-		const contractBaseName = path.basename(importPath);
-		const source = this._contractSourcesIfExists[contractBaseName];
-		const importContents: ImportContents = {
-			contents: source,
-		};
-		return importContents;
-	}
-	/**
-	 * Creates the artifacts directory if it does not already exist.
-	 */
-	private async _createArtifactsDirIfDoesNotExistAsync(): Promise<void> {
-		if (!fsWrapper.doesPathExistSync(this._artifactsDir)) {
-			utils.consoleLog('Creating artifacts directory...');
-			await fsWrapper.mkdirAsync(this._artifactsDir);
-		}
-	}
+        const artifactString = utils.stringifyWithFormatting(newArtifact);
+        await fsWrapper.writeFileAsync(currentArtifactPath, artifactString);
+        utils.consoleLog(`${contractBaseName} artifact saved!`);
+    }
+    /**
+     * Callback to resolve dependencies with `solc.compile`.
+     * Throws error if contractSources not yet initialized.
+     * @param  importPath Path to an imported dependency.
+     * @return Import contents object containing source code of dependency.
+     */
+    private _findImportsIfSourcesExist(importPath: string): ImportContents {
+        if (_.isUndefined(this._contractSourcesIfExists)) {
+            throw new Error('Contract sources not yet initialized');
+        }
+        const contractBaseName = path.basename(importPath);
+        const source = this._contractSourcesIfExists[contractBaseName];
+        const importContents: ImportContents = {
+            contents: source,
+        };
+        return importContents;
+    }
+    /**
+     * Creates the artifacts directory if it does not already exist.
+     */
+    private async _createArtifactsDirIfDoesNotExistAsync(): Promise<void> {
+        if (!fsWrapper.doesPathExistSync(this._artifactsDir)) {
+            utils.consoleLog('Creating artifacts directory...');
+            await fsWrapper.mkdirAsync(this._artifactsDir);
+        }
+    }
 }
diff --git a/packages/deployer/src/deployer.ts b/packages/deployer/src/deployer.ts
index 34e20a197..6f03581e8 100644
--- a/packages/deployer/src/deployer.ts
+++ b/packages/deployer/src/deployer.ts
@@ -13,168 +13,168 @@ import { utils } from './utils/utils';
 const EXTRA_GAS = 200000;
 
 export class Deployer {
-	public web3Wrapper: Web3Wrapper;
-	private _artifactsDir: string;
-	private _jsonrpcPort: number;
-	private _networkId: number;
-	private _defaults: Partial<TxData>;
+    public web3Wrapper: Web3Wrapper;
+    private _artifactsDir: string;
+    private _jsonrpcPort: number;
+    private _networkId: number;
+    private _defaults: Partial<TxData>;
 
-	constructor(opts: DeployerOptions) {
-		this._artifactsDir = opts.artifactsDir;
-		this._jsonrpcPort = opts.jsonrpcPort;
-		this._networkId = opts.networkId;
-		const jsonrpcUrl = `http://localhost:${this._jsonrpcPort}`;
-		const web3Provider = new Web3.providers.HttpProvider(jsonrpcUrl);
-		this._defaults = opts.defaults;
-		this.web3Wrapper = new Web3Wrapper(web3Provider, this._defaults);
-	}
-	/**
-	 * Loads contract artifact and deploys contract with given arguments.
-	 * @param contractName Name of the contract to deploy. Must match name of an artifact in artifacts directory.
-	 * @param args Array of contract constructor arguments.
-	 * @return Deployed contract instance.
-	 */
-	public async deployAsync(contractName: string, args: any[] = []): Promise<Web3.ContractInstance> {
-		const contractArtifact: ContractArtifact = this._loadContractArtifactIfExists(contractName);
-		const contractData: ContractData = this._getContractDataFromArtifactIfExists(contractArtifact);
-		const data = contractData.unlinked_binary;
-		const from = await this._getFromAddressAsync();
-		const gas = await this._getAllowableGasEstimateAsync(data);
-		const txData = {
-			gasPrice: this._defaults.gasPrice,
-			from,
-			data,
-			gas,
-		};
-		const abi = contractData.abi;
-		const web3ContractInstance = await this._deployFromAbiAsync(abi, args, txData);
-		utils.consoleLog(`${contractName}.sol successfully deployed at ${web3ContractInstance.address}`);
-		const contractInstance = new Contract(web3ContractInstance, this._defaults);
-		return contractInstance;
-	}
-	/**
-	 * Loads contract artifact, deploys with given arguments, and saves updated data to artifact.
-	 * @param contractName Name of the contract to deploy. Must match name of an artifact in artifacts directory.
-	 * @param args Array of contract constructor arguments.
-	 * @return Deployed contract instance.
-	 */
-	public async deployAndSaveAsync(contractName: string, args: any[] = []): Promise<Web3.ContractInstance> {
-		const contractInstance = await this.deployAsync(contractName, args);
-		await this._saveContractDataToArtifactAsync(contractName, contractInstance.address, args);
-		return contractInstance;
-	}
-	/**
-	 * Deploys a contract given its ABI, arguments, and transaction data.
-	 * @param abi ABI of contract to deploy.
-	 * @param args Constructor arguments to use in deployment.
-	 * @param txData Tx options used for deployment.
-	 * @return Promise that resolves to a web3 contract instance.
-	 */
-	private async _deployFromAbiAsync(abi: Web3.ContractAbi, args: any[], txData: Web3.TxData): Promise<any> {
-		const contract: Web3.Contract<Web3.ContractInstance> = this.web3Wrapper.getContractFromAbi(abi);
-		const deployPromise = new Promise((resolve, reject) => {
-			/**
-			 * Contract is inferred as 'any' because TypeScript
-			 * is not able to read 'new' from the Contract interface
-			 */
-			(contract as any).new(...args, txData, (err: Error, res: any): any => {
-				if (err) {
-					reject(err);
-				} else if (_.isUndefined(res.address) && !_.isUndefined(res.transactionHash)) {
-					utils.consoleLog(`transactionHash: ${res.transactionHash}`);
-				} else {
-					resolve(res);
-				}
-			});
-		});
-		return deployPromise;
-	}
-	/**
-	 * Updates a contract artifact's address and encoded constructor arguments.
-	 * @param contractName Name of contract. Must match an existing artifact.
-	 * @param contractAddress Contract address to save to artifact.
-	 * @param args Contract constructor arguments that will be encoded and saved to artifact.
-	 */
-	private async _saveContractDataToArtifactAsync(
-		contractName: string,
-		contractAddress: string,
-		args: any[],
-	): Promise<void> {
-		const contractArtifact: ContractArtifact = this._loadContractArtifactIfExists(contractName);
-		const contractData: ContractData = this._getContractDataFromArtifactIfExists(contractArtifact);
-		const abi = contractData.abi;
-		const encodedConstructorArgs = encoder.encodeConstructorArgsFromAbi(args, abi);
-		const newContractData = {
-			...contractData,
-			address: contractAddress,
-			constructor_args: encodedConstructorArgs,
-		};
-		const newArtifact = {
-			...contractArtifact,
-			networks: {
-				...contractArtifact.networks,
-				[this._networkId]: newContractData,
-			},
-		};
-		const artifactString = utils.stringifyWithFormatting(newArtifact);
-		const artifactPath = `${this._artifactsDir}/${contractName}.json`;
-		await fsWrapper.writeFileAsync(artifactPath, artifactString);
-	}
-	/**
-	 * Loads a contract artifact, if it exists.
-	 * @param contractName Name of the contract, without the extension.
-	 * @return The contract artifact.
-	 */
-	private _loadContractArtifactIfExists(contractName: string): ContractArtifact {
-		const artifactPath = `${this._artifactsDir}/${contractName}.json`;
-		try {
-			const contractArtifact: ContractArtifact = require(artifactPath);
-			return contractArtifact;
-		} catch (err) {
-			throw new Error(`Artifact not found for contract: ${contractName}`);
-		}
-	}
-	/**
-	 * Gets data for current networkId stored in artifact.
-	 * @param contractArtifact The contract artifact.
-	 * @return Network specific contract data.
-	 */
-	private _getContractDataFromArtifactIfExists(contractArtifact: ContractArtifact): ContractData {
-		const contractData = contractArtifact.networks[this._networkId];
-		if (_.isUndefined(contractData)) {
-			throw new Error(`Data not found in artifact for contract: ${contractArtifact.contract_name}`);
-		}
-		return contractData;
-	}
-	/**
-	 * Gets the address to use for sending a transaction.
-	 * @return The default from address. If not specified, returns the first address accessible by web3.
-	 */
-	private async _getFromAddressAsync(): Promise<string> {
-		let from: string;
-		if (_.isUndefined(this._defaults.from)) {
-			const accounts = await this.web3Wrapper.getAvailableAddressesAsync();
-			from = accounts[0];
-		} else {
-			from = this._defaults.from;
-		}
-		return from;
-	}
-	/**
-	 * Estimates the gas required for a transaction.
-	 * If gas would be over the block gas limit, the max allowable gas is returned instead.
-	 * @param data Bytecode to estimate gas for.
-	 * @return Gas estimate for transaction data.
-	 */
-	private async _getAllowableGasEstimateAsync(data: string): Promise<number> {
-		const block = await this.web3Wrapper.getBlockAsync('latest');
-		let gas: number;
-		try {
-			const gasEstimate: number = await this.web3Wrapper.estimateGasAsync(data);
-			gas = Math.min(gasEstimate + EXTRA_GAS, block.gasLimit);
-		} catch (err) {
-			gas = block.gasLimit;
-		}
-		return gas;
-	}
+    constructor(opts: DeployerOptions) {
+        this._artifactsDir = opts.artifactsDir;
+        this._jsonrpcPort = opts.jsonrpcPort;
+        this._networkId = opts.networkId;
+        const jsonrpcUrl = `http://localhost:${this._jsonrpcPort}`;
+        const web3Provider = new Web3.providers.HttpProvider(jsonrpcUrl);
+        this._defaults = opts.defaults;
+        this.web3Wrapper = new Web3Wrapper(web3Provider, this._defaults);
+    }
+    /**
+     * Loads contract artifact and deploys contract with given arguments.
+     * @param contractName Name of the contract to deploy. Must match name of an artifact in artifacts directory.
+     * @param args Array of contract constructor arguments.
+     * @return Deployed contract instance.
+     */
+    public async deployAsync(contractName: string, args: any[] = []): Promise<Web3.ContractInstance> {
+        const contractArtifact: ContractArtifact = this._loadContractArtifactIfExists(contractName);
+        const contractData: ContractData = this._getContractDataFromArtifactIfExists(contractArtifact);
+        const data = contractData.unlinked_binary;
+        const from = await this._getFromAddressAsync();
+        const gas = await this._getAllowableGasEstimateAsync(data);
+        const txData = {
+            gasPrice: this._defaults.gasPrice,
+            from,
+            data,
+            gas,
+        };
+        const abi = contractData.abi;
+        const web3ContractInstance = await this._deployFromAbiAsync(abi, args, txData);
+        utils.consoleLog(`${contractName}.sol successfully deployed at ${web3ContractInstance.address}`);
+        const contractInstance = new Contract(web3ContractInstance, this._defaults);
+        return contractInstance;
+    }
+    /**
+     * Loads contract artifact, deploys with given arguments, and saves updated data to artifact.
+     * @param contractName Name of the contract to deploy. Must match name of an artifact in artifacts directory.
+     * @param args Array of contract constructor arguments.
+     * @return Deployed contract instance.
+     */
+    public async deployAndSaveAsync(contractName: string, args: any[] = []): Promise<Web3.ContractInstance> {
+        const contractInstance = await this.deployAsync(contractName, args);
+        await this._saveContractDataToArtifactAsync(contractName, contractInstance.address, args);
+        return contractInstance;
+    }
+    /**
+     * Deploys a contract given its ABI, arguments, and transaction data.
+     * @param abi ABI of contract to deploy.
+     * @param args Constructor arguments to use in deployment.
+     * @param txData Tx options used for deployment.
+     * @return Promise that resolves to a web3 contract instance.
+     */
+    private async _deployFromAbiAsync(abi: Web3.ContractAbi, args: any[], txData: Web3.TxData): Promise<any> {
+        const contract: Web3.Contract<Web3.ContractInstance> = this.web3Wrapper.getContractFromAbi(abi);
+        const deployPromise = new Promise((resolve, reject) => {
+            /**
+             * Contract is inferred as 'any' because TypeScript
+             * is not able to read 'new' from the Contract interface
+             */
+            (contract as any).new(...args, txData, (err: Error, res: any): any => {
+                if (err) {
+                    reject(err);
+                } else if (_.isUndefined(res.address) && !_.isUndefined(res.transactionHash)) {
+                    utils.consoleLog(`transactionHash: ${res.transactionHash}`);
+                } else {
+                    resolve(res);
+                }
+            });
+        });
+        return deployPromise;
+    }
+    /**
+     * Updates a contract artifact's address and encoded constructor arguments.
+     * @param contractName Name of contract. Must match an existing artifact.
+     * @param contractAddress Contract address to save to artifact.
+     * @param args Contract constructor arguments that will be encoded and saved to artifact.
+     */
+    private async _saveContractDataToArtifactAsync(
+        contractName: string,
+        contractAddress: string,
+        args: any[],
+    ): Promise<void> {
+        const contractArtifact: ContractArtifact = this._loadContractArtifactIfExists(contractName);
+        const contractData: ContractData = this._getContractDataFromArtifactIfExists(contractArtifact);
+        const abi = contractData.abi;
+        const encodedConstructorArgs = encoder.encodeConstructorArgsFromAbi(args, abi);
+        const newContractData = {
+            ...contractData,
+            address: contractAddress,
+            constructor_args: encodedConstructorArgs,
+        };
+        const newArtifact = {
+            ...contractArtifact,
+            networks: {
+                ...contractArtifact.networks,
+                [this._networkId]: newContractData,
+            },
+        };
+        const artifactString = utils.stringifyWithFormatting(newArtifact);
+        const artifactPath = `${this._artifactsDir}/${contractName}.json`;
+        await fsWrapper.writeFileAsync(artifactPath, artifactString);
+    }
+    /**
+     * Loads a contract artifact, if it exists.
+     * @param contractName Name of the contract, without the extension.
+     * @return The contract artifact.
+     */
+    private _loadContractArtifactIfExists(contractName: string): ContractArtifact {
+        const artifactPath = `${this._artifactsDir}/${contractName}.json`;
+        try {
+            const contractArtifact: ContractArtifact = require(artifactPath);
+            return contractArtifact;
+        } catch (err) {
+            throw new Error(`Artifact not found for contract: ${contractName}`);
+        }
+    }
+    /**
+     * Gets data for current networkId stored in artifact.
+     * @param contractArtifact The contract artifact.
+     * @return Network specific contract data.
+     */
+    private _getContractDataFromArtifactIfExists(contractArtifact: ContractArtifact): ContractData {
+        const contractData = contractArtifact.networks[this._networkId];
+        if (_.isUndefined(contractData)) {
+            throw new Error(`Data not found in artifact for contract: ${contractArtifact.contract_name}`);
+        }
+        return contractData;
+    }
+    /**
+     * Gets the address to use for sending a transaction.
+     * @return The default from address. If not specified, returns the first address accessible by web3.
+     */
+    private async _getFromAddressAsync(): Promise<string> {
+        let from: string;
+        if (_.isUndefined(this._defaults.from)) {
+            const accounts = await this.web3Wrapper.getAvailableAddressesAsync();
+            from = accounts[0];
+        } else {
+            from = this._defaults.from;
+        }
+        return from;
+    }
+    /**
+     * Estimates the gas required for a transaction.
+     * If gas would be over the block gas limit, the max allowable gas is returned instead.
+     * @param data Bytecode to estimate gas for.
+     * @return Gas estimate for transaction data.
+     */
+    private async _getAllowableGasEstimateAsync(data: string): Promise<number> {
+        const block = await this.web3Wrapper.getBlockAsync('latest');
+        let gas: number;
+        try {
+            const gasEstimate: number = await this.web3Wrapper.estimateGasAsync(data);
+            gas = Math.min(gasEstimate + EXTRA_GAS, block.gasLimit);
+        } catch (err) {
+            gas = block.gasLimit;
+        }
+        return gas;
+    }
 }
diff --git a/packages/deployer/src/globals.d.ts b/packages/deployer/src/globals.d.ts
index d61f54870..0a35002da 100644
--- a/packages/deployer/src/globals.d.ts
+++ b/packages/deployer/src/globals.d.ts
@@ -1,8 +1,8 @@
 declare module 'solc' {
-	export function compile(sources: any, optimizerEnabled: number, findImports: (importPath: string) => any): any;
-	export function setupMethods(solcBin: any): any;
+    export function compile(sources: any, optimizerEnabled: number, findImports: (importPath: string) => any): any;
+    export function setupMethods(solcBin: any): any;
 }
 
 declare module 'web3-eth-abi' {
-	export function encodeParameters(typesArray: string[], parameters: any[]): string;
+    export function encodeParameters(typesArray: string[], parameters: any[]): string;
 }
diff --git a/packages/deployer/src/migrations/config/multisig_sample.ts b/packages/deployer/src/migrations/config/multisig_sample.ts
index d65ab06d2..dabeb7a4f 100644
--- a/packages/deployer/src/migrations/config/multisig_sample.ts
+++ b/packages/deployer/src/migrations/config/multisig_sample.ts
@@ -2,9 +2,9 @@ import { MultiSigConfigByNetwork } from '../../types';
 
 // Make a copy of this file named `multisig.js` and input custom params as needed
 export const multiSig: MultiSigConfigByNetwork = {
-	kovan: {
-		owners: [],
-		confirmationsRequired: 0,
-		secondsRequired: 0,
-	},
+    kovan: {
+        owners: [],
+        confirmationsRequired: 0,
+        secondsRequired: 0,
+    },
 };
diff --git a/packages/deployer/src/migrations/config/token_info.ts b/packages/deployer/src/migrations/config/token_info.ts
index ebcd3f796..7e822fc3b 100644
--- a/packages/deployer/src/migrations/config/token_info.ts
+++ b/packages/deployer/src/migrations/config/token_info.ts
@@ -2,39 +2,39 @@ import { constants } from '../../utils/constants';
 import { Token } from '../../types';
 
 export const tokenInfo: Token[] = [
-	{
-		name: 'Augur Reputation Token',
-		symbol: 'REP',
-		decimals: 18,
-		ipfsHash: constants.NULL_BYTES,
-		swarmHash: constants.NULL_BYTES,
-	},
-	{
-		name: 'Digix DAO Token',
-		symbol: 'DGD',
-		decimals: 18,
-		ipfsHash: constants.NULL_BYTES,
-		swarmHash: constants.NULL_BYTES,
-	},
-	{
-		name: 'Golem Network Token',
-		symbol: 'GNT',
-		decimals: 18,
-		ipfsHash: constants.NULL_BYTES,
-		swarmHash: constants.NULL_BYTES,
-	},
-	{
-		name: 'MakerDAO',
-		symbol: 'MKR',
-		decimals: 18,
-		ipfsHash: constants.NULL_BYTES,
-		swarmHash: constants.NULL_BYTES,
-	},
-	{
-		name: 'Melon Token',
-		symbol: 'MLN',
-		decimals: 18,
-		ipfsHash: constants.NULL_BYTES,
-		swarmHash: constants.NULL_BYTES,
-	},
+    {
+        name: 'Augur Reputation Token',
+        symbol: 'REP',
+        decimals: 18,
+        ipfsHash: constants.NULL_BYTES,
+        swarmHash: constants.NULL_BYTES,
+    },
+    {
+        name: 'Digix DAO Token',
+        symbol: 'DGD',
+        decimals: 18,
+        ipfsHash: constants.NULL_BYTES,
+        swarmHash: constants.NULL_BYTES,
+    },
+    {
+        name: 'Golem Network Token',
+        symbol: 'GNT',
+        decimals: 18,
+        ipfsHash: constants.NULL_BYTES,
+        swarmHash: constants.NULL_BYTES,
+    },
+    {
+        name: 'MakerDAO',
+        symbol: 'MKR',
+        decimals: 18,
+        ipfsHash: constants.NULL_BYTES,
+        swarmHash: constants.NULL_BYTES,
+    },
+    {
+        name: 'Melon Token',
+        symbol: 'MLN',
+        decimals: 18,
+        ipfsHash: constants.NULL_BYTES,
+        swarmHash: constants.NULL_BYTES,
+    },
 ];
diff --git a/packages/deployer/src/migrations/migrate.ts b/packages/deployer/src/migrations/migrate.ts
index 48cf93000..393806b45 100644
--- a/packages/deployer/src/migrations/migrate.ts
+++ b/packages/deployer/src/migrations/migrate.ts
@@ -7,84 +7,84 @@ import { constants } from '../utils/constants';
 import { tokenInfo } from './config/token_info';
 
 export const migrator = {
-	/**
-	 * Custom migrations should be defined in this function. This will be called with the CLI 'migrate' command.
-	 * Some operations might be completed in parallel, but we don't do that on purpose.
-	 * That way the addresses are deterministic.
-	 * @param deployer Deployer instance.
-	 */
-	async runMigrationsAsync(deployer: Deployer): Promise<void> {
-		const web3Wrapper: Web3Wrapper = deployer.web3Wrapper;
-		const accounts: string[] = await web3Wrapper.getAvailableAddressesAsync();
+    /**
+     * Custom migrations should be defined in this function. This will be called with the CLI 'migrate' command.
+     * Some operations might be completed in parallel, but we don't do that on purpose.
+     * That way the addresses are deterministic.
+     * @param deployer Deployer instance.
+     */
+    async runMigrationsAsync(deployer: Deployer): Promise<void> {
+        const web3Wrapper: Web3Wrapper = deployer.web3Wrapper;
+        const accounts: string[] = await web3Wrapper.getAvailableAddressesAsync();
 
-		const tokenTransferProxy = await deployer.deployAndSaveAsync('TokenTransferProxy');
-		const zrxToken = await deployer.deployAndSaveAsync('ZRXToken');
-		const etherToken = await deployer.deployAndSaveAsync('WETH9');
-		const tokenReg = await deployer.deployAndSaveAsync('TokenRegistry');
+        const tokenTransferProxy = await deployer.deployAndSaveAsync('TokenTransferProxy');
+        const zrxToken = await deployer.deployAndSaveAsync('ZRXToken');
+        const etherToken = await deployer.deployAndSaveAsync('WETH9');
+        const tokenReg = await deployer.deployAndSaveAsync('TokenRegistry');
 
-		const exchangeArgs = [zrxToken.address, tokenTransferProxy.address];
-		const owners = [accounts[0], accounts[1]];
-		const confirmationsRequired = new BigNumber(2);
-		const secondsRequired = new BigNumber(0);
-		const multiSigArgs = [owners, confirmationsRequired, secondsRequired, tokenTransferProxy.address];
-		const exchange = await deployer.deployAndSaveAsync('Exchange', exchangeArgs);
-		const multiSig = await deployer.deployAndSaveAsync(
-			'MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress',
-			multiSigArgs,
-		);
+        const exchangeArgs = [zrxToken.address, tokenTransferProxy.address];
+        const owners = [accounts[0], accounts[1]];
+        const confirmationsRequired = new BigNumber(2);
+        const secondsRequired = new BigNumber(0);
+        const multiSigArgs = [owners, confirmationsRequired, secondsRequired, tokenTransferProxy.address];
+        const exchange = await deployer.deployAndSaveAsync('Exchange', exchangeArgs);
+        const multiSig = await deployer.deployAndSaveAsync(
+            'MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress',
+            multiSigArgs,
+        );
 
-		const owner = accounts[0];
-		await tokenTransferProxy.addAuthorizedAddress.sendTransactionAsync(exchange.address, { from: owner });
-		await tokenTransferProxy.transferOwnership.sendTransactionAsync(multiSig.address, { from: owner });
-		const addTokenGasEstimate = await tokenReg.addToken.estimateGasAsync(
-			zrxToken.address,
-			tokenInfo[0].name,
-			tokenInfo[0].symbol,
-			tokenInfo[0].decimals,
-			tokenInfo[0].ipfsHash,
-			tokenInfo[0].swarmHash,
-			{ from: owner },
-		);
-		await tokenReg.addToken.sendTransactionAsync(
-			zrxToken.address,
-			'0x Protocol Token',
-			'ZRX',
-			18,
-			constants.NULL_BYTES,
-			constants.NULL_BYTES,
-			{
-				from: owner,
-				gas: addTokenGasEstimate,
-			},
-		);
-		await tokenReg.addToken.sendTransactionAsync(
-			etherToken.address,
-			'Ether Token',
-			'WETH',
-			18,
-			constants.NULL_BYTES,
-			constants.NULL_BYTES,
-			{
-				from: owner,
-				gas: addTokenGasEstimate,
-			},
-		);
-		for (const token of tokenInfo) {
-			const totalSupply = new BigNumber(0);
-			const args = [token.name, token.symbol, token.decimals, totalSupply];
-			const dummyToken = await deployer.deployAsync('DummyToken', args);
-			await tokenReg.addToken.sendTransactionAsync(
-				dummyToken.address,
-				token.name,
-				token.symbol,
-				token.decimals,
-				token.ipfsHash,
-				token.swarmHash,
-				{
-					from: owner,
-					gas: addTokenGasEstimate,
-				},
-			);
-		}
-	},
+        const owner = accounts[0];
+        await tokenTransferProxy.addAuthorizedAddress.sendTransactionAsync(exchange.address, { from: owner });
+        await tokenTransferProxy.transferOwnership.sendTransactionAsync(multiSig.address, { from: owner });
+        const addTokenGasEstimate = await tokenReg.addToken.estimateGasAsync(
+            zrxToken.address,
+            tokenInfo[0].name,
+            tokenInfo[0].symbol,
+            tokenInfo[0].decimals,
+            tokenInfo[0].ipfsHash,
+            tokenInfo[0].swarmHash,
+            { from: owner },
+        );
+        await tokenReg.addToken.sendTransactionAsync(
+            zrxToken.address,
+            '0x Protocol Token',
+            'ZRX',
+            18,
+            constants.NULL_BYTES,
+            constants.NULL_BYTES,
+            {
+                from: owner,
+                gas: addTokenGasEstimate,
+            },
+        );
+        await tokenReg.addToken.sendTransactionAsync(
+            etherToken.address,
+            'Ether Token',
+            'WETH',
+            18,
+            constants.NULL_BYTES,
+            constants.NULL_BYTES,
+            {
+                from: owner,
+                gas: addTokenGasEstimate,
+            },
+        );
+        for (const token of tokenInfo) {
+            const totalSupply = new BigNumber(0);
+            const args = [token.name, token.symbol, token.decimals, totalSupply];
+            const dummyToken = await deployer.deployAsync('DummyToken', args);
+            await tokenReg.addToken.sendTransactionAsync(
+                dummyToken.address,
+                token.name,
+                token.symbol,
+                token.decimals,
+                token.ipfsHash,
+                token.swarmHash,
+                {
+                    from: owner,
+                    gas: addTokenGasEstimate,
+                },
+            );
+        }
+    },
 };
diff --git a/packages/deployer/src/solc/bin_paths.ts b/packages/deployer/src/solc/bin_paths.ts
index 7a22f911a..e5b107101 100644
--- a/packages/deployer/src/solc/bin_paths.ts
+++ b/packages/deployer/src/solc/bin_paths.ts
@@ -1,15 +1,15 @@
 export interface BinaryPaths {
-	[key: string]: string;
+    [key: string]: string;
 }
 
 export const binPaths: BinaryPaths = {
-	'0.4.10': 'soljson-v0.4.10+commit.f0d539ae.js',
-	'0.4.11': 'soljson-v0.4.11+commit.68ef5810.js',
-	'0.4.12': 'soljson-v0.4.12+commit.194ff033.js',
-	'0.4.13': 'soljson-v0.4.13+commit.fb4cb1a.js',
-	'0.4.14': 'soljson-v0.4.14+commit.c2215d46.js',
-	'0.4.15': 'soljson-v0.4.15+commit.bbb8e64f.js',
-	'0.4.16': 'soljson-v0.4.16+commit.d7661dd9.js',
-	'0.4.17': 'soljson-v0.4.17+commit.bdeb9e52.js',
-	'0.4.18': 'soljson-v0.4.18+commit.9cf6e910.js',
+    '0.4.10': 'soljson-v0.4.10+commit.f0d539ae.js',
+    '0.4.11': 'soljson-v0.4.11+commit.68ef5810.js',
+    '0.4.12': 'soljson-v0.4.12+commit.194ff033.js',
+    '0.4.13': 'soljson-v0.4.13+commit.fb4cb1a.js',
+    '0.4.14': 'soljson-v0.4.14+commit.c2215d46.js',
+    '0.4.15': 'soljson-v0.4.15+commit.bbb8e64f.js',
+    '0.4.16': 'soljson-v0.4.16+commit.d7661dd9.js',
+    '0.4.17': 'soljson-v0.4.17+commit.bdeb9e52.js',
+    '0.4.18': 'soljson-v0.4.18+commit.9cf6e910.js',
 };
diff --git a/packages/deployer/src/types.ts b/packages/deployer/src/types.ts
index aeff39d46..58d1e5b4f 100644
--- a/packages/deployer/src/types.ts
+++ b/packages/deployer/src/types.ts
@@ -1,23 +1,23 @@
 export interface MultiSigConfig {
-	owners: string[];
-	confirmationsRequired: number;
-	secondsRequired: number;
+    owners: string[];
+    confirmationsRequired: number;
+    secondsRequired: number;
 }
 
 export interface MultiSigConfigByNetwork {
-	[networkName: string]: MultiSigConfig;
+    [networkName: string]: MultiSigConfig;
 }
 
 export interface Token {
-	address?: string;
-	name: string;
-	symbol: string;
-	decimals: number;
-	ipfsHash: string;
-	swarmHash: string;
+    address?: string;
+    name: string;
+    symbol: string;
+    decimals: number;
+    ipfsHash: string;
+    swarmHash: string;
 }
 
 export interface TokenInfoByNetwork {
-	development: Token[];
-	live: Token[];
+    development: Token[];
+    live: Token[];
 }
diff --git a/packages/deployer/src/utils/constants.ts b/packages/deployer/src/utils/constants.ts
index 9f22114e7..8871a470d 100644
--- a/packages/deployer/src/utils/constants.ts
+++ b/packages/deployer/src/utils/constants.ts
@@ -1,3 +1,3 @@
 export const constants = {
-	NULL_BYTES: '0x',
+    NULL_BYTES: '0x',
 };
diff --git a/packages/deployer/src/utils/contract.ts b/packages/deployer/src/utils/contract.ts
index 473ca95c8..546e82dfb 100644
--- a/packages/deployer/src/utils/contract.ts
+++ b/packages/deployer/src/utils/contract.ts
@@ -6,76 +6,76 @@ import * as Web3 from 'web3';
 import { AbiType } from './types';
 
 export class Contract implements Web3.ContractInstance {
-	public address: string;
-	public abi: Web3.ContractAbi;
-	private _contract: Web3.ContractInstance;
-	private _defaults: Partial<Web3.TxData>;
-	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<Web3.TxData>) {
-		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) as Web3.FunctionAbi[];
-		_.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) as Web3.EventAbi[];
-		_.forEach(eventsAbi, (eventAbi: Web3.EventAbi) => {
-			this[eventAbi.name] = this._contract[eventAbi.name];
-		});
-	}
-	private _promisifyWithDefaultParams(fn: (...args: any[]) => void): (...args: any[]) => Promise<any> {
-		const promisifiedWithDefaultParams = async (...args: any[]) => {
-			const promise = new Promise((resolve, reject) => {
-				const lastArg = args[args.length - 1];
-				let txData: Partial<Web3.TxData> = {};
-				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;
-	}
+    public address: string;
+    public abi: Web3.ContractAbi;
+    private _contract: Web3.ContractInstance;
+    private _defaults: Partial<Web3.TxData>;
+    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<Web3.TxData>) {
+        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) as Web3.FunctionAbi[];
+        _.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) as Web3.EventAbi[];
+        _.forEach(eventsAbi, (eventAbi: Web3.EventAbi) => {
+            this[eventAbi.name] = this._contract[eventAbi.name];
+        });
+    }
+    private _promisifyWithDefaultParams(fn: (...args: any[]) => void): (...args: any[]) => Promise<any> {
+        const promisifiedWithDefaultParams = async (...args: any[]) => {
+            const promise = new Promise((resolve, reject) => {
+                const lastArg = args[args.length - 1];
+                let txData: Partial<Web3.TxData> = {};
+                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/packages/deployer/src/utils/encoder.ts b/packages/deployer/src/utils/encoder.ts
index 30772b4bc..d5f807774 100644
--- a/packages/deployer/src/utils/encoder.ts
+++ b/packages/deployer/src/utils/encoder.ts
@@ -5,16 +5,16 @@ import * as web3Abi from 'web3-eth-abi';
 import { AbiType } from './types';
 
 export const encoder = {
-	encodeConstructorArgsFromAbi(args: any[], abi: Web3.ContractAbi): string {
-		const constructorTypes: string[] = [];
-		_.each(abi, (element: Web3.AbiDefinition) => {
-			if (element.type === AbiType.Constructor) {
-				_.each(element.inputs, (input: Web3.FunctionParameter) => {
-					constructorTypes.push(input.type);
-				});
-			}
-		});
-		const encodedParameters = web3Abi.encodeParameters(constructorTypes, args);
-		return encodedParameters;
-	},
+    encodeConstructorArgsFromAbi(args: any[], abi: Web3.ContractAbi): string {
+        const constructorTypes: string[] = [];
+        _.each(abi, (element: Web3.AbiDefinition) => {
+            if (element.type === AbiType.Constructor) {
+                _.each(element.inputs, (input: Web3.FunctionParameter) => {
+                    constructorTypes.push(input.type);
+                });
+            }
+        });
+        const encodedParameters = web3Abi.encodeParameters(constructorTypes, args);
+        return encodedParameters;
+    },
 };
diff --git a/packages/deployer/src/utils/fs_wrapper.ts b/packages/deployer/src/utils/fs_wrapper.ts
index 42bdc9969..34c7caa0e 100644
--- a/packages/deployer/src/utils/fs_wrapper.ts
+++ b/packages/deployer/src/utils/fs_wrapper.ts
@@ -2,10 +2,10 @@ import { promisify } from '@0xproject/utils';
 import * as fs from 'fs';
 
 export const fsWrapper = {
-	readdirAsync: promisify<string[]>(fs.readdir),
-	readFileAsync: promisify<string>(fs.readFile),
-	writeFileAsync: promisify<undefined>(fs.writeFile),
-	mkdirAsync: promisify<undefined>(fs.mkdir),
-	doesPathExistSync: fs.existsSync,
-	removeFileAsync: promisify<undefined>(fs.unlink),
+    readdirAsync: promisify<string[]>(fs.readdir),
+    readFileAsync: promisify<string>(fs.readFile),
+    writeFileAsync: promisify<undefined>(fs.writeFile),
+    mkdirAsync: promisify<undefined>(fs.mkdir),
+    doesPathExistSync: fs.existsSync,
+    removeFileAsync: promisify<undefined>(fs.unlink),
 };
diff --git a/packages/deployer/src/utils/types.ts b/packages/deployer/src/utils/types.ts
index 9e1378e24..e054b9cc2 100644
--- a/packages/deployer/src/utils/types.ts
+++ b/packages/deployer/src/utils/types.ts
@@ -3,95 +3,95 @@ import * as Web3 from 'web3';
 import * as yargs from 'yargs';
 
 export enum AbiType {
-	Function = 'function',
-	Constructor = 'constructor',
-	Event = 'event',
-	Fallback = 'fallback',
+    Function = 'function',
+    Constructor = 'constructor',
+    Event = 'event',
+    Fallback = 'fallback',
 }
 
 export interface ContractArtifact {
-	contract_name: string;
-	networks: ContractNetworks;
+    contract_name: string;
+    networks: ContractNetworks;
 }
 
 export interface ContractNetworks {
-	[key: number]: ContractData;
+    [key: number]: ContractData;
 }
 
 export interface ContractData {
-	solc_version: string;
-	optimizer_enabled: number;
-	keccak256: string;
-	abi: Web3.ContractAbi;
-	unlinked_binary: string;
-	address?: string;
-	constructor_args?: string;
-	updated_at: number;
+    solc_version: string;
+    optimizer_enabled: number;
+    keccak256: string;
+    abi: Web3.ContractAbi;
+    unlinked_binary: string;
+    address?: string;
+    constructor_args?: string;
+    updated_at: number;
 }
 
 export interface SolcErrors {
-	[key: string]: boolean;
+    [key: string]: boolean;
 }
 
 export interface CliOptions extends yargs.Arguments {
-	artifactsDir: string;
-	contractsDir: string;
-	jsonrpcPort: number;
-	networkId: number;
-	shouldOptimize: boolean;
-	gasPrice: string;
-	account?: string;
-	contract?: string;
-	args?: string;
+    artifactsDir: string;
+    contractsDir: string;
+    jsonrpcPort: number;
+    networkId: number;
+    shouldOptimize: boolean;
+    gasPrice: string;
+    account?: string;
+    contract?: string;
+    args?: string;
 }
 
 export interface CompilerOptions {
-	contractsDir: string;
-	networkId: number;
-	optimizerEnabled: number;
-	artifactsDir: string;
+    contractsDir: string;
+    networkId: number;
+    optimizerEnabled: number;
+    artifactsDir: string;
 }
 
 export interface DeployerOptions {
-	artifactsDir: string;
-	jsonrpcPort: number;
-	networkId: number;
-	defaults: Partial<TxData>;
+    artifactsDir: string;
+    jsonrpcPort: number;
+    networkId: number;
+    defaults: Partial<TxData>;
 }
 
 export interface ContractSources {
-	[key: string]: string;
+    [key: string]: string;
 }
 
 export interface ImportContents {
-	contents: string;
+    contents: string;
 }
 
 // TODO: Consolidate with 0x.js definitions once types are moved into a separate package.
 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',
+    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',
 }
 
 export interface Token {
-	address?: string;
-	name: string;
-	symbol: string;
-	decimals: number;
-	ipfsHash: string;
-	swarmHash: string;
+    address?: string;
+    name: string;
+    symbol: string;
+    decimals: number;
+    ipfsHash: string;
+    swarmHash: string;
 }
 
 export type DoneCallback = (err?: Error) => void;
diff --git a/packages/deployer/src/utils/utils.ts b/packages/deployer/src/utils/utils.ts
index 931ad6f73..4390d8813 100644
--- a/packages/deployer/src/utils/utils.ts
+++ b/packages/deployer/src/utils/utils.ts
@@ -1,13 +1,13 @@
 export const utils = {
-	consoleLog(message: string): void {
-		/* tslint:disable */
-		console.log(message);
-		/* tslint:enable */
-	},
-	stringifyWithFormatting(obj: any): string {
-		const jsonReplacer: null = null;
-		const numberOfJsonSpaces = 4;
-		const stringifiedObj = JSON.stringify(obj, jsonReplacer, numberOfJsonSpaces);
-		return stringifiedObj;
-	},
+    consoleLog(message: string): void {
+        /* tslint:disable */
+        console.log(message);
+        /* tslint:enable */
+    },
+    stringifyWithFormatting(obj: any): string {
+        const jsonReplacer: null = null;
+        const numberOfJsonSpaces = 4;
+        const stringifiedObj = JSON.stringify(obj, jsonReplacer, numberOfJsonSpaces);
+        return stringifiedObj;
+    },
 };
diff --git a/packages/deployer/test/deploy_test.ts b/packages/deployer/test/deploy_test.ts
index 583601154..5df729a04 100644
--- a/packages/deployer/test/deploy_test.ts
+++ b/packages/deployer/test/deploy_test.ts
@@ -13,79 +13,79 @@ const artifactsDir = `${__dirname}/fixtures/artifacts`;
 const contractsDir = `${__dirname}/fixtures/contracts`;
 const exchangeArtifactPath = `${artifactsDir}/Exchange.json`;
 const compilerOpts: CompilerOptions = {
-	artifactsDir,
-	contractsDir,
-	networkId: constants.networkId,
-	optimizerEnabled: constants.optimizerEnabled,
+    artifactsDir,
+    contractsDir,
+    networkId: constants.networkId,
+    optimizerEnabled: constants.optimizerEnabled,
 };
 const compiler = new Compiler(compilerOpts);
 const deployerOpts = {
-	artifactsDir,
-	networkId: constants.networkId,
-	jsonrpcPort: constants.jsonrpcPort,
-	defaults: {
-		gasPrice: constants.gasPrice,
-	},
+    artifactsDir,
+    networkId: constants.networkId,
+    jsonrpcPort: constants.jsonrpcPort,
+    defaults: {
+        gasPrice: constants.gasPrice,
+    },
 };
 const deployer = new Deployer(deployerOpts);
 
 /* tslint:disable */
 beforeEach(function(done: DoneCallback) {
-	this.timeout(constants.timeoutMs);
-	(async () => {
-		if (fsWrapper.doesPathExistSync(exchangeArtifactPath)) {
-			await fsWrapper.removeFileAsync(exchangeArtifactPath);
-		}
-		await compiler.compileAllAsync();
-		done();
-	})().catch(done);
+    this.timeout(constants.timeoutMs);
+    (async () => {
+        if (fsWrapper.doesPathExistSync(exchangeArtifactPath)) {
+            await fsWrapper.removeFileAsync(exchangeArtifactPath);
+        }
+        await compiler.compileAllAsync();
+        done();
+    })().catch(done);
 });
 /* tslint:enable */
 
 describe('#Compiler', () => {
-	it('should create an Exchange artifact with the correct unlinked binary', async () => {
-		const opts = {
-			encoding: 'utf8',
-		};
-		const exchangeArtifactString = await fsWrapper.readFileAsync(exchangeArtifactPath, opts);
-		const exchangeArtifact: ContractArtifact = JSON.parse(exchangeArtifactString);
-		const exchangeContractData: ContractData = exchangeArtifact.networks[constants.networkId];
-		// The last 43 bytes of the binaries are metadata which may not be equivalent
-		const unlinkedBinaryWithoutMetadata = exchangeContractData.unlinked_binary.slice(0, -86);
-		const exchangeBinaryWithoutMetadata = exchange_binary.slice(0, -86);
-		expect(unlinkedBinaryWithoutMetadata).to.equal(exchangeBinaryWithoutMetadata);
-	});
+    it('should create an Exchange artifact with the correct unlinked binary', async () => {
+        const opts = {
+            encoding: 'utf8',
+        };
+        const exchangeArtifactString = await fsWrapper.readFileAsync(exchangeArtifactPath, opts);
+        const exchangeArtifact: ContractArtifact = JSON.parse(exchangeArtifactString);
+        const exchangeContractData: ContractData = exchangeArtifact.networks[constants.networkId];
+        // The last 43 bytes of the binaries are metadata which may not be equivalent
+        const unlinkedBinaryWithoutMetadata = exchangeContractData.unlinked_binary.slice(0, -86);
+        const exchangeBinaryWithoutMetadata = exchange_binary.slice(0, -86);
+        expect(unlinkedBinaryWithoutMetadata).to.equal(exchangeBinaryWithoutMetadata);
+    });
 });
 describe('#Deployer', () => {
-	describe('#deployAsync', () => {
-		it('should deploy the Exchange contract without updating the Exchange artifact', async () => {
-			const exchangeConstructorArgs = [constants.zrxTokenAddress, constants.tokenTransferProxyAddress];
-			const exchangeContractInstance = await deployer.deployAsync('Exchange', exchangeConstructorArgs);
-			const opts = {
-				encoding: 'utf8',
-			};
-			const exchangeArtifactString = await fsWrapper.readFileAsync(exchangeArtifactPath, opts);
-			const exchangeArtifact: ContractArtifact = JSON.parse(exchangeArtifactString);
-			const exchangeContractData: ContractData = exchangeArtifact.networks[constants.networkId];
-			const exchangeAddress = exchangeContractInstance.address;
-			expect(exchangeAddress).to.not.equal(undefined);
-			expect(exchangeContractData.address).to.equal(undefined);
-			expect(exchangeContractData.constructor_args).to.equal(undefined);
-		});
-	});
-	describe('#deployAndSaveAsync', () => {
-		it('should save the correct contract address and constructor arguments to the Exchange artifact', async () => {
-			const exchangeConstructorArgs = [constants.zrxTokenAddress, constants.tokenTransferProxyAddress];
-			const exchangeContractInstance = await deployer.deployAndSaveAsync('Exchange', exchangeConstructorArgs);
-			const opts = {
-				encoding: 'utf8',
-			};
-			const exchangeArtifactString = await fsWrapper.readFileAsync(exchangeArtifactPath, opts);
-			const exchangeArtifact: ContractArtifact = JSON.parse(exchangeArtifactString);
-			const exchangeContractData: ContractData = exchangeArtifact.networks[constants.networkId];
-			const exchangeAddress = exchangeContractInstance.address;
-			expect(exchangeAddress).to.be.equal(exchangeContractData.address);
-			expect(constructor_args).to.be.equal(exchangeContractData.constructor_args);
-		});
-	});
+    describe('#deployAsync', () => {
+        it('should deploy the Exchange contract without updating the Exchange artifact', async () => {
+            const exchangeConstructorArgs = [constants.zrxTokenAddress, constants.tokenTransferProxyAddress];
+            const exchangeContractInstance = await deployer.deployAsync('Exchange', exchangeConstructorArgs);
+            const opts = {
+                encoding: 'utf8',
+            };
+            const exchangeArtifactString = await fsWrapper.readFileAsync(exchangeArtifactPath, opts);
+            const exchangeArtifact: ContractArtifact = JSON.parse(exchangeArtifactString);
+            const exchangeContractData: ContractData = exchangeArtifact.networks[constants.networkId];
+            const exchangeAddress = exchangeContractInstance.address;
+            expect(exchangeAddress).to.not.equal(undefined);
+            expect(exchangeContractData.address).to.equal(undefined);
+            expect(exchangeContractData.constructor_args).to.equal(undefined);
+        });
+    });
+    describe('#deployAndSaveAsync', () => {
+        it('should save the correct contract address and constructor arguments to the Exchange artifact', async () => {
+            const exchangeConstructorArgs = [constants.zrxTokenAddress, constants.tokenTransferProxyAddress];
+            const exchangeContractInstance = await deployer.deployAndSaveAsync('Exchange', exchangeConstructorArgs);
+            const opts = {
+                encoding: 'utf8',
+            };
+            const exchangeArtifactString = await fsWrapper.readFileAsync(exchangeArtifactPath, opts);
+            const exchangeArtifact: ContractArtifact = JSON.parse(exchangeArtifactString);
+            const exchangeContractData: ContractData = exchangeArtifact.networks[constants.networkId];
+            const exchangeAddress = exchangeContractInstance.address;
+            expect(exchangeAddress).to.be.equal(exchangeContractData.address);
+            expect(constructor_args).to.be.equal(exchangeContractData.constructor_args);
+        });
+    });
 });
diff --git a/packages/deployer/test/fixtures/exchange_bin.ts b/packages/deployer/test/fixtures/exchange_bin.ts
index 9c58b5e02..a6eae515e 100644
--- a/packages/deployer/test/fixtures/exchange_bin.ts
+++ b/packages/deployer/test/fixtures/exchange_bin.ts
@@ -1,4 +1,4 @@
 export const constructor_args =
-	'0x000000000000000000000000e41d2489571d322189246dafa5ebde1f4699f4980000000000000000000000008da0d80f5007ef1e431dd2127178d224e32c2ef4';
+    '0x000000000000000000000000e41d2489571d322189246dafa5ebde1f4699f4980000000000000000000000008da0d80f5007ef1e431dd2127178d224e32c2ef4';
 export const exchange_binary =
-	'0x6060604052341561000f57600080fd5b604051604080612c4d833981016040528080519060200190919080519060200190919050505b816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b50505b612b84806100c96000396000f300606060405236156100fa576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806314df96ee146100ff578063288cdc911461014c5780632ac1262214610187578063363349be146101c2578063394c21e7146103bc5780633b30ba591461044b5780634f150787146104a0578063741bcc93146106b25780637e9abb50146107535780638163681e1461078e57806398024a8b14610812578063add1cbc51461085b578063b7b2c7d6146108b0578063baa0181d14610acd578063bc61394a14610c1f578063cfc4d0ec14610cdf578063f06bbf7514610d6d578063ffa1ad7414610d9e575b600080fd5b341561010a57600080fd5b6101326004808035906020019091908035906020019091908035906020019091905050610e2d565b604051808215151515815260200191505060405180910390f35b341561015757600080fd5b610171600480803560001916906020019091905050610e7c565b6040518082815260200191505060405180910390f35b341561019257600080fd5b6101ac600480803560001916906020019091905050610e94565b6040518082815260200191505060405180910390f35b34156101cd57600080fd5b6103a660048080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b8282101561024857848483905060a002016005806020026040519081016040528092919082600560200280828437820191505050505081526020019060010190610203565b5050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b828210156102c457848483905060c00201600680602002604051908101604052809291908260066020028082843782019150505050508152602001906001019061027f565b5050505050919080359060200190919080351515906020019091908035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091905050610eac565b6040518082815260200191505060405180910390f35b34156103c757600080fd5b6104356004808060a001906005806020026040519081016040528092919082600560200280828437820191505050505091908060c001906006806020026040519081016040528092919082600660200280828437820191505050505091908035906020019091905050611013565b6040518082815260200191505060405180910390f35b341561045657600080fd5b61045e6114fb565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156104ab57600080fd5b6106b060048080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b8282101561052657848483905060a0020160058060200260405190810160405280929190826005602002808284378201915050505050815260200190600101906104e1565b5050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b828210156105a257848483905060c00201600680602002604051908101604052809291908260066020028082843782019150505050508152602001906001019061055d565b50505050509190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091908035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091905050611520565b005b34156106bd57600080fd5b6107516004808060a001906005806020026040519081016040528092919082600560200280828437820191505050505091908060c00190600680602002604051908101604052809291908260066020028082843782019150505050509190803590602001909190803560ff1690602001909190803560001916906020019091908035600019169060200190919050506115df565b005b341561075e57600080fd5b610778600480803560001916906020019091905050611605565b6040518082815260200191505060405180910390f35b341561079957600080fd5b6107f8600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919080356000191690602001909190803560ff16906020019091908035600019169060200190919080356000191690602001909190505061164f565b604051808215151515815260200191505060405180910390f35b341561081d57600080fd5b6108456004808035906020019091908035906020019091908035906020019091905050611757565b6040518082815260200191505060405180910390f35b341561086657600080fd5b61086e611776565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156108bb57600080fd5b610acb60048080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b8282101561093657848483905060a0020160058060200260405190810160405280929190826005602002808284378201915050505050815260200190600101906108f1565b5050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b828210156109b257848483905060c00201600680602002604051908101604052809291908260066020028082843782019150505050508152602001906001019061096d565b50505050509190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091908035151590602001909190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091908035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509190505061179c565b005b3415610ad857600080fd5b610c1d60048080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b82821015610b5357848483905060a002016005806020026040519081016040528092919082600560200280828437820191505050505081526020019060010190610b0e565b5050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b82821015610bcf57848483905060c002016006806020026040519081016040528092919082600660200280828437820191505050505081526020019060010190610b8a565b5050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509190505061185e565b005b3415610c2a57600080fd5b610cc96004808060a001906005806020026040519081016040528092919082600560200280828437820191505050505091908060c001906006806020026040519081016040528092919082600660200280828437820191505050505091908035906020019091908035151590602001909190803560ff1690602001909190803560001916906020019091908035600019169060200190919050506118d3565b6040518082815260200191505060405180910390f35b3415610cea57600080fd5b610d4f6004808060a001906005806020026040519081016040528092919082600560200280828437820191505050505091908060c001906006806020026040519081016040528092919082600660200280828437820191505050505091905050612073565b60405180826000191660001916815260200191505060405180910390f35b3415610d7857600080fd5b610d8061231f565b604051808261ffff1661ffff16815260200191505060405180910390f35b3415610da957600080fd5b610db1612325565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610df25780820151818401525b602081019050610dd6565b50505050905090810190601f168015610e1f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60008060008486850991506000821415610e4a5760009250610e73565b610e69610e5a83620f424061235e565b610e64888761235e565b612392565b90506103e8811192505b50509392505050565b60026020528060005260406000206000915090505481565b60036020528060005260406000206000915090505481565b6000806000809150600090505b895181101561100257896000815181101515610ed157fe5b906020019060200201516003600581101515610ee957fe5b602002015173ffffffffffffffffffffffffffffffffffffffff168a82815181101515610f1257fe5b906020019060200201516003600581101515610f2a57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff16141515610f5157600080fd5b610fe582610fe08c84815181101515610f6657fe5b906020019060200201518c85815181101515610f7e57fe5b90602001906020020151610f928d886123ae565b8c8c88815181101515610fa157fe5b906020019060200201518c89815181101515610fb957fe5b906020019060200201518c8a815181101515610fd157fe5b906020019060200201516118d3565b6123c8565b915087821415610ff457611002565b5b8080600101915050610eb9565b8192505b5050979650505050505050565b600061101d612a8c565b6000806101606040519081016040528088600060058110151561103c57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff16815260200188600160058110151561106b57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff16815260200188600260058110151561109a57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018860036005811015156110c957fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018860046005811015156110f857fe5b602002015173ffffffffffffffffffffffffffffffffffffffff16815260200187600060068110151561112757fe5b6020020151815260200187600160068110151561114057fe5b6020020151815260200187600260068110151561115957fe5b6020020151815260200187600360068110151561117257fe5b6020020151815260200187600460068110151561118b57fe5b6020020151815260200161119f8989612073565b6000191681525092503373ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff161415156111e657600080fd5b60008360a001511180156111fe575060008360c00151115b801561120a5750600085115b151561121557600080fd5b8261012001514210151561127257826101400151600019166000600381111561123a57fe5b60ff167f36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e9060405160405180910390a3600093506114f1565b61128d8360c00151611288856101400151611605565b6123ae565b915061129985836123e7565b905060008114156112f35782610140015160001916600160038111156112bb57fe5b60ff167f36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e9060405160405180910390a3600093506114f1565b61131d600360008561014001516000191660001916815260200190815260200160002054826123c8565b60036000856101400151600019166000191681526020019081526020016000208190555082604001518360600151604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c0100000000000000000000000002815260140192505050604051809103902060001916836080015173ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff167f67d66f160bc93d925d05dae1794c90d2d6d6688b29b84ff069398a9b0458713186604001518760600151611455878a60c001518b60a00151611757565b878a6101400151604051808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200184815260200183815260200182600019166000191681526020019550505050505060405180910390a48093505b5050509392505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008090505b86518110156115d5576115c7878281518110151561154057fe5b90602001906020020151878381518110151561155857fe5b90602001906020020151878481518110151561157057fe5b90602001906020020151878581518110151561158857fe5b9060200190602002015187868151811015156115a057fe5b9060200190602002015187878151811015156115b857fe5b906020019060200201516115df565b5b8080600101915050611526565b5b50505050505050565b836115f087878760008888886118d3565b1415156115fc57600080fd5b5b505050505050565b600061164760026000846000191660001916815260200190815260200160002054600360008560001916600019168152602001908152602001600020546123c8565b90505b919050565b600060018560405180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c0182600019166000191681526020019150506040518091039020858585604051600081526020016040526000604051602001526040518085600019166000191681526020018460ff1660ff16815260200183600019166000191681526020018260001916600019168152602001945050505050602060405160208103908084039060008661646e5a03f1151561171457600080fd5b50506020604051035173ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161490505b95945050505050565b600061176c611766858461235e565b84612392565b90505b9392505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008090505b87518110156118535761184488828151811015156117bc57fe5b9060200190602002015188838151811015156117d457fe5b9060200190602002015188848151811015156117ec57fe5b9060200190602002015188888681518110151561180557fe5b90602001906020020151888781518110151561181d57fe5b90602001906020020151888881518110151561183557fe5b906020019060200201516118d3565b505b80806001019150506117a2565b5b5050505050505050565b60008090505b83518110156118cc576118bd848281518110151561187e57fe5b90602001906020020151848381518110151561189657fe5b9060200190602002015184848151811015156118ae57fe5b90602001906020020151611013565b505b8080600101915050611864565b5b50505050565b60006118dd612a8c565b600080600080610160604051908101604052808e60006005811015156118ff57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018e600160058110151561192e57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018e600260058110151561195d57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018e600360058110151561198c57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018e60046005811015156119bb57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018d60006006811015156119ea57fe5b602002015181526020018d6001600681101515611a0357fe5b602002015181526020018d6002600681101515611a1c57fe5b602002015181526020018d6003600681101515611a3557fe5b602002015181526020018d6004600681101515611a4e57fe5b60200201518152602001611a628f8f612073565b600019168152509450600073ffffffffffffffffffffffffffffffffffffffff16856020015173ffffffffffffffffffffffffffffffffffffffff161480611ad957503373ffffffffffffffffffffffffffffffffffffffff16856020015173ffffffffffffffffffffffffffffffffffffffff16145b1515611ae457600080fd5b60008560a00151118015611afc575060008560c00151115b8015611b08575060008b115b1515611b1357600080fd5b611b2985600001518661014001518b8b8b61164f565b1515611b3457600080fd5b84610120015142101515611b91578461014001516000191660006003811115611b5957fe5b60ff167f36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e9060405160405180910390a360009550612063565b611bac8560c00151611ba7876101400151611605565b6123ae565b9350611bb88b856123e7565b95506000861415611c12578461014001516000191660016003811115611bda57fe5b60ff167f36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e9060405160405180910390a360009550612063565b611c25868660c001518760a00151610e2d565b15611c79578461014001516000191660026003811115611c4157fe5b60ff167f36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e9060405160405180910390a360009550612063565b89158015611c8e5750611c8c8587612401565b155b15611ce15784610140015160001916600380811115611ca957fe5b60ff167f36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e9060405160405180910390a360009550612063565b611cf4868660c001518760a00151611757565b9250611d20600260008761014001516000191660001916815260200190815260200160002054876123c8565b600260008761014001516000191660001916815260200190815260200160002081905550611d58856040015186600001513386612751565b1515611d6357600080fd5b611d77856060015133876000015189612751565b1515611d8257600080fd5b600073ffffffffffffffffffffffffffffffffffffffff16856080015173ffffffffffffffffffffffffffffffffffffffff16141515611e815760008560e001511115611e1f57611ddc868660c001518760e00151611757565b9150611e136000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168660000151876080015185612751565b1515611e1e57600080fd5b5b60008561010001511115611e8057611e41868660c00151876101000151611757565b9050611e746000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1633876080015184612751565b1515611e7f57600080fd5b5b5b84604001518560600151604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c0100000000000000000000000002815260140192505050604051809103902060001916856080015173ffffffffffffffffffffffffffffffffffffffff16866000015173ffffffffffffffffffffffffffffffffffffffff167f0d0b9391970d9a25552f37d436d2aae2925e2bfe1b2a923754bada030c498cb33389604001518a60600151898d8a8a8f6101400151604051808973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200186815260200185815260200184815260200183815260200182600019166000191681526020019850505050505050505060405180910390a48595505b5050505050979650505050505050565b60003083600060058110151561208557fe5b602002015184600160058110151561209957fe5b60200201518560026005811015156120ad57fe5b60200201518660036005811015156120c157fe5b60200201518760046005811015156120d557fe5b60200201518760006006811015156120e957fe5b60200201518860016006811015156120fd57fe5b602002015189600260068110151561211157fe5b60200201518a600360068110151561212557fe5b60200201518b600460068110151561213957fe5b60200201518c600560068110151561214d57fe5b6020020151604051808d73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018781526020018681526020018581526020018481526020018381526020018281526020019c50505050505050505050505050604051809103902090505b92915050565b61138781565b6040805190810160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b6000808284029050600084148061237f575082848281151561237c57fe5b04145b151561238757fe5b8091505b5092915050565b60008082848115156123a057fe5b0490508091505b5092915050565b60008282111515156123bc57fe5b81830390505b92915050565b60008082840190508381101515156123dc57fe5b8091505b5092915050565b60008183106123f657816123f8565b825b90505b92915050565b60008060008060008060008060003397506124258a8c60c001518d60a00151611757565b9650600073ffffffffffffffffffffffffffffffffffffffff168b6080015173ffffffffffffffffffffffffffffffffffffffff161415156126d2576000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168b6040015173ffffffffffffffffffffffffffffffffffffffff161495506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168b6060015173ffffffffffffffffffffffffffffffffffffffff161494506125208a8c60c001518d60e00151611757565b93506125368a8c60c001518d6101000151611757565b925085612543578361254e565b61254d87856123c8565b5b91508461255b5782612566565b6125658a846123c8565b5b9050816125986000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168d600001516128ae565b10806125d15750816125cf6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168d60000151612972565b105b806126055750806126036000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168a6128ae565b105b806126395750806126376000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168a612972565b105b156126475760009850612743565b851580156126805750866126638c604001518d600001516128ae565b108061267f57508661267d8c604001518d60000151612972565b105b5b1561268e5760009850612743565b841580156126bf5750896126a68c606001518a6128ae565b10806126be5750896126bc8c606001518a612972565b105b5b156126cd5760009850612743565b61273e565b866126e58c604001518d600001516128ae565b10806127015750866126ff8c604001518d60000151612972565b105b806127185750896127168c606001518a6128ae565b105b8061272f57508961272d8c606001518a612972565b105b1561273d5760009850612743565b5b600198505b505050505050505092915050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166315dacbea868686866000604051602001526040518563ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001945050505050602060405180830381600087803b151561288857600080fd5b6102c65a03f1151561289957600080fd5b5050506040518051905090505b949350505050565b60008273ffffffffffffffffffffffffffffffffffffffff166370a0823161138761ffff16846040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600088803b151561295157600080fd5b87f1151561295e57600080fd5b505050506040518051905090505b92915050565b60008273ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e61138761ffff1684600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050602060405180830381600088803b1515612a6b57600080fd5b87f11515612a7857600080fd5b505050506040518051905090505b92915050565b61016060405190810160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160008152602001600081526020016000815260200160008152602001600081526020016000801916815250905600a165627a7a72305820df5cabdc3a116e993e10bfb14823d18d9b798038d4c463a1703f9a584c456b7e0029';
+    '0x6060604052341561000f57600080fd5b604051604080612c4d833981016040528080519060200190919080519060200190919050505b816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b50505b612b84806100c96000396000f300606060405236156100fa576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806314df96ee146100ff578063288cdc911461014c5780632ac1262214610187578063363349be146101c2578063394c21e7146103bc5780633b30ba591461044b5780634f150787146104a0578063741bcc93146106b25780637e9abb50146107535780638163681e1461078e57806398024a8b14610812578063add1cbc51461085b578063b7b2c7d6146108b0578063baa0181d14610acd578063bc61394a14610c1f578063cfc4d0ec14610cdf578063f06bbf7514610d6d578063ffa1ad7414610d9e575b600080fd5b341561010a57600080fd5b6101326004808035906020019091908035906020019091908035906020019091905050610e2d565b604051808215151515815260200191505060405180910390f35b341561015757600080fd5b610171600480803560001916906020019091905050610e7c565b6040518082815260200191505060405180910390f35b341561019257600080fd5b6101ac600480803560001916906020019091905050610e94565b6040518082815260200191505060405180910390f35b34156101cd57600080fd5b6103a660048080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b8282101561024857848483905060a002016005806020026040519081016040528092919082600560200280828437820191505050505081526020019060010190610203565b5050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b828210156102c457848483905060c00201600680602002604051908101604052809291908260066020028082843782019150505050508152602001906001019061027f565b5050505050919080359060200190919080351515906020019091908035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091905050610eac565b6040518082815260200191505060405180910390f35b34156103c757600080fd5b6104356004808060a001906005806020026040519081016040528092919082600560200280828437820191505050505091908060c001906006806020026040519081016040528092919082600660200280828437820191505050505091908035906020019091905050611013565b6040518082815260200191505060405180910390f35b341561045657600080fd5b61045e6114fb565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156104ab57600080fd5b6106b060048080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b8282101561052657848483905060a0020160058060200260405190810160405280929190826005602002808284378201915050505050815260200190600101906104e1565b5050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b828210156105a257848483905060c00201600680602002604051908101604052809291908260066020028082843782019150505050508152602001906001019061055d565b50505050509190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091908035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091905050611520565b005b34156106bd57600080fd5b6107516004808060a001906005806020026040519081016040528092919082600560200280828437820191505050505091908060c00190600680602002604051908101604052809291908260066020028082843782019150505050509190803590602001909190803560ff1690602001909190803560001916906020019091908035600019169060200190919050506115df565b005b341561075e57600080fd5b610778600480803560001916906020019091905050611605565b6040518082815260200191505060405180910390f35b341561079957600080fd5b6107f8600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919080356000191690602001909190803560ff16906020019091908035600019169060200190919080356000191690602001909190505061164f565b604051808215151515815260200191505060405180910390f35b341561081d57600080fd5b6108456004808035906020019091908035906020019091908035906020019091905050611757565b6040518082815260200191505060405180910390f35b341561086657600080fd5b61086e611776565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156108bb57600080fd5b610acb60048080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b8282101561093657848483905060a0020160058060200260405190810160405280929190826005602002808284378201915050505050815260200190600101906108f1565b5050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b828210156109b257848483905060c00201600680602002604051908101604052809291908260066020028082843782019150505050508152602001906001019061096d565b50505050509190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091908035151590602001909190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091908035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509190505061179c565b005b3415610ad857600080fd5b610c1d60048080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b82821015610b5357848483905060a002016005806020026040519081016040528092919082600560200280828437820191505050505081526020019060010190610b0e565b5050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b82821015610bcf57848483905060c002016006806020026040519081016040528092919082600660200280828437820191505050505081526020019060010190610b8a565b5050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509190505061185e565b005b3415610c2a57600080fd5b610cc96004808060a001906005806020026040519081016040528092919082600560200280828437820191505050505091908060c001906006806020026040519081016040528092919082600660200280828437820191505050505091908035906020019091908035151590602001909190803560ff1690602001909190803560001916906020019091908035600019169060200190919050506118d3565b6040518082815260200191505060405180910390f35b3415610cea57600080fd5b610d4f6004808060a001906005806020026040519081016040528092919082600560200280828437820191505050505091908060c001906006806020026040519081016040528092919082600660200280828437820191505050505091905050612073565b60405180826000191660001916815260200191505060405180910390f35b3415610d7857600080fd5b610d8061231f565b604051808261ffff1661ffff16815260200191505060405180910390f35b3415610da957600080fd5b610db1612325565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610df25780820151818401525b602081019050610dd6565b50505050905090810190601f168015610e1f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60008060008486850991506000821415610e4a5760009250610e73565b610e69610e5a83620f424061235e565b610e64888761235e565b612392565b90506103e8811192505b50509392505050565b60026020528060005260406000206000915090505481565b60036020528060005260406000206000915090505481565b6000806000809150600090505b895181101561100257896000815181101515610ed157fe5b906020019060200201516003600581101515610ee957fe5b602002015173ffffffffffffffffffffffffffffffffffffffff168a82815181101515610f1257fe5b906020019060200201516003600581101515610f2a57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff16141515610f5157600080fd5b610fe582610fe08c84815181101515610f6657fe5b906020019060200201518c85815181101515610f7e57fe5b90602001906020020151610f928d886123ae565b8c8c88815181101515610fa157fe5b906020019060200201518c89815181101515610fb957fe5b906020019060200201518c8a815181101515610fd157fe5b906020019060200201516118d3565b6123c8565b915087821415610ff457611002565b5b8080600101915050610eb9565b8192505b5050979650505050505050565b600061101d612a8c565b6000806101606040519081016040528088600060058110151561103c57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff16815260200188600160058110151561106b57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff16815260200188600260058110151561109a57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018860036005811015156110c957fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018860046005811015156110f857fe5b602002015173ffffffffffffffffffffffffffffffffffffffff16815260200187600060068110151561112757fe5b6020020151815260200187600160068110151561114057fe5b6020020151815260200187600260068110151561115957fe5b6020020151815260200187600360068110151561117257fe5b6020020151815260200187600460068110151561118b57fe5b6020020151815260200161119f8989612073565b6000191681525092503373ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff161415156111e657600080fd5b60008360a001511180156111fe575060008360c00151115b801561120a5750600085115b151561121557600080fd5b8261012001514210151561127257826101400151600019166000600381111561123a57fe5b60ff167f36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e9060405160405180910390a3600093506114f1565b61128d8360c00151611288856101400151611605565b6123ae565b915061129985836123e7565b905060008114156112f35782610140015160001916600160038111156112bb57fe5b60ff167f36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e9060405160405180910390a3600093506114f1565b61131d600360008561014001516000191660001916815260200190815260200160002054826123c8565b60036000856101400151600019166000191681526020019081526020016000208190555082604001518360600151604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c0100000000000000000000000002815260140192505050604051809103902060001916836080015173ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff167f67d66f160bc93d925d05dae1794c90d2d6d6688b29b84ff069398a9b0458713186604001518760600151611455878a60c001518b60a00151611757565b878a6101400151604051808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200184815260200183815260200182600019166000191681526020019550505050505060405180910390a48093505b5050509392505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008090505b86518110156115d5576115c7878281518110151561154057fe5b90602001906020020151878381518110151561155857fe5b90602001906020020151878481518110151561157057fe5b90602001906020020151878581518110151561158857fe5b9060200190602002015187868151811015156115a057fe5b9060200190602002015187878151811015156115b857fe5b906020019060200201516115df565b5b8080600101915050611526565b5b50505050505050565b836115f087878760008888886118d3565b1415156115fc57600080fd5b5b505050505050565b600061164760026000846000191660001916815260200190815260200160002054600360008560001916600019168152602001908152602001600020546123c8565b90505b919050565b600060018560405180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c0182600019166000191681526020019150506040518091039020858585604051600081526020016040526000604051602001526040518085600019166000191681526020018460ff1660ff16815260200183600019166000191681526020018260001916600019168152602001945050505050602060405160208103908084039060008661646e5a03f1151561171457600080fd5b50506020604051035173ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161490505b95945050505050565b600061176c611766858461235e565b84612392565b90505b9392505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008090505b87518110156118535761184488828151811015156117bc57fe5b9060200190602002015188838151811015156117d457fe5b9060200190602002015188848151811015156117ec57fe5b9060200190602002015188888681518110151561180557fe5b90602001906020020151888781518110151561181d57fe5b90602001906020020151888881518110151561183557fe5b906020019060200201516118d3565b505b80806001019150506117a2565b5b5050505050505050565b60008090505b83518110156118cc576118bd848281518110151561187e57fe5b90602001906020020151848381518110151561189657fe5b9060200190602002015184848151811015156118ae57fe5b90602001906020020151611013565b505b8080600101915050611864565b5b50505050565b60006118dd612a8c565b600080600080610160604051908101604052808e60006005811015156118ff57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018e600160058110151561192e57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018e600260058110151561195d57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018e600360058110151561198c57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018e60046005811015156119bb57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018d60006006811015156119ea57fe5b602002015181526020018d6001600681101515611a0357fe5b602002015181526020018d6002600681101515611a1c57fe5b602002015181526020018d6003600681101515611a3557fe5b602002015181526020018d6004600681101515611a4e57fe5b60200201518152602001611a628f8f612073565b600019168152509450600073ffffffffffffffffffffffffffffffffffffffff16856020015173ffffffffffffffffffffffffffffffffffffffff161480611ad957503373ffffffffffffffffffffffffffffffffffffffff16856020015173ffffffffffffffffffffffffffffffffffffffff16145b1515611ae457600080fd5b60008560a00151118015611afc575060008560c00151115b8015611b08575060008b115b1515611b1357600080fd5b611b2985600001518661014001518b8b8b61164f565b1515611b3457600080fd5b84610120015142101515611b91578461014001516000191660006003811115611b5957fe5b60ff167f36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e9060405160405180910390a360009550612063565b611bac8560c00151611ba7876101400151611605565b6123ae565b9350611bb88b856123e7565b95506000861415611c12578461014001516000191660016003811115611bda57fe5b60ff167f36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e9060405160405180910390a360009550612063565b611c25868660c001518760a00151610e2d565b15611c79578461014001516000191660026003811115611c4157fe5b60ff167f36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e9060405160405180910390a360009550612063565b89158015611c8e5750611c8c8587612401565b155b15611ce15784610140015160001916600380811115611ca957fe5b60ff167f36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e9060405160405180910390a360009550612063565b611cf4868660c001518760a00151611757565b9250611d20600260008761014001516000191660001916815260200190815260200160002054876123c8565b600260008761014001516000191660001916815260200190815260200160002081905550611d58856040015186600001513386612751565b1515611d6357600080fd5b611d77856060015133876000015189612751565b1515611d8257600080fd5b600073ffffffffffffffffffffffffffffffffffffffff16856080015173ffffffffffffffffffffffffffffffffffffffff16141515611e815760008560e001511115611e1f57611ddc868660c001518760e00151611757565b9150611e136000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168660000151876080015185612751565b1515611e1e57600080fd5b5b60008561010001511115611e8057611e41868660c00151876101000151611757565b9050611e746000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1633876080015184612751565b1515611e7f57600080fd5b5b5b84604001518560600151604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c0100000000000000000000000002815260140192505050604051809103902060001916856080015173ffffffffffffffffffffffffffffffffffffffff16866000015173ffffffffffffffffffffffffffffffffffffffff167f0d0b9391970d9a25552f37d436d2aae2925e2bfe1b2a923754bada030c498cb33389604001518a60600151898d8a8a8f6101400151604051808973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200186815260200185815260200184815260200183815260200182600019166000191681526020019850505050505050505060405180910390a48595505b5050505050979650505050505050565b60003083600060058110151561208557fe5b602002015184600160058110151561209957fe5b60200201518560026005811015156120ad57fe5b60200201518660036005811015156120c157fe5b60200201518760046005811015156120d557fe5b60200201518760006006811015156120e957fe5b60200201518860016006811015156120fd57fe5b602002015189600260068110151561211157fe5b60200201518a600360068110151561212557fe5b60200201518b600460068110151561213957fe5b60200201518c600560068110151561214d57fe5b6020020151604051808d73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018781526020018681526020018581526020018481526020018381526020018281526020019c50505050505050505050505050604051809103902090505b92915050565b61138781565b6040805190810160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b6000808284029050600084148061237f575082848281151561237c57fe5b04145b151561238757fe5b8091505b5092915050565b60008082848115156123a057fe5b0490508091505b5092915050565b60008282111515156123bc57fe5b81830390505b92915050565b60008082840190508381101515156123dc57fe5b8091505b5092915050565b60008183106123f657816123f8565b825b90505b92915050565b60008060008060008060008060003397506124258a8c60c001518d60a00151611757565b9650600073ffffffffffffffffffffffffffffffffffffffff168b6080015173ffffffffffffffffffffffffffffffffffffffff161415156126d2576000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168b6040015173ffffffffffffffffffffffffffffffffffffffff161495506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168b6060015173ffffffffffffffffffffffffffffffffffffffff161494506125208a8c60c001518d60e00151611757565b93506125368a8c60c001518d6101000151611757565b925085612543578361254e565b61254d87856123c8565b5b91508461255b5782612566565b6125658a846123c8565b5b9050816125986000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168d600001516128ae565b10806125d15750816125cf6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168d60000151612972565b105b806126055750806126036000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168a6128ae565b105b806126395750806126376000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168a612972565b105b156126475760009850612743565b851580156126805750866126638c604001518d600001516128ae565b108061267f57508661267d8c604001518d60000151612972565b105b5b1561268e5760009850612743565b841580156126bf5750896126a68c606001518a6128ae565b10806126be5750896126bc8c606001518a612972565b105b5b156126cd5760009850612743565b61273e565b866126e58c604001518d600001516128ae565b10806127015750866126ff8c604001518d60000151612972565b105b806127185750896127168c606001518a6128ae565b105b8061272f57508961272d8c606001518a612972565b105b1561273d5760009850612743565b5b600198505b505050505050505092915050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166315dacbea868686866000604051602001526040518563ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001945050505050602060405180830381600087803b151561288857600080fd5b6102c65a03f1151561289957600080fd5b5050506040518051905090505b949350505050565b60008273ffffffffffffffffffffffffffffffffffffffff166370a0823161138761ffff16846040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600088803b151561295157600080fd5b87f1151561295e57600080fd5b505050506040518051905090505b92915050565b60008273ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e61138761ffff1684600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050602060405180830381600088803b1515612a6b57600080fd5b87f11515612a7857600080fd5b505050506040518051905090505b92915050565b61016060405190810160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160008152602001600081526020016000815260200160008152602001600081526020016000801916815250905600a165627a7a72305820df5cabdc3a116e993e10bfb14823d18d9b798038d4c463a1703f9a584c456b7e0029';
diff --git a/packages/deployer/test/util/constants.ts b/packages/deployer/test/util/constants.ts
index d69ce5385..d52076607 100644
--- a/packages/deployer/test/util/constants.ts
+++ b/packages/deployer/test/util/constants.ts
@@ -1,11 +1,11 @@
 import { BigNumber } from '@0xproject/utils';
 
 export const constants = {
-	networkId: 0,
-	jsonrpcPort: 8545,
-	optimizerEnabled: 0,
-	gasPrice: new BigNumber(20000000000),
-	timeoutMs: 20000,
-	zrxTokenAddress: '0xe41d2489571d322189246dafa5ebde1f4699f498',
-	tokenTransferProxyAddress: '0x8da0d80f5007ef1e431dd2127178d224e32c2ef4',
+    networkId: 0,
+    jsonrpcPort: 8545,
+    optimizerEnabled: 0,
+    gasPrice: new BigNumber(20000000000),
+    timeoutMs: 20000,
+    zrxTokenAddress: '0xe41d2489571d322189246dafa5ebde1f4699f498',
+    tokenTransferProxyAddress: '0x8da0d80f5007ef1e431dd2127178d224e32c2ef4',
 };
diff --git a/packages/deployer/tsconfig.json b/packages/deployer/tsconfig.json
index f11c9245e..4e1edb510 100644
--- a/packages/deployer/tsconfig.json
+++ b/packages/deployer/tsconfig.json
@@ -1,16 +1,16 @@
 {
-	"extends": "../../tsconfig",
-	"compilerOptions": {
-		"outDir": "lib",
-		"strictFunctionTypes": false,
-		"strictNullChecks": false
-	},
-	"include": [
-		"./src/**/*",
-		"./test/**/*",
-		"../../node_modules/types-bn/index.d.ts",
-		"../../node_modules/types-ethereumjs-util/index.d.ts",
-		"../../node_modules/chai-typescript-typings/index.d.ts",
-		"../../node_modules/web3-typescript-typings/index.d.ts"
-	]
+    "extends": "../../tsconfig",
+    "compilerOptions": {
+        "outDir": "lib",
+        "strictFunctionTypes": false,
+        "strictNullChecks": false
+    },
+    "include": [
+        "./src/**/*",
+        "./test/**/*",
+        "../../node_modules/types-bn/index.d.ts",
+        "../../node_modules/types-ethereumjs-util/index.d.ts",
+        "../../node_modules/chai-typescript-typings/index.d.ts",
+        "../../node_modules/web3-typescript-typings/index.d.ts"
+    ]
 }
diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json
index d7c764285..ea940fb1d 100644
--- a/packages/dev-utils/package.json
+++ b/packages/dev-utils/package.json
@@ -1,37 +1,37 @@
 {
-	"name": "@0xproject/dev-utils",
-	"version": "0.0.7",
-	"description": "0x dev TS utils",
-	"main": "lib/index.js",
-	"types": "lib/index.d.ts",
-	"scripts": {
-		"build": "tsc",
-		"clean": "shx rm -rf lib",
-		"lint": "tslint --project . 'src/**/*.ts'"
-	},
-	"license": "Apache-2.0",
-	"repository": {
-		"type": "git",
-		"url": "https://github.com/0xProject/0x.js.git"
-	},
-	"bugs": {
-		"url": "https://github.com/0xProject/0x.js/issues"
-	},
-	"homepage": "https://github.com/0xProject/0x.js/packages/dev-utils/README.md",
-	"devDependencies": {
-		"@0xproject/tslint-config": "^0.4.4",
-		"@types/lodash": "^4.14.86",
-		"npm-run-all": "^4.1.2",
-		"shx": "^0.2.2",
-		"tslint": "5.8.0",
-		"types-bn": "^0.0.1",
-		"types-ethereumjs-util": "0xProject/types-ethereumjs-util",
-		"typescript": "~2.6.1"
-	},
-	"dependencies": {
-		"@0xproject/utils": "^0.2.2",
-		"ethereumjs-util": "^5.1.2",
-		"lodash": "^4.17.4",
-		"request-promise-native": "^1.0.5"
-	}
+    "name": "@0xproject/dev-utils",
+    "version": "0.0.7",
+    "description": "0x dev TS utils",
+    "main": "lib/index.js",
+    "types": "lib/index.d.ts",
+    "scripts": {
+        "build": "tsc",
+        "clean": "shx rm -rf lib",
+        "lint": "tslint --project . 'src/**/*.ts'"
+    },
+    "license": "Apache-2.0",
+    "repository": {
+        "type": "git",
+        "url": "https://github.com/0xProject/0x.js.git"
+    },
+    "bugs": {
+        "url": "https://github.com/0xProject/0x.js/issues"
+    },
+    "homepage": "https://github.com/0xProject/0x.js/packages/dev-utils/README.md",
+    "devDependencies": {
+        "@0xproject/tslint-config": "^0.4.4",
+        "@types/lodash": "^4.14.86",
+        "npm-run-all": "^4.1.2",
+        "shx": "^0.2.2",
+        "tslint": "5.8.0",
+        "types-bn": "^0.0.1",
+        "types-ethereumjs-util": "0xProject/types-ethereumjs-util",
+        "typescript": "~2.6.1"
+    },
+    "dependencies": {
+        "@0xproject/utils": "^0.2.2",
+        "ethereumjs-util": "^5.1.2",
+        "lodash": "^4.17.4",
+        "request-promise-native": "^1.0.5"
+    }
 }
diff --git a/packages/dev-utils/src/blockchain_lifecycle.ts b/packages/dev-utils/src/blockchain_lifecycle.ts
index fafa62c84..18f5d5c61 100644
--- a/packages/dev-utils/src/blockchain_lifecycle.ts
+++ b/packages/dev-utils/src/blockchain_lifecycle.ts
@@ -1,23 +1,23 @@
 import { RPC } from './rpc';
 
 export class BlockchainLifecycle {
-	private _rpc: RPC;
-	private _snapshotIdsStack: number[];
-	constructor(url: string) {
-		this._rpc = new RPC(url);
-		this._snapshotIdsStack = [];
-	}
-	// TODO: In order to run these tests on an actual node, we should check if we are running against
-	// TestRPC, if so, use snapshots, otherwise re-deploy contracts before every test
-	public async startAsync(): Promise<void> {
-		const snapshotId = await this._rpc.takeSnapshotAsync();
-		this._snapshotIdsStack.push(snapshotId);
-	}
-	public async revertAsync(): Promise<void> {
-		const snapshotId = this._snapshotIdsStack.pop() as number;
-		const didRevert = await this._rpc.revertSnapshotAsync(snapshotId);
-		if (!didRevert) {
-			throw new Error(`Snapshot with id #${snapshotId} failed to revert`);
-		}
-	}
+    private _rpc: RPC;
+    private _snapshotIdsStack: number[];
+    constructor(url: string) {
+        this._rpc = new RPC(url);
+        this._snapshotIdsStack = [];
+    }
+    // TODO: In order to run these tests on an actual node, we should check if we are running against
+    // TestRPC, if so, use snapshots, otherwise re-deploy contracts before every test
+    public async startAsync(): Promise<void> {
+        const snapshotId = await this._rpc.takeSnapshotAsync();
+        this._snapshotIdsStack.push(snapshotId);
+    }
+    public async revertAsync(): Promise<void> {
+        const snapshotId = this._snapshotIdsStack.pop() as number;
+        const didRevert = await this._rpc.revertSnapshotAsync(snapshotId);
+        if (!didRevert) {
+            throw new Error(`Snapshot with id #${snapshotId} failed to revert`);
+        }
+    }
 }
diff --git a/packages/dev-utils/src/rpc.ts b/packages/dev-utils/src/rpc.ts
index 6241ab971..36f8b1ef9 100644
--- a/packages/dev-utils/src/rpc.ts
+++ b/packages/dev-utils/src/rpc.ts
@@ -2,59 +2,59 @@ import * as ethUtil from 'ethereumjs-util';
 import * as request from 'request-promise-native';
 
 export class RPC {
-	private _url: string;
-	private _id: number;
-	constructor(url: string) {
-		this._url = url;
-		this._id = 0;
-	}
-	public async takeSnapshotAsync(): Promise<number> {
-		const method = 'evm_snapshot';
-		const params: any[] = [];
-		const payload = this._toPayload(method, params);
-		const snapshotIdHex = await this._sendAsync(payload);
-		const snapshotId = ethUtil.bufferToInt(ethUtil.toBuffer(snapshotIdHex));
-		return snapshotId;
-	}
-	public async revertSnapshotAsync(snapshotId: number): Promise<boolean> {
-		const method = 'evm_revert';
-		const params = [snapshotId];
-		const payload = this._toPayload(method, params);
-		const didRevert = await this._sendAsync(payload);
-		return didRevert;
-	}
-	public async increaseTimeAsync(time: number) {
-		const method = 'evm_increaseTime';
-		const params = [time];
-		const payload = this._toPayload(method, params);
-		return this._sendAsync(payload);
-	}
-	public async mineBlockAsync(): Promise<void> {
-		const method = 'evm_mine';
-		const params: any[] = [];
-		const payload = this._toPayload(method, params);
-		await this._sendAsync(payload);
-	}
-	private _toPayload(method: string, params: any[] = []): string {
-		const payload = JSON.stringify({
-			id: this._id,
-			method,
-			params,
-		});
-		this._id += 1;
-		return payload;
-	}
-	private async _sendAsync(payload: string): Promise<any> {
-		const opts = {
-			method: 'POST',
-			uri: this._url,
-			body: payload,
-			headers: {
-				'content-type': 'application/json',
-			},
-		};
-		const bodyString = await request(opts);
-		const body = JSON.parse(bodyString);
-		return body.result;
-	}
+    private _url: string;
+    private _id: number;
+    constructor(url: string) {
+        this._url = url;
+        this._id = 0;
+    }
+    public async takeSnapshotAsync(): Promise<number> {
+        const method = 'evm_snapshot';
+        const params: any[] = [];
+        const payload = this._toPayload(method, params);
+        const snapshotIdHex = await this._sendAsync(payload);
+        const snapshotId = ethUtil.bufferToInt(ethUtil.toBuffer(snapshotIdHex));
+        return snapshotId;
+    }
+    public async revertSnapshotAsync(snapshotId: number): Promise<boolean> {
+        const method = 'evm_revert';
+        const params = [snapshotId];
+        const payload = this._toPayload(method, params);
+        const didRevert = await this._sendAsync(payload);
+        return didRevert;
+    }
+    public async increaseTimeAsync(time: number) {
+        const method = 'evm_increaseTime';
+        const params = [time];
+        const payload = this._toPayload(method, params);
+        return this._sendAsync(payload);
+    }
+    public async mineBlockAsync(): Promise<void> {
+        const method = 'evm_mine';
+        const params: any[] = [];
+        const payload = this._toPayload(method, params);
+        await this._sendAsync(payload);
+    }
+    private _toPayload(method: string, params: any[] = []): string {
+        const payload = JSON.stringify({
+            id: this._id,
+            method,
+            params,
+        });
+        this._id += 1;
+        return payload;
+    }
+    private async _sendAsync(payload: string): Promise<any> {
+        const opts = {
+            method: 'POST',
+            uri: this._url,
+            body: payload,
+            headers: {
+                'content-type': 'application/json',
+            },
+        };
+        const bodyString = await request(opts);
+        const body = JSON.parse(bodyString);
+        return body.result;
+    }
 }
diff --git a/packages/dev-utils/tsconfig.json b/packages/dev-utils/tsconfig.json
index 83a0e2451..b28e45170 100644
--- a/packages/dev-utils/tsconfig.json
+++ b/packages/dev-utils/tsconfig.json
@@ -1,11 +1,11 @@
 {
-	"extends": "../../tsconfig",
-	"compilerOptions": {
-		"outDir": "lib"
-	},
-	"include": [
-		"./src/**/*",
-		"../../node_modules/types-bn/index.d.ts",
-		"../../node_modules/types-ethereumjs-util/index.d.ts"
-	]
+    "extends": "../../tsconfig",
+    "compilerOptions": {
+        "outDir": "lib"
+    },
+    "include": [
+        "./src/**/*",
+        "../../node_modules/types-bn/index.d.ts",
+        "../../node_modules/types-ethereumjs-util/index.d.ts"
+    ]
 }
diff --git a/packages/dev-utils/tslint.json b/packages/dev-utils/tslint.json
index e63054bfc..ffaefe83a 100644
--- a/packages/dev-utils/tslint.json
+++ b/packages/dev-utils/tslint.json
@@ -1,3 +1,3 @@
 {
-	"extends": ["@0xproject/tslint-config"]
+    "extends": ["@0xproject/tslint-config"]
 }
diff --git a/packages/json-schemas/package.json b/packages/json-schemas/package.json
index 30cccb12f..d67cb64f7 100644
--- a/packages/json-schemas/package.json
+++ b/packages/json-schemas/package.json
@@ -1,45 +1,45 @@
 {
-	"name": "@0xproject/json-schemas",
-	"version": "0.7.5",
-	"description": "0x-related json schemas",
-	"main": "lib/src/index.js",
-	"types": "lib/src/index.d.ts",
-	"scripts": {
-		"lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'",
-		"test": "run-s clean build run_mocha",
-		"test:circleci": "yarn test",
-		"run_mocha": "mocha lib/test/**/*_test.js",
-		"clean": "shx rm -rf _bundles lib test_temp",
-		"build": "tsc"
-	},
-	"repository": {
-		"type": "git",
-		"url": "https://github.com/0xProject/0x.js.git"
-	},
-	"author": "",
-	"license": "Apache-2.0",
-	"bugs": {
-		"url": "https://github.com/0xProject/0x.js/issues"
-	},
-	"homepage": "https://github.com/0xProject/0x.js/packages/json-schemas/README.md",
-	"dependencies": {
-		"jsonschema": "^1.2.0",
-		"lodash.values": "^4.3.0"
-	},
-	"devDependencies": {
-		"@0xproject/tslint-config": "^0.4.4",
-		"@0xproject/utils": "^0.2.2",
-		"@types/lodash.foreach": "^4.5.3",
-		"@types/lodash.values": "^4.3.3",
-		"@types/mocha": "^2.2.42",
-		"chai": "^4.0.1",
-		"chai-typescript-typings": "^0.0.2",
-		"dirty-chai": "^2.0.1",
-		"lodash.foreach": "^4.5.0",
-		"mocha": "^4.0.1",
-		"npm-run-all": "^4.1.2",
-		"shx": "^0.2.2",
-		"tslint": "5.8.0",
-		"typescript": "~2.6.1"
-	}
+    "name": "@0xproject/json-schemas",
+    "version": "0.7.5",
+    "description": "0x-related json schemas",
+    "main": "lib/src/index.js",
+    "types": "lib/src/index.d.ts",
+    "scripts": {
+        "lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'",
+        "test": "run-s clean build run_mocha",
+        "test:circleci": "yarn test",
+        "run_mocha": "mocha lib/test/**/*_test.js",
+        "clean": "shx rm -rf _bundles lib test_temp",
+        "build": "tsc"
+    },
+    "repository": {
+        "type": "git",
+        "url": "https://github.com/0xProject/0x.js.git"
+    },
+    "author": "",
+    "license": "Apache-2.0",
+    "bugs": {
+        "url": "https://github.com/0xProject/0x.js/issues"
+    },
+    "homepage": "https://github.com/0xProject/0x.js/packages/json-schemas/README.md",
+    "dependencies": {
+        "jsonschema": "^1.2.0",
+        "lodash.values": "^4.3.0"
+    },
+    "devDependencies": {
+        "@0xproject/tslint-config": "^0.4.4",
+        "@0xproject/utils": "^0.2.2",
+        "@types/lodash.foreach": "^4.5.3",
+        "@types/lodash.values": "^4.3.3",
+        "@types/mocha": "^2.2.42",
+        "chai": "^4.0.1",
+        "chai-typescript-typings": "^0.0.2",
+        "dirty-chai": "^2.0.1",
+        "lodash.foreach": "^4.5.0",
+        "mocha": "^4.0.1",
+        "npm-run-all": "^4.1.2",
+        "shx": "^0.2.2",
+        "tslint": "5.8.0",
+        "typescript": "~2.6.1"
+    }
 }
diff --git a/packages/json-schemas/schemas/basic_type_schemas.ts b/packages/json-schemas/schemas/basic_type_schemas.ts
index aa2eea867..9d81ff333 100644
--- a/packages/json-schemas/schemas/basic_type_schemas.ts
+++ b/packages/json-schemas/schemas/basic_type_schemas.ts
@@ -1,11 +1,11 @@
 export const addressSchema = {
-	id: '/Address',
-	type: 'string',
-	pattern: '^0x[0-9a-f]{40}$',
+    id: '/Address',
+    type: 'string',
+    pattern: '^0x[0-9a-f]{40}$',
 };
 
 export const numberSchema = {
-	id: '/Number',
-	type: 'string',
-	pattern: '^\\d+(\\.\\d+)?$',
+    id: '/Number',
+    type: 'string',
+    pattern: '^\\d+(\\.\\d+)?$',
 };
diff --git a/packages/json-schemas/schemas/block_range_schema.ts b/packages/json-schemas/schemas/block_range_schema.ts
index 8697bba96..1f6a63151 100644
--- a/packages/json-schemas/schemas/block_range_schema.ts
+++ b/packages/json-schemas/schemas/block_range_schema.ts
@@ -1,20 +1,20 @@
 export const blockParamSchema = {
-	id: '/BlockParam',
-	oneOf: [
-		{
-			type: 'number',
-		},
-		{
-			enum: ['latest', 'earliest', 'pending'],
-		},
-	],
+    id: '/BlockParam',
+    oneOf: [
+        {
+            type: 'number',
+        },
+        {
+            enum: ['latest', 'earliest', 'pending'],
+        },
+    ],
 };
 
 export const blockRangeSchema = {
-	id: '/BlockRange',
-	properties: {
-		fromBlock: { $ref: '/BlockParam' },
-		toBlock: { $ref: '/BlockParam' },
-	},
-	type: 'object',
+    id: '/BlockRange',
+    properties: {
+        fromBlock: { $ref: '/BlockParam' },
+        toBlock: { $ref: '/BlockParam' },
+    },
+    type: 'object',
 };
diff --git a/packages/json-schemas/schemas/ec_signature_schema.ts b/packages/json-schemas/schemas/ec_signature_schema.ts
index 299ca283b..71b840dd8 100644
--- a/packages/json-schemas/schemas/ec_signature_schema.ts
+++ b/packages/json-schemas/schemas/ec_signature_schema.ts
@@ -1,20 +1,20 @@
 export const ecSignatureParameterSchema = {
-	id: '/ECSignatureParameter',
-	type: 'string',
-	pattern: '^0[xX][0-9A-Fa-f]{64}$',
+    id: '/ECSignatureParameter',
+    type: 'string',
+    pattern: '^0[xX][0-9A-Fa-f]{64}$',
 };
 
 export const ecSignatureSchema = {
-	id: '/ECSignature',
-	properties: {
-		v: {
-			type: 'number',
-			minimum: 27,
-			maximum: 28,
-		},
-		r: { $ref: '/ECSignatureParameter' },
-		s: { $ref: '/ECSignatureParameter' },
-	},
-	required: ['v', 'r', 's'],
-	type: 'object',
+    id: '/ECSignature',
+    properties: {
+        v: {
+            type: 'number',
+            minimum: 27,
+            maximum: 28,
+        },
+        r: { $ref: '/ECSignatureParameter' },
+        s: { $ref: '/ECSignatureParameter' },
+    },
+    required: ['v', 'r', 's'],
+    type: 'object',
 };
diff --git a/packages/json-schemas/schemas/index_filter_values_schema.ts b/packages/json-schemas/schemas/index_filter_values_schema.ts
index 6e9f36c54..3374d63e0 100644
--- a/packages/json-schemas/schemas/index_filter_values_schema.ts
+++ b/packages/json-schemas/schemas/index_filter_values_schema.ts
@@ -1,7 +1,7 @@
 export const indexFilterValuesSchema = {
-	id: '/IndexFilterValues',
-	additionalProperties: {
-		oneOf: [{ $ref: '/Number' }, { $ref: '/Address' }, { $ref: '/OrderHashSchema' }],
-	},
-	type: 'object',
+    id: '/IndexFilterValues',
+    additionalProperties: {
+        oneOf: [{ $ref: '/Number' }, { $ref: '/Address' }, { $ref: '/OrderHashSchema' }],
+    },
+    type: 'object',
 };
diff --git a/packages/json-schemas/schemas/order_cancel_schema.ts b/packages/json-schemas/schemas/order_cancel_schema.ts
index f2aa80e7a..ad23d01cc 100644
--- a/packages/json-schemas/schemas/order_cancel_schema.ts
+++ b/packages/json-schemas/schemas/order_cancel_schema.ts
@@ -1,12 +1,12 @@
 export const orderCancellationRequestsSchema = {
-	id: '/OrderCancellationRequests',
-	type: 'array',
-	items: {
-		properties: {
-			order: { $ref: '/Order' },
-			takerTokenCancelAmount: { $ref: '/Number' },
-		},
-		required: ['order', 'takerTokenCancelAmount'],
-		type: 'object',
-	},
+    id: '/OrderCancellationRequests',
+    type: 'array',
+    items: {
+        properties: {
+            order: { $ref: '/Order' },
+            takerTokenCancelAmount: { $ref: '/Number' },
+        },
+        required: ['order', 'takerTokenCancelAmount'],
+        type: 'object',
+    },
 };
diff --git a/packages/json-schemas/schemas/order_fill_or_kill_requests_schema.ts b/packages/json-schemas/schemas/order_fill_or_kill_requests_schema.ts
index f13bc9cc3..61f2c8849 100644
--- a/packages/json-schemas/schemas/order_fill_or_kill_requests_schema.ts
+++ b/packages/json-schemas/schemas/order_fill_or_kill_requests_schema.ts
@@ -1,12 +1,12 @@
 export const orderFillOrKillRequestsSchema = {
-	id: '/OrderFillOrKillRequests',
-	type: 'array',
-	items: {
-		properties: {
-			signedOrder: { $ref: '/SignedOrder' },
-			fillTakerAmount: { $ref: '/Number' },
-		},
-		required: ['signedOrder', 'fillTakerAmount'],
-		type: 'object',
-	},
+    id: '/OrderFillOrKillRequests',
+    type: 'array',
+    items: {
+        properties: {
+            signedOrder: { $ref: '/SignedOrder' },
+            fillTakerAmount: { $ref: '/Number' },
+        },
+        required: ['signedOrder', 'fillTakerAmount'],
+        type: 'object',
+    },
 };
diff --git a/packages/json-schemas/schemas/order_fill_requests_schema.ts b/packages/json-schemas/schemas/order_fill_requests_schema.ts
index 45cd927be..419d0670f 100644
--- a/packages/json-schemas/schemas/order_fill_requests_schema.ts
+++ b/packages/json-schemas/schemas/order_fill_requests_schema.ts
@@ -1,12 +1,12 @@
 export const orderFillRequestsSchema = {
-	id: '/OrderFillRequests',
-	type: 'array',
-	items: {
-		properties: {
-			signedOrder: { $ref: '/SignedOrder' },
-			takerTokenFillAmount: { $ref: '/Number' },
-		},
-		required: ['signedOrder', 'takerTokenFillAmount'],
-		type: 'object',
-	},
+    id: '/OrderFillRequests',
+    type: 'array',
+    items: {
+        properties: {
+            signedOrder: { $ref: '/SignedOrder' },
+            takerTokenFillAmount: { $ref: '/Number' },
+        },
+        required: ['signedOrder', 'takerTokenFillAmount'],
+        type: 'object',
+    },
 };
diff --git a/packages/json-schemas/schemas/order_hash_schema.ts b/packages/json-schemas/schemas/order_hash_schema.ts
index 5eed112ca..6af06927f 100644
--- a/packages/json-schemas/schemas/order_hash_schema.ts
+++ b/packages/json-schemas/schemas/order_hash_schema.ts
@@ -1,5 +1,5 @@
 export const orderHashSchema = {
-	id: '/OrderHashSchema',
-	type: 'string',
-	pattern: '^0x[0-9a-fA-F]{64}$',
+    id: '/OrderHashSchema',
+    type: 'string',
+    pattern: '^0x[0-9a-fA-F]{64}$',
 };
diff --git a/packages/json-schemas/schemas/order_schemas.ts b/packages/json-schemas/schemas/order_schemas.ts
index ee5f2c137..6f17224ad 100644
--- a/packages/json-schemas/schemas/order_schemas.ts
+++ b/packages/json-schemas/schemas/order_schemas.ts
@@ -1,43 +1,43 @@
 export const orderSchema = {
-	id: '/Order',
-	properties: {
-		maker: { $ref: '/Address' },
-		taker: { $ref: '/Address' },
-		makerFee: { $ref: '/Number' },
-		takerFee: { $ref: '/Number' },
-		makerTokenAmount: { $ref: '/Number' },
-		takerTokenAmount: { $ref: '/Number' },
-		makerTokenAddress: { $ref: '/Address' },
-		takerTokenAddress: { $ref: '/Address' },
-		salt: { $ref: '/Number' },
-		feeRecipient: { $ref: '/Address' },
-		expirationUnixTimestampSec: { $ref: '/Number' },
-		exchangeContractAddress: { $ref: '/Address' },
-	},
-	required: [
-		'maker',
-		'taker',
-		'makerFee',
-		'takerFee',
-		'makerTokenAmount',
-		'takerTokenAmount',
-		'salt',
-		'feeRecipient',
-		'expirationUnixTimestampSec',
-		'exchangeContractAddress',
-	],
-	type: 'object',
+    id: '/Order',
+    properties: {
+        maker: { $ref: '/Address' },
+        taker: { $ref: '/Address' },
+        makerFee: { $ref: '/Number' },
+        takerFee: { $ref: '/Number' },
+        makerTokenAmount: { $ref: '/Number' },
+        takerTokenAmount: { $ref: '/Number' },
+        makerTokenAddress: { $ref: '/Address' },
+        takerTokenAddress: { $ref: '/Address' },
+        salt: { $ref: '/Number' },
+        feeRecipient: { $ref: '/Address' },
+        expirationUnixTimestampSec: { $ref: '/Number' },
+        exchangeContractAddress: { $ref: '/Address' },
+    },
+    required: [
+        'maker',
+        'taker',
+        'makerFee',
+        'takerFee',
+        'makerTokenAmount',
+        'takerTokenAmount',
+        'salt',
+        'feeRecipient',
+        'expirationUnixTimestampSec',
+        'exchangeContractAddress',
+    ],
+    type: 'object',
 };
 
 export const signedOrderSchema = {
-	id: '/SignedOrder',
-	allOf: [
-		{ $ref: '/Order' },
-		{
-			properties: {
-				ecSignature: { $ref: '/ECSignature' },
-			},
-			required: ['ecSignature'],
-		},
-	],
+    id: '/SignedOrder',
+    allOf: [
+        { $ref: '/Order' },
+        {
+            properties: {
+                ecSignature: { $ref: '/ECSignature' },
+            },
+            required: ['ecSignature'],
+        },
+    ],
 };
diff --git a/packages/json-schemas/schemas/relayer_api_error_response_schema.ts b/packages/json-schemas/schemas/relayer_api_error_response_schema.ts
index 3d3a96364..27fdb166f 100644
--- a/packages/json-schemas/schemas/relayer_api_error_response_schema.ts
+++ b/packages/json-schemas/schemas/relayer_api_error_response_schema.ts
@@ -1,21 +1,21 @@
 export const relayerApiErrorResponseSchema = {
-	id: '/RelayerApiErrorResponse',
-	type: 'object',
-	properties: {
-		code: { type: 'number' },
-		reason: { type: 'string' },
-		validationErrors: {
-			type: 'array',
-			items: {
-				type: 'object',
-				properties: {
-					field: { type: 'string' },
-					code: { type: 'number' },
-					reason: { type: 'string' },
-				},
-				required: ['field', 'code', 'reason'],
-			},
-		},
-	},
-	required: ['code', 'reason'],
+    id: '/RelayerApiErrorResponse',
+    type: 'object',
+    properties: {
+        code: { type: 'number' },
+        reason: { type: 'string' },
+        validationErrors: {
+            type: 'array',
+            items: {
+                type: 'object',
+                properties: {
+                    field: { type: 'string' },
+                    code: { type: 'number' },
+                    reason: { type: 'string' },
+                },
+                required: ['field', 'code', 'reason'],
+            },
+        },
+    },
+    required: ['code', 'reason'],
 };
diff --git a/packages/json-schemas/schemas/relayer_api_fees_payload_schema.ts b/packages/json-schemas/schemas/relayer_api_fees_payload_schema.ts
index f79308594..eaaf777a1 100644
--- a/packages/json-schemas/schemas/relayer_api_fees_payload_schema.ts
+++ b/packages/json-schemas/schemas/relayer_api_fees_payload_schema.ts
@@ -1,24 +1,24 @@
 export const relayerApiFeesPayloadSchema = {
-	id: '/RelayerApiFeesPayload',
-	type: 'object',
-	properties: {
-		exchangeContractAddress: { $ref: '/Address' },
-		maker: { $ref: '/Address' },
-		taker: { $ref: '/Address' },
-		makerTokenAddress: { $ref: '/Address' },
-		takerTokenAddress: { $ref: '/Address' },
-		makerTokenAmount: { $ref: '/Number' },
-		takerTokenAmount: { $ref: '/Number' },
-		expirationUnixTimestampSec: { $ref: '/Number' },
-		salt: { $ref: '/Number' },
-	},
-	required: [
-		'exchangeContractAddress',
-		'maker',
-		'taker',
-		'makerTokenAddress',
-		'takerTokenAddress',
-		'expirationUnixTimestampSec',
-		'salt',
-	],
+    id: '/RelayerApiFeesPayload',
+    type: 'object',
+    properties: {
+        exchangeContractAddress: { $ref: '/Address' },
+        maker: { $ref: '/Address' },
+        taker: { $ref: '/Address' },
+        makerTokenAddress: { $ref: '/Address' },
+        takerTokenAddress: { $ref: '/Address' },
+        makerTokenAmount: { $ref: '/Number' },
+        takerTokenAmount: { $ref: '/Number' },
+        expirationUnixTimestampSec: { $ref: '/Number' },
+        salt: { $ref: '/Number' },
+    },
+    required: [
+        'exchangeContractAddress',
+        'maker',
+        'taker',
+        'makerTokenAddress',
+        'takerTokenAddress',
+        'expirationUnixTimestampSec',
+        'salt',
+    ],
 };
diff --git a/packages/json-schemas/schemas/relayer_api_fees_response_schema.ts b/packages/json-schemas/schemas/relayer_api_fees_response_schema.ts
index d87c2fcdb..e7440613f 100644
--- a/packages/json-schemas/schemas/relayer_api_fees_response_schema.ts
+++ b/packages/json-schemas/schemas/relayer_api_fees_response_schema.ts
@@ -1,10 +1,10 @@
 export const relayerApiFeesResponseSchema = {
-	id: '/RelayerApiFeesResponse',
-	type: 'object',
-	properties: {
-		makerFee: { $ref: '/Number' },
-		takerFee: { $ref: '/Number' },
-		feeRecipient: { $ref: '/Address' },
-	},
-	required: ['makerFee', 'takerFee', 'feeRecipient'],
+    id: '/RelayerApiFeesResponse',
+    type: 'object',
+    properties: {
+        makerFee: { $ref: '/Number' },
+        takerFee: { $ref: '/Number' },
+        feeRecipient: { $ref: '/Address' },
+    },
+    required: ['makerFee', 'takerFee', 'feeRecipient'],
 };
diff --git a/packages/json-schemas/schemas/relayer_api_orberbook_channel_subscribe_schema.ts b/packages/json-schemas/schemas/relayer_api_orberbook_channel_subscribe_schema.ts
index 1d443c625..d93fa73d6 100644
--- a/packages/json-schemas/schemas/relayer_api_orberbook_channel_subscribe_schema.ts
+++ b/packages/json-schemas/schemas/relayer_api_orberbook_channel_subscribe_schema.ts
@@ -1,23 +1,23 @@
 export const relayerApiOrderbookChannelSubscribeSchema = {
-	id: '/RelayerApiOrderbookChannelSubscribe',
-	type: 'object',
-	properties: {
-		type: { enum: ['subscribe'] },
-		channel: { enum: ['orderbook'] },
-		requestId: { type: 'number' },
-		payload: { $ref: '/RelayerApiOrderbookChannelSubscribePayload' },
-	},
-	required: ['type', 'channel', 'requestId', 'payload'],
+    id: '/RelayerApiOrderbookChannelSubscribe',
+    type: 'object',
+    properties: {
+        type: { enum: ['subscribe'] },
+        channel: { enum: ['orderbook'] },
+        requestId: { type: 'number' },
+        payload: { $ref: '/RelayerApiOrderbookChannelSubscribePayload' },
+    },
+    required: ['type', 'channel', 'requestId', 'payload'],
 };
 
 export const relayerApiOrderbookChannelSubscribePayload = {
-	id: '/RelayerApiOrderbookChannelSubscribePayload',
-	type: 'object',
-	properties: {
-		baseTokenAddress: { $ref: '/Address' },
-		quoteTokenAddress: { $ref: '/Address' },
-		snapshot: { type: 'boolean' },
-		limit: { type: 'number' },
-	},
-	required: ['baseTokenAddress', 'quoteTokenAddress'],
+    id: '/RelayerApiOrderbookChannelSubscribePayload',
+    type: 'object',
+    properties: {
+        baseTokenAddress: { $ref: '/Address' },
+        quoteTokenAddress: { $ref: '/Address' },
+        snapshot: { type: 'boolean' },
+        limit: { type: 'number' },
+    },
+    required: ['baseTokenAddress', 'quoteTokenAddress'],
 };
diff --git a/packages/json-schemas/schemas/relayer_api_orderbook_channel_snapshot_schema.ts b/packages/json-schemas/schemas/relayer_api_orderbook_channel_snapshot_schema.ts
index e954185a8..fe1510d5b 100644
--- a/packages/json-schemas/schemas/relayer_api_orderbook_channel_snapshot_schema.ts
+++ b/packages/json-schemas/schemas/relayer_api_orderbook_channel_snapshot_schema.ts
@@ -1,21 +1,21 @@
 export const relayerApiOrderbookChannelSnapshotSchema = {
-	id: '/RelayerApiOrderbookChannelSnapshot',
-	type: 'object',
-	properties: {
-		type: { enum: ['snapshot'] },
-		channel: { enum: ['orderbook'] },
-		requestId: { type: 'number' },
-		payload: { $ref: '/RelayerApiOrderbookChannelSnapshotPayload' },
-	},
-	required: ['type', 'channel', 'requestId', 'payload'],
+    id: '/RelayerApiOrderbookChannelSnapshot',
+    type: 'object',
+    properties: {
+        type: { enum: ['snapshot'] },
+        channel: { enum: ['orderbook'] },
+        requestId: { type: 'number' },
+        payload: { $ref: '/RelayerApiOrderbookChannelSnapshotPayload' },
+    },
+    required: ['type', 'channel', 'requestId', 'payload'],
 };
 
 export const relayerApiOrderbookChannelSnapshotPayload = {
-	id: '/RelayerApiOrderbookChannelSnapshotPayload',
-	type: 'object',
-	properties: {
-		bids: { $ref: '/signedOrdersSchema' },
-		asks: { $ref: '/signedOrdersSchema' },
-	},
-	required: ['bids', 'asks'],
+    id: '/RelayerApiOrderbookChannelSnapshotPayload',
+    type: 'object',
+    properties: {
+        bids: { $ref: '/signedOrdersSchema' },
+        asks: { $ref: '/signedOrdersSchema' },
+    },
+    required: ['bids', 'asks'],
 };
diff --git a/packages/json-schemas/schemas/relayer_api_orderbook_channel_update_response_schema.ts b/packages/json-schemas/schemas/relayer_api_orderbook_channel_update_response_schema.ts
index 7c2ba6531..9a6d83d4c 100644
--- a/packages/json-schemas/schemas/relayer_api_orderbook_channel_update_response_schema.ts
+++ b/packages/json-schemas/schemas/relayer_api_orderbook_channel_update_response_schema.ts
@@ -1,11 +1,11 @@
 export const relayerApiOrderbookChannelUpdateSchema = {
-	id: '/RelayerApiOrderbookChannelUpdate',
-	type: 'object',
-	properties: {
-		type: { enum: ['update'] },
-		channel: { enum: ['orderbook'] },
-		requestId: { type: 'number' },
-		payload: { $ref: '/SignedOrder' },
-	},
-	required: ['type', 'channel', 'requestId', 'payload'],
+    id: '/RelayerApiOrderbookChannelUpdate',
+    type: 'object',
+    properties: {
+        type: { enum: ['update'] },
+        channel: { enum: ['orderbook'] },
+        requestId: { type: 'number' },
+        payload: { $ref: '/SignedOrder' },
+    },
+    required: ['type', 'channel', 'requestId', 'payload'],
 };
diff --git a/packages/json-schemas/schemas/relayer_api_orderbook_response_schema.ts b/packages/json-schemas/schemas/relayer_api_orderbook_response_schema.ts
index d9abfc77d..5c409c807 100644
--- a/packages/json-schemas/schemas/relayer_api_orderbook_response_schema.ts
+++ b/packages/json-schemas/schemas/relayer_api_orderbook_response_schema.ts
@@ -1,9 +1,9 @@
 export const relayerApiOrderBookResponseSchema = {
-	id: '/RelayerApiOrderBookResponse',
-	type: 'object',
-	properties: {
-		bids: { $ref: '/signedOrdersSchema' },
-		asks: { $ref: '/signedOrdersSchema' },
-	},
-	required: ['bids', 'asks'],
+    id: '/RelayerApiOrderBookResponse',
+    type: 'object',
+    properties: {
+        bids: { $ref: '/signedOrdersSchema' },
+        asks: { $ref: '/signedOrdersSchema' },
+    },
+    required: ['bids', 'asks'],
 };
diff --git a/packages/json-schemas/schemas/relayer_api_token_pairs_response_schema.ts b/packages/json-schemas/schemas/relayer_api_token_pairs_response_schema.ts
index 471bed7b4..5009c7955 100644
--- a/packages/json-schemas/schemas/relayer_api_token_pairs_response_schema.ts
+++ b/packages/json-schemas/schemas/relayer_api_token_pairs_response_schema.ts
@@ -1,24 +1,24 @@
 export const relayerApiTokenPairsResponseSchema = {
-	id: '/RelayerApiTokenPairsResponse',
-	type: 'array',
-	items: {
-		properties: {
-			tokenA: { $ref: '/RelayerApiTokenTradeInfo' },
-			tokenB: { $ref: '/RelayerApiTokenTradeInfo' },
-		},
-		required: ['tokenA', 'tokenB'],
-		type: 'object',
-	},
+    id: '/RelayerApiTokenPairsResponse',
+    type: 'array',
+    items: {
+        properties: {
+            tokenA: { $ref: '/RelayerApiTokenTradeInfo' },
+            tokenB: { $ref: '/RelayerApiTokenTradeInfo' },
+        },
+        required: ['tokenA', 'tokenB'],
+        type: 'object',
+    },
 };
 
 export const relayerApiTokenTradeInfoSchema = {
-	id: '/RelayerApiTokenTradeInfo',
-	type: 'object',
-	properties: {
-		address: { $ref: '/Address' },
-		minAmount: { $ref: '/Number' },
-		maxAmount: { $ref: '/Number' },
-		precision: { type: 'number' },
-	},
-	required: ['address'],
+    id: '/RelayerApiTokenTradeInfo',
+    type: 'object',
+    properties: {
+        address: { $ref: '/Address' },
+        minAmount: { $ref: '/Number' },
+        maxAmount: { $ref: '/Number' },
+        precision: { type: 'number' },
+    },
+    required: ['address'],
 };
diff --git a/packages/json-schemas/schemas/signed_orders_schema.ts b/packages/json-schemas/schemas/signed_orders_schema.ts
index 7d66b7027..34d956836 100644
--- a/packages/json-schemas/schemas/signed_orders_schema.ts
+++ b/packages/json-schemas/schemas/signed_orders_schema.ts
@@ -1,5 +1,5 @@
 export const signedOrdersSchema = {
-	id: '/signedOrdersSchema',
-	type: 'array',
-	items: { $ref: '/SignedOrder' },
+    id: '/signedOrdersSchema',
+    type: 'array',
+    items: { $ref: '/SignedOrder' },
 };
diff --git a/packages/json-schemas/schemas/token_schema.ts b/packages/json-schemas/schemas/token_schema.ts
index d2bb10f09..e64565c8b 100644
--- a/packages/json-schemas/schemas/token_schema.ts
+++ b/packages/json-schemas/schemas/token_schema.ts
@@ -1,11 +1,11 @@
 export const tokenSchema = {
-	id: '/Token',
-	properties: {
-		name: { type: 'string' },
-		symbol: { type: 'string' },
-		decimals: { type: 'number' },
-		address: { $ref: '/Address' },
-	},
-	required: ['name', 'symbol', 'decimals', 'address'],
-	type: 'object',
+    id: '/Token',
+    properties: {
+        name: { type: 'string' },
+        symbol: { type: 'string' },
+        decimals: { type: 'number' },
+        address: { $ref: '/Address' },
+    },
+    required: ['name', 'symbol', 'decimals', 'address'],
+    type: 'object',
 };
diff --git a/packages/json-schemas/schemas/tx_data_schema.ts b/packages/json-schemas/schemas/tx_data_schema.ts
index 00c1d3e08..4274c553f 100644
--- a/packages/json-schemas/schemas/tx_data_schema.ts
+++ b/packages/json-schemas/schemas/tx_data_schema.ts
@@ -1,33 +1,33 @@
 export const jsNumber = {
-	id: '/JsNumber',
-	type: 'number',
-	minimum: 0,
+    id: '/JsNumber',
+    type: 'number',
+    minimum: 0,
 };
 
 export const txDataSchema = {
-	id: '/TxData',
-	properties: {
-		from: { $ref: '/Address' },
-		to: { $ref: '/Address' },
-		value: {
-			oneOf: [{ $ref: '/Number' }, { $ref: '/JsNumber' }],
-		},
-		gas: {
-			oneOf: [{ $ref: '/Number' }, { $ref: '/JsNumber' }],
-		},
-		gasPrice: {
-			oneOf: [{ $ref: '/Number' }, { $ref: '/JsNumber' }],
-		},
-		data: {
-			type: 'string',
-			pattern: '^0x[0-9a-f]*$',
-		},
-		nonce: {
-			type: 'number',
-			minimum: 0,
-		},
-	},
-	required: ['from'],
-	type: 'object',
-	additionalProperties: false,
+    id: '/TxData',
+    properties: {
+        from: { $ref: '/Address' },
+        to: { $ref: '/Address' },
+        value: {
+            oneOf: [{ $ref: '/Number' }, { $ref: '/JsNumber' }],
+        },
+        gas: {
+            oneOf: [{ $ref: '/Number' }, { $ref: '/JsNumber' }],
+        },
+        gasPrice: {
+            oneOf: [{ $ref: '/Number' }, { $ref: '/JsNumber' }],
+        },
+        data: {
+            type: 'string',
+            pattern: '^0x[0-9a-f]*$',
+        },
+        nonce: {
+            type: 'number',
+            minimum: 0,
+        },
+    },
+    required: ['from'],
+    type: 'object',
+    additionalProperties: false,
 };
diff --git a/packages/json-schemas/src/schema_validator.ts b/packages/json-schemas/src/schema_validator.ts
index 686c38d17..e13326d2a 100644
--- a/packages/json-schemas/src/schema_validator.ts
+++ b/packages/json-schemas/src/schema_validator.ts
@@ -4,26 +4,26 @@ import values = require('lodash.values');
 import { schemas } from './schemas';
 
 export class SchemaValidator {
-	private _validator: Validator;
-	constructor() {
-		this._validator = new Validator();
-		for (const schema of values(schemas)) {
-			this._validator.addSchema(schema, schema.id);
-		}
-	}
-	public addSchema(schema: Schema) {
-		this._validator.addSchema(schema, schema.id);
-	}
-	// In order to validate a complex JS object using jsonschema, we must replace any complex
-	// sub-types (e.g BigNumber) with a simpler string representation. Since BigNumber and other
-	// complex types implement the `toString` method, we can stringify the object and
-	// then parse it. The resultant object can then be checked using jsonschema.
-	public validate(instance: any, schema: Schema): ValidatorResult {
-		const jsonSchemaCompatibleObject = JSON.parse(JSON.stringify(instance));
-		return this._validator.validate(jsonSchemaCompatibleObject, schema);
-	}
-	public isValid(instance: any, schema: Schema): boolean {
-		const isValid = this.validate(instance, schema).errors.length === 0;
-		return isValid;
-	}
+    private _validator: Validator;
+    constructor() {
+        this._validator = new Validator();
+        for (const schema of values(schemas)) {
+            this._validator.addSchema(schema, schema.id);
+        }
+    }
+    public addSchema(schema: Schema) {
+        this._validator.addSchema(schema, schema.id);
+    }
+    // In order to validate a complex JS object using jsonschema, we must replace any complex
+    // sub-types (e.g BigNumber) with a simpler string representation. Since BigNumber and other
+    // complex types implement the `toString` method, we can stringify the object and
+    // then parse it. The resultant object can then be checked using jsonschema.
+    public validate(instance: any, schema: Schema): ValidatorResult {
+        const jsonSchemaCompatibleObject = JSON.parse(JSON.stringify(instance));
+        return this._validator.validate(jsonSchemaCompatibleObject, schema);
+    }
+    public isValid(instance: any, schema: Schema): boolean {
+        const isValid = this.validate(instance, schema).errors.length === 0;
+        return isValid;
+    }
 }
diff --git a/packages/json-schemas/src/schemas.ts b/packages/json-schemas/src/schemas.ts
index bdc227aea..5cb07acfe 100644
--- a/packages/json-schemas/src/schemas.ts
+++ b/packages/json-schemas/src/schemas.ts
@@ -11,50 +11,50 @@ import { relayerApiErrorResponseSchema } from '../schemas/relayer_api_error_resp
 import { relayerApiFeesPayloadSchema } from '../schemas/relayer_api_fees_payload_schema';
 import { relayerApiFeesResponseSchema } from '../schemas/relayer_api_fees_response_schema';
 import {
-	relayerApiOrderbookChannelSubscribePayload,
-	relayerApiOrderbookChannelSubscribeSchema,
+    relayerApiOrderbookChannelSubscribePayload,
+    relayerApiOrderbookChannelSubscribeSchema,
 } from '../schemas/relayer_api_orberbook_channel_subscribe_schema';
 import {
-	relayerApiOrderbookChannelSnapshotPayload,
-	relayerApiOrderbookChannelSnapshotSchema,
+    relayerApiOrderbookChannelSnapshotPayload,
+    relayerApiOrderbookChannelSnapshotSchema,
 } from '../schemas/relayer_api_orderbook_channel_snapshot_schema';
 import { relayerApiOrderbookChannelUpdateSchema } from '../schemas/relayer_api_orderbook_channel_update_response_schema';
 import { relayerApiOrderBookResponseSchema } from '../schemas/relayer_api_orderbook_response_schema';
 import {
-	relayerApiTokenPairsResponseSchema,
-	relayerApiTokenTradeInfoSchema,
+    relayerApiTokenPairsResponseSchema,
+    relayerApiTokenTradeInfoSchema,
 } from '../schemas/relayer_api_token_pairs_response_schema';
 import { signedOrdersSchema } from '../schemas/signed_orders_schema';
 import { tokenSchema } from '../schemas/token_schema';
 import { jsNumber, txDataSchema } from '../schemas/tx_data_schema';
 
 export const schemas = {
-	numberSchema,
-	addressSchema,
-	ecSignatureSchema,
-	ecSignatureParameterSchema,
-	indexFilterValuesSchema,
-	orderCancellationRequestsSchema,
-	orderFillOrKillRequestsSchema,
-	orderFillRequestsSchema,
-	orderHashSchema,
-	orderSchema,
-	signedOrderSchema,
-	signedOrdersSchema,
-	blockParamSchema,
-	blockRangeSchema,
-	tokenSchema,
-	jsNumber,
-	txDataSchema,
-	relayerApiErrorResponseSchema,
-	relayerApiFeesPayloadSchema,
-	relayerApiFeesResponseSchema,
-	relayerApiOrderBookResponseSchema,
-	relayerApiTokenPairsResponseSchema,
-	relayerApiTokenTradeInfoSchema,
-	relayerApiOrderbookChannelSubscribeSchema,
-	relayerApiOrderbookChannelSubscribePayload,
-	relayerApiOrderbookChannelUpdateSchema,
-	relayerApiOrderbookChannelSnapshotSchema,
-	relayerApiOrderbookChannelSnapshotPayload,
+    numberSchema,
+    addressSchema,
+    ecSignatureSchema,
+    ecSignatureParameterSchema,
+    indexFilterValuesSchema,
+    orderCancellationRequestsSchema,
+    orderFillOrKillRequestsSchema,
+    orderFillRequestsSchema,
+    orderHashSchema,
+    orderSchema,
+    signedOrderSchema,
+    signedOrdersSchema,
+    blockParamSchema,
+    blockRangeSchema,
+    tokenSchema,
+    jsNumber,
+    txDataSchema,
+    relayerApiErrorResponseSchema,
+    relayerApiFeesPayloadSchema,
+    relayerApiFeesResponseSchema,
+    relayerApiOrderBookResponseSchema,
+    relayerApiTokenPairsResponseSchema,
+    relayerApiTokenTradeInfoSchema,
+    relayerApiOrderbookChannelSubscribeSchema,
+    relayerApiOrderbookChannelSubscribePayload,
+    relayerApiOrderbookChannelUpdateSchema,
+    relayerApiOrderbookChannelSnapshotSchema,
+    relayerApiOrderbookChannelSnapshotPayload,
 };
diff --git a/packages/json-schemas/test/schema_test.ts b/packages/json-schemas/test/schema_test.ts
index a6162c8e3..7b058781d 100644
--- a/packages/json-schemas/test/schema_test.ts
+++ b/packages/json-schemas/test/schema_test.ts
@@ -11,906 +11,906 @@ chai.use(dirtyChai);
 const expect = chai.expect;
 const NULL_ADDRESS = '0x0000000000000000000000000000000000000000';
 const {
-	numberSchema,
-	addressSchema,
-	ecSignatureSchema,
-	ecSignatureParameterSchema,
-	orderCancellationRequestsSchema,
-	orderFillOrKillRequestsSchema,
-	orderFillRequestsSchema,
-	orderHashSchema,
-	orderSchema,
-	signedOrderSchema,
-	signedOrdersSchema,
-	blockParamSchema,
-	blockRangeSchema,
-	tokenSchema,
-	jsNumber,
-	txDataSchema,
-	relayerApiErrorResponseSchema,
-	relayerApiOrderBookResponseSchema,
-	relayerApiTokenPairsResponseSchema,
-	relayerApiFeesPayloadSchema,
-	relayerApiFeesResponseSchema,
-	relayerApiOrderbookChannelSubscribeSchema,
-	relayerApiOrderbookChannelUpdateSchema,
-	relayerApiOrderbookChannelSnapshotSchema,
+    numberSchema,
+    addressSchema,
+    ecSignatureSchema,
+    ecSignatureParameterSchema,
+    orderCancellationRequestsSchema,
+    orderFillOrKillRequestsSchema,
+    orderFillRequestsSchema,
+    orderHashSchema,
+    orderSchema,
+    signedOrderSchema,
+    signedOrdersSchema,
+    blockParamSchema,
+    blockRangeSchema,
+    tokenSchema,
+    jsNumber,
+    txDataSchema,
+    relayerApiErrorResponseSchema,
+    relayerApiOrderBookResponseSchema,
+    relayerApiTokenPairsResponseSchema,
+    relayerApiFeesPayloadSchema,
+    relayerApiFeesResponseSchema,
+    relayerApiOrderbookChannelSubscribeSchema,
+    relayerApiOrderbookChannelUpdateSchema,
+    relayerApiOrderbookChannelSnapshotSchema,
 } = schemas;
 
 describe('Schema', () => {
-	const validator = new SchemaValidator();
-	const validateAgainstSchema = (testCases: any[], schema: any, shouldFail = false) => {
-		forEach(testCases, (testCase: any) => {
-			const validationResult = validator.validate(testCase, schema);
-			const hasErrors = validationResult.errors.length !== 0;
-			if (shouldFail) {
-				if (!hasErrors) {
-					throw new Error(
-						`Expected testCase: ${JSON.stringify(testCase, null, '\t')} to fail and it didn't.`,
-					);
-				}
-			} else {
-				if (hasErrors) {
-					throw new Error(JSON.stringify(validationResult.errors, null, '\t'));
-				}
-			}
-		});
-	};
-	describe('#numberSchema', () => {
-		it('should validate valid numbers', () => {
-			const testCases = ['42', '0', '1.3', '0.2', '00.00'];
-			validateAgainstSchema(testCases, numberSchema);
-		});
-		it('should fail for invalid numbers', () => {
-			const testCases = ['.3', '1.', 'abacaba', 'и', '1..0'];
-			const shouldFail = true;
-			validateAgainstSchema(testCases, numberSchema, shouldFail);
-		});
-	});
-	describe('#addressSchema', () => {
-		it('should validate valid addresses', () => {
-			const testCases = ['0x8b0292b11a196601ed2ce54b665cafeca0347d42', NULL_ADDRESS];
-			validateAgainstSchema(testCases, addressSchema);
-		});
-		it('should fail for invalid addresses', () => {
-			const testCases = [
-				'0x',
-				'0',
-				'0x00',
-				'0xzzzzzzB11a196601eD2ce54B665CaFEca0347D42',
-				'0x8b0292B11a196601eD2ce54B665CaFEca0347D42',
-			];
-			const shouldFail = true;
-			validateAgainstSchema(testCases, addressSchema, shouldFail);
-		});
-	});
-	describe('#ecSignatureParameterSchema', () => {
-		it('should validate valid parameters', () => {
-			const testCases = [
-				'0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
-				'0X40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
-			];
-			validateAgainstSchema(testCases, ecSignatureParameterSchema);
-		});
-		it('should fail for invalid parameters', () => {
-			const testCases = [
-				'0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc3', // shorter
-				'0xzzzz9190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254', // invalid characters
-				'40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254', // no 0x
-			];
-			const shouldFail = true;
-			validateAgainstSchema(testCases, ecSignatureParameterSchema, shouldFail);
-		});
-	});
-	describe('#ecSignatureSchema', () => {
-		it('should validate valid signature', () => {
-			const signature = {
-				v: 27,
-				r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
-				s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
-			};
-			const testCases = [
-				signature,
-				{
-					...signature,
-					v: 28,
-				},
-			];
-			validateAgainstSchema(testCases, ecSignatureSchema);
-		});
-		it('should fail for invalid signature', () => {
-			const v = 27;
-			const r = '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33';
-			const s = '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254';
-			const testCases = [{}, { v }, { r, s, v: 31 }];
-			const shouldFail = true;
-			validateAgainstSchema(testCases, ecSignatureSchema, shouldFail);
-		});
-	});
-	describe('#orderHashSchema', () => {
-		it('should validate valid order hash', () => {
-			const testCases = [
-				'0x61a3ed31B43c8780e905a260a35faefEc527be7516aa11c0256729b5b351bc33',
-				'0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
-			];
-			validateAgainstSchema(testCases, orderHashSchema);
-		});
-		it('should fail for invalid order hash', () => {
-			const testCases = [
-				{},
-				'0x',
-				'0x8b0292B11a196601eD2ce54B665CaFEca0347D42',
-				'61a3ed31B43c8780e905a260a35faefEc527be7516aa11c0256729b5b351bc33',
-			];
-			const shouldFail = true;
-			validateAgainstSchema(testCases, orderHashSchema, shouldFail);
-		});
-	});
-	describe('#blockParamSchema', () => {
-		it('should validate valid block param', () => {
-			const testCases = [42, 'latest', 'pending', 'earliest'];
-			validateAgainstSchema(testCases, blockParamSchema);
-		});
-		it('should fail for invalid block param', () => {
-			const testCases = [{}, '42', 'pemding'];
-			const shouldFail = true;
-			validateAgainstSchema(testCases, blockParamSchema, shouldFail);
-		});
-	});
-	describe('#blockRangeSchema', () => {
-		it('should validate valid subscription opts', () => {
-			const testCases = [{ fromBlock: 42, toBlock: 'latest' }, { fromBlock: 42 }, {}];
-			validateAgainstSchema(testCases, blockRangeSchema);
-		});
-		it('should fail for invalid subscription opts', () => {
-			const testCases = [{ fromBlock: '42' }];
-			const shouldFail = true;
-			validateAgainstSchema(testCases, blockRangeSchema, shouldFail);
-		});
-	});
-	describe('#tokenSchema', () => {
-		const token = {
-			name: 'Zero Ex',
-			symbol: 'ZRX',
-			decimals: 100500,
-			address: '0x8b0292b11a196601ed2ce54b665cafeca0347d42',
-			url: 'https://0xproject.com',
-		};
-		it('should validate valid token', () => {
-			const testCases = [token];
-			validateAgainstSchema(testCases, tokenSchema);
-		});
-		it('should fail for invalid token', () => {
-			const testCases = [
-				{
-					...token,
-					address: null,
-				},
-				{
-					...token,
-					decimals: undefined,
-				},
-				[],
-				4,
-			];
-			const shouldFail = true;
-			validateAgainstSchema(testCases, tokenSchema, shouldFail);
-		});
-	});
-	describe('order including schemas', () => {
-		const order = {
-			maker: NULL_ADDRESS,
-			taker: NULL_ADDRESS,
-			makerFee: '1',
-			takerFee: '2',
-			makerTokenAmount: '1',
-			takerTokenAmount: '2',
-			makerTokenAddress: NULL_ADDRESS,
-			takerTokenAddress: NULL_ADDRESS,
-			salt: '67006738228878699843088602623665307406148487219438534730168799356281242528500',
-			feeRecipient: NULL_ADDRESS,
-			exchangeContractAddress: NULL_ADDRESS,
-			expirationUnixTimestampSec: '42',
-		};
-		describe('#orderSchema', () => {
-			it('should validate valid order', () => {
-				const testCases = [order];
-				validateAgainstSchema(testCases, orderSchema);
-			});
-			it('should fail for invalid order', () => {
-				const testCases = [
-					{
-						...order,
-						salt: undefined,
-					},
-					{
-						...order,
-						salt: 'salt',
-					},
-					'order',
-				];
-				const shouldFail = true;
-				validateAgainstSchema(testCases, orderSchema, shouldFail);
-			});
-		});
-		describe('signed order including schemas', () => {
-			const signedOrder = {
-				...order,
-				ecSignature: {
-					v: 27,
-					r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
-					s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
-				},
-			};
-			describe('#signedOrdersSchema', () => {
-				it('should validate valid signed orders', () => {
-					const testCases = [[signedOrder], []];
-					validateAgainstSchema(testCases, signedOrdersSchema);
-				});
-				it('should fail for invalid signed orders', () => {
-					const testCases = [[signedOrder, 1]];
-					const shouldFail = true;
-					validateAgainstSchema(testCases, signedOrdersSchema, shouldFail);
-				});
-			});
-			describe('#signedOrderSchema', () => {
-				it('should validate valid signed order', () => {
-					const testCases = [signedOrder];
-					validateAgainstSchema(testCases, signedOrderSchema);
-				});
-				it('should fail for invalid signed order', () => {
-					const testCases = [
-						{
-							...signedOrder,
-							ecSignature: undefined,
-						},
-					];
-					const shouldFail = true;
-					validateAgainstSchema(testCases, signedOrderSchema, shouldFail);
-				});
-			});
-			describe('#orderFillOrKillRequestsSchema', () => {
-				const orderFillOrKillRequests = [
-					{
-						signedOrder,
-						fillTakerAmount: '5',
-					},
-				];
-				it('should validate valid order fill or kill requests', () => {
-					const testCases = [orderFillOrKillRequests];
-					validateAgainstSchema(testCases, orderFillOrKillRequestsSchema);
-				});
-				it('should fail for invalid order fill or kill requests', () => {
-					const testCases = [
-						[
-							{
-								...orderFillOrKillRequests[0],
-								fillTakerAmount: undefined,
-							},
-						],
-					];
-					const shouldFail = true;
-					validateAgainstSchema(testCases, orderFillOrKillRequestsSchema, shouldFail);
-				});
-			});
-			describe('#orderCancellationRequestsSchema', () => {
-				const orderCancellationRequests = [
-					{
-						order,
-						takerTokenCancelAmount: '5',
-					},
-				];
-				it('should validate valid order cancellation requests', () => {
-					const testCases = [orderCancellationRequests];
-					validateAgainstSchema(testCases, orderCancellationRequestsSchema);
-				});
-				it('should fail for invalid order cancellation requests', () => {
-					const testCases = [
-						[
-							{
-								...orderCancellationRequests[0],
-								takerTokenCancelAmount: undefined,
-							},
-						],
-					];
-					const shouldFail = true;
-					validateAgainstSchema(testCases, orderCancellationRequestsSchema, shouldFail);
-				});
-			});
-			describe('#orderFillRequestsSchema', () => {
-				const orderFillRequests = [
-					{
-						signedOrder,
-						takerTokenFillAmount: '5',
-					},
-				];
-				it('should validate valid order fill requests', () => {
-					const testCases = [orderFillRequests];
-					validateAgainstSchema(testCases, orderFillRequestsSchema);
-				});
-				it('should fail for invalid order fill requests', () => {
-					const testCases = [
-						[
-							{
-								...orderFillRequests[0],
-								takerTokenFillAmount: undefined,
-							},
-						],
-					];
-					const shouldFail = true;
-					validateAgainstSchema(testCases, orderFillRequestsSchema, shouldFail);
-				});
-			});
-			describe('#relayerApiOrderBookResponseSchema', () => {
-				it('should validate valid order book responses', () => {
-					const testCases = [
-						{
-							bids: [],
-							asks: [],
-						},
-						{
-							bids: [signedOrder, signedOrder],
-							asks: [],
-						},
-						{
-							bids: [],
-							asks: [signedOrder, signedOrder],
-						},
-						{
-							bids: [signedOrder],
-							asks: [signedOrder, signedOrder],
-						},
-					];
-					validateAgainstSchema(testCases, relayerApiOrderBookResponseSchema);
-				});
-				it('should fail for invalid order fill requests', () => {
-					const testCases = [
-						{},
-						{
-							bids: [signedOrder, signedOrder],
-						},
-						{
-							asks: [signedOrder, signedOrder],
-						},
-						{
-							bids: signedOrder,
-							asks: [signedOrder, signedOrder],
-						},
-						{
-							bids: [signedOrder],
-							asks: signedOrder,
-						},
-					];
-					const shouldFail = true;
-					validateAgainstSchema(testCases, relayerApiOrderBookResponseSchema, shouldFail);
-				});
-			});
-			describe('#relayerApiOrderbookChannelSubscribeSchema', () => {
-				it('should validate valid orderbook channel websocket subscribe message', () => {
-					const testCases = [
-						{
-							type: 'subscribe',
-							channel: 'orderbook',
-							requestId: 1,
-							payload: {
-								baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-								quoteTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-								snapshot: true,
-								limit: 100,
-							},
-						},
-						{
-							type: 'subscribe',
-							channel: 'orderbook',
-							requestId: 1,
-							payload: {
-								baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-								quoteTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-							},
-						},
-					];
-					validateAgainstSchema(testCases, relayerApiOrderbookChannelSubscribeSchema);
-				});
-				it('should fail for invalid orderbook channel websocket subscribe message', () => {
-					const checksummedAddress = '0xA2b31daCf30a9C50ca473337c01d8A201ae33e32';
-					const testCases = [
-						{
-							type: 'subscribe',
-							channel: 'orderbook',
-							payload: {
-								baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-								quoteTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-								snapshot: true,
-								limit: 100,
-							},
-						},
-						{
-							type: 'foo',
-							channel: 'orderbook',
-							requestId: 1,
-							payload: {
-								baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-								quoteTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-							},
-						},
-						{
-							type: 'subscribe',
-							channel: 'bar',
-							requestId: 1,
-							payload: {
-								baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-								quoteTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-							},
-						},
-						{
-							type: 'subscribe',
-							channel: 'orderbook',
-							requestId: 1,
-							payload: {
-								baseTokenAddress: checksummedAddress,
-								quoteTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-							},
-						},
-						{
-							type: 'subscribe',
-							channel: 'orderbook',
-							requestId: 1,
-							payload: {
-								baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-								quoteTokenAddress: checksummedAddress,
-							},
-						},
-						{
-							type: 'subscribe',
-							channel: 'orderbook',
-							requestId: 1,
-							payload: {
-								quoteTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-							},
-						},
-						{
-							type: 'subscribe',
-							channel: 'orderbook',
-							requestId: 1,
-							payload: {
-								baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-							},
-						},
-						{
-							type: 'subscribe',
-							channel: 'orderbook',
-							requestId: 1,
-							payload: {
-								baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-								quoteTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-								snapshot: 'true',
-								limit: 100,
-							},
-						},
-						{
-							type: 'subscribe',
-							channel: 'orderbook',
-							requestId: 1,
-							payload: {
-								baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-								quoteTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-								snapshot: true,
-								limit: '100',
-							},
-						},
-					];
-					const shouldFail = true;
-					validateAgainstSchema(testCases, relayerApiOrderbookChannelSubscribeSchema, shouldFail);
-				});
-			});
-			describe('#relayerApiOrderbookChannelSnapshotSchema', () => {
-				it('should validate valid orderbook channel websocket snapshot message', () => {
-					const testCases = [
-						{
-							type: 'snapshot',
-							channel: 'orderbook',
-							requestId: 2,
-							payload: {
-								bids: [],
-								asks: [],
-							},
-						},
-						{
-							type: 'snapshot',
-							channel: 'orderbook',
-							requestId: 2,
-							payload: {
-								bids: [signedOrder],
-								asks: [signedOrder],
-							},
-						},
-					];
-					validateAgainstSchema(testCases, relayerApiOrderbookChannelSnapshotSchema);
-				});
-				it('should fail for invalid orderbook channel websocket snapshot message', () => {
-					const testCases = [
-						{
-							type: 'foo',
-							channel: 'orderbook',
-							requestId: 2,
-							payload: {
-								bids: [signedOrder],
-								asks: [signedOrder],
-							},
-						},
-						{
-							type: 'snapshot',
-							channel: 'bar',
-							requestId: 2,
-							payload: {
-								bids: [signedOrder],
-								asks: [signedOrder],
-							},
-						},
-						{
-							type: 'snapshot',
-							channel: 'orderbook',
-							payload: {
-								bids: [signedOrder],
-								asks: [signedOrder],
-							},
-						},
-						{
-							type: 'snapshot',
-							channel: 'orderbook',
-							requestId: '2',
-							payload: {
-								bids: [signedOrder],
-								asks: [signedOrder],
-							},
-						},
-						{
-							type: 'snapshot',
-							channel: 'orderbook',
-							requestId: 2,
-							payload: {
-								bids: [signedOrder],
-							},
-						},
-						{
-							type: 'snapshot',
-							channel: 'orderbook',
-							requestId: 2,
-							payload: {
-								asks: [signedOrder],
-							},
-						},
-						{
-							type: 'snapshot',
-							channel: 'orderbook',
-							requestId: 2,
-							payload: {
-								bids: [signedOrder],
-								asks: [{}],
-							},
-						},
-						{
-							type: 'snapshot',
-							channel: 'orderbook',
-							requestId: 2,
-							payload: {
-								bids: [{}],
-								asks: [signedOrder],
-							},
-						},
-					];
-					const shouldFail = true;
-					validateAgainstSchema(testCases, relayerApiOrderbookChannelSnapshotSchema, shouldFail);
-				});
-			});
-			describe('#relayerApiOrderbookChannelUpdateSchema', () => {
-				it('should validate valid orderbook channel websocket update message', () => {
-					const testCases = [
-						{
-							type: 'update',
-							channel: 'orderbook',
-							requestId: 2,
-							payload: signedOrder,
-						},
-					];
-					validateAgainstSchema(testCases, relayerApiOrderbookChannelUpdateSchema);
-				});
-				it('should fail for invalid orderbook channel websocket update message', () => {
-					const testCases = [
-						{
-							type: 'foo',
-							channel: 'orderbook',
-							requestId: 2,
-							payload: signedOrder,
-						},
-						{
-							type: 'update',
-							channel: 'bar',
-							requestId: 2,
-							payload: signedOrder,
-						},
-						{
-							type: 'update',
-							channel: 'orderbook',
-							requestId: 2,
-							payload: {},
-						},
-					];
-					const shouldFail = true;
-					validateAgainstSchema(testCases, relayerApiOrderbookChannelUpdateSchema, shouldFail);
-				});
-			});
-		});
-	});
-	describe('BigNumber serialization', () => {
-		it('should correctly serialize BigNumbers', () => {
-			const testCases = {
-				'42': '42',
-				'0': '0',
-				'1.3': '1.3',
-				'0.2': '0.2',
-				'00.00': '0',
-				'.3': '0.3',
-			};
-			forEach(testCases, (serialized: string, input: string) => {
-				expect(JSON.parse(JSON.stringify(new BigNumber(input)))).to.be.equal(serialized);
-			});
-		});
-	});
-	describe('#relayerApiErrorResponseSchema', () => {
-		it('should validate valid errorResponse', () => {
-			const testCases = [
-				{
-					code: 102,
-					reason: 'Order submission disabled',
-				},
-				{
-					code: 101,
-					reason: 'Validation failed',
-					validationErrors: [
-						{
-							field: 'maker',
-							code: 1002,
-							reason: 'Invalid address',
-						},
-					],
-				},
-			];
-			validateAgainstSchema(testCases, relayerApiErrorResponseSchema);
-		});
-		it('should fail for invalid error responses', () => {
-			const testCases = [
-				{},
-				{
-					code: 102,
-				},
-				{
-					code: '102',
-					reason: 'Order submission disabled',
-				},
-				{
-					reason: 'Order submission disabled',
-				},
-				{
-					code: 101,
-					reason: 'Validation failed',
-					validationErrors: [
-						{
-							field: 'maker',
-							reason: 'Invalid address',
-						},
-					],
-				},
-				{
-					code: 101,
-					reason: 'Validation failed',
-					validationErrors: [
-						{
-							field: 'maker',
-							code: '1002',
-							reason: 'Invalid address',
-						},
-					],
-				},
-			];
-			const shouldFail = true;
-			validateAgainstSchema(testCases, relayerApiErrorResponseSchema, shouldFail);
-		});
-	});
-	describe('#relayerApiFeesPayloadSchema', () => {
-		it('should validate valid fees payloads', () => {
-			const testCases = [
-				{
-					exchangeContractAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-					maker: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-					taker: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-					makerTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-					takerTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
-					makerTokenAmount: '10000000000000000000',
-					takerTokenAmount: '30000000000000000000',
-					expirationUnixTimestampSec: '42',
-					salt: '67006738228878699843088602623665307406148487219438534730168799356281242528500',
-				},
-			];
-			validateAgainstSchema(testCases, relayerApiFeesPayloadSchema);
-		});
-		it('should fail for invalid fees payloads', () => {
-			const checksummedAddress = '0xA2b31daCf30a9C50ca473337c01d8A201ae33e32';
-			const testCases = [
-				{},
-				{
-					takerTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
-					makerTokenAmount: '10000000000000000000',
-					takerTokenAmount: '30000000000000000000',
-				},
-				{
-					taker: checksummedAddress,
-					makerTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-					takerTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
-					makerTokenAmount: '10000000000000000000',
-					takerTokenAmount: '30000000000000000000',
-				},
-				{
-					makerTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-					takerTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
-					makerTokenAmount: 10000000000000000000,
-					takerTokenAmount: 30000000000000000000,
-				},
-			];
-			const shouldFail = true;
-			validateAgainstSchema(testCases, relayerApiFeesPayloadSchema, shouldFail);
-		});
-	});
-	describe('#relayerApiFeesResponseSchema', () => {
-		it('should validate valid fees responses', () => {
-			const testCases = [
-				{
-					makerFee: '10000000000000000',
-					takerFee: '30000000000000000',
-					feeRecipient: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-				},
-			];
-			validateAgainstSchema(testCases, relayerApiFeesResponseSchema);
-		});
-		it('should fail for invalid fees responses', () => {
-			const checksummedAddress = '0xA2b31daCf30a9C50ca473337c01d8A201ae33e32';
-			const testCases = [
-				{},
-				{
-					makerFee: 10000000000000000,
-					takerFee: 30000000000000000,
-				},
-				{
-					feeRecipient: checksummedAddress,
-					takerToSpecify: checksummedAddress,
-					makerFee: '10000000000000000',
-					takerFee: '30000000000000000',
-				},
-			];
-			const shouldFail = true;
-			validateAgainstSchema(testCases, relayerApiFeesResponseSchema, shouldFail);
-		});
-	});
-	describe('#relayerApiTokenPairsResponseSchema', () => {
-		it('should validate valid tokenPairs response', () => {
-			const testCases = [
-				[],
-				[
-					{
-						tokenA: {
-							address: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-							minAmount: '0',
-							maxAmount: '10000000000000000000',
-							precision: 5,
-						},
-						tokenB: {
-							address: '0xef7fff64389b814a946f3e92105513705ca6b990',
-							minAmount: '0',
-							maxAmount: '50000000000000000000',
-							precision: 5,
-						},
-					},
-				],
-				[
-					{
-						tokenA: {
-							address: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-						},
-						tokenB: {
-							address: '0xef7fff64389b814a946f3e92105513705ca6b990',
-						},
-					},
-				],
-			];
-			validateAgainstSchema(testCases, relayerApiTokenPairsResponseSchema);
-		});
-		it('should fail for invalid tokenPairs responses', () => {
-			const checksummedAddress = '0xA2b31daCf30a9C50ca473337c01d8A201ae33e32';
-			const testCases = [
-				[
-					{
-						tokenA: {
-							address: checksummedAddress,
-						},
-						tokenB: {
-							address: checksummedAddress,
-						},
-					},
-				],
-				[
-					{
-						tokenA: {
-							address: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-							minAmount: 0,
-							maxAmount: 10000000000000000000,
-						},
-						tokenB: {
-							address: '0xef7fff64389b814a946f3e92105513705ca6b990',
-							minAmount: 0,
-							maxAmount: 50000000000000000000,
-						},
-					},
-				],
-				[
-					{
-						tokenA: {
-							address: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
-							precision: '5',
-						},
-						tokenB: {
-							address: '0xef7fff64389b814a946f3e92105513705ca6b990',
-							precision: '5',
-						},
-					},
-				],
-			];
-			const shouldFail = true;
-			validateAgainstSchema(testCases, relayerApiTokenPairsResponseSchema, shouldFail);
-		});
-	});
-	describe('#jsNumberSchema', () => {
-		it('should validate valid js number', () => {
-			const testCases = [1, 42];
-			validateAgainstSchema(testCases, jsNumber);
-		});
-		it('should fail for invalid js number', () => {
-			const testCases = [NaN, -1, new BigNumber(1)];
-			const shouldFail = true;
-			validateAgainstSchema(testCases, jsNumber, shouldFail);
-		});
-	});
-	describe('#txDataSchema', () => {
-		it('should validate valid txData', () => {
-			const testCases = [
-				{
-					from: NULL_ADDRESS,
-				},
-				{
-					from: NULL_ADDRESS,
-					gas: new BigNumber(42),
-				},
-				{
-					from: NULL_ADDRESS,
-					gas: 42,
-				},
-			];
-			validateAgainstSchema(testCases, txDataSchema);
-		});
-		it('should fail for invalid txData', () => {
-			const testCases = [
-				{
-					gas: new BigNumber(42),
-				},
-				{
-					from: NULL_ADDRESS,
-					unknownProp: 'here',
-				},
-				{},
-				[],
-				new BigNumber(1),
-			];
-			const shouldFail = true;
-			validateAgainstSchema(testCases, txDataSchema, shouldFail);
-		});
-	});
+    const validator = new SchemaValidator();
+    const validateAgainstSchema = (testCases: any[], schema: any, shouldFail = false) => {
+        forEach(testCases, (testCase: any) => {
+            const validationResult = validator.validate(testCase, schema);
+            const hasErrors = validationResult.errors.length !== 0;
+            if (shouldFail) {
+                if (!hasErrors) {
+                    throw new Error(
+                        `Expected testCase: ${JSON.stringify(testCase, null, '\t')} to fail and it didn't.`,
+                    );
+                }
+            } else {
+                if (hasErrors) {
+                    throw new Error(JSON.stringify(validationResult.errors, null, '\t'));
+                }
+            }
+        });
+    };
+    describe('#numberSchema', () => {
+        it('should validate valid numbers', () => {
+            const testCases = ['42', '0', '1.3', '0.2', '00.00'];
+            validateAgainstSchema(testCases, numberSchema);
+        });
+        it('should fail for invalid numbers', () => {
+            const testCases = ['.3', '1.', 'abacaba', 'и', '1..0'];
+            const shouldFail = true;
+            validateAgainstSchema(testCases, numberSchema, shouldFail);
+        });
+    });
+    describe('#addressSchema', () => {
+        it('should validate valid addresses', () => {
+            const testCases = ['0x8b0292b11a196601ed2ce54b665cafeca0347d42', NULL_ADDRESS];
+            validateAgainstSchema(testCases, addressSchema);
+        });
+        it('should fail for invalid addresses', () => {
+            const testCases = [
+                '0x',
+                '0',
+                '0x00',
+                '0xzzzzzzB11a196601eD2ce54B665CaFEca0347D42',
+                '0x8b0292B11a196601eD2ce54B665CaFEca0347D42',
+            ];
+            const shouldFail = true;
+            validateAgainstSchema(testCases, addressSchema, shouldFail);
+        });
+    });
+    describe('#ecSignatureParameterSchema', () => {
+        it('should validate valid parameters', () => {
+            const testCases = [
+                '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
+                '0X40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
+            ];
+            validateAgainstSchema(testCases, ecSignatureParameterSchema);
+        });
+        it('should fail for invalid parameters', () => {
+            const testCases = [
+                '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc3', // shorter
+                '0xzzzz9190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254', // invalid characters
+                '40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254', // no 0x
+            ];
+            const shouldFail = true;
+            validateAgainstSchema(testCases, ecSignatureParameterSchema, shouldFail);
+        });
+    });
+    describe('#ecSignatureSchema', () => {
+        it('should validate valid signature', () => {
+            const signature = {
+                v: 27,
+                r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
+                s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
+            };
+            const testCases = [
+                signature,
+                {
+                    ...signature,
+                    v: 28,
+                },
+            ];
+            validateAgainstSchema(testCases, ecSignatureSchema);
+        });
+        it('should fail for invalid signature', () => {
+            const v = 27;
+            const r = '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33';
+            const s = '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254';
+            const testCases = [{}, { v }, { r, s, v: 31 }];
+            const shouldFail = true;
+            validateAgainstSchema(testCases, ecSignatureSchema, shouldFail);
+        });
+    });
+    describe('#orderHashSchema', () => {
+        it('should validate valid order hash', () => {
+            const testCases = [
+                '0x61a3ed31B43c8780e905a260a35faefEc527be7516aa11c0256729b5b351bc33',
+                '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
+            ];
+            validateAgainstSchema(testCases, orderHashSchema);
+        });
+        it('should fail for invalid order hash', () => {
+            const testCases = [
+                {},
+                '0x',
+                '0x8b0292B11a196601eD2ce54B665CaFEca0347D42',
+                '61a3ed31B43c8780e905a260a35faefEc527be7516aa11c0256729b5b351bc33',
+            ];
+            const shouldFail = true;
+            validateAgainstSchema(testCases, orderHashSchema, shouldFail);
+        });
+    });
+    describe('#blockParamSchema', () => {
+        it('should validate valid block param', () => {
+            const testCases = [42, 'latest', 'pending', 'earliest'];
+            validateAgainstSchema(testCases, blockParamSchema);
+        });
+        it('should fail for invalid block param', () => {
+            const testCases = [{}, '42', 'pemding'];
+            const shouldFail = true;
+            validateAgainstSchema(testCases, blockParamSchema, shouldFail);
+        });
+    });
+    describe('#blockRangeSchema', () => {
+        it('should validate valid subscription opts', () => {
+            const testCases = [{ fromBlock: 42, toBlock: 'latest' }, { fromBlock: 42 }, {}];
+            validateAgainstSchema(testCases, blockRangeSchema);
+        });
+        it('should fail for invalid subscription opts', () => {
+            const testCases = [{ fromBlock: '42' }];
+            const shouldFail = true;
+            validateAgainstSchema(testCases, blockRangeSchema, shouldFail);
+        });
+    });
+    describe('#tokenSchema', () => {
+        const token = {
+            name: 'Zero Ex',
+            symbol: 'ZRX',
+            decimals: 100500,
+            address: '0x8b0292b11a196601ed2ce54b665cafeca0347d42',
+            url: 'https://0xproject.com',
+        };
+        it('should validate valid token', () => {
+            const testCases = [token];
+            validateAgainstSchema(testCases, tokenSchema);
+        });
+        it('should fail for invalid token', () => {
+            const testCases = [
+                {
+                    ...token,
+                    address: null,
+                },
+                {
+                    ...token,
+                    decimals: undefined,
+                },
+                [],
+                4,
+            ];
+            const shouldFail = true;
+            validateAgainstSchema(testCases, tokenSchema, shouldFail);
+        });
+    });
+    describe('order including schemas', () => {
+        const order = {
+            maker: NULL_ADDRESS,
+            taker: NULL_ADDRESS,
+            makerFee: '1',
+            takerFee: '2',
+            makerTokenAmount: '1',
+            takerTokenAmount: '2',
+            makerTokenAddress: NULL_ADDRESS,
+            takerTokenAddress: NULL_ADDRESS,
+            salt: '67006738228878699843088602623665307406148487219438534730168799356281242528500',
+            feeRecipient: NULL_ADDRESS,
+            exchangeContractAddress: NULL_ADDRESS,
+            expirationUnixTimestampSec: '42',
+        };
+        describe('#orderSchema', () => {
+            it('should validate valid order', () => {
+                const testCases = [order];
+                validateAgainstSchema(testCases, orderSchema);
+            });
+            it('should fail for invalid order', () => {
+                const testCases = [
+                    {
+                        ...order,
+                        salt: undefined,
+                    },
+                    {
+                        ...order,
+                        salt: 'salt',
+                    },
+                    'order',
+                ];
+                const shouldFail = true;
+                validateAgainstSchema(testCases, orderSchema, shouldFail);
+            });
+        });
+        describe('signed order including schemas', () => {
+            const signedOrder = {
+                ...order,
+                ecSignature: {
+                    v: 27,
+                    r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
+                    s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
+                },
+            };
+            describe('#signedOrdersSchema', () => {
+                it('should validate valid signed orders', () => {
+                    const testCases = [[signedOrder], []];
+                    validateAgainstSchema(testCases, signedOrdersSchema);
+                });
+                it('should fail for invalid signed orders', () => {
+                    const testCases = [[signedOrder, 1]];
+                    const shouldFail = true;
+                    validateAgainstSchema(testCases, signedOrdersSchema, shouldFail);
+                });
+            });
+            describe('#signedOrderSchema', () => {
+                it('should validate valid signed order', () => {
+                    const testCases = [signedOrder];
+                    validateAgainstSchema(testCases, signedOrderSchema);
+                });
+                it('should fail for invalid signed order', () => {
+                    const testCases = [
+                        {
+                            ...signedOrder,
+                            ecSignature: undefined,
+                        },
+                    ];
+                    const shouldFail = true;
+                    validateAgainstSchema(testCases, signedOrderSchema, shouldFail);
+                });
+            });
+            describe('#orderFillOrKillRequestsSchema', () => {
+                const orderFillOrKillRequests = [
+                    {
+                        signedOrder,
+                        fillTakerAmount: '5',
+                    },
+                ];
+                it('should validate valid order fill or kill requests', () => {
+                    const testCases = [orderFillOrKillRequests];
+                    validateAgainstSchema(testCases, orderFillOrKillRequestsSchema);
+                });
+                it('should fail for invalid order fill or kill requests', () => {
+                    const testCases = [
+                        [
+                            {
+                                ...orderFillOrKillRequests[0],
+                                fillTakerAmount: undefined,
+                            },
+                        ],
+                    ];
+                    const shouldFail = true;
+                    validateAgainstSchema(testCases, orderFillOrKillRequestsSchema, shouldFail);
+                });
+            });
+            describe('#orderCancellationRequestsSchema', () => {
+                const orderCancellationRequests = [
+                    {
+                        order,
+                        takerTokenCancelAmount: '5',
+                    },
+                ];
+                it('should validate valid order cancellation requests', () => {
+                    const testCases = [orderCancellationRequests];
+                    validateAgainstSchema(testCases, orderCancellationRequestsSchema);
+                });
+                it('should fail for invalid order cancellation requests', () => {
+                    const testCases = [
+                        [
+                            {
+                                ...orderCancellationRequests[0],
+                                takerTokenCancelAmount: undefined,
+                            },
+                        ],
+                    ];
+                    const shouldFail = true;
+                    validateAgainstSchema(testCases, orderCancellationRequestsSchema, shouldFail);
+                });
+            });
+            describe('#orderFillRequestsSchema', () => {
+                const orderFillRequests = [
+                    {
+                        signedOrder,
+                        takerTokenFillAmount: '5',
+                    },
+                ];
+                it('should validate valid order fill requests', () => {
+                    const testCases = [orderFillRequests];
+                    validateAgainstSchema(testCases, orderFillRequestsSchema);
+                });
+                it('should fail for invalid order fill requests', () => {
+                    const testCases = [
+                        [
+                            {
+                                ...orderFillRequests[0],
+                                takerTokenFillAmount: undefined,
+                            },
+                        ],
+                    ];
+                    const shouldFail = true;
+                    validateAgainstSchema(testCases, orderFillRequestsSchema, shouldFail);
+                });
+            });
+            describe('#relayerApiOrderBookResponseSchema', () => {
+                it('should validate valid order book responses', () => {
+                    const testCases = [
+                        {
+                            bids: [],
+                            asks: [],
+                        },
+                        {
+                            bids: [signedOrder, signedOrder],
+                            asks: [],
+                        },
+                        {
+                            bids: [],
+                            asks: [signedOrder, signedOrder],
+                        },
+                        {
+                            bids: [signedOrder],
+                            asks: [signedOrder, signedOrder],
+                        },
+                    ];
+                    validateAgainstSchema(testCases, relayerApiOrderBookResponseSchema);
+                });
+                it('should fail for invalid order fill requests', () => {
+                    const testCases = [
+                        {},
+                        {
+                            bids: [signedOrder, signedOrder],
+                        },
+                        {
+                            asks: [signedOrder, signedOrder],
+                        },
+                        {
+                            bids: signedOrder,
+                            asks: [signedOrder, signedOrder],
+                        },
+                        {
+                            bids: [signedOrder],
+                            asks: signedOrder,
+                        },
+                    ];
+                    const shouldFail = true;
+                    validateAgainstSchema(testCases, relayerApiOrderBookResponseSchema, shouldFail);
+                });
+            });
+            describe('#relayerApiOrderbookChannelSubscribeSchema', () => {
+                it('should validate valid orderbook channel websocket subscribe message', () => {
+                    const testCases = [
+                        {
+                            type: 'subscribe',
+                            channel: 'orderbook',
+                            requestId: 1,
+                            payload: {
+                                baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+                                quoteTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+                                snapshot: true,
+                                limit: 100,
+                            },
+                        },
+                        {
+                            type: 'subscribe',
+                            channel: 'orderbook',
+                            requestId: 1,
+                            payload: {
+                                baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+                                quoteTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+                            },
+                        },
+                    ];
+                    validateAgainstSchema(testCases, relayerApiOrderbookChannelSubscribeSchema);
+                });
+                it('should fail for invalid orderbook channel websocket subscribe message', () => {
+                    const checksummedAddress = '0xA2b31daCf30a9C50ca473337c01d8A201ae33e32';
+                    const testCases = [
+                        {
+                            type: 'subscribe',
+                            channel: 'orderbook',
+                            payload: {
+                                baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+                                quoteTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+                                snapshot: true,
+                                limit: 100,
+                            },
+                        },
+                        {
+                            type: 'foo',
+                            channel: 'orderbook',
+                            requestId: 1,
+                            payload: {
+                                baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+                                quoteTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+                            },
+                        },
+                        {
+                            type: 'subscribe',
+                            channel: 'bar',
+                            requestId: 1,
+                            payload: {
+                                baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+                                quoteTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+                            },
+                        },
+                        {
+                            type: 'subscribe',
+                            channel: 'orderbook',
+                            requestId: 1,
+                            payload: {
+                                baseTokenAddress: checksummedAddress,
+                                quoteTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+                            },
+                        },
+                        {
+                            type: 'subscribe',
+                            channel: 'orderbook',
+                            requestId: 1,
+                            payload: {
+                                baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+                                quoteTokenAddress: checksummedAddress,
+                            },
+                        },
+                        {
+                            type: 'subscribe',
+                            channel: 'orderbook',
+                            requestId: 1,
+                            payload: {
+                                quoteTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+                            },
+                        },
+                        {
+                            type: 'subscribe',
+                            channel: 'orderbook',
+                            requestId: 1,
+                            payload: {
+                                baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+                            },
+                        },
+                        {
+                            type: 'subscribe',
+                            channel: 'orderbook',
+                            requestId: 1,
+                            payload: {
+                                baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+                                quoteTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+                                snapshot: 'true',
+                                limit: 100,
+                            },
+                        },
+                        {
+                            type: 'subscribe',
+                            channel: 'orderbook',
+                            requestId: 1,
+                            payload: {
+                                baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+                                quoteTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+                                snapshot: true,
+                                limit: '100',
+                            },
+                        },
+                    ];
+                    const shouldFail = true;
+                    validateAgainstSchema(testCases, relayerApiOrderbookChannelSubscribeSchema, shouldFail);
+                });
+            });
+            describe('#relayerApiOrderbookChannelSnapshotSchema', () => {
+                it('should validate valid orderbook channel websocket snapshot message', () => {
+                    const testCases = [
+                        {
+                            type: 'snapshot',
+                            channel: 'orderbook',
+                            requestId: 2,
+                            payload: {
+                                bids: [],
+                                asks: [],
+                            },
+                        },
+                        {
+                            type: 'snapshot',
+                            channel: 'orderbook',
+                            requestId: 2,
+                            payload: {
+                                bids: [signedOrder],
+                                asks: [signedOrder],
+                            },
+                        },
+                    ];
+                    validateAgainstSchema(testCases, relayerApiOrderbookChannelSnapshotSchema);
+                });
+                it('should fail for invalid orderbook channel websocket snapshot message', () => {
+                    const testCases = [
+                        {
+                            type: 'foo',
+                            channel: 'orderbook',
+                            requestId: 2,
+                            payload: {
+                                bids: [signedOrder],
+                                asks: [signedOrder],
+                            },
+                        },
+                        {
+                            type: 'snapshot',
+                            channel: 'bar',
+                            requestId: 2,
+                            payload: {
+                                bids: [signedOrder],
+                                asks: [signedOrder],
+                            },
+                        },
+                        {
+                            type: 'snapshot',
+                            channel: 'orderbook',
+                            payload: {
+                                bids: [signedOrder],
+                                asks: [signedOrder],
+                            },
+                        },
+                        {
+                            type: 'snapshot',
+                            channel: 'orderbook',
+                            requestId: '2',
+                            payload: {
+                                bids: [signedOrder],
+                                asks: [signedOrder],
+                            },
+                        },
+                        {
+                            type: 'snapshot',
+                            channel: 'orderbook',
+                            requestId: 2,
+                            payload: {
+                                bids: [signedOrder],
+                            },
+                        },
+                        {
+                            type: 'snapshot',
+                            channel: 'orderbook',
+                            requestId: 2,
+                            payload: {
+                                asks: [signedOrder],
+                            },
+                        },
+                        {
+                            type: 'snapshot',
+                            channel: 'orderbook',
+                            requestId: 2,
+                            payload: {
+                                bids: [signedOrder],
+                                asks: [{}],
+                            },
+                        },
+                        {
+                            type: 'snapshot',
+                            channel: 'orderbook',
+                            requestId: 2,
+                            payload: {
+                                bids: [{}],
+                                asks: [signedOrder],
+                            },
+                        },
+                    ];
+                    const shouldFail = true;
+                    validateAgainstSchema(testCases, relayerApiOrderbookChannelSnapshotSchema, shouldFail);
+                });
+            });
+            describe('#relayerApiOrderbookChannelUpdateSchema', () => {
+                it('should validate valid orderbook channel websocket update message', () => {
+                    const testCases = [
+                        {
+                            type: 'update',
+                            channel: 'orderbook',
+                            requestId: 2,
+                            payload: signedOrder,
+                        },
+                    ];
+                    validateAgainstSchema(testCases, relayerApiOrderbookChannelUpdateSchema);
+                });
+                it('should fail for invalid orderbook channel websocket update message', () => {
+                    const testCases = [
+                        {
+                            type: 'foo',
+                            channel: 'orderbook',
+                            requestId: 2,
+                            payload: signedOrder,
+                        },
+                        {
+                            type: 'update',
+                            channel: 'bar',
+                            requestId: 2,
+                            payload: signedOrder,
+                        },
+                        {
+                            type: 'update',
+                            channel: 'orderbook',
+                            requestId: 2,
+                            payload: {},
+                        },
+                    ];
+                    const shouldFail = true;
+                    validateAgainstSchema(testCases, relayerApiOrderbookChannelUpdateSchema, shouldFail);
+                });
+            });
+        });
+    });
+    describe('BigNumber serialization', () => {
+        it('should correctly serialize BigNumbers', () => {
+            const testCases = {
+                '42': '42',
+                '0': '0',
+                '1.3': '1.3',
+                '0.2': '0.2',
+                '00.00': '0',
+                '.3': '0.3',
+            };
+            forEach(testCases, (serialized: string, input: string) => {
+                expect(JSON.parse(JSON.stringify(new BigNumber(input)))).to.be.equal(serialized);
+            });
+        });
+    });
+    describe('#relayerApiErrorResponseSchema', () => {
+        it('should validate valid errorResponse', () => {
+            const testCases = [
+                {
+                    code: 102,
+                    reason: 'Order submission disabled',
+                },
+                {
+                    code: 101,
+                    reason: 'Validation failed',
+                    validationErrors: [
+                        {
+                            field: 'maker',
+                            code: 1002,
+                            reason: 'Invalid address',
+                        },
+                    ],
+                },
+            ];
+            validateAgainstSchema(testCases, relayerApiErrorResponseSchema);
+        });
+        it('should fail for invalid error responses', () => {
+            const testCases = [
+                {},
+                {
+                    code: 102,
+                },
+                {
+                    code: '102',
+                    reason: 'Order submission disabled',
+                },
+                {
+                    reason: 'Order submission disabled',
+                },
+                {
+                    code: 101,
+                    reason: 'Validation failed',
+                    validationErrors: [
+                        {
+                            field: 'maker',
+                            reason: 'Invalid address',
+                        },
+                    ],
+                },
+                {
+                    code: 101,
+                    reason: 'Validation failed',
+                    validationErrors: [
+                        {
+                            field: 'maker',
+                            code: '1002',
+                            reason: 'Invalid address',
+                        },
+                    ],
+                },
+            ];
+            const shouldFail = true;
+            validateAgainstSchema(testCases, relayerApiErrorResponseSchema, shouldFail);
+        });
+    });
+    describe('#relayerApiFeesPayloadSchema', () => {
+        it('should validate valid fees payloads', () => {
+            const testCases = [
+                {
+                    exchangeContractAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+                    maker: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+                    taker: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+                    makerTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+                    takerTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
+                    makerTokenAmount: '10000000000000000000',
+                    takerTokenAmount: '30000000000000000000',
+                    expirationUnixTimestampSec: '42',
+                    salt: '67006738228878699843088602623665307406148487219438534730168799356281242528500',
+                },
+            ];
+            validateAgainstSchema(testCases, relayerApiFeesPayloadSchema);
+        });
+        it('should fail for invalid fees payloads', () => {
+            const checksummedAddress = '0xA2b31daCf30a9C50ca473337c01d8A201ae33e32';
+            const testCases = [
+                {},
+                {
+                    takerTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
+                    makerTokenAmount: '10000000000000000000',
+                    takerTokenAmount: '30000000000000000000',
+                },
+                {
+                    taker: checksummedAddress,
+                    makerTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+                    takerTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
+                    makerTokenAmount: '10000000000000000000',
+                    takerTokenAmount: '30000000000000000000',
+                },
+                {
+                    makerTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+                    takerTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
+                    makerTokenAmount: 10000000000000000000,
+                    takerTokenAmount: 30000000000000000000,
+                },
+            ];
+            const shouldFail = true;
+            validateAgainstSchema(testCases, relayerApiFeesPayloadSchema, shouldFail);
+        });
+    });
+    describe('#relayerApiFeesResponseSchema', () => {
+        it('should validate valid fees responses', () => {
+            const testCases = [
+                {
+                    makerFee: '10000000000000000',
+                    takerFee: '30000000000000000',
+                    feeRecipient: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+                },
+            ];
+            validateAgainstSchema(testCases, relayerApiFeesResponseSchema);
+        });
+        it('should fail for invalid fees responses', () => {
+            const checksummedAddress = '0xA2b31daCf30a9C50ca473337c01d8A201ae33e32';
+            const testCases = [
+                {},
+                {
+                    makerFee: 10000000000000000,
+                    takerFee: 30000000000000000,
+                },
+                {
+                    feeRecipient: checksummedAddress,
+                    takerToSpecify: checksummedAddress,
+                    makerFee: '10000000000000000',
+                    takerFee: '30000000000000000',
+                },
+            ];
+            const shouldFail = true;
+            validateAgainstSchema(testCases, relayerApiFeesResponseSchema, shouldFail);
+        });
+    });
+    describe('#relayerApiTokenPairsResponseSchema', () => {
+        it('should validate valid tokenPairs response', () => {
+            const testCases = [
+                [],
+                [
+                    {
+                        tokenA: {
+                            address: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+                            minAmount: '0',
+                            maxAmount: '10000000000000000000',
+                            precision: 5,
+                        },
+                        tokenB: {
+                            address: '0xef7fff64389b814a946f3e92105513705ca6b990',
+                            minAmount: '0',
+                            maxAmount: '50000000000000000000',
+                            precision: 5,
+                        },
+                    },
+                ],
+                [
+                    {
+                        tokenA: {
+                            address: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+                        },
+                        tokenB: {
+                            address: '0xef7fff64389b814a946f3e92105513705ca6b990',
+                        },
+                    },
+                ],
+            ];
+            validateAgainstSchema(testCases, relayerApiTokenPairsResponseSchema);
+        });
+        it('should fail for invalid tokenPairs responses', () => {
+            const checksummedAddress = '0xA2b31daCf30a9C50ca473337c01d8A201ae33e32';
+            const testCases = [
+                [
+                    {
+                        tokenA: {
+                            address: checksummedAddress,
+                        },
+                        tokenB: {
+                            address: checksummedAddress,
+                        },
+                    },
+                ],
+                [
+                    {
+                        tokenA: {
+                            address: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+                            minAmount: 0,
+                            maxAmount: 10000000000000000000,
+                        },
+                        tokenB: {
+                            address: '0xef7fff64389b814a946f3e92105513705ca6b990',
+                            minAmount: 0,
+                            maxAmount: 50000000000000000000,
+                        },
+                    },
+                ],
+                [
+                    {
+                        tokenA: {
+                            address: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+                            precision: '5',
+                        },
+                        tokenB: {
+                            address: '0xef7fff64389b814a946f3e92105513705ca6b990',
+                            precision: '5',
+                        },
+                    },
+                ],
+            ];
+            const shouldFail = true;
+            validateAgainstSchema(testCases, relayerApiTokenPairsResponseSchema, shouldFail);
+        });
+    });
+    describe('#jsNumberSchema', () => {
+        it('should validate valid js number', () => {
+            const testCases = [1, 42];
+            validateAgainstSchema(testCases, jsNumber);
+        });
+        it('should fail for invalid js number', () => {
+            const testCases = [NaN, -1, new BigNumber(1)];
+            const shouldFail = true;
+            validateAgainstSchema(testCases, jsNumber, shouldFail);
+        });
+    });
+    describe('#txDataSchema', () => {
+        it('should validate valid txData', () => {
+            const testCases = [
+                {
+                    from: NULL_ADDRESS,
+                },
+                {
+                    from: NULL_ADDRESS,
+                    gas: new BigNumber(42),
+                },
+                {
+                    from: NULL_ADDRESS,
+                    gas: 42,
+                },
+            ];
+            validateAgainstSchema(testCases, txDataSchema);
+        });
+        it('should fail for invalid txData', () => {
+            const testCases = [
+                {
+                    gas: new BigNumber(42),
+                },
+                {
+                    from: NULL_ADDRESS,
+                    unknownProp: 'here',
+                },
+                {},
+                [],
+                new BigNumber(1),
+            ];
+            const shouldFail = true;
+            validateAgainstSchema(testCases, txDataSchema, shouldFail);
+        });
+    });
 }); // tslint:disable:max-file-line-count
diff --git a/packages/json-schemas/tsconfig.json b/packages/json-schemas/tsconfig.json
index 8314a9459..88a467ccb 100644
--- a/packages/json-schemas/tsconfig.json
+++ b/packages/json-schemas/tsconfig.json
@@ -1,7 +1,7 @@
 {
-	"extends": "../../tsconfig",
-	"compilerOptions": {
-		"outDir": "lib"
-	},
-	"include": ["./src/**/*", "./test/**/*", "../../node_modules/chai-typescript-typings/index.d.ts"]
+    "extends": "../../tsconfig",
+    "compilerOptions": {
+        "outDir": "lib"
+    },
+    "include": ["./src/**/*", "./test/**/*", "../../node_modules/chai-typescript-typings/index.d.ts"]
 }
diff --git a/packages/json-schemas/tslint.json b/packages/json-schemas/tslint.json
index e63054bfc..ffaefe83a 100644
--- a/packages/json-schemas/tslint.json
+++ b/packages/json-schemas/tslint.json
@@ -1,3 +1,3 @@
 {
-	"extends": ["@0xproject/tslint-config"]
+    "extends": ["@0xproject/tslint-config"]
 }
diff --git a/packages/monorepo-scripts/package.json b/packages/monorepo-scripts/package.json
index 31eaf6eca..2bf2aa796 100644
--- a/packages/monorepo-scripts/package.json
+++ b/packages/monorepo-scripts/package.json
@@ -1,34 +1,34 @@
 {
-	"name": "@0xproject/monorepo-scripts",
-	"version": "0.1.6",
-	"private": true,
-	"description": "Helper scripts for the monorepo",
-	"scripts": {
-		"deps_versions": "node ./lib/deps_versions.js",
-		"lint": "tslint --project . 'src/**/*.ts'",
-		"clean": "shx rm -rf lib",
-		"build": "tsc"
-	},
-	"repository": {
-		"type": "git",
-		"url": "https://github.com/0xProject/0x.js.git"
-	},
-	"license": "Apache-2.0",
-	"bugs": {
-		"url": "https://github.com/0xProject/0x.js/issues"
-	},
-	"homepage": "https://github.com/0xProject/0x.js/packages/monorepo-scripts/README.md",
-	"devDependencies": {
-		"@0xproject/tslint-config": "^0.4.4",
-		"@types/glob": "^5.0.33",
-		"@types/node": "^8.0.53",
-		"shx": "^0.2.2",
-		"tslint": "5.8.0",
-		"typescript": "~2.6.1"
-	},
-	"dependencies": {
-		"chalk": "^2.3.0",
-		"glob": "^7.1.2",
-		"lodash": "^4.17.4"
-	}
+    "name": "@0xproject/monorepo-scripts",
+    "version": "0.1.6",
+    "private": true,
+    "description": "Helper scripts for the monorepo",
+    "scripts": {
+        "deps_versions": "node ./lib/deps_versions.js",
+        "lint": "tslint --project . 'src/**/*.ts'",
+        "clean": "shx rm -rf lib",
+        "build": "tsc"
+    },
+    "repository": {
+        "type": "git",
+        "url": "https://github.com/0xProject/0x.js.git"
+    },
+    "license": "Apache-2.0",
+    "bugs": {
+        "url": "https://github.com/0xProject/0x.js/issues"
+    },
+    "homepage": "https://github.com/0xProject/0x.js/packages/monorepo-scripts/README.md",
+    "devDependencies": {
+        "@0xproject/tslint-config": "^0.4.4",
+        "@types/glob": "^5.0.33",
+        "@types/node": "^8.0.53",
+        "shx": "^0.2.2",
+        "tslint": "5.8.0",
+        "typescript": "~2.6.1"
+    },
+    "dependencies": {
+        "chalk": "^2.3.0",
+        "glob": "^7.1.2",
+        "lodash": "^4.17.4"
+    }
 }
diff --git a/packages/monorepo-scripts/src/deps_versions.ts b/packages/monorepo-scripts/src/deps_versions.ts
index 2c0aa6c54..5c9a2d6ff 100644
--- a/packages/monorepo-scripts/src/deps_versions.ts
+++ b/packages/monorepo-scripts/src/deps_versions.ts
@@ -6,51 +6,51 @@ import { sync as globSync } from 'glob';
 import * as _ from 'lodash';
 
 interface Dependencies {
-	[depName: string]: string;
+    [depName: string]: string;
 }
 interface Versions {
-	[packageName: string]: string;
+    [packageName: string]: string;
 }
 interface VersionsByDependency {
-	[depName: string]: Versions;
+    [depName: string]: Versions;
 }
 
 const PACKAGE_JSON_GLOB = '../*/package.json';
 
 function log(...args: any[]) {
-	console.log(...args); // tslint:disable-line:no-console
+    console.log(...args); // tslint:disable-line:no-console
 }
 
 function getDependencies(path: string): Dependencies {
-	const file = fs.readFileSync(path).toString();
-	const parsed = JSON.parse(file);
-	const dependencies = {
-		...parsed.dependencies,
-		...parsed.devDependencies,
-	};
-	return dependencies;
+    const file = fs.readFileSync(path).toString();
+    const parsed = JSON.parse(file);
+    const dependencies = {
+        ...parsed.dependencies,
+        ...parsed.devDependencies,
+    };
+    return dependencies;
 }
 
 const files = globSync(PACKAGE_JSON_GLOB);
 const versionsByDependency: VersionsByDependency = {};
 files.map(path => {
-	const [_1, packageName, _2] = path.split('/');
-	const dependencies = getDependencies(path);
-	_.map(dependencies, (version: string, depName: string) => {
-		if (_.isUndefined(versionsByDependency[depName])) {
-			versionsByDependency[depName] = {};
-		}
-		versionsByDependency[depName][packageName] = version;
-	});
+    const [_1, packageName, _2] = path.split('/');
+    const dependencies = getDependencies(path);
+    _.map(dependencies, (version: string, depName: string) => {
+        if (_.isUndefined(versionsByDependency[depName])) {
+            versionsByDependency[depName] = {};
+        }
+        versionsByDependency[depName][packageName] = version;
+    });
 });
 
 _.map(versionsByDependency, (versions: Versions, depName: string) => {
-	if (_.uniq(_.values(versions)).length === 1) {
-		delete versionsByDependency[depName];
-	} else {
-		log(chalk.bold(depName));
-		_.map(versions, (version: string, packageName: string) => {
-			log(`├── ${packageName} -> ${version}`);
-		});
-	}
+    if (_.uniq(_.values(versions)).length === 1) {
+        delete versionsByDependency[depName];
+    } else {
+        log(chalk.bold(depName));
+        _.map(versions, (version: string, packageName: string) => {
+            log(`├── ${packageName} -> ${version}`);
+        });
+    }
 });
diff --git a/packages/monorepo-scripts/tsconfig.json b/packages/monorepo-scripts/tsconfig.json
index ad674c2b0..c56d255d5 100644
--- a/packages/monorepo-scripts/tsconfig.json
+++ b/packages/monorepo-scripts/tsconfig.json
@@ -1,7 +1,7 @@
 {
-	"extends": "../../tsconfig",
-	"compilerOptions": {
-		"outDir": "lib"
-	},
-	"include": ["./src/**/*"]
+    "extends": "../../tsconfig",
+    "compilerOptions": {
+        "outDir": "lib"
+    },
+    "include": ["./src/**/*"]
 }
diff --git a/packages/monorepo-scripts/tslint.json b/packages/monorepo-scripts/tslint.json
index e63054bfc..ffaefe83a 100644
--- a/packages/monorepo-scripts/tslint.json
+++ b/packages/monorepo-scripts/tslint.json
@@ -1,3 +1,3 @@
 {
-	"extends": ["@0xproject/tslint-config"]
+    "extends": ["@0xproject/tslint-config"]
 }
diff --git a/packages/subproviders/package.json b/packages/subproviders/package.json
index 1da019e2d..146c94496 100644
--- a/packages/subproviders/package.json
+++ b/packages/subproviders/package.json
@@ -1,55 +1,55 @@
 {
-	"name": "@0xproject/subproviders",
-	"version": "0.3.3",
-	"main": "lib/src/index.js",
-	"types": "lib/src/index.d.ts",
-	"license": "Apache-2.0",
-	"scripts": {
-		"clean": "shx rm -rf lib",
-		"build": "tsc",
-		"lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'",
-		"run_mocha_unit": "mocha lib/test/unit/**/*_test.js --timeout 10000 --bail --exit",
-		"run_mocha_integration": "mocha lib/test/integration/**/*_test.js --timeout 10000 --bail --exit",
-		"test": "npm run test:unit",
-		"test:circleci": "npm run test:unit",
-		"test:all": "run-s test:unit test:integration",
-		"test:unit": "run-s clean build run_mocha_unit",
-		"test:integration": "run-s clean build run_mocha_integration"
-	},
-	"dependencies": {
-		"@0xproject/assert": "^0.0.13",
-		"@0xproject/utils": "^0.2.2",
-		"bn.js": "^4.11.8",
-		"es6-promisify": "^5.0.0",
-		"ethereumjs-tx": "^1.3.3",
-		"ethereumjs-util": "^5.1.1",
-		"hdkey": "^0.7.1",
-		"ledgerco": "0xProject/ledger-node-js-api",
-		"lodash": "^4.17.4",
-		"semaphore-async-await": "^1.5.1",
-		"web3": "^0.20.0",
-		"web3-provider-engine": "^13.0.1"
-	},
-	"devDependencies": {
-		"@0xproject/tslint-config": "^0.4.4",
-		"@0xproject/utils": "^0.2.2",
-		"@types/lodash": "^4.14.86",
-		"@types/mocha": "^2.2.42",
-		"@types/node": "^8.0.53",
-		"awesome-typescript-loader": "^3.1.3",
-		"chai": "^4.0.1",
-		"chai-as-promised": "^7.1.0",
-		"chai-as-promised-typescript-typings": "^0.0.6",
-		"chai-typescript-typings": "^0.0.2",
-		"dirty-chai": "^2.0.1",
-		"mocha": "^4.0.1",
-		"npm-run-all": "^4.1.2",
-		"shx": "^0.2.2",
-		"tslint": "5.8.0",
-		"types-bn": "^0.0.1",
-		"types-ethereumjs-util": "0xproject/types-ethereumjs-util",
-		"typescript": "~2.6.1",
-		"web3-typescript-typings": "^0.7.2",
-		"webpack": "^3.1.0"
-	}
+    "name": "@0xproject/subproviders",
+    "version": "0.3.3",
+    "main": "lib/src/index.js",
+    "types": "lib/src/index.d.ts",
+    "license": "Apache-2.0",
+    "scripts": {
+        "clean": "shx rm -rf lib",
+        "build": "tsc",
+        "lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'",
+        "run_mocha_unit": "mocha lib/test/unit/**/*_test.js --timeout 10000 --bail --exit",
+        "run_mocha_integration": "mocha lib/test/integration/**/*_test.js --timeout 10000 --bail --exit",
+        "test": "npm run test:unit",
+        "test:circleci": "npm run test:unit",
+        "test:all": "run-s test:unit test:integration",
+        "test:unit": "run-s clean build run_mocha_unit",
+        "test:integration": "run-s clean build run_mocha_integration"
+    },
+    "dependencies": {
+        "@0xproject/assert": "^0.0.13",
+        "@0xproject/utils": "^0.2.2",
+        "bn.js": "^4.11.8",
+        "es6-promisify": "^5.0.0",
+        "ethereumjs-tx": "^1.3.3",
+        "ethereumjs-util": "^5.1.1",
+        "hdkey": "^0.7.1",
+        "ledgerco": "0xProject/ledger-node-js-api",
+        "lodash": "^4.17.4",
+        "semaphore-async-await": "^1.5.1",
+        "web3": "^0.20.0",
+        "web3-provider-engine": "^13.0.1"
+    },
+    "devDependencies": {
+        "@0xproject/tslint-config": "^0.4.4",
+        "@0xproject/utils": "^0.2.2",
+        "@types/lodash": "^4.14.86",
+        "@types/mocha": "^2.2.42",
+        "@types/node": "^8.0.53",
+        "awesome-typescript-loader": "^3.1.3",
+        "chai": "^4.0.1",
+        "chai-as-promised": "^7.1.0",
+        "chai-as-promised-typescript-typings": "^0.0.6",
+        "chai-typescript-typings": "^0.0.2",
+        "dirty-chai": "^2.0.1",
+        "mocha": "^4.0.1",
+        "npm-run-all": "^4.1.2",
+        "shx": "^0.2.2",
+        "tslint": "5.8.0",
+        "types-bn": "^0.0.1",
+        "types-ethereumjs-util": "0xproject/types-ethereumjs-util",
+        "typescript": "~2.6.1",
+        "web3-typescript-typings": "^0.7.2",
+        "webpack": "^3.1.0"
+    }
 }
diff --git a/packages/subproviders/src/globals.d.ts b/packages/subproviders/src/globals.d.ts
index ed4fbc145..53457fa24 100644
--- a/packages/subproviders/src/globals.d.ts
+++ b/packages/subproviders/src/globals.d.ts
@@ -8,103 +8,103 @@ declare module 'es6-promisify';
 
 // Ethereumjs-tx declarations
 declare module 'ethereumjs-tx' {
-	class EthereumTx {
-		public raw: Buffer[];
-		public r: Buffer;
-		public s: Buffer;
-		public v: Buffer;
-		public serialize(): Buffer;
-		constructor(txParams: any);
-	}
-	export = EthereumTx;
+    class EthereumTx {
+        public raw: Buffer[];
+        public r: Buffer;
+        public s: Buffer;
+        public v: Buffer;
+        public serialize(): Buffer;
+        constructor(txParams: any);
+    }
+    export = EthereumTx;
 }
 
 // Ledgerco declarations
 interface ECSignatureString {
-	v: string;
-	r: string;
-	s: string;
+    v: string;
+    r: string;
+    s: string;
 }
 interface ECSignature {
-	v: number;
-	r: string;
-	s: string;
+    v: number;
+    r: string;
+    s: string;
 }
 declare module 'ledgerco' {
-	interface comm {
-		close_async(): Promise<void>;
-	}
-	export class comm_node implements comm {
-		public static create_async(timeoutMilliseconds?: number): Promise<comm_node>;
-		public close_async(): Promise<void>;
-	}
-	export class comm_u2f implements comm {
-		public static create_async(): Promise<comm_u2f>;
-		public close_async(): Promise<void>;
-	}
-	export class eth {
-		public comm: comm;
-		constructor(comm: comm);
-		public getAddress_async(
-			path: string,
-			display?: boolean,
-			chaincode?: boolean,
-		): Promise<{ publicKey: string; address: string; chainCode: string }>;
-		public signTransaction_async(path: string, rawTxHex: string): Promise<ECSignatureString>;
-		public getAppConfiguration_async(): Promise<{
-			arbitraryDataEnabled: number;
-			version: string;
-		}>;
-		public signPersonalMessage_async(path: string, messageHex: string): Promise<ECSignature>;
-	}
+    interface comm {
+        close_async(): Promise<void>;
+    }
+    export class comm_node implements comm {
+        public static create_async(timeoutMilliseconds?: number): Promise<comm_node>;
+        public close_async(): Promise<void>;
+    }
+    export class comm_u2f implements comm {
+        public static create_async(): Promise<comm_u2f>;
+        public close_async(): Promise<void>;
+    }
+    export class eth {
+        public comm: comm;
+        constructor(comm: comm);
+        public getAddress_async(
+            path: string,
+            display?: boolean,
+            chaincode?: boolean,
+        ): Promise<{ publicKey: string; address: string; chainCode: string }>;
+        public signTransaction_async(path: string, rawTxHex: string): Promise<ECSignatureString>;
+        public getAppConfiguration_async(): Promise<{
+            arbitraryDataEnabled: number;
+            version: string;
+        }>;
+        public signPersonalMessage_async(path: string, messageHex: string): Promise<ECSignature>;
+    }
 }
 
 // Semaphore-async-await declarations
 declare module 'semaphore-async-await' {
-	class Semaphore {
-		constructor(permits: number);
-		public wait(): Promise<void>;
-		public signal(): void;
-	}
-	export default Semaphore;
+    class Semaphore {
+        constructor(permits: number);
+        public wait(): Promise<void>;
+        public signal(): void;
+    }
+    export default Semaphore;
 }
 
 // web3-provider-engine declarations
 declare module 'web3-provider-engine/subproviders/subprovider' {
-	class Subprovider {}
-	export = Subprovider;
+    class Subprovider {}
+    export = Subprovider;
 }
 declare module 'web3-provider-engine/subproviders/rpc' {
-	import * as Web3 from 'web3';
-	class RpcSubprovider {
-		constructor(options: { rpcUrl: string });
-		public handleRequest(
-			payload: Web3.JSONRPCRequestPayload,
-			next: () => void,
-			end: (err: Error | null, data?: any) => void,
-		): void;
-	}
-	export = RpcSubprovider;
+    import * as Web3 from 'web3';
+    class RpcSubprovider {
+        constructor(options: { rpcUrl: string });
+        public handleRequest(
+            payload: Web3.JSONRPCRequestPayload,
+            next: () => void,
+            end: (err: Error | null, data?: any) => void,
+        ): void;
+    }
+    export = RpcSubprovider;
 }
 declare module 'web3-provider-engine' {
-	class Web3ProviderEngine {
-		public on(event: string, handler: () => void): void;
-		public send(payload: any): void;
-		public sendAsync(payload: any, callback: (error: any, response: any) => void): void;
-		public addProvider(provider: any): void;
-		public start(): void;
-		public stop(): void;
-	}
-	export = Web3ProviderEngine;
+    class Web3ProviderEngine {
+        public on(event: string, handler: () => void): void;
+        public send(payload: any): void;
+        public sendAsync(payload: any, callback: (error: any, response: any) => void): void;
+        public addProvider(provider: any): void;
+        public start(): void;
+        public stop(): void;
+    }
+    export = Web3ProviderEngine;
 }
 
 // hdkey declarations
 declare module 'hdkey' {
-	class HDNode {
-		public publicKey: Buffer;
-		public chainCode: Buffer;
-		public constructor();
-		public derive(path: string): HDNode;
-	}
-	export = HDNode;
+    class HDNode {
+        public publicKey: Buffer;
+        public chainCode: Buffer;
+        public constructor();
+        public derive(path: string): HDNode;
+    }
+    export = HDNode;
 }
diff --git a/packages/subproviders/src/index.ts b/packages/subproviders/src/index.ts
index ecba186df..720c4362f 100644
--- a/packages/subproviders/src/index.ts
+++ b/packages/subproviders/src/index.ts
@@ -1,7 +1,7 @@
 import {
-	comm_node as LedgerNodeCommunication,
-	comm_u2f as LedgerBrowserCommunication,
-	eth as LedgerEthereumClientFn,
+    comm_node as LedgerNodeCommunication,
+    comm_u2f as LedgerBrowserCommunication,
+    eth as LedgerEthereumClientFn,
 } from 'ledgerco';
 
 import { LedgerEthereumClient } from './types';
@@ -16,9 +16,9 @@ export { ECSignature, LedgerWalletSubprovider, LedgerCommunicationClient } from
  * @return LedgerEthereumClient A browser client
  */
 export async function ledgerEthereumBrowserClientFactoryAsync(): Promise<LedgerEthereumClient> {
-	const ledgerConnection = await LedgerBrowserCommunication.create_async();
-	const ledgerEthClient = new LedgerEthereumClientFn(ledgerConnection);
-	return ledgerEthClient;
+    const ledgerConnection = await LedgerBrowserCommunication.create_async();
+    const ledgerEthClient = new LedgerEthereumClientFn(ledgerConnection);
+    return ledgerEthClient;
 }
 
 /**
@@ -26,7 +26,7 @@ export async function ledgerEthereumBrowserClientFactoryAsync(): Promise<LedgerE
  * @return LedgerEthereumClient A Node.js client
  */
 export async function ledgerEthereumNodeJsClientFactoryAsync(): Promise<LedgerEthereumClient> {
-	const ledgerConnection = await LedgerNodeCommunication.create_async();
-	const ledgerEthClient = new LedgerEthereumClientFn(ledgerConnection);
-	return ledgerEthClient;
+    const ledgerConnection = await LedgerNodeCommunication.create_async();
+    const ledgerEthClient = new LedgerEthereumClientFn(ledgerConnection);
+    return ledgerEthClient;
 }
diff --git a/packages/subproviders/src/subproviders/injected_web3.ts b/packages/subproviders/src/subproviders/injected_web3.ts
index dc1b8b24c..bd29acb22 100644
--- a/packages/subproviders/src/subproviders/injected_web3.ts
+++ b/packages/subproviders/src/subproviders/injected_web3.ts
@@ -9,41 +9,41 @@ import Web3ProviderEngine = require('web3-provider-engine');
  * Source: https://github.com/MetaMask/provider-engine/blob/master/subproviders/subprovider.js
  */
 export class InjectedWeb3Subprovider {
-	private _injectedWeb3: Web3;
-	constructor(injectedWeb3: Web3) {
-		this._injectedWeb3 = injectedWeb3;
-	}
-	public handleRequest(
-		payload: Web3.JSONRPCRequestPayload,
-		next: () => void,
-		end: (err: Error | null, result: any) => void,
-	) {
-		switch (payload.method) {
-			case 'web3_clientVersion':
-				this._injectedWeb3.version.getNode(end);
-				return;
-			case 'eth_accounts':
-				this._injectedWeb3.eth.getAccounts(end);
-				return;
+    private _injectedWeb3: Web3;
+    constructor(injectedWeb3: Web3) {
+        this._injectedWeb3 = injectedWeb3;
+    }
+    public handleRequest(
+        payload: Web3.JSONRPCRequestPayload,
+        next: () => void,
+        end: (err: Error | null, result: any) => void,
+    ) {
+        switch (payload.method) {
+            case 'web3_clientVersion':
+                this._injectedWeb3.version.getNode(end);
+                return;
+            case 'eth_accounts':
+                this._injectedWeb3.eth.getAccounts(end);
+                return;
 
-			case 'eth_sendTransaction':
-				const [txParams] = payload.params;
-				this._injectedWeb3.eth.sendTransaction(txParams, end);
-				return;
+            case 'eth_sendTransaction':
+                const [txParams] = payload.params;
+                this._injectedWeb3.eth.sendTransaction(txParams, end);
+                return;
 
-			case 'eth_sign':
-				const [address, message] = payload.params;
-				this._injectedWeb3.eth.sign(address, message, end);
-				return;
+            case 'eth_sign':
+                const [address, message] = payload.params;
+                this._injectedWeb3.eth.sign(address, message, end);
+                return;
 
-			default:
-				next();
-				return;
-		}
-	}
-	// Required to implement this method despite not needing it for this subprovider
-	// tslint:disable-next-line:prefer-function-over-method
-	public setEngine(engine: Web3ProviderEngine) {
-		// noop
-	}
+            default:
+                next();
+                return;
+        }
+    }
+    // Required to implement this method despite not needing it for this subprovider
+    // tslint:disable-next-line:prefer-function-over-method
+    public setEngine(engine: Web3ProviderEngine) {
+        // noop
+    }
 }
diff --git a/packages/subproviders/src/subproviders/ledger.ts b/packages/subproviders/src/subproviders/ledger.ts
index 00649873b..7267a793e 100644
--- a/packages/subproviders/src/subproviders/ledger.ts
+++ b/packages/subproviders/src/subproviders/ledger.ts
@@ -8,12 +8,12 @@ import Semaphore from 'semaphore-async-await';
 import Web3 = require('web3');
 
 import {
-	LedgerEthereumClient,
-	LedgerEthereumClientFactoryAsync,
-	LedgerSubproviderConfigs,
-	LedgerSubproviderErrors,
-	PartialTxParams,
-	ResponseWithTxParams,
+    LedgerEthereumClient,
+    LedgerEthereumClientFactoryAsync,
+    LedgerSubproviderConfigs,
+    LedgerSubproviderErrors,
+    PartialTxParams,
+    ResponseWithTxParams,
 } from '../types';
 
 import { Subprovider } from './subprovider';
@@ -24,284 +24,284 @@ const ASK_FOR_ON_DEVICE_CONFIRMATION = false;
 const SHOULD_GET_CHAIN_CODE = true;
 
 export class LedgerSubprovider extends Subprovider {
-	private _nonceLock: Semaphore;
-	private _connectionLock: Semaphore;
-	private _networkId: number;
-	private _derivationPath: string;
-	private _derivationPathIndex: number;
-	private _ledgerEthereumClientFactoryAsync: LedgerEthereumClientFactoryAsync;
-	private _ledgerClientIfExists?: LedgerEthereumClient;
-	private _shouldAlwaysAskForConfirmation: boolean;
-	private static _validateSender(sender: string) {
-		if (_.isUndefined(sender) || !addressUtils.isAddress(sender)) {
-			throw new Error(LedgerSubproviderErrors.SenderInvalidOrNotSupplied);
-		}
-	}
-	constructor(config: LedgerSubproviderConfigs) {
-		super();
-		this._nonceLock = new Semaphore(1);
-		this._connectionLock = new Semaphore(1);
-		this._networkId = config.networkId;
-		this._ledgerEthereumClientFactoryAsync = config.ledgerEthereumClientFactoryAsync;
-		this._derivationPath = config.derivationPath || DEFAULT_DERIVATION_PATH;
-		this._shouldAlwaysAskForConfirmation =
-			!_.isUndefined(config.accountFetchingConfigs) &&
-			!_.isUndefined(config.accountFetchingConfigs.shouldAskForOnDeviceConfirmation)
-				? config.accountFetchingConfigs.shouldAskForOnDeviceConfirmation
-				: ASK_FOR_ON_DEVICE_CONFIRMATION;
-		this._derivationPathIndex = 0;
-	}
-	public getPath(): string {
-		return this._derivationPath;
-	}
-	public setPath(derivationPath: string) {
-		this._derivationPath = derivationPath;
-	}
-	public setPathIndex(pathIndex: number) {
-		this._derivationPathIndex = pathIndex;
-	}
-	public async handleRequest(
-		payload: Web3.JSONRPCRequestPayload,
-		next: () => void,
-		end: (err: Error | null, result?: any) => void,
-	) {
-		let accounts;
-		let txParams;
-		switch (payload.method) {
-			case 'eth_coinbase':
-				try {
-					accounts = await this.getAccountsAsync();
-					end(null, accounts[0]);
-				} catch (err) {
-					end(err);
-				}
-				return;
+    private _nonceLock: Semaphore;
+    private _connectionLock: Semaphore;
+    private _networkId: number;
+    private _derivationPath: string;
+    private _derivationPathIndex: number;
+    private _ledgerEthereumClientFactoryAsync: LedgerEthereumClientFactoryAsync;
+    private _ledgerClientIfExists?: LedgerEthereumClient;
+    private _shouldAlwaysAskForConfirmation: boolean;
+    private static _validateSender(sender: string) {
+        if (_.isUndefined(sender) || !addressUtils.isAddress(sender)) {
+            throw new Error(LedgerSubproviderErrors.SenderInvalidOrNotSupplied);
+        }
+    }
+    constructor(config: LedgerSubproviderConfigs) {
+        super();
+        this._nonceLock = new Semaphore(1);
+        this._connectionLock = new Semaphore(1);
+        this._networkId = config.networkId;
+        this._ledgerEthereumClientFactoryAsync = config.ledgerEthereumClientFactoryAsync;
+        this._derivationPath = config.derivationPath || DEFAULT_DERIVATION_PATH;
+        this._shouldAlwaysAskForConfirmation =
+            !_.isUndefined(config.accountFetchingConfigs) &&
+            !_.isUndefined(config.accountFetchingConfigs.shouldAskForOnDeviceConfirmation)
+                ? config.accountFetchingConfigs.shouldAskForOnDeviceConfirmation
+                : ASK_FOR_ON_DEVICE_CONFIRMATION;
+        this._derivationPathIndex = 0;
+    }
+    public getPath(): string {
+        return this._derivationPath;
+    }
+    public setPath(derivationPath: string) {
+        this._derivationPath = derivationPath;
+    }
+    public setPathIndex(pathIndex: number) {
+        this._derivationPathIndex = pathIndex;
+    }
+    public async handleRequest(
+        payload: Web3.JSONRPCRequestPayload,
+        next: () => void,
+        end: (err: Error | null, result?: any) => void,
+    ) {
+        let accounts;
+        let txParams;
+        switch (payload.method) {
+            case 'eth_coinbase':
+                try {
+                    accounts = await this.getAccountsAsync();
+                    end(null, accounts[0]);
+                } catch (err) {
+                    end(err);
+                }
+                return;
 
-			case 'eth_accounts':
-				try {
-					accounts = await this.getAccountsAsync();
-					end(null, accounts);
-				} catch (err) {
-					end(err);
-				}
-				return;
+            case 'eth_accounts':
+                try {
+                    accounts = await this.getAccountsAsync();
+                    end(null, accounts);
+                } catch (err) {
+                    end(err);
+                }
+                return;
 
-			case 'eth_sendTransaction':
-				txParams = payload.params[0];
-				try {
-					LedgerSubprovider._validateSender(txParams.from);
-					const result = await this._sendTransactionAsync(txParams);
-					end(null, result);
-				} catch (err) {
-					end(err);
-				}
-				return;
+            case 'eth_sendTransaction':
+                txParams = payload.params[0];
+                try {
+                    LedgerSubprovider._validateSender(txParams.from);
+                    const result = await this._sendTransactionAsync(txParams);
+                    end(null, result);
+                } catch (err) {
+                    end(err);
+                }
+                return;
 
-			case 'eth_signTransaction':
-				txParams = payload.params[0];
-				try {
-					const result = await this._signTransactionWithoutSendingAsync(txParams);
-					end(null, result);
-				} catch (err) {
-					end(err);
-				}
-				return;
+            case 'eth_signTransaction':
+                txParams = payload.params[0];
+                try {
+                    const result = await this._signTransactionWithoutSendingAsync(txParams);
+                    end(null, result);
+                } catch (err) {
+                    end(err);
+                }
+                return;
 
-			case 'eth_sign':
-			case 'personal_sign':
-				const data = payload.method === 'eth_sign' ? payload.params[1] : payload.params[0];
-				try {
-					if (_.isUndefined(data)) {
-						throw new Error(LedgerSubproviderErrors.DataMissingForSignPersonalMessage);
-					}
-					assert.isHexString('data', data);
-					const ecSignatureHex = await this.signPersonalMessageAsync(data);
-					end(null, ecSignatureHex);
-				} catch (err) {
-					end(err);
-				}
-				return;
+            case 'eth_sign':
+            case 'personal_sign':
+                const data = payload.method === 'eth_sign' ? payload.params[1] : payload.params[0];
+                try {
+                    if (_.isUndefined(data)) {
+                        throw new Error(LedgerSubproviderErrors.DataMissingForSignPersonalMessage);
+                    }
+                    assert.isHexString('data', data);
+                    const ecSignatureHex = await this.signPersonalMessageAsync(data);
+                    end(null, ecSignatureHex);
+                } catch (err) {
+                    end(err);
+                }
+                return;
 
-			default:
-				next();
-				return;
-		}
-	}
-	public async getAccountsAsync(): Promise<string[]> {
-		this._ledgerClientIfExists = await this._createLedgerClientAsync();
+            default:
+                next();
+                return;
+        }
+    }
+    public async getAccountsAsync(): Promise<string[]> {
+        this._ledgerClientIfExists = await this._createLedgerClientAsync();
 
-		let ledgerResponse;
-		try {
-			ledgerResponse = await this._ledgerClientIfExists.getAddress_async(
-				this._derivationPath,
-				this._shouldAlwaysAskForConfirmation,
-				SHOULD_GET_CHAIN_CODE,
-			);
-		} finally {
-			await this._destroyLedgerClientAsync();
-		}
+        let ledgerResponse;
+        try {
+            ledgerResponse = await this._ledgerClientIfExists.getAddress_async(
+                this._derivationPath,
+                this._shouldAlwaysAskForConfirmation,
+                SHOULD_GET_CHAIN_CODE,
+            );
+        } finally {
+            await this._destroyLedgerClientAsync();
+        }
 
-		const hdKey = new HDNode();
-		hdKey.publicKey = new Buffer(ledgerResponse.publicKey, 'hex');
-		hdKey.chainCode = new Buffer(ledgerResponse.chainCode, 'hex');
+        const hdKey = new HDNode();
+        hdKey.publicKey = new Buffer(ledgerResponse.publicKey, 'hex');
+        hdKey.chainCode = new Buffer(ledgerResponse.chainCode, 'hex');
 
-		const accounts = [];
-		for (let i = 0; i < NUM_ADDRESSES_TO_FETCH; i++) {
-			const derivedHDNode = hdKey.derive(`m/${i + this._derivationPathIndex}`);
-			const derivedPublicKey = derivedHDNode.publicKey;
-			const shouldSanitizePublicKey = true;
-			const ethereumAddressUnprefixed = ethUtil
-				.publicToAddress(derivedPublicKey, shouldSanitizePublicKey)
-				.toString('hex');
-			const ethereumAddressPrefixed = ethUtil.addHexPrefix(ethereumAddressUnprefixed);
-			accounts.push(ethereumAddressPrefixed.toLowerCase());
-		}
-		return accounts;
-	}
-	public async signTransactionAsync(txParams: PartialTxParams): Promise<string> {
-		this._ledgerClientIfExists = await this._createLedgerClientAsync();
+        const accounts = [];
+        for (let i = 0; i < NUM_ADDRESSES_TO_FETCH; i++) {
+            const derivedHDNode = hdKey.derive(`m/${i + this._derivationPathIndex}`);
+            const derivedPublicKey = derivedHDNode.publicKey;
+            const shouldSanitizePublicKey = true;
+            const ethereumAddressUnprefixed = ethUtil
+                .publicToAddress(derivedPublicKey, shouldSanitizePublicKey)
+                .toString('hex');
+            const ethereumAddressPrefixed = ethUtil.addHexPrefix(ethereumAddressUnprefixed);
+            accounts.push(ethereumAddressPrefixed.toLowerCase());
+        }
+        return accounts;
+    }
+    public async signTransactionAsync(txParams: PartialTxParams): Promise<string> {
+        this._ledgerClientIfExists = await this._createLedgerClientAsync();
 
-		const tx = new EthereumTx(txParams);
+        const tx = new EthereumTx(txParams);
 
-		// Set the EIP155 bits
-		tx.raw[6] = Buffer.from([this._networkId]); // v
-		tx.raw[7] = Buffer.from([]); // r
-		tx.raw[8] = Buffer.from([]); // s
+        // Set the EIP155 bits
+        tx.raw[6] = Buffer.from([this._networkId]); // v
+        tx.raw[7] = Buffer.from([]); // r
+        tx.raw[8] = Buffer.from([]); // s
 
-		const txHex = tx.serialize().toString('hex');
-		try {
-			const derivationPath = this._getDerivationPath();
-			const result = await this._ledgerClientIfExists.signTransaction_async(derivationPath, txHex);
-			// Store signature in transaction
-			tx.r = Buffer.from(result.r, 'hex');
-			tx.s = Buffer.from(result.s, 'hex');
-			tx.v = Buffer.from(result.v, 'hex');
+        const txHex = tx.serialize().toString('hex');
+        try {
+            const derivationPath = this._getDerivationPath();
+            const result = await this._ledgerClientIfExists.signTransaction_async(derivationPath, txHex);
+            // Store signature in transaction
+            tx.r = Buffer.from(result.r, 'hex');
+            tx.s = Buffer.from(result.s, 'hex');
+            tx.v = Buffer.from(result.v, 'hex');
 
-			// EIP155: v should be chain_id * 2 + {35, 36}
-			const signedChainId = Math.floor((tx.v[0] - 35) / 2);
-			if (signedChainId !== this._networkId) {
-				await this._destroyLedgerClientAsync();
-				const err = new Error(LedgerSubproviderErrors.TooOldLedgerFirmware);
-				throw err;
-			}
+            // EIP155: v should be chain_id * 2 + {35, 36}
+            const signedChainId = Math.floor((tx.v[0] - 35) / 2);
+            if (signedChainId !== this._networkId) {
+                await this._destroyLedgerClientAsync();
+                const err = new Error(LedgerSubproviderErrors.TooOldLedgerFirmware);
+                throw err;
+            }
 
-			const signedTxHex = `0x${tx.serialize().toString('hex')}`;
-			await this._destroyLedgerClientAsync();
-			return signedTxHex;
-		} catch (err) {
-			await this._destroyLedgerClientAsync();
-			throw err;
-		}
-	}
-	public async signPersonalMessageAsync(data: string): Promise<string> {
-		this._ledgerClientIfExists = await this._createLedgerClientAsync();
-		try {
-			const derivationPath = this._getDerivationPath();
-			const result = await this._ledgerClientIfExists.signPersonalMessage_async(
-				derivationPath,
-				ethUtil.stripHexPrefix(data),
-			);
-			const v = result.v - 27;
-			let vHex = v.toString(16);
-			if (vHex.length < 2) {
-				vHex = `0${v}`;
-			}
-			const signature = `0x${result.r}${result.s}${vHex}`;
-			await this._destroyLedgerClientAsync();
-			return signature;
-		} catch (err) {
-			await this._destroyLedgerClientAsync();
-			throw err;
-		}
-	}
-	private _getDerivationPath() {
-		const derivationPath = `${this.getPath()}/${this._derivationPathIndex}`;
-		return derivationPath;
-	}
-	private async _createLedgerClientAsync(): Promise<LedgerEthereumClient> {
-		await this._connectionLock.wait();
-		if (!_.isUndefined(this._ledgerClientIfExists)) {
-			this._connectionLock.signal();
-			throw new Error(LedgerSubproviderErrors.MultipleOpenConnectionsDisallowed);
-		}
-		const ledgerEthereumClient = await this._ledgerEthereumClientFactoryAsync();
-		this._connectionLock.signal();
-		return ledgerEthereumClient;
-	}
-	private async _destroyLedgerClientAsync() {
-		await this._connectionLock.wait();
-		if (_.isUndefined(this._ledgerClientIfExists)) {
-			this._connectionLock.signal();
-			return;
-		}
-		await this._ledgerClientIfExists.comm.close_async();
-		this._ledgerClientIfExists = undefined;
-		this._connectionLock.signal();
-	}
-	private async _sendTransactionAsync(txParams: PartialTxParams): Promise<string> {
-		await this._nonceLock.wait();
-		try {
-			// fill in the extras
-			const filledParams = await this._populateMissingTxParamsAsync(txParams);
-			// sign it
-			const signedTx = await this.signTransactionAsync(filledParams);
-			// emit a submit
-			const payload = {
-				method: 'eth_sendRawTransaction',
-				params: [signedTx],
-			};
-			const result = await this.emitPayloadAsync(payload);
-			this._nonceLock.signal();
-			return result.result;
-		} catch (err) {
-			this._nonceLock.signal();
-			throw err;
-		}
-	}
-	private async _signTransactionWithoutSendingAsync(txParams: PartialTxParams): Promise<ResponseWithTxParams> {
-		await this._nonceLock.wait();
-		try {
-			// fill in the extras
-			const filledParams = await this._populateMissingTxParamsAsync(txParams);
-			// sign it
-			const signedTx = await this.signTransactionAsync(filledParams);
+            const signedTxHex = `0x${tx.serialize().toString('hex')}`;
+            await this._destroyLedgerClientAsync();
+            return signedTxHex;
+        } catch (err) {
+            await this._destroyLedgerClientAsync();
+            throw err;
+        }
+    }
+    public async signPersonalMessageAsync(data: string): Promise<string> {
+        this._ledgerClientIfExists = await this._createLedgerClientAsync();
+        try {
+            const derivationPath = this._getDerivationPath();
+            const result = await this._ledgerClientIfExists.signPersonalMessage_async(
+                derivationPath,
+                ethUtil.stripHexPrefix(data),
+            );
+            const v = result.v - 27;
+            let vHex = v.toString(16);
+            if (vHex.length < 2) {
+                vHex = `0${v}`;
+            }
+            const signature = `0x${result.r}${result.s}${vHex}`;
+            await this._destroyLedgerClientAsync();
+            return signature;
+        } catch (err) {
+            await this._destroyLedgerClientAsync();
+            throw err;
+        }
+    }
+    private _getDerivationPath() {
+        const derivationPath = `${this.getPath()}/${this._derivationPathIndex}`;
+        return derivationPath;
+    }
+    private async _createLedgerClientAsync(): Promise<LedgerEthereumClient> {
+        await this._connectionLock.wait();
+        if (!_.isUndefined(this._ledgerClientIfExists)) {
+            this._connectionLock.signal();
+            throw new Error(LedgerSubproviderErrors.MultipleOpenConnectionsDisallowed);
+        }
+        const ledgerEthereumClient = await this._ledgerEthereumClientFactoryAsync();
+        this._connectionLock.signal();
+        return ledgerEthereumClient;
+    }
+    private async _destroyLedgerClientAsync() {
+        await this._connectionLock.wait();
+        if (_.isUndefined(this._ledgerClientIfExists)) {
+            this._connectionLock.signal();
+            return;
+        }
+        await this._ledgerClientIfExists.comm.close_async();
+        this._ledgerClientIfExists = undefined;
+        this._connectionLock.signal();
+    }
+    private async _sendTransactionAsync(txParams: PartialTxParams): Promise<string> {
+        await this._nonceLock.wait();
+        try {
+            // fill in the extras
+            const filledParams = await this._populateMissingTxParamsAsync(txParams);
+            // sign it
+            const signedTx = await this.signTransactionAsync(filledParams);
+            // emit a submit
+            const payload = {
+                method: 'eth_sendRawTransaction',
+                params: [signedTx],
+            };
+            const result = await this.emitPayloadAsync(payload);
+            this._nonceLock.signal();
+            return result.result;
+        } catch (err) {
+            this._nonceLock.signal();
+            throw err;
+        }
+    }
+    private async _signTransactionWithoutSendingAsync(txParams: PartialTxParams): Promise<ResponseWithTxParams> {
+        await this._nonceLock.wait();
+        try {
+            // fill in the extras
+            const filledParams = await this._populateMissingTxParamsAsync(txParams);
+            // sign it
+            const signedTx = await this.signTransactionAsync(filledParams);
 
-			this._nonceLock.signal();
-			const result = {
-				raw: signedTx,
-				tx: txParams,
-			};
-			return result;
-		} catch (err) {
-			this._nonceLock.signal();
-			throw err;
-		}
-	}
-	private async _populateMissingTxParamsAsync(txParams: PartialTxParams): Promise<PartialTxParams> {
-		if (_.isUndefined(txParams.gasPrice)) {
-			const gasPriceResult = await this.emitPayloadAsync({
-				method: 'eth_gasPrice',
-				params: [],
-			});
-			const gasPrice = gasPriceResult.result.toString();
-			txParams.gasPrice = gasPrice;
-		}
-		if (_.isUndefined(txParams.nonce)) {
-			const nonceResult = await this.emitPayloadAsync({
-				method: 'eth_getTransactionCount',
-				params: [txParams.from, 'pending'],
-			});
-			const nonce = nonceResult.result;
-			txParams.nonce = nonce;
-		}
-		if (_.isUndefined(txParams.gas)) {
-			const gasResult = await this.emitPayloadAsync({
-				method: 'eth_estimateGas',
-				params: [txParams],
-			});
-			const gas = gasResult.result.toString();
-			txParams.gas = gas;
-		}
-		return txParams;
-	}
+            this._nonceLock.signal();
+            const result = {
+                raw: signedTx,
+                tx: txParams,
+            };
+            return result;
+        } catch (err) {
+            this._nonceLock.signal();
+            throw err;
+        }
+    }
+    private async _populateMissingTxParamsAsync(txParams: PartialTxParams): Promise<PartialTxParams> {
+        if (_.isUndefined(txParams.gasPrice)) {
+            const gasPriceResult = await this.emitPayloadAsync({
+                method: 'eth_gasPrice',
+                params: [],
+            });
+            const gasPrice = gasPriceResult.result.toString();
+            txParams.gasPrice = gasPrice;
+        }
+        if (_.isUndefined(txParams.nonce)) {
+            const nonceResult = await this.emitPayloadAsync({
+                method: 'eth_getTransactionCount',
+                params: [txParams.from, 'pending'],
+            });
+            const nonce = nonceResult.result;
+            txParams.nonce = nonce;
+        }
+        if (_.isUndefined(txParams.gas)) {
+            const gasResult = await this.emitPayloadAsync({
+                method: 'eth_estimateGas',
+                params: [txParams],
+            });
+            const gas = gasResult.result.toString();
+            txParams.gas = gas;
+        }
+        return txParams;
+    }
 }
diff --git a/packages/subproviders/src/subproviders/redundant_rpc.ts b/packages/subproviders/src/subproviders/redundant_rpc.ts
index 92d7ae8ae..a3cb463a8 100644
--- a/packages/subproviders/src/subproviders/redundant_rpc.ts
+++ b/packages/subproviders/src/subproviders/redundant_rpc.ts
@@ -7,46 +7,46 @@ import { JSONRPCPayload } from '../types';
 import { Subprovider } from './subprovider';
 
 export class RedundantRPCSubprovider extends Subprovider {
-	private _rpcs: RpcSubprovider[];
-	private static async _firstSuccessAsync(
-		rpcs: RpcSubprovider[],
-		payload: JSONRPCPayload,
-		next: () => void,
-	): Promise<any> {
-		let lastErr: Error | undefined;
-		for (const rpc of rpcs) {
-			try {
-				const data = await promisify(rpc.handleRequest.bind(rpc))(payload, next);
-				return data;
-			} catch (err) {
-				lastErr = err;
-				continue;
-			}
-		}
-		if (!_.isUndefined(lastErr)) {
-			throw lastErr;
-		}
-	}
-	constructor(endpoints: string[]) {
-		super();
-		this._rpcs = _.map(endpoints, endpoint => {
-			return new RpcSubprovider({
-				rpcUrl: endpoint,
-			});
-		});
-	}
-	// tslint:disable-next-line:async-suffix
-	public async handleRequest(
-		payload: JSONRPCPayload,
-		next: () => void,
-		end: (err: Error | null, data?: any) => void,
-	): Promise<void> {
-		const rpcsCopy = this._rpcs.slice();
-		try {
-			const data = await RedundantRPCSubprovider._firstSuccessAsync(rpcsCopy, payload, next);
-			end(null, data);
-		} catch (err) {
-			end(err);
-		}
-	}
+    private _rpcs: RpcSubprovider[];
+    private static async _firstSuccessAsync(
+        rpcs: RpcSubprovider[],
+        payload: JSONRPCPayload,
+        next: () => void,
+    ): Promise<any> {
+        let lastErr: Error | undefined;
+        for (const rpc of rpcs) {
+            try {
+                const data = await promisify(rpc.handleRequest.bind(rpc))(payload, next);
+                return data;
+            } catch (err) {
+                lastErr = err;
+                continue;
+            }
+        }
+        if (!_.isUndefined(lastErr)) {
+            throw lastErr;
+        }
+    }
+    constructor(endpoints: string[]) {
+        super();
+        this._rpcs = _.map(endpoints, endpoint => {
+            return new RpcSubprovider({
+                rpcUrl: endpoint,
+            });
+        });
+    }
+    // tslint:disable-next-line:async-suffix
+    public async handleRequest(
+        payload: JSONRPCPayload,
+        next: () => void,
+        end: (err: Error | null, data?: any) => void,
+    ): Promise<void> {
+        const rpcsCopy = this._rpcs.slice();
+        try {
+            const data = await RedundantRPCSubprovider._firstSuccessAsync(rpcsCopy, payload, next);
+            end(null, data);
+        } catch (err) {
+            end(err);
+        }
+    }
 }
diff --git a/packages/subproviders/src/subproviders/subprovider.ts b/packages/subproviders/src/subproviders/subprovider.ts
index b6bb16918..6435c9f65 100644
--- a/packages/subproviders/src/subproviders/subprovider.ts
+++ b/packages/subproviders/src/subproviders/subprovider.ts
@@ -8,33 +8,33 @@ import { JSONRPCPayload } from '../types';
  * Altered version of: https://github.com/MetaMask/provider-engine/blob/master/subproviders/subprovider.js
  */
 export class Subprovider {
-	private _engine: any;
-	// Ported from: https://github.com/MetaMask/provider-engine/blob/master/util/random-id.js
-	private static _getRandomId() {
-		const extraDigits = 3;
-		// 13 time digits
-		const datePart = new Date().getTime() * Math.pow(10, extraDigits);
-		// 3 random digits
-		const extraPart = Math.floor(Math.random() * Math.pow(10, extraDigits));
-		// 16 digits
-		return datePart + extraPart;
-	}
-	private static _createFinalPayload(payload: JSONRPCPayload): Web3.JSONRPCRequestPayload {
-		const finalPayload = {
-			// defaults
-			id: Subprovider._getRandomId(),
-			jsonrpc: '2.0',
-			params: [],
-			...payload,
-		};
-		return finalPayload;
-	}
-	public setEngine(engine: any): void {
-		this._engine = engine;
-	}
-	public async emitPayloadAsync(payload: JSONRPCPayload): Promise<any> {
-		const finalPayload = Subprovider._createFinalPayload(payload);
-		const response = await promisify(this._engine.sendAsync, this._engine)(finalPayload);
-		return response;
-	}
+    private _engine: any;
+    // Ported from: https://github.com/MetaMask/provider-engine/blob/master/util/random-id.js
+    private static _getRandomId() {
+        const extraDigits = 3;
+        // 13 time digits
+        const datePart = new Date().getTime() * Math.pow(10, extraDigits);
+        // 3 random digits
+        const extraPart = Math.floor(Math.random() * Math.pow(10, extraDigits));
+        // 16 digits
+        return datePart + extraPart;
+    }
+    private static _createFinalPayload(payload: JSONRPCPayload): Web3.JSONRPCRequestPayload {
+        const finalPayload = {
+            // defaults
+            id: Subprovider._getRandomId(),
+            jsonrpc: '2.0',
+            params: [],
+            ...payload,
+        };
+        return finalPayload;
+    }
+    public setEngine(engine: any): void {
+        this._engine = engine;
+    }
+    public async emitPayloadAsync(payload: JSONRPCPayload): Promise<any> {
+        const finalPayload = Subprovider._createFinalPayload(payload);
+        const response = await promisify(this._engine.sendAsync, this._engine)(finalPayload);
+        return response;
+    }
 }
diff --git a/packages/subproviders/src/types.ts b/packages/subproviders/src/types.ts
index ec1eedd34..3db8be943 100644
--- a/packages/subproviders/src/types.ts
+++ b/packages/subproviders/src/types.ts
@@ -1,7 +1,7 @@
 import * as _ from 'lodash';
 
 export interface LedgerCommunicationClient {
-	close_async: () => Promise<void>;
+    close_async: () => Promise<void>;
 }
 
 /*
@@ -10,28 +10,28 @@ export interface LedgerCommunicationClient {
  * NodeJs and Browser communication are supported.
  */
 export interface LedgerEthereumClient {
-	// shouldGetChainCode is defined as `true` instead of `boolean` because other types rely on the assumption
-	// that we get back the chain code and we don't have dependent types to express it properly
-	getAddress_async: (
-		derivationPath: string,
-		askForDeviceConfirmation: boolean,
-		shouldGetChainCode: true,
-	) => Promise<LedgerGetAddressResult>;
-	signPersonalMessage_async: (derivationPath: string, messageHex: string) => Promise<ECSignature>;
-	signTransaction_async: (derivationPath: string, txHex: string) => Promise<ECSignatureString>;
-	comm: LedgerCommunicationClient;
+    // shouldGetChainCode is defined as `true` instead of `boolean` because other types rely on the assumption
+    // that we get back the chain code and we don't have dependent types to express it properly
+    getAddress_async: (
+        derivationPath: string,
+        askForDeviceConfirmation: boolean,
+        shouldGetChainCode: true,
+    ) => Promise<LedgerGetAddressResult>;
+    signPersonalMessage_async: (derivationPath: string, messageHex: string) => Promise<ECSignature>;
+    signTransaction_async: (derivationPath: string, txHex: string) => Promise<ECSignatureString>;
+    comm: LedgerCommunicationClient;
 }
 
 export interface ECSignatureString {
-	v: string;
-	r: string;
-	s: string;
+    v: string;
+    r: string;
+    s: string;
 }
 
 export interface ECSignature {
-	v: number;
-	r: string;
-	s: string;
+    v: number;
+    r: string;
+    s: string;
 }
 
 export type LedgerEthereumClientFactoryAsync = () => Promise<LedgerEthereumClient>;
@@ -43,10 +43,10 @@ export type LedgerEthereumClientFactoryAsync = () => Promise<LedgerEthereumClien
  * accountFetchingConfigs: configs related to fetching accounts from a Ledger
  */
 export interface LedgerSubproviderConfigs {
-	networkId: number;
-	ledgerEthereumClientFactoryAsync: LedgerEthereumClientFactoryAsync;
-	derivationPath?: string;
-	accountFetchingConfigs?: AccountFetchingConfigs;
+    networkId: number;
+    ledgerEthereumClientFactoryAsync: LedgerEthereumClientFactoryAsync;
+    derivationPath?: string;
+    accountFetchingConfigs?: AccountFetchingConfigs;
 }
 
 /*
@@ -55,60 +55,60 @@ export interface LedgerSubproviderConfigs {
  *                                   before fetching their addresses
  */
 export interface AccountFetchingConfigs {
-	numAddressesToReturn?: number;
-	shouldAskForOnDeviceConfirmation?: boolean;
+    numAddressesToReturn?: number;
+    shouldAskForOnDeviceConfirmation?: boolean;
 }
 
 export interface SignatureData {
-	hash: string;
-	r: string;
-	s: string;
-	v: number;
+    hash: string;
+    r: string;
+    s: string;
+    v: number;
 }
 
 export interface LedgerGetAddressResult {
-	address: string;
-	publicKey: string;
-	chainCode: string;
+    address: string;
+    publicKey: string;
+    chainCode: string;
 }
 
 export interface LedgerWalletSubprovider {
-	getPath: () => string;
-	setPath: (path: string) => void;
-	setPathIndex: (pathIndex: number) => void;
+    getPath: () => string;
+    setPath: (path: string) => void;
+    setPathIndex: (pathIndex: number) => void;
 }
 
 export interface PartialTxParams {
-	nonce: string;
-	gasPrice?: string;
-	gas: string;
-	to: string;
-	from?: string;
-	value?: string;
-	data?: string;
-	chainId: number; // EIP 155 chainId - mainnet: 1, ropsten: 3
+    nonce: string;
+    gasPrice?: string;
+    gas: string;
+    to: string;
+    from?: string;
+    value?: string;
+    data?: string;
+    chainId: number; // EIP 155 chainId - mainnet: 1, ropsten: 3
 }
 
 export type DoneCallback = (err?: Error) => void;
 
 export interface JSONRPCPayload {
-	params: any[];
-	method: string;
+    params: any[];
+    method: string;
 }
 
 export interface LedgerCommunication {
-	close_async: () => Promise<void>;
+    close_async: () => Promise<void>;
 }
 
 export interface ResponseWithTxParams {
-	raw: string;
-	tx: PartialTxParams;
+    raw: string;
+    tx: PartialTxParams;
 }
 
 export enum LedgerSubproviderErrors {
-	TooOldLedgerFirmware = 'TOO_OLD_LEDGER_FIRMWARE',
-	FromAddressMissingOrInvalid = 'FROM_ADDRESS_MISSING_OR_INVALID',
-	DataMissingForSignPersonalMessage = 'DATA_MISSING_FOR_SIGN_PERSONAL_MESSAGE',
-	SenderInvalidOrNotSupplied = 'SENDER_INVALID_OR_NOT_SUPPLIED',
-	MultipleOpenConnectionsDisallowed = 'MULTIPLE_OPEN_CONNECTIONS_DISALLOWED',
+    TooOldLedgerFirmware = 'TOO_OLD_LEDGER_FIRMWARE',
+    FromAddressMissingOrInvalid = 'FROM_ADDRESS_MISSING_OR_INVALID',
+    DataMissingForSignPersonalMessage = 'DATA_MISSING_FOR_SIGN_PERSONAL_MESSAGE',
+    SenderInvalidOrNotSupplied = 'SENDER_INVALID_OR_NOT_SUPPLIED',
+    MultipleOpenConnectionsDisallowed = 'MULTIPLE_OPEN_CONNECTIONS_DISALLOWED',
 }
diff --git a/packages/subproviders/test/chai_setup.ts b/packages/subproviders/test/chai_setup.ts
index 941a141d5..a281bab6c 100644
--- a/packages/subproviders/test/chai_setup.ts
+++ b/packages/subproviders/test/chai_setup.ts
@@ -3,9 +3,9 @@ import chaiAsPromised = require('chai-as-promised');
 import * as dirtyChai from 'dirty-chai';
 
 export const chaiSetup = {
-	configure() {
-		chai.config.includeStack = true;
-		chai.use(dirtyChai);
-		chai.use(chaiAsPromised);
-	},
+    configure() {
+        chai.config.includeStack = true;
+        chai.use(dirtyChai);
+        chai.use(chaiAsPromised);
+    },
 };
diff --git a/packages/subproviders/test/integration/ledger_subprovider_test.ts b/packages/subproviders/test/integration/ledger_subprovider_test.ts
index 6c1de46aa..628b532d7 100644
--- a/packages/subproviders/test/integration/ledger_subprovider_test.ts
+++ b/packages/subproviders/test/integration/ledger_subprovider_test.ts
@@ -17,168 +17,168 @@ const expect = chai.expect;
 const TEST_RPC_ACCOUNT_0 = '0x5409ed021d9299bf6814279a6a1411a7e866a631';
 
 describe('LedgerSubprovider', () => {
-	let ledgerSubprovider: LedgerSubprovider;
-	const networkId: number = 42;
-	before(async () => {
-		ledgerSubprovider = new LedgerSubprovider({
-			networkId,
-			ledgerEthereumClientFactoryAsync: ledgerEthereumNodeJsClientFactoryAsync,
-		});
-	});
-	describe('direct method calls', () => {
-		it('returns a list of accounts', async () => {
-			const accounts = await ledgerSubprovider.getAccountsAsync();
-			expect(accounts[0]).to.not.be.an('undefined');
-			expect(accounts.length).to.be.equal(10);
-		});
-		it('signs a personal message', async () => {
-			const data = ethUtils.bufferToHex(ethUtils.toBuffer('hello world'));
-			const ecSignatureHex = await ledgerSubprovider.signPersonalMessageAsync(data);
-			expect(ecSignatureHex.length).to.be.equal(132);
-			expect(ecSignatureHex.substr(0, 2)).to.be.equal('0x');
-		});
-		it('signs a transaction', async () => {
-			const tx = {
-				nonce: '0x00',
-				gas: '0x2710',
-				to: '0x0000000000000000000000000000000000000000',
-				value: '0x00',
-				chainId: 3,
-			};
-			const txHex = await ledgerSubprovider.signTransactionAsync(tx);
-			expect(txHex).to.be.equal(
-				'0xf85f8080822710940000000000000000000000000000000000000000808077a088a95ef1378487bc82be558e82c8478baf840c545d5b887536bb1da63673a98ba0019f4a4b9a107d1e6752bf7f701e275f28c13791d6e76af895b07373462cefaa',
-			);
-		});
-	});
-	describe('calls through a provider', () => {
-		let defaultProvider: Web3ProviderEngine;
-		let ledgerProvider: Web3ProviderEngine;
-		before(() => {
-			ledgerProvider = new Web3ProviderEngine();
-			ledgerProvider.addProvider(ledgerSubprovider);
-			const httpProvider = new RpcSubprovider({
-				rpcUrl: 'http://localhost:8545',
-			});
-			ledgerProvider.addProvider(httpProvider);
-			ledgerProvider.start();
+    let ledgerSubprovider: LedgerSubprovider;
+    const networkId: number = 42;
+    before(async () => {
+        ledgerSubprovider = new LedgerSubprovider({
+            networkId,
+            ledgerEthereumClientFactoryAsync: ledgerEthereumNodeJsClientFactoryAsync,
+        });
+    });
+    describe('direct method calls', () => {
+        it('returns a list of accounts', async () => {
+            const accounts = await ledgerSubprovider.getAccountsAsync();
+            expect(accounts[0]).to.not.be.an('undefined');
+            expect(accounts.length).to.be.equal(10);
+        });
+        it('signs a personal message', async () => {
+            const data = ethUtils.bufferToHex(ethUtils.toBuffer('hello world'));
+            const ecSignatureHex = await ledgerSubprovider.signPersonalMessageAsync(data);
+            expect(ecSignatureHex.length).to.be.equal(132);
+            expect(ecSignatureHex.substr(0, 2)).to.be.equal('0x');
+        });
+        it('signs a transaction', async () => {
+            const tx = {
+                nonce: '0x00',
+                gas: '0x2710',
+                to: '0x0000000000000000000000000000000000000000',
+                value: '0x00',
+                chainId: 3,
+            };
+            const txHex = await ledgerSubprovider.signTransactionAsync(tx);
+            expect(txHex).to.be.equal(
+                '0xf85f8080822710940000000000000000000000000000000000000000808077a088a95ef1378487bc82be558e82c8478baf840c545d5b887536bb1da63673a98ba0019f4a4b9a107d1e6752bf7f701e275f28c13791d6e76af895b07373462cefaa',
+            );
+        });
+    });
+    describe('calls through a provider', () => {
+        let defaultProvider: Web3ProviderEngine;
+        let ledgerProvider: Web3ProviderEngine;
+        before(() => {
+            ledgerProvider = new Web3ProviderEngine();
+            ledgerProvider.addProvider(ledgerSubprovider);
+            const httpProvider = new RpcSubprovider({
+                rpcUrl: 'http://localhost:8545',
+            });
+            ledgerProvider.addProvider(httpProvider);
+            ledgerProvider.start();
 
-			defaultProvider = new Web3ProviderEngine();
-			defaultProvider.addProvider(httpProvider);
-			defaultProvider.start();
-		});
-		it('returns a list of accounts', (done: DoneCallback) => {
-			const payload = {
-				jsonrpc: '2.0',
-				method: 'eth_accounts',
-				params: [],
-				id: 1,
-			};
-			const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
-				expect(err).to.be.a('null');
-				expect(response.result.length).to.be.equal(10);
-				done();
-			});
-			ledgerProvider.sendAsync(payload, callback);
-		});
-		it('signs a personal message with eth_sign', (done: DoneCallback) => {
-			(async () => {
-				const messageHex = ethUtils.bufferToHex(ethUtils.toBuffer('hello world'));
-				const accounts = await ledgerSubprovider.getAccountsAsync();
-				const signer = accounts[0];
-				const payload = {
-					jsonrpc: '2.0',
-					method: 'eth_sign',
-					params: [signer, messageHex],
-					id: 1,
-				};
-				const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
-					expect(err).to.be.a('null');
-					expect(response.result.length).to.be.equal(132);
-					expect(response.result.substr(0, 2)).to.be.equal('0x');
-					done();
-				});
-				ledgerProvider.sendAsync(payload, callback);
-			})().catch(done);
-		});
-		it('signs a personal message with personal_sign', (done: DoneCallback) => {
-			(async () => {
-				const messageHex = ethUtils.bufferToHex(ethUtils.toBuffer('hello world'));
-				const accounts = await ledgerSubprovider.getAccountsAsync();
-				const signer = accounts[0];
-				const payload = {
-					jsonrpc: '2.0',
-					method: 'personal_sign',
-					params: [messageHex, signer],
-					id: 1,
-				};
-				const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
-					expect(err).to.be.a('null');
-					expect(response.result.length).to.be.equal(132);
-					expect(response.result.substr(0, 2)).to.be.equal('0x');
-					done();
-				});
-				ledgerProvider.sendAsync(payload, callback);
-			})().catch(done);
-		});
-		it('signs a transaction', (done: DoneCallback) => {
-			const tx = {
-				to: '0xafa3f8684e54059998bc3a7b0d2b0da075154d66',
-				value: '0x00',
-			};
-			const payload = {
-				jsonrpc: '2.0',
-				method: 'eth_signTransaction',
-				params: [tx],
-				id: 1,
-			};
-			const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
-				expect(err).to.be.a('null');
-				expect(response.result.raw.length).to.be.equal(206);
-				expect(response.result.raw.substr(0, 2)).to.be.equal('0x');
-				done();
-			});
-			ledgerProvider.sendAsync(payload, callback);
-		});
-		it('signs and sends a transaction', (done: DoneCallback) => {
-			(async () => {
-				const accounts = await ledgerSubprovider.getAccountsAsync();
+            defaultProvider = new Web3ProviderEngine();
+            defaultProvider.addProvider(httpProvider);
+            defaultProvider.start();
+        });
+        it('returns a list of accounts', (done: DoneCallback) => {
+            const payload = {
+                jsonrpc: '2.0',
+                method: 'eth_accounts',
+                params: [],
+                id: 1,
+            };
+            const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
+                expect(err).to.be.a('null');
+                expect(response.result.length).to.be.equal(10);
+                done();
+            });
+            ledgerProvider.sendAsync(payload, callback);
+        });
+        it('signs a personal message with eth_sign', (done: DoneCallback) => {
+            (async () => {
+                const messageHex = ethUtils.bufferToHex(ethUtils.toBuffer('hello world'));
+                const accounts = await ledgerSubprovider.getAccountsAsync();
+                const signer = accounts[0];
+                const payload = {
+                    jsonrpc: '2.0',
+                    method: 'eth_sign',
+                    params: [signer, messageHex],
+                    id: 1,
+                };
+                const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
+                    expect(err).to.be.a('null');
+                    expect(response.result.length).to.be.equal(132);
+                    expect(response.result.substr(0, 2)).to.be.equal('0x');
+                    done();
+                });
+                ledgerProvider.sendAsync(payload, callback);
+            })().catch(done);
+        });
+        it('signs a personal message with personal_sign', (done: DoneCallback) => {
+            (async () => {
+                const messageHex = ethUtils.bufferToHex(ethUtils.toBuffer('hello world'));
+                const accounts = await ledgerSubprovider.getAccountsAsync();
+                const signer = accounts[0];
+                const payload = {
+                    jsonrpc: '2.0',
+                    method: 'personal_sign',
+                    params: [messageHex, signer],
+                    id: 1,
+                };
+                const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
+                    expect(err).to.be.a('null');
+                    expect(response.result.length).to.be.equal(132);
+                    expect(response.result.substr(0, 2)).to.be.equal('0x');
+                    done();
+                });
+                ledgerProvider.sendAsync(payload, callback);
+            })().catch(done);
+        });
+        it('signs a transaction', (done: DoneCallback) => {
+            const tx = {
+                to: '0xafa3f8684e54059998bc3a7b0d2b0da075154d66',
+                value: '0x00',
+            };
+            const payload = {
+                jsonrpc: '2.0',
+                method: 'eth_signTransaction',
+                params: [tx],
+                id: 1,
+            };
+            const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
+                expect(err).to.be.a('null');
+                expect(response.result.raw.length).to.be.equal(206);
+                expect(response.result.raw.substr(0, 2)).to.be.equal('0x');
+                done();
+            });
+            ledgerProvider.sendAsync(payload, callback);
+        });
+        it('signs and sends a transaction', (done: DoneCallback) => {
+            (async () => {
+                const accounts = await ledgerSubprovider.getAccountsAsync();
 
-				// Give first account on Ledger sufficient ETH to complete tx send
-				let tx = {
-					to: accounts[0],
-					from: TEST_RPC_ACCOUNT_0,
-					value: '0x8ac7230489e80000', // 10 ETH
-				};
-				let payload = {
-					jsonrpc: '2.0',
-					method: 'eth_sendTransaction',
-					params: [tx],
-					id: 1,
-				};
-				await promisify(defaultProvider.sendAsync, defaultProvider)(payload);
+                // Give first account on Ledger sufficient ETH to complete tx send
+                let tx = {
+                    to: accounts[0],
+                    from: TEST_RPC_ACCOUNT_0,
+                    value: '0x8ac7230489e80000', // 10 ETH
+                };
+                let payload = {
+                    jsonrpc: '2.0',
+                    method: 'eth_sendTransaction',
+                    params: [tx],
+                    id: 1,
+                };
+                await promisify(defaultProvider.sendAsync, defaultProvider)(payload);
 
-				// Send transaction from Ledger
-				tx = {
-					to: '0xafa3f8684e54059998bc3a7b0d2b0da075154d66',
-					from: accounts[0],
-					value: '0xde0b6b3a7640000',
-				};
-				payload = {
-					jsonrpc: '2.0',
-					method: 'eth_sendTransaction',
-					params: [tx],
-					id: 1,
-				};
-				const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
-					expect(err).to.be.a('null');
-					const result = response.result.result;
-					expect(result.length).to.be.equal(66);
-					expect(result.substr(0, 2)).to.be.equal('0x');
-					done();
-				});
-				ledgerProvider.sendAsync(payload, callback);
-			})().catch(done);
-		});
-	});
+                // Send transaction from Ledger
+                tx = {
+                    to: '0xafa3f8684e54059998bc3a7b0d2b0da075154d66',
+                    from: accounts[0],
+                    value: '0xde0b6b3a7640000',
+                };
+                payload = {
+                    jsonrpc: '2.0',
+                    method: 'eth_sendTransaction',
+                    params: [tx],
+                    id: 1,
+                };
+                const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
+                    expect(err).to.be.a('null');
+                    const result = response.result.result;
+                    expect(result.length).to.be.equal(66);
+                    expect(result.substr(0, 2)).to.be.equal('0x');
+                    done();
+                });
+                ledgerProvider.sendAsync(payload, callback);
+            })().catch(done);
+        });
+    });
 });
diff --git a/packages/subproviders/test/unit/ledger_subprovider_test.ts b/packages/subproviders/test/unit/ledger_subprovider_test.ts
index 101b6b906..1c70dd3a6 100644
--- a/packages/subproviders/test/unit/ledger_subprovider_test.ts
+++ b/packages/subproviders/test/unit/ledger_subprovider_test.ts
@@ -15,230 +15,230 @@ const expect = chai.expect;
 const FAKE_ADDRESS = '0xb088a3bc93f71b4de97b9de773e9647645983688';
 
 describe('LedgerSubprovider', () => {
-	const networkId: number = 42;
-	let ledgerSubprovider: LedgerSubprovider;
-	before(async () => {
-		const ledgerEthereumClientFactoryAsync = async () => {
-			// tslint:disable:no-object-literal-type-assertion
-			const ledgerEthClient = {
-				getAddress_async: async () => {
-					const publicKey =
-						'04f428290f4c5ed6a198f71b8205f488141dbb3f0840c923bbfa798ecbee6370986c03b5575d94d506772fb48a6a44e345e4ebd4f028a6f609c44b655d6d3e71a1';
-					const chainCode = 'ac055a5537c0c7e9e02d14a197cad6b857836da2a12043b46912a37d959b5ae8';
-					const address = '0xBa388BA5e5EEF2c6cE42d831c2B3A28D3c99bdB1';
-					return {
-						publicKey,
-						address,
-						chainCode,
-					};
-				},
-				signPersonalMessage_async: async () => {
-					const ecSignature = {
-						v: 28,
-						r: 'a6cc284bff14b42bdf5e9286730c152be91719d478605ec46b3bebcd0ae49148',
-						s: '0652a1a7b742ceb0213d1e744316e285f41f878d8af0b8e632cbca4c279132d0',
-					};
-					return ecSignature;
-				},
-				signTransaction_async: async (derivationPath: string, txHex: string) => {
-					const ecSignature = {
-						v: '77',
-						r: '88a95ef1378487bc82be558e82c8478baf840c545d5b887536bb1da63673a98b',
-						s: '019f4a4b9a107d1e6752bf7f701e275f28c13791d6e76af895b07373462cefaa',
-					};
-					return ecSignature;
-				},
-				comm: {
-					close_async: _.noop,
-				} as LedgerCommunicationClient,
-			};
-			// tslint:enable:no-object-literal-type-assertion
-			return ledgerEthClient;
-		};
-		ledgerSubprovider = new LedgerSubprovider({
-			networkId,
-			ledgerEthereumClientFactoryAsync,
-		});
-	});
-	describe('direct method calls', () => {
-		describe('success cases', () => {
-			it('returns a list of accounts', async () => {
-				const accounts = await ledgerSubprovider.getAccountsAsync();
-				expect(accounts[0]).to.be.equal(FAKE_ADDRESS);
-				expect(accounts.length).to.be.equal(10);
-			});
-			it('signs a personal message', async () => {
-				const data = ethUtils.bufferToHex(ethUtils.toBuffer('hello world'));
-				const ecSignatureHex = await ledgerSubprovider.signPersonalMessageAsync(data);
-				expect(ecSignatureHex).to.be.equal(
-					'0xa6cc284bff14b42bdf5e9286730c152be91719d478605ec46b3bebcd0ae491480652a1a7b742ceb0213d1e744316e285f41f878d8af0b8e632cbca4c279132d001',
-				);
-			});
-		});
-		describe('failure cases', () => {
-			it('cannot open multiple simultaneous connections to the Ledger device', async () => {
-				const data = ethUtils.bufferToHex(ethUtils.toBuffer('hello world'));
-				return expect(
-					Promise.all([
-						ledgerSubprovider.getAccountsAsync(),
-						ledgerSubprovider.signPersonalMessageAsync(data),
-					]),
-				).to.be.rejectedWith(LedgerSubproviderErrors.MultipleOpenConnectionsDisallowed);
-			});
-		});
-	});
-	describe('calls through a provider', () => {
-		let provider: Web3ProviderEngine;
-		before(() => {
-			provider = new Web3ProviderEngine();
-			provider.addProvider(ledgerSubprovider);
-			const httpProvider = new RpcSubprovider({
-				rpcUrl: 'http://localhost:8545',
-			});
-			provider.addProvider(httpProvider);
-			provider.start();
-		});
-		describe('success cases', () => {
-			it('returns a list of accounts', (done: DoneCallback) => {
-				const payload = {
-					jsonrpc: '2.0',
-					method: 'eth_accounts',
-					params: [],
-					id: 1,
-				};
-				const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
-					expect(err).to.be.a('null');
-					expect(response.result.length).to.be.equal(10);
-					expect(response.result[0]).to.be.equal(FAKE_ADDRESS);
-					done();
-				});
-				provider.sendAsync(payload, callback);
-			});
-			it('signs a personal message with eth_sign', (done: DoneCallback) => {
-				const messageHex = ethUtils.bufferToHex(ethUtils.toBuffer('hello world'));
-				const payload = {
-					jsonrpc: '2.0',
-					method: 'eth_sign',
-					params: ['0x0000000000000000000000000000000000000000', messageHex],
-					id: 1,
-				};
-				const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
-					expect(err).to.be.a('null');
-					expect(response.result).to.be.equal(
-						'0xa6cc284bff14b42bdf5e9286730c152be91719d478605ec46b3bebcd0ae491480652a1a7b742ceb0213d1e744316e285f41f878d8af0b8e632cbca4c279132d001',
-					);
-					done();
-				});
-				provider.sendAsync(payload, callback);
-			});
-			it('signs a personal message with personal_sign', (done: DoneCallback) => {
-				const messageHex = ethUtils.bufferToHex(ethUtils.toBuffer('hello world'));
-				const payload = {
-					jsonrpc: '2.0',
-					method: 'personal_sign',
-					params: [messageHex, '0x0000000000000000000000000000000000000000'],
-					id: 1,
-				};
-				const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
-					expect(err).to.be.a('null');
-					expect(response.result).to.be.equal(
-						'0xa6cc284bff14b42bdf5e9286730c152be91719d478605ec46b3bebcd0ae491480652a1a7b742ceb0213d1e744316e285f41f878d8af0b8e632cbca4c279132d001',
-					);
-					done();
-				});
-				provider.sendAsync(payload, callback);
-			});
-			it('signs a transaction', (done: DoneCallback) => {
-				const tx = {
-					to: '0xafa3f8684e54059998bc3a7b0d2b0da075154d66',
-					value: '0x00',
-					gasPrice: '0x00',
-					nonce: '0x00',
-					gas: '0x00',
-				};
-				const payload = {
-					jsonrpc: '2.0',
-					method: 'eth_signTransaction',
-					params: [tx],
-					id: 1,
-				};
-				const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
-					expect(err).to.be.a('null');
-					expect(response.result.raw.length).to.be.equal(192);
-					expect(response.result.raw.substr(0, 2)).to.be.equal('0x');
-					done();
-				});
-				provider.sendAsync(payload, callback);
-			});
-		});
-		describe('failure cases', () => {
-			it('should throw if `data` param not hex when calling eth_sign', (done: DoneCallback) => {
-				const nonHexMessage = 'hello world';
-				const payload = {
-					jsonrpc: '2.0',
-					method: 'eth_sign',
-					params: ['0x0000000000000000000000000000000000000000', nonHexMessage],
-					id: 1,
-				};
-				const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
-					expect(err).to.not.be.a('null');
-					expect(err.message).to.be.equal('Expected data to be of type HexString, encountered: hello world');
-					done();
-				});
-				provider.sendAsync(payload, callback);
-			});
-			it('should throw if `data` param not hex when calling personal_sign', (done: DoneCallback) => {
-				const nonHexMessage = 'hello world';
-				const payload = {
-					jsonrpc: '2.0',
-					method: 'personal_sign',
-					params: [nonHexMessage, '0x0000000000000000000000000000000000000000'],
-					id: 1,
-				};
-				const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
-					expect(err).to.not.be.a('null');
-					expect(err.message).to.be.equal('Expected data to be of type HexString, encountered: hello world');
-					done();
-				});
-				provider.sendAsync(payload, callback);
-			});
-			it('should throw if `from` param missing when calling eth_sendTransaction', (done: DoneCallback) => {
-				const tx = {
-					to: '0xafa3f8684e54059998bc3a7b0d2b0da075154d66',
-					value: '0xde0b6b3a7640000',
-				};
-				const payload = {
-					jsonrpc: '2.0',
-					method: 'eth_sendTransaction',
-					params: [tx],
-					id: 1,
-				};
-				const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
-					expect(err).to.not.be.a('null');
-					expect(err.message).to.be.equal(LedgerSubproviderErrors.SenderInvalidOrNotSupplied);
-					done();
-				});
-				provider.sendAsync(payload, callback);
-			});
-			it('should throw if `from` param invalid address when calling eth_sendTransaction', (done: DoneCallback) => {
-				const tx = {
-					to: '0xafa3f8684e54059998bc3a7b0d2b0da075154d66',
-					from: '0xIncorrectEthereumAddress',
-					value: '0xde0b6b3a7640000',
-				};
-				const payload = {
-					jsonrpc: '2.0',
-					method: 'eth_sendTransaction',
-					params: [tx],
-					id: 1,
-				};
-				const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
-					expect(err).to.not.be.a('null');
-					expect(err.message).to.be.equal(LedgerSubproviderErrors.SenderInvalidOrNotSupplied);
-					done();
-				});
-				provider.sendAsync(payload, callback);
-			});
-		});
-	});
+    const networkId: number = 42;
+    let ledgerSubprovider: LedgerSubprovider;
+    before(async () => {
+        const ledgerEthereumClientFactoryAsync = async () => {
+            // tslint:disable:no-object-literal-type-assertion
+            const ledgerEthClient = {
+                getAddress_async: async () => {
+                    const publicKey =
+                        '04f428290f4c5ed6a198f71b8205f488141dbb3f0840c923bbfa798ecbee6370986c03b5575d94d506772fb48a6a44e345e4ebd4f028a6f609c44b655d6d3e71a1';
+                    const chainCode = 'ac055a5537c0c7e9e02d14a197cad6b857836da2a12043b46912a37d959b5ae8';
+                    const address = '0xBa388BA5e5EEF2c6cE42d831c2B3A28D3c99bdB1';
+                    return {
+                        publicKey,
+                        address,
+                        chainCode,
+                    };
+                },
+                signPersonalMessage_async: async () => {
+                    const ecSignature = {
+                        v: 28,
+                        r: 'a6cc284bff14b42bdf5e9286730c152be91719d478605ec46b3bebcd0ae49148',
+                        s: '0652a1a7b742ceb0213d1e744316e285f41f878d8af0b8e632cbca4c279132d0',
+                    };
+                    return ecSignature;
+                },
+                signTransaction_async: async (derivationPath: string, txHex: string) => {
+                    const ecSignature = {
+                        v: '77',
+                        r: '88a95ef1378487bc82be558e82c8478baf840c545d5b887536bb1da63673a98b',
+                        s: '019f4a4b9a107d1e6752bf7f701e275f28c13791d6e76af895b07373462cefaa',
+                    };
+                    return ecSignature;
+                },
+                comm: {
+                    close_async: _.noop,
+                } as LedgerCommunicationClient,
+            };
+            // tslint:enable:no-object-literal-type-assertion
+            return ledgerEthClient;
+        };
+        ledgerSubprovider = new LedgerSubprovider({
+            networkId,
+            ledgerEthereumClientFactoryAsync,
+        });
+    });
+    describe('direct method calls', () => {
+        describe('success cases', () => {
+            it('returns a list of accounts', async () => {
+                const accounts = await ledgerSubprovider.getAccountsAsync();
+                expect(accounts[0]).to.be.equal(FAKE_ADDRESS);
+                expect(accounts.length).to.be.equal(10);
+            });
+            it('signs a personal message', async () => {
+                const data = ethUtils.bufferToHex(ethUtils.toBuffer('hello world'));
+                const ecSignatureHex = await ledgerSubprovider.signPersonalMessageAsync(data);
+                expect(ecSignatureHex).to.be.equal(
+                    '0xa6cc284bff14b42bdf5e9286730c152be91719d478605ec46b3bebcd0ae491480652a1a7b742ceb0213d1e744316e285f41f878d8af0b8e632cbca4c279132d001',
+                );
+            });
+        });
+        describe('failure cases', () => {
+            it('cannot open multiple simultaneous connections to the Ledger device', async () => {
+                const data = ethUtils.bufferToHex(ethUtils.toBuffer('hello world'));
+                return expect(
+                    Promise.all([
+                        ledgerSubprovider.getAccountsAsync(),
+                        ledgerSubprovider.signPersonalMessageAsync(data),
+                    ]),
+                ).to.be.rejectedWith(LedgerSubproviderErrors.MultipleOpenConnectionsDisallowed);
+            });
+        });
+    });
+    describe('calls through a provider', () => {
+        let provider: Web3ProviderEngine;
+        before(() => {
+            provider = new Web3ProviderEngine();
+            provider.addProvider(ledgerSubprovider);
+            const httpProvider = new RpcSubprovider({
+                rpcUrl: 'http://localhost:8545',
+            });
+            provider.addProvider(httpProvider);
+            provider.start();
+        });
+        describe('success cases', () => {
+            it('returns a list of accounts', (done: DoneCallback) => {
+                const payload = {
+                    jsonrpc: '2.0',
+                    method: 'eth_accounts',
+                    params: [],
+                    id: 1,
+                };
+                const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
+                    expect(err).to.be.a('null');
+                    expect(response.result.length).to.be.equal(10);
+                    expect(response.result[0]).to.be.equal(FAKE_ADDRESS);
+                    done();
+                });
+                provider.sendAsync(payload, callback);
+            });
+            it('signs a personal message with eth_sign', (done: DoneCallback) => {
+                const messageHex = ethUtils.bufferToHex(ethUtils.toBuffer('hello world'));
+                const payload = {
+                    jsonrpc: '2.0',
+                    method: 'eth_sign',
+                    params: ['0x0000000000000000000000000000000000000000', messageHex],
+                    id: 1,
+                };
+                const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
+                    expect(err).to.be.a('null');
+                    expect(response.result).to.be.equal(
+                        '0xa6cc284bff14b42bdf5e9286730c152be91719d478605ec46b3bebcd0ae491480652a1a7b742ceb0213d1e744316e285f41f878d8af0b8e632cbca4c279132d001',
+                    );
+                    done();
+                });
+                provider.sendAsync(payload, callback);
+            });
+            it('signs a personal message with personal_sign', (done: DoneCallback) => {
+                const messageHex = ethUtils.bufferToHex(ethUtils.toBuffer('hello world'));
+                const payload = {
+                    jsonrpc: '2.0',
+                    method: 'personal_sign',
+                    params: [messageHex, '0x0000000000000000000000000000000000000000'],
+                    id: 1,
+                };
+                const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
+                    expect(err).to.be.a('null');
+                    expect(response.result).to.be.equal(
+                        '0xa6cc284bff14b42bdf5e9286730c152be91719d478605ec46b3bebcd0ae491480652a1a7b742ceb0213d1e744316e285f41f878d8af0b8e632cbca4c279132d001',
+                    );
+                    done();
+                });
+                provider.sendAsync(payload, callback);
+            });
+            it('signs a transaction', (done: DoneCallback) => {
+                const tx = {
+                    to: '0xafa3f8684e54059998bc3a7b0d2b0da075154d66',
+                    value: '0x00',
+                    gasPrice: '0x00',
+                    nonce: '0x00',
+                    gas: '0x00',
+                };
+                const payload = {
+                    jsonrpc: '2.0',
+                    method: 'eth_signTransaction',
+                    params: [tx],
+                    id: 1,
+                };
+                const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
+                    expect(err).to.be.a('null');
+                    expect(response.result.raw.length).to.be.equal(192);
+                    expect(response.result.raw.substr(0, 2)).to.be.equal('0x');
+                    done();
+                });
+                provider.sendAsync(payload, callback);
+            });
+        });
+        describe('failure cases', () => {
+            it('should throw if `data` param not hex when calling eth_sign', (done: DoneCallback) => {
+                const nonHexMessage = 'hello world';
+                const payload = {
+                    jsonrpc: '2.0',
+                    method: 'eth_sign',
+                    params: ['0x0000000000000000000000000000000000000000', nonHexMessage],
+                    id: 1,
+                };
+                const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
+                    expect(err).to.not.be.a('null');
+                    expect(err.message).to.be.equal('Expected data to be of type HexString, encountered: hello world');
+                    done();
+                });
+                provider.sendAsync(payload, callback);
+            });
+            it('should throw if `data` param not hex when calling personal_sign', (done: DoneCallback) => {
+                const nonHexMessage = 'hello world';
+                const payload = {
+                    jsonrpc: '2.0',
+                    method: 'personal_sign',
+                    params: [nonHexMessage, '0x0000000000000000000000000000000000000000'],
+                    id: 1,
+                };
+                const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
+                    expect(err).to.not.be.a('null');
+                    expect(err.message).to.be.equal('Expected data to be of type HexString, encountered: hello world');
+                    done();
+                });
+                provider.sendAsync(payload, callback);
+            });
+            it('should throw if `from` param missing when calling eth_sendTransaction', (done: DoneCallback) => {
+                const tx = {
+                    to: '0xafa3f8684e54059998bc3a7b0d2b0da075154d66',
+                    value: '0xde0b6b3a7640000',
+                };
+                const payload = {
+                    jsonrpc: '2.0',
+                    method: 'eth_sendTransaction',
+                    params: [tx],
+                    id: 1,
+                };
+                const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
+                    expect(err).to.not.be.a('null');
+                    expect(err.message).to.be.equal(LedgerSubproviderErrors.SenderInvalidOrNotSupplied);
+                    done();
+                });
+                provider.sendAsync(payload, callback);
+            });
+            it('should throw if `from` param invalid address when calling eth_sendTransaction', (done: DoneCallback) => {
+                const tx = {
+                    to: '0xafa3f8684e54059998bc3a7b0d2b0da075154d66',
+                    from: '0xIncorrectEthereumAddress',
+                    value: '0xde0b6b3a7640000',
+                };
+                const payload = {
+                    jsonrpc: '2.0',
+                    method: 'eth_sendTransaction',
+                    params: [tx],
+                    id: 1,
+                };
+                const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
+                    expect(err).to.not.be.a('null');
+                    expect(err.message).to.be.equal(LedgerSubproviderErrors.SenderInvalidOrNotSupplied);
+                    done();
+                });
+                provider.sendAsync(payload, callback);
+            });
+        });
+    });
 });
diff --git a/packages/subproviders/test/unit/redundant_rpc_subprovider_test.ts b/packages/subproviders/test/unit/redundant_rpc_subprovider_test.ts
index defb741dd..c3170745c 100644
--- a/packages/subproviders/test/unit/redundant_rpc_subprovider_test.ts
+++ b/packages/subproviders/test/unit/redundant_rpc_subprovider_test.ts
@@ -12,45 +12,45 @@ const expect = chai.expect;
 chaiSetup.configure();
 
 describe('RedundantRpcSubprovider', () => {
-	let provider: Web3ProviderEngine;
-	it('succeeds when supplied a healthy endpoint', (done: DoneCallback) => {
-		provider = new Web3ProviderEngine();
-		const endpoints = ['http://localhost:8545'];
-		const redundantSubprovider = new RedundantRPCSubprovider(endpoints);
-		provider.addProvider(redundantSubprovider);
-		provider.start();
+    let provider: Web3ProviderEngine;
+    it('succeeds when supplied a healthy endpoint', (done: DoneCallback) => {
+        provider = new Web3ProviderEngine();
+        const endpoints = ['http://localhost:8545'];
+        const redundantSubprovider = new RedundantRPCSubprovider(endpoints);
+        provider.addProvider(redundantSubprovider);
+        provider.start();
 
-		const payload = {
-			jsonrpc: '2.0',
-			method: 'eth_accounts',
-			params: [],
-			id: 1,
-		};
-		const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
-			expect(err).to.be.a('null');
-			expect(response.result.length).to.be.equal(10);
-			done();
-		});
-		provider.sendAsync(payload, callback);
-	});
-	it('succeeds when supplied at least one healthy endpoint', (done: DoneCallback) => {
-		provider = new Web3ProviderEngine();
-		const endpoints = ['http://does-not-exist:3000', 'http://localhost:8545'];
-		const redundantSubprovider = new RedundantRPCSubprovider(endpoints);
-		provider.addProvider(redundantSubprovider);
-		provider.start();
+        const payload = {
+            jsonrpc: '2.0',
+            method: 'eth_accounts',
+            params: [],
+            id: 1,
+        };
+        const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
+            expect(err).to.be.a('null');
+            expect(response.result.length).to.be.equal(10);
+            done();
+        });
+        provider.sendAsync(payload, callback);
+    });
+    it('succeeds when supplied at least one healthy endpoint', (done: DoneCallback) => {
+        provider = new Web3ProviderEngine();
+        const endpoints = ['http://does-not-exist:3000', 'http://localhost:8545'];
+        const redundantSubprovider = new RedundantRPCSubprovider(endpoints);
+        provider.addProvider(redundantSubprovider);
+        provider.start();
 
-		const payload = {
-			jsonrpc: '2.0',
-			method: 'eth_accounts',
-			params: [],
-			id: 1,
-		};
-		const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
-			expect(err).to.be.a('null');
-			expect(response.result.length).to.be.equal(10);
-			done();
-		});
-		provider.sendAsync(payload, callback);
-	});
+        const payload = {
+            jsonrpc: '2.0',
+            method: 'eth_accounts',
+            params: [],
+            id: 1,
+        };
+        const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => {
+            expect(err).to.be.a('null');
+            expect(response.result.length).to.be.equal(10);
+            done();
+        });
+        provider.sendAsync(payload, callback);
+    });
 });
diff --git a/packages/subproviders/test/utils/report_callback_errors.ts b/packages/subproviders/test/utils/report_callback_errors.ts
index e6aadfa84..8a8f4d966 100644
--- a/packages/subproviders/test/utils/report_callback_errors.ts
+++ b/packages/subproviders/test/utils/report_callback_errors.ts
@@ -1,14 +1,14 @@
 import { DoneCallback } from '../../src/types';
 
 export const reportCallbackErrors = (done: DoneCallback) => {
-	return (f: (...args: any[]) => void) => {
-		const wrapped = async (...args: any[]) => {
-			try {
-				f(...args);
-			} catch (err) {
-				done(err);
-			}
-		};
-		return wrapped;
-	};
+    return (f: (...args: any[]) => void) => {
+        const wrapped = async (...args: any[]) => {
+            try {
+                f(...args);
+            } catch (err) {
+                done(err);
+            }
+        };
+        return wrapped;
+    };
 };
diff --git a/packages/subproviders/tsconfig.json b/packages/subproviders/tsconfig.json
index 4d92e88a5..9a65a0a97 100644
--- a/packages/subproviders/tsconfig.json
+++ b/packages/subproviders/tsconfig.json
@@ -1,15 +1,15 @@
 {
-	"extends": "../../tsconfig",
-	"compilerOptions": {
-		"outDir": "lib"
-	},
-	"include": [
-		"./src/**/*",
-		"./test/**/*",
-		"../../node_modules/chai-typescript-typings/index.d.ts",
-		"../../node_modules/web3-typescript-typings/index.d.ts",
-		"../../node_modules/types-bn/index.d.ts",
-		"../../node_modules/types-ethereumjs-util/index.d.ts",
-		"../../node_modules/chai-as-promised-typescript-typings/index.d.ts"
-	]
+    "extends": "../../tsconfig",
+    "compilerOptions": {
+        "outDir": "lib"
+    },
+    "include": [
+        "./src/**/*",
+        "./test/**/*",
+        "../../node_modules/chai-typescript-typings/index.d.ts",
+        "../../node_modules/web3-typescript-typings/index.d.ts",
+        "../../node_modules/types-bn/index.d.ts",
+        "../../node_modules/types-ethereumjs-util/index.d.ts",
+        "../../node_modules/chai-as-promised-typescript-typings/index.d.ts"
+    ]
 }
diff --git a/packages/subproviders/tslint.json b/packages/subproviders/tslint.json
index e63054bfc..ffaefe83a 100644
--- a/packages/subproviders/tslint.json
+++ b/packages/subproviders/tslint.json
@@ -1,3 +1,3 @@
 {
-	"extends": ["@0xproject/tslint-config"]
+    "extends": ["@0xproject/tslint-config"]
 }
diff --git a/packages/testnet-faucets/README.md b/packages/testnet-faucets/README.md
index 36322e76e..a52d16a00 100644
--- a/packages/testnet-faucets/README.md
+++ b/packages/testnet-faucets/README.md
@@ -63,26 +63,26 @@ Returns a JSON payload describing the state of the queues for each network. For
 
 ```json
 {
-	"3": {
-		"ether": {
-			"full": false,
-			"size": 4
-		},
-		"zrx": {
-			"full": false,
-			"size": 6
-		}
-	},
-	"42": {
-		"ether": {
-			"full": false,
-			"size": 8
-		},
-		"zrx": {
-			"full": false,
-			"size": 20
-		}
-	}
+    "3": {
+        "ether": {
+            "full": false,
+            "size": 4
+        },
+        "zrx": {
+            "full": false,
+            "size": 6
+        }
+    },
+    "42": {
+        "ether": {
+            "full": false,
+            "size": 8
+        },
+        "zrx": {
+            "full": false,
+            "size": 20
+        }
+    }
 }
 ```
 
diff --git a/packages/testnet-faucets/package.json b/packages/testnet-faucets/package.json
index 4f8bcfdcf..6c27df0d5 100644
--- a/packages/testnet-faucets/package.json
+++ b/packages/testnet-faucets/package.json
@@ -1,43 +1,43 @@
 {
-	"private": true,
-	"name": "@0xproject/testnet-faucets",
-	"version": "1.0.7",
-	"description": "A faucet micro-service that dispenses test ERC20 tokens or Ether",
-	"main": "server.js",
-	"scripts": {
-		"build": "node ../../node_modules/gulp/bin/gulp.js build",
-		"dev": "node ../../node_modules/gulp/bin/gulp.js run",
-		"start": "node ./bin/server.js",
-		"lint": "tslint --project . 'src/**/*.ts'",
-		"clean": "shx rm -rf bin"
-	},
-	"author": "Fabio Berger",
-	"license": "Apache-2.0",
-	"dependencies": {
-		"0x.js": "^0.30.2",
-		"@0xproject/utils": "^0.2.2",
-		"body-parser": "^1.17.1",
-		"ethereumjs-tx": "^1.3.3",
-		"express": "^4.15.2",
-		"lodash": "^4.17.4",
-		"rollbar": "^0.6.5",
-		"web3": "^0.20.0",
-		"web3-provider-engine": "^13.0.1"
-	},
-	"devDependencies": {
-		"@0xproject/tslint-config": "^0.4.4",
-		"@types/body-parser": "^1.16.1",
-		"@types/express": "^4.0.35",
-		"@types/lodash": "^4.14.86",
-		"awesome-typescript-loader": "^3.1.3",
-		"gulp": "^3.9.1",
-		"nodemon": "^1.11.0",
-		"shx": "^0.2.2",
-		"source-map-loader": "^0.1.6",
-		"tslint": "5.8.0",
-		"typescript": "~2.6.1",
-		"web3-typescript-typings": "^0.9.6",
-		"webpack": "^3.1.0",
-		"webpack-node-externals": "^1.6.0"
-	}
+    "private": true,
+    "name": "@0xproject/testnet-faucets",
+    "version": "1.0.7",
+    "description": "A faucet micro-service that dispenses test ERC20 tokens or Ether",
+    "main": "server.js",
+    "scripts": {
+        "build": "node ../../node_modules/gulp/bin/gulp.js build",
+        "dev": "node ../../node_modules/gulp/bin/gulp.js run",
+        "start": "node ./bin/server.js",
+        "lint": "tslint --project . 'src/**/*.ts'",
+        "clean": "shx rm -rf bin"
+    },
+    "author": "Fabio Berger",
+    "license": "Apache-2.0",
+    "dependencies": {
+        "0x.js": "^0.30.2",
+        "@0xproject/utils": "^0.2.2",
+        "body-parser": "^1.17.1",
+        "ethereumjs-tx": "^1.3.3",
+        "express": "^4.15.2",
+        "lodash": "^4.17.4",
+        "rollbar": "^0.6.5",
+        "web3": "^0.20.0",
+        "web3-provider-engine": "^13.0.1"
+    },
+    "devDependencies": {
+        "@0xproject/tslint-config": "^0.4.4",
+        "@types/body-parser": "^1.16.1",
+        "@types/express": "^4.0.35",
+        "@types/lodash": "^4.14.86",
+        "awesome-typescript-loader": "^3.1.3",
+        "gulp": "^3.9.1",
+        "nodemon": "^1.11.0",
+        "shx": "^0.2.2",
+        "source-map-loader": "^0.1.6",
+        "tslint": "5.8.0",
+        "typescript": "~2.6.1",
+        "web3-typescript-typings": "^0.9.6",
+        "webpack": "^3.1.0",
+        "webpack-node-externals": "^1.6.0"
+    }
 }
diff --git a/packages/testnet-faucets/src/ts/configs.ts b/packages/testnet-faucets/src/ts/configs.ts
index 038df5322..038c8e22a 100644
--- a/packages/testnet-faucets/src/ts/configs.ts
+++ b/packages/testnet-faucets/src/ts/configs.ts
@@ -1,7 +1,7 @@
 export const configs = {
-	DISPENSER_ADDRESS: (process.env.DISPENSER_ADDRESS as string).toLowerCase(),
-	DISPENSER_PRIVATE_KEY: process.env.DISPENSER_PRIVATE_KEY,
-	ENVIRONMENT: process.env.FAUCET_ENVIRONMENT,
-	INFURA_API_KEY: process.env.INFURA_API_KEY,
-	ROLLBAR_ACCESS_KEY: process.env.FAUCET_ROLLBAR_ACCESS_KEY,
+    DISPENSER_ADDRESS: (process.env.DISPENSER_ADDRESS as string).toLowerCase(),
+    DISPENSER_PRIVATE_KEY: process.env.DISPENSER_PRIVATE_KEY,
+    ENVIRONMENT: process.env.FAUCET_ENVIRONMENT,
+    INFURA_API_KEY: process.env.INFURA_API_KEY,
+    ROLLBAR_ACCESS_KEY: process.env.FAUCET_ROLLBAR_ACCESS_KEY,
 };
diff --git a/packages/testnet-faucets/src/ts/error_reporter.ts b/packages/testnet-faucets/src/ts/error_reporter.ts
index 0cef6cfa8..6865d3893 100644
--- a/packages/testnet-faucets/src/ts/error_reporter.ts
+++ b/packages/testnet-faucets/src/ts/error_reporter.ts
@@ -5,36 +5,36 @@ import { configs } from './configs';
 import { utils } from './utils';
 
 export const errorReporter = {
-	setup() {
-		rollbar.init(configs.ROLLBAR_ACCESS_KEY, {
-			environment: configs.ENVIRONMENT,
-		});
+    setup() {
+        rollbar.init(configs.ROLLBAR_ACCESS_KEY, {
+            environment: configs.ENVIRONMENT,
+        });
 
-		rollbar.handleUncaughtExceptions(configs.ROLLBAR_ACCESS_KEY);
+        rollbar.handleUncaughtExceptions(configs.ROLLBAR_ACCESS_KEY);
 
-		process.on('unhandledRejection', async (err: Error) => {
-			utils.consoleLog(`Uncaught exception ${err}. Stack: ${err.stack}`);
-			await this.reportAsync(err);
-			process.exit(1);
-		});
-	},
-	async reportAsync(err: Error, req?: express.Request): Promise<any> {
-		if (configs.ENVIRONMENT === 'development') {
-			return; // Do not log development environment errors
-		}
+        process.on('unhandledRejection', async (err: Error) => {
+            utils.consoleLog(`Uncaught exception ${err}. Stack: ${err.stack}`);
+            await this.reportAsync(err);
+            process.exit(1);
+        });
+    },
+    async reportAsync(err: Error, req?: express.Request): Promise<any> {
+        if (configs.ENVIRONMENT === 'development') {
+            return; // Do not log development environment errors
+        }
 
-		return new Promise((resolve, reject) => {
-			rollbar.handleError(err, req, (rollbarErr: Error) => {
-				if (rollbarErr) {
-					utils.consoleLog(`Error reporting to rollbar, ignoring: ${rollbarErr}`);
-					reject(rollbarErr);
-				} else {
-					resolve();
-				}
-			});
-		});
-	},
-	errorHandler() {
-		return rollbar.errorHandler(configs.ROLLBAR_ACCESS_KEY);
-	},
+        return new Promise((resolve, reject) => {
+            rollbar.handleError(err, req, (rollbarErr: Error) => {
+                if (rollbarErr) {
+                    utils.consoleLog(`Error reporting to rollbar, ignoring: ${rollbarErr}`);
+                    reject(rollbarErr);
+                } else {
+                    resolve();
+                }
+            });
+        });
+    },
+    errorHandler() {
+        return rollbar.errorHandler(configs.ROLLBAR_ACCESS_KEY);
+    },
 };
diff --git a/packages/testnet-faucets/src/ts/ether_request_queue.ts b/packages/testnet-faucets/src/ts/ether_request_queue.ts
index aa75a00e4..1c4b19ab9 100644
--- a/packages/testnet-faucets/src/ts/ether_request_queue.ts
+++ b/packages/testnet-faucets/src/ts/ether_request_queue.ts
@@ -9,19 +9,19 @@ import { utils } from './utils';
 const DISPENSE_AMOUNT_ETHER = 0.1;
 
 export class EtherRequestQueue extends RequestQueue {
-	protected async processNextRequestFireAndForgetAsync(recipientAddress: string) {
-		utils.consoleLog(`Processing ETH ${recipientAddress}`);
-		const sendTransactionAsync = promisify(this.web3.eth.sendTransaction);
-		try {
-			const txHash = await sendTransactionAsync({
-				from: configs.DISPENSER_ADDRESS,
-				to: recipientAddress,
-				value: this.web3.toWei(DISPENSE_AMOUNT_ETHER, 'ether'),
-			});
-			utils.consoleLog(`Sent ${DISPENSE_AMOUNT_ETHER} ETH to ${recipientAddress} tx: ${txHash}`);
-		} catch (err) {
-			utils.consoleLog(`Unexpected err: ${err} - ${JSON.stringify(err)}`);
-			await errorReporter.reportAsync(err);
-		}
-	}
+    protected async processNextRequestFireAndForgetAsync(recipientAddress: string) {
+        utils.consoleLog(`Processing ETH ${recipientAddress}`);
+        const sendTransactionAsync = promisify(this.web3.eth.sendTransaction);
+        try {
+            const txHash = await sendTransactionAsync({
+                from: configs.DISPENSER_ADDRESS,
+                to: recipientAddress,
+                value: this.web3.toWei(DISPENSE_AMOUNT_ETHER, 'ether'),
+            });
+            utils.consoleLog(`Sent ${DISPENSE_AMOUNT_ETHER} ETH to ${recipientAddress} tx: ${txHash}`);
+        } catch (err) {
+            utils.consoleLog(`Unexpected err: ${err} - ${JSON.stringify(err)}`);
+            await errorReporter.reportAsync(err);
+        }
+    }
 }
diff --git a/packages/testnet-faucets/src/ts/global.d.ts b/packages/testnet-faucets/src/ts/global.d.ts
index 90866565d..97cd35680 100644
--- a/packages/testnet-faucets/src/ts/global.d.ts
+++ b/packages/testnet-faucets/src/ts/global.d.ts
@@ -5,22 +5,22 @@ declare module 'web3-provider-engine/subproviders/nonce-tracker';
 declare module 'web3-provider-engine/subproviders/hooked-wallet';
 
 declare module '*.json' {
-	const json: any;
-	/* tslint:disable */
-	export default json;
-	/* tslint:enable */
+    const json: any;
+    /* tslint:disable */
+    export default json;
+    /* tslint:enable */
 }
 
 // Ethereumjs-tx declarations
 declare module 'ethereumjs-tx' {
-	class EthereumTx {
-		public raw: Buffer[];
-		public r: Buffer;
-		public s: Buffer;
-		public v: Buffer;
-		public serialize(): Buffer;
-		public sign(buffer: Buffer): void;
-		constructor(txParams: any);
-	}
-	export = EthereumTx;
+    class EthereumTx {
+        public raw: Buffer[];
+        public r: Buffer;
+        public s: Buffer;
+        public v: Buffer;
+        public serialize(): Buffer;
+        public sign(buffer: Buffer): void;
+        constructor(txParams: any);
+    }
+    export = EthereumTx;
 }
diff --git a/packages/testnet-faucets/src/ts/handler.ts b/packages/testnet-faucets/src/ts/handler.ts
index 455a925e3..bf5b3e81e 100644
--- a/packages/testnet-faucets/src/ts/handler.ts
+++ b/packages/testnet-faucets/src/ts/handler.ts
@@ -20,95 +20,95 @@ import { ZRXRequestQueue } from './zrx_request_queue';
 import * as Web3 from 'web3';
 
 interface RequestQueueByNetworkId {
-	[networkId: string]: RequestQueue;
+    [networkId: string]: RequestQueue;
 }
 
 enum QueueType {
-	ETH = 'ETH',
-	ZRX = 'ZRX',
+    ETH = 'ETH',
+    ZRX = 'ZRX',
 }
 
 const DEFAULT_NETWORK_ID = 42; // kovan
 
 export class Handler {
-	private _etherRequestQueueByNetworkId: RequestQueueByNetworkId = {};
-	private _zrxRequestQueueByNetworkId: RequestQueueByNetworkId = {};
-	constructor() {
-		_.forIn(rpcUrls, (rpcUrl: string, networkId: string) => {
-			const providerObj = this._createProviderEngine(rpcUrl);
-			const web3 = new Web3(providerObj);
-			this._etherRequestQueueByNetworkId[networkId] = new EtherRequestQueue(web3);
-			this._zrxRequestQueueByNetworkId[networkId] = new ZRXRequestQueue(web3, +networkId);
-		});
-	}
-	public getQueueInfo(req: express.Request, res: express.Response) {
-		res.setHeader('Content-Type', 'application/json');
-		const queueInfo = _.mapValues(rpcUrls, (rpcUrl: string, networkId: string) => {
-			utils.consoleLog(networkId);
-			const etherRequestQueue = this._etherRequestQueueByNetworkId[networkId];
-			const zrxRequestQueue = this._zrxRequestQueueByNetworkId[networkId];
-			return {
-				ether: {
-					full: etherRequestQueue.isFull(),
-					size: etherRequestQueue.size(),
-				},
-				zrx: {
-					full: zrxRequestQueue.isFull(),
-					size: zrxRequestQueue.size(),
-				},
-			};
-		});
-		const payload = JSON.stringify(queueInfo);
-		res.status(200).send(payload);
-	}
-	public dispenseEther(req: express.Request, res: express.Response) {
-		this._dispense(req, res, this._etherRequestQueueByNetworkId, QueueType.ETH);
-	}
-	public dispenseZRX(req: express.Request, res: express.Response) {
-		this._dispense(req, res, this._zrxRequestQueueByNetworkId, QueueType.ZRX);
-	}
-	private _dispense(
-		req: express.Request,
-		res: express.Response,
-		requestQueueByNetworkId: RequestQueueByNetworkId,
-		queueType: QueueType,
-	) {
-		const recipientAddress = req.params.recipient;
-		if (_.isUndefined(recipientAddress) || !this._isValidEthereumAddress(recipientAddress)) {
-			res.status(400).send('INVALID_RECIPIENT_ADDRESS');
-			return;
-		}
-		const networkId = _.get(req.query, 'networkId', DEFAULT_NETWORK_ID);
-		const requestQueue = _.get(requestQueueByNetworkId, networkId);
-		if (_.isUndefined(requestQueue)) {
-			res.status(400).send('INVALID_NETWORK_ID');
-			return;
-		}
-		const lowerCaseRecipientAddress = recipientAddress.toLowerCase();
-		const didAddToQueue = requestQueue.add(lowerCaseRecipientAddress);
-		if (!didAddToQueue) {
-			res.status(503).send('QUEUE_IS_FULL');
-			return;
-		}
-		utils.consoleLog(`Added ${lowerCaseRecipientAddress} to queue: ${queueType} networkId: ${networkId}`);
-		res.status(200).end();
-	}
-	// tslint:disable-next-line:prefer-function-over-method
-	private _createProviderEngine(rpcUrl: string) {
-		const engine = new ProviderEngine();
-		engine.addProvider(new NonceSubprovider());
-		engine.addProvider(new HookedWalletSubprovider(idManagement));
-		engine.addProvider(
-			new RpcSubprovider({
-				rpcUrl,
-			}),
-		);
-		engine.start();
-		return engine;
-	}
-	// tslint:disable-next-line:prefer-function-over-method
-	private _isValidEthereumAddress(address: string): boolean {
-		const lowercaseAddress = address.toLowerCase();
-		return addressUtils.isAddress(lowercaseAddress);
-	}
+    private _etherRequestQueueByNetworkId: RequestQueueByNetworkId = {};
+    private _zrxRequestQueueByNetworkId: RequestQueueByNetworkId = {};
+    constructor() {
+        _.forIn(rpcUrls, (rpcUrl: string, networkId: string) => {
+            const providerObj = this._createProviderEngine(rpcUrl);
+            const web3 = new Web3(providerObj);
+            this._etherRequestQueueByNetworkId[networkId] = new EtherRequestQueue(web3);
+            this._zrxRequestQueueByNetworkId[networkId] = new ZRXRequestQueue(web3, +networkId);
+        });
+    }
+    public getQueueInfo(req: express.Request, res: express.Response) {
+        res.setHeader('Content-Type', 'application/json');
+        const queueInfo = _.mapValues(rpcUrls, (rpcUrl: string, networkId: string) => {
+            utils.consoleLog(networkId);
+            const etherRequestQueue = this._etherRequestQueueByNetworkId[networkId];
+            const zrxRequestQueue = this._zrxRequestQueueByNetworkId[networkId];
+            return {
+                ether: {
+                    full: etherRequestQueue.isFull(),
+                    size: etherRequestQueue.size(),
+                },
+                zrx: {
+                    full: zrxRequestQueue.isFull(),
+                    size: zrxRequestQueue.size(),
+                },
+            };
+        });
+        const payload = JSON.stringify(queueInfo);
+        res.status(200).send(payload);
+    }
+    public dispenseEther(req: express.Request, res: express.Response) {
+        this._dispense(req, res, this._etherRequestQueueByNetworkId, QueueType.ETH);
+    }
+    public dispenseZRX(req: express.Request, res: express.Response) {
+        this._dispense(req, res, this._zrxRequestQueueByNetworkId, QueueType.ZRX);
+    }
+    private _dispense(
+        req: express.Request,
+        res: express.Response,
+        requestQueueByNetworkId: RequestQueueByNetworkId,
+        queueType: QueueType,
+    ) {
+        const recipientAddress = req.params.recipient;
+        if (_.isUndefined(recipientAddress) || !this._isValidEthereumAddress(recipientAddress)) {
+            res.status(400).send('INVALID_RECIPIENT_ADDRESS');
+            return;
+        }
+        const networkId = _.get(req.query, 'networkId', DEFAULT_NETWORK_ID);
+        const requestQueue = _.get(requestQueueByNetworkId, networkId);
+        if (_.isUndefined(requestQueue)) {
+            res.status(400).send('INVALID_NETWORK_ID');
+            return;
+        }
+        const lowerCaseRecipientAddress = recipientAddress.toLowerCase();
+        const didAddToQueue = requestQueue.add(lowerCaseRecipientAddress);
+        if (!didAddToQueue) {
+            res.status(503).send('QUEUE_IS_FULL');
+            return;
+        }
+        utils.consoleLog(`Added ${lowerCaseRecipientAddress} to queue: ${queueType} networkId: ${networkId}`);
+        res.status(200).end();
+    }
+    // tslint:disable-next-line:prefer-function-over-method
+    private _createProviderEngine(rpcUrl: string) {
+        const engine = new ProviderEngine();
+        engine.addProvider(new NonceSubprovider());
+        engine.addProvider(new HookedWalletSubprovider(idManagement));
+        engine.addProvider(
+            new RpcSubprovider({
+                rpcUrl,
+            }),
+        );
+        engine.start();
+        return engine;
+    }
+    // tslint:disable-next-line:prefer-function-over-method
+    private _isValidEthereumAddress(address: string): boolean {
+        const lowercaseAddress = address.toLowerCase();
+        return addressUtils.isAddress(lowercaseAddress);
+    }
 }
diff --git a/packages/testnet-faucets/src/ts/id_management.ts b/packages/testnet-faucets/src/ts/id_management.ts
index 2f04b5ff9..db9b610a3 100644
--- a/packages/testnet-faucets/src/ts/id_management.ts
+++ b/packages/testnet-faucets/src/ts/id_management.ts
@@ -5,17 +5,17 @@ import { configs } from './configs';
 type Callback = (err: Error | null, accounts: any) => void;
 
 export const idManagement = {
-	getAccounts(callback: Callback) {
-		callback(null, [configs.DISPENSER_ADDRESS]);
-	},
-	approveTransaction(txData: object, callback: Callback) {
-		callback(null, true);
-	},
-	signTransaction(txData: object, callback: Callback) {
-		const tx = new EthereumTx(txData);
-		const privateKeyBuffer = new Buffer(configs.DISPENSER_PRIVATE_KEY as string, 'hex');
-		tx.sign(privateKeyBuffer);
-		const rawTx = `0x${tx.serialize().toString('hex')}`;
-		callback(null, rawTx);
-	},
+    getAccounts(callback: Callback) {
+        callback(null, [configs.DISPENSER_ADDRESS]);
+    },
+    approveTransaction(txData: object, callback: Callback) {
+        callback(null, true);
+    },
+    signTransaction(txData: object, callback: Callback) {
+        const tx = new EthereumTx(txData);
+        const privateKeyBuffer = new Buffer(configs.DISPENSER_PRIVATE_KEY as string, 'hex');
+        tx.sign(privateKeyBuffer);
+        const rawTx = `0x${tx.serialize().toString('hex')}`;
+        callback(null, rawTx);
+    },
 };
diff --git a/packages/testnet-faucets/src/ts/request_queue.ts b/packages/testnet-faucets/src/ts/request_queue.ts
index 37b5505f8..20f2833a1 100644
--- a/packages/testnet-faucets/src/ts/request_queue.ts
+++ b/packages/testnet-faucets/src/ts/request_queue.ts
@@ -11,46 +11,46 @@ const MAX_QUEUE_SIZE = 500;
 const DEFAULT_QUEUE_INTERVAL_MS = 1000;
 
 export class RequestQueue {
-	protected queueIntervalMs: number;
-	protected queue: string[];
-	protected queueIntervalId: NodeJS.Timer;
-	protected web3: Web3;
-	constructor(web3: any) {
-		this.queueIntervalMs = DEFAULT_QUEUE_INTERVAL_MS;
-		this.queue = [];
+    protected queueIntervalMs: number;
+    protected queue: string[];
+    protected queueIntervalId: NodeJS.Timer;
+    protected web3: Web3;
+    constructor(web3: any) {
+        this.queueIntervalMs = DEFAULT_QUEUE_INTERVAL_MS;
+        this.queue = [];
 
-		this.web3 = web3;
+        this.web3 = web3;
 
-		this.start();
-	}
-	public add(recipientAddress: string): boolean {
-		if (this.isFull()) {
-			return false;
-		}
-		this.queue.push(recipientAddress);
-		return true;
-	}
-	public size(): number {
-		return this.queue.length;
-	}
-	public isFull(): boolean {
-		return this.size() >= MAX_QUEUE_SIZE;
-	}
-	protected start() {
-		this.queueIntervalId = timers.setInterval(() => {
-			const recipientAddress = this.queue.shift();
-			if (_.isUndefined(recipientAddress)) {
-				return;
-			}
-			// tslint:disable-next-line:no-floating-promises
-			this.processNextRequestFireAndForgetAsync(recipientAddress);
-		}, this.queueIntervalMs);
-	}
-	protected stop() {
-		clearInterval(this.queueIntervalId);
-	}
-	// tslint:disable-next-line:prefer-function-over-method
-	protected async processNextRequestFireAndForgetAsync(recipientAddress: string) {
-		throw new Error('Expected processNextRequestFireAndForgetAsync to be implemented by a subclass');
-	}
+        this.start();
+    }
+    public add(recipientAddress: string): boolean {
+        if (this.isFull()) {
+            return false;
+        }
+        this.queue.push(recipientAddress);
+        return true;
+    }
+    public size(): number {
+        return this.queue.length;
+    }
+    public isFull(): boolean {
+        return this.size() >= MAX_QUEUE_SIZE;
+    }
+    protected start() {
+        this.queueIntervalId = timers.setInterval(() => {
+            const recipientAddress = this.queue.shift();
+            if (_.isUndefined(recipientAddress)) {
+                return;
+            }
+            // tslint:disable-next-line:no-floating-promises
+            this.processNextRequestFireAndForgetAsync(recipientAddress);
+        }, this.queueIntervalMs);
+    }
+    protected stop() {
+        clearInterval(this.queueIntervalId);
+    }
+    // tslint:disable-next-line:prefer-function-over-method
+    protected async processNextRequestFireAndForgetAsync(recipientAddress: string) {
+        throw new Error('Expected processNextRequestFireAndForgetAsync to be implemented by a subclass');
+    }
 }
diff --git a/packages/testnet-faucets/src/ts/rpc_urls.ts b/packages/testnet-faucets/src/ts/rpc_urls.ts
index 9e12bca37..25a3b938f 100644
--- a/packages/testnet-faucets/src/ts/rpc_urls.ts
+++ b/packages/testnet-faucets/src/ts/rpc_urls.ts
@@ -1,13 +1,13 @@
 import { configs } from './configs';
 
 const productionRpcUrls = {
-	'2': `https://ropsten.infura.io/${configs.INFURA_API_KEY}`,
-	'3': `https://rinkeby.infura.io/${configs.INFURA_API_KEY}`,
-	'42': `https://kovan.infura.io/${configs.INFURA_API_KEY}`,
+    '2': `https://ropsten.infura.io/${configs.INFURA_API_KEY}`,
+    '3': `https://rinkeby.infura.io/${configs.INFURA_API_KEY}`,
+    '42': `https://kovan.infura.io/${configs.INFURA_API_KEY}`,
 };
 
 const developmentRpcUrls = {
-	'50': 'http://127.0.0.1:8545',
+    '50': 'http://127.0.0.1:8545',
 };
 
 export const rpcUrls = configs.ENVIRONMENT === 'development' ? developmentRpcUrls : productionRpcUrls;
diff --git a/packages/testnet-faucets/src/ts/server.ts b/packages/testnet-faucets/src/ts/server.ts
index 6fb555538..26edfff5a 100644
--- a/packages/testnet-faucets/src/ts/server.ts
+++ b/packages/testnet-faucets/src/ts/server.ts
@@ -10,14 +10,14 @@ errorReporter.setup();
 const app = express();
 app.use(bodyParser.json()); // for parsing application/json
 app.use((req, res, next) => {
-	res.header('Access-Control-Allow-Origin', '*');
-	res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
-	next();
+    res.header('Access-Control-Allow-Origin', '*');
+    res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
+    next();
 });
 
 const handler = new Handler();
 app.get('/ping', (req: express.Request, res: express.Response) => {
-	res.status(200).send('pong');
+    res.status(200).send('pong');
 });
 app.get('/info', handler.getQueueInfo.bind(handler));
 app.get('/ether/:recipient', handler.dispenseEther.bind(handler));
diff --git a/packages/testnet-faucets/src/ts/utils.ts b/packages/testnet-faucets/src/ts/utils.ts
index 821fe453c..893f82ca3 100644
--- a/packages/testnet-faucets/src/ts/utils.ts
+++ b/packages/testnet-faucets/src/ts/utils.ts
@@ -1,7 +1,7 @@
 export const utils = {
-	consoleLog(message: string) {
-		/* tslint:disable */
-		console.log(message);
-		/* tslint:enable */
-	},
+    consoleLog(message: string) {
+        /* tslint:disable */
+        console.log(message);
+        /* tslint:enable */
+    },
 };
diff --git a/packages/testnet-faucets/src/ts/zrx_request_queue.ts b/packages/testnet-faucets/src/ts/zrx_request_queue.ts
index b81a44cd1..3d73f9dd2 100644
--- a/packages/testnet-faucets/src/ts/zrx_request_queue.ts
+++ b/packages/testnet-faucets/src/ts/zrx_request_queue.ts
@@ -17,30 +17,30 @@ const DISPENSE_AMOUNT_ZRX = new BigNumber(0.1);
 const QUEUE_INTERVAL_MS = 5000;
 
 export class ZRXRequestQueue extends RequestQueue {
-	private _zeroEx: ZeroEx;
-	constructor(web3: Web3, networkId: number) {
-		super(web3);
-		this.queueIntervalMs = QUEUE_INTERVAL_MS;
-		const zeroExConfig = {
-			networkId,
-		};
-		this._zeroEx = new ZeroEx(web3.currentProvider, zeroExConfig);
-	}
-	protected async processNextRequestFireAndForgetAsync(recipientAddress: string) {
-		utils.consoleLog(`Processing ZRX ${recipientAddress}`);
-		const baseUnitAmount = ZeroEx.toBaseUnitAmount(DISPENSE_AMOUNT_ZRX, 18);
-		try {
-			const zrxTokenAddress = this._zeroEx.exchange.getZRXTokenAddress();
-			const txHash = await this._zeroEx.token.transferAsync(
-				zrxTokenAddress,
-				configs.DISPENSER_ADDRESS,
-				recipientAddress,
-				baseUnitAmount,
-			);
-			utils.consoleLog(`Sent ${DISPENSE_AMOUNT_ZRX} ZRX to ${recipientAddress} tx: ${txHash}`);
-		} catch (err) {
-			utils.consoleLog(`Unexpected err: ${err} - ${JSON.stringify(err)}`);
-			await errorReporter.reportAsync(err);
-		}
-	}
+    private _zeroEx: ZeroEx;
+    constructor(web3: Web3, networkId: number) {
+        super(web3);
+        this.queueIntervalMs = QUEUE_INTERVAL_MS;
+        const zeroExConfig = {
+            networkId,
+        };
+        this._zeroEx = new ZeroEx(web3.currentProvider, zeroExConfig);
+    }
+    protected async processNextRequestFireAndForgetAsync(recipientAddress: string) {
+        utils.consoleLog(`Processing ZRX ${recipientAddress}`);
+        const baseUnitAmount = ZeroEx.toBaseUnitAmount(DISPENSE_AMOUNT_ZRX, 18);
+        try {
+            const zrxTokenAddress = this._zeroEx.exchange.getZRXTokenAddress();
+            const txHash = await this._zeroEx.token.transferAsync(
+                zrxTokenAddress,
+                configs.DISPENSER_ADDRESS,
+                recipientAddress,
+                baseUnitAmount,
+            );
+            utils.consoleLog(`Sent ${DISPENSE_AMOUNT_ZRX} ZRX to ${recipientAddress} tx: ${txHash}`);
+        } catch (err) {
+            utils.consoleLog(`Unexpected err: ${err} - ${JSON.stringify(err)}`);
+            await errorReporter.reportAsync(err);
+        }
+    }
 }
diff --git a/packages/testnet-faucets/tsconfig.json b/packages/testnet-faucets/tsconfig.json
index e3353cc95..7f0c084ff 100644
--- a/packages/testnet-faucets/tsconfig.json
+++ b/packages/testnet-faucets/tsconfig.json
@@ -1,7 +1,7 @@
 {
-	"extends": "../../tsconfig",
-	"compilerOptions": {
-		"outDir": "lib"
-	},
-	"include": ["./src/ts/**/*", "../../node_modules/web3-typescript-typings/index.d.ts"]
+    "extends": "../../tsconfig",
+    "compilerOptions": {
+        "outDir": "lib"
+    },
+    "include": ["./src/ts/**/*", "../../node_modules/web3-typescript-typings/index.d.ts"]
 }
diff --git a/packages/testnet-faucets/tslint.json b/packages/testnet-faucets/tslint.json
index e63054bfc..ffaefe83a 100644
--- a/packages/testnet-faucets/tslint.json
+++ b/packages/testnet-faucets/tslint.json
@@ -1,3 +1,3 @@
 {
-	"extends": ["@0xproject/tslint-config"]
+    "extends": ["@0xproject/tslint-config"]
 }
diff --git a/packages/tslint-config/README.md b/packages/tslint-config/README.md
index 71fdd9772..8a6fa8a2f 100644
--- a/packages/tslint-config/README.md
+++ b/packages/tslint-config/README.md
@@ -14,7 +14,7 @@ Add the following to your `tslint.json` file
 
 ```json
 {
-	"extends": ["@0xproject/tslint-config"]
+    "extends": ["@0xproject/tslint-config"]
 }
 ```
 
diff --git a/packages/tslint-config/package.json b/packages/tslint-config/package.json
index 95bd67ac6..8dd884370 100644
--- a/packages/tslint-config/package.json
+++ b/packages/tslint-config/package.json
@@ -1,37 +1,37 @@
 {
-	"name": "@0xproject/tslint-config",
-	"version": "0.4.4",
-	"description": "Lint rules related to 0xProject for TSLint",
-	"main": "tslint.json",
-	"scripts": {
-		"build": "tsc",
-		"clean": "shx rm -rf lib",
-		"lint": "tslint --project . 'rules/**/*.ts'"
-	},
-	"files": ["tslint.js", "README.md", "LICENSE"],
-	"repository": {
-		"type": "git",
-		"url": "git://github.com/0xProject/0x.js.git"
-	},
-	"keywords": ["tslint", "config", "0xProject", "typescript", "ts"],
-	"author": {
-		"name": "Fabio Berger",
-		"email": "fabio@0xproject.com"
-	},
-	"license": "Apache-2.0",
-	"bugs": {
-		"url": "https://github.com/0xProject/0x.js/issues"
-	},
-	"homepage": "https://github.com/0xProject/0x.js/packages/tslint-config/README.md",
-	"devDependencies": {
-		"@types/lodash": "^4.14.86",
-		"shx": "^0.2.2",
-		"tslint": "5.8.0",
-		"tslint-eslint-rules": "^4.1.1",
-		"typescript": "~2.6.1"
-	},
-	"dependencies": {
-		"lodash": "^4.17.4",
-		"tslint-react": "^3.2.0"
-	}
+    "name": "@0xproject/tslint-config",
+    "version": "0.4.4",
+    "description": "Lint rules related to 0xProject for TSLint",
+    "main": "tslint.json",
+    "scripts": {
+        "build": "tsc",
+        "clean": "shx rm -rf lib",
+        "lint": "tslint --project . 'rules/**/*.ts'"
+    },
+    "files": ["tslint.js", "README.md", "LICENSE"],
+    "repository": {
+        "type": "git",
+        "url": "git://github.com/0xProject/0x.js.git"
+    },
+    "keywords": ["tslint", "config", "0xProject", "typescript", "ts"],
+    "author": {
+        "name": "Fabio Berger",
+        "email": "fabio@0xproject.com"
+    },
+    "license": "Apache-2.0",
+    "bugs": {
+        "url": "https://github.com/0xProject/0x.js/issues"
+    },
+    "homepage": "https://github.com/0xProject/0x.js/packages/tslint-config/README.md",
+    "devDependencies": {
+        "@types/lodash": "^4.14.86",
+        "shx": "^0.2.2",
+        "tslint": "5.8.0",
+        "tslint-eslint-rules": "^4.1.1",
+        "typescript": "~2.6.1"
+    },
+    "dependencies": {
+        "lodash": "^4.17.4",
+        "tslint-react": "^3.2.0"
+    }
 }
diff --git a/packages/tslint-config/rules/asyncSuffixRule.ts b/packages/tslint-config/rules/asyncSuffixRule.ts
index 8af9d88d4..5215c7151 100644
--- a/packages/tslint-config/rules/asyncSuffixRule.ts
+++ b/packages/tslint-config/rules/asyncSuffixRule.ts
@@ -4,7 +4,7 @@ import * as ts from 'typescript';
 import { AsyncSuffixWalker } from './walkers/async_suffix';
 
 export class Rule extends Lint.Rules.AbstractRule {
-	public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
-		return this.applyWithWalker(new AsyncSuffixWalker(sourceFile, this.getOptions()));
-	}
+    public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
+        return this.applyWithWalker(new AsyncSuffixWalker(sourceFile, this.getOptions()));
+    }
 }
diff --git a/packages/tslint-config/rules/underscorePrivatesRule.ts b/packages/tslint-config/rules/underscorePrivatesRule.ts
index 4d9ee69f7..472ea09ff 100644
--- a/packages/tslint-config/rules/underscorePrivatesRule.ts
+++ b/packages/tslint-config/rules/underscorePrivatesRule.ts
@@ -4,58 +4,58 @@ import * as ts from 'typescript';
 const UNDERSCORE = '_';
 
 type RelevantClassMember =
-	| ts.MethodDeclaration
-	| ts.PropertyDeclaration
-	| ts.GetAccessorDeclaration
-	| ts.SetAccessorDeclaration;
+    | ts.MethodDeclaration
+    | ts.PropertyDeclaration
+    | ts.GetAccessorDeclaration
+    | ts.SetAccessorDeclaration;
 
 // Copied from: https://github.com/DanielRosenwasser/underscore-privates-tslint-rule
 // The version on github is not published on npm
 export class Rule extends Lint.Rules.AbstractRule {
-	public static FAILURE_STRING = 'private members must be prefixed with an underscore';
+    public static FAILURE_STRING = 'private members must be prefixed with an underscore';
 
-	public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
-		return this.applyWithFunction(sourceFile, walk);
-	}
+    public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
+        return this.applyWithFunction(sourceFile, walk);
+    }
 }
 function walk(ctx: Lint.WalkContext<void>): void {
-	traverse(ctx.sourceFile);
+    traverse(ctx.sourceFile);
 
-	function traverse(node: ts.Node): void {
-		checkNodeForViolations(ctx, node);
-		return ts.forEachChild(node, traverse);
-	}
+    function traverse(node: ts.Node): void {
+        checkNodeForViolations(ctx, node);
+        return ts.forEachChild(node, traverse);
+    }
 }
 function checkNodeForViolations(ctx: Lint.WalkContext<void>, node: ts.Node): void {
-	if (!isRelevantClassMember(node)) {
-		return;
-	}
-	// The declaration might have a computed property name or a numeric name.
-	const name = node.name;
-	if (!nameIsIdentifier(name)) {
-		return;
-	}
-	if (!nameStartsWithUnderscore(name.text) && memberIsPrivate(node)) {
-		ctx.addFailureAtNode(name, Rule.FAILURE_STRING);
-	}
+    if (!isRelevantClassMember(node)) {
+        return;
+    }
+    // The declaration might have a computed property name or a numeric name.
+    const name = node.name;
+    if (!nameIsIdentifier(name)) {
+        return;
+    }
+    if (!nameStartsWithUnderscore(name.text) && memberIsPrivate(node)) {
+        ctx.addFailureAtNode(name, Rule.FAILURE_STRING);
+    }
 }
 function isRelevantClassMember(node: ts.Node): node is RelevantClassMember {
-	switch (node.kind) {
-		case ts.SyntaxKind.MethodDeclaration:
-		case ts.SyntaxKind.PropertyDeclaration:
-		case ts.SyntaxKind.GetAccessor:
-		case ts.SyntaxKind.SetAccessor:
-			return true;
-		default:
-			return false;
-	}
+    switch (node.kind) {
+        case ts.SyntaxKind.MethodDeclaration:
+        case ts.SyntaxKind.PropertyDeclaration:
+        case ts.SyntaxKind.GetAccessor:
+        case ts.SyntaxKind.SetAccessor:
+            return true;
+        default:
+            return false;
+    }
 }
 function nameStartsWithUnderscore(text: string) {
-	return text.charCodeAt(0) === UNDERSCORE.charCodeAt(0);
+    return text.charCodeAt(0) === UNDERSCORE.charCodeAt(0);
 }
 function memberIsPrivate(node: ts.Declaration) {
-	return Lint.hasModifier(node.modifiers, ts.SyntaxKind.PrivateKeyword);
+    return Lint.hasModifier(node.modifiers, ts.SyntaxKind.PrivateKeyword);
 }
 function nameIsIdentifier(node: ts.Node): node is ts.Identifier {
-	return node.kind === ts.SyntaxKind.Identifier;
+    return node.kind === ts.SyntaxKind.Identifier;
 }
diff --git a/packages/tslint-config/rules/walkers/async_suffix.ts b/packages/tslint-config/rules/walkers/async_suffix.ts
index e1138de8d..eaec9c5f6 100644
--- a/packages/tslint-config/rules/walkers/async_suffix.ts
+++ b/packages/tslint-config/rules/walkers/async_suffix.ts
@@ -3,24 +3,24 @@ import * as Lint from 'tslint';
 import * as ts from 'typescript';
 
 export class AsyncSuffixWalker extends Lint.RuleWalker {
-	public static FAILURE_STRING = 'async functions must have an Async suffix';
-	public visitMethodDeclaration(node: ts.MethodDeclaration): void {
-		const methodNameNode = node.name;
-		const methodName = methodNameNode.getText();
-		if (!_.isUndefined(node.type)) {
-			if (node.type.kind === ts.SyntaxKind.TypeReference) {
-				// tslint:disable-next-line:no-unnecessary-type-assertion
-				const returnTypeName = (node.type as ts.TypeReferenceNode).typeName.getText();
-				if (returnTypeName === 'Promise' && !methodName.endsWith('Async')) {
-					const failure = this.createFailure(
-						methodNameNode.getStart(),
-						methodNameNode.getWidth(),
-						AsyncSuffixWalker.FAILURE_STRING,
-					);
-					this.addFailure(failure);
-				}
-			}
-		}
-		super.visitMethodDeclaration(node);
-	}
+    public static FAILURE_STRING = 'async functions must have an Async suffix';
+    public visitMethodDeclaration(node: ts.MethodDeclaration): void {
+        const methodNameNode = node.name;
+        const methodName = methodNameNode.getText();
+        if (!_.isUndefined(node.type)) {
+            if (node.type.kind === ts.SyntaxKind.TypeReference) {
+                // tslint:disable-next-line:no-unnecessary-type-assertion
+                const returnTypeName = (node.type as ts.TypeReferenceNode).typeName.getText();
+                if (returnTypeName === 'Promise' && !methodName.endsWith('Async')) {
+                    const failure = this.createFailure(
+                        methodNameNode.getStart(),
+                        methodNameNode.getWidth(),
+                        AsyncSuffixWalker.FAILURE_STRING,
+                    );
+                    this.addFailure(failure);
+                }
+            }
+        }
+        super.visitMethodDeclaration(node);
+    }
 }
diff --git a/packages/tslint-config/tsconfig.json b/packages/tslint-config/tsconfig.json
index 83db0fcd2..15da53092 100644
--- a/packages/tslint-config/tsconfig.json
+++ b/packages/tslint-config/tsconfig.json
@@ -1,7 +1,7 @@
 {
-	"extends": "../../tsconfig",
-	"compilerOptions": {
-		"outDir": "lib"
-	},
-	"include": ["./rules/**/*"]
+    "extends": "../../tsconfig",
+    "compilerOptions": {
+        "outDir": "lib"
+    },
+    "include": ["./rules/**/*"]
 }
diff --git a/packages/tslint-config/tslint.json b/packages/tslint-config/tslint.json
index f2a9558b9..971588b08 100644
--- a/packages/tslint-config/tslint.json
+++ b/packages/tslint-config/tslint.json
@@ -1,101 +1,101 @@
 {
-	"extends": ["tslint:latest", "tslint-react", "tslint-eslint-rules"],
-	"rules": {
-		"adjacent-overload-signatures": true,
-		"arrow-parens": [true, "ban-single-arg-parens"],
-		"arrow-return-shorthand": true,
-		"async-suffix": true,
-		"await-promise": true,
-		"binary-expression-operand-order": true,
-		"callable-types": true,
-		"class-name": true,
-		"completed-docs": [
-			true,
-			{
-				"functions": { "visibilities": ["exported"] },
-				"methods": { "locations": "instance", "privacies": ["public", "protected"] }
-			}
-		],
-		"curly": true,
-		"eofline": true,
-		"encoding": true,
-		"import-spacing": true,
-		"indent": [true, "spaces", 4],
-		"interface-name": false,
-		"interface-over-type-literal": true,
-		"linebreak-style": [true, "LF"],
-		"max-classes-per-file": false,
-		"max-classes-per-file": [true, 1],
-		"max-line-length": false,
-		"max-file-line-count": [true, 500],
-		"member-access": true,
-		"member-ordering": [true, "public-before-private", "static-before-instance", "variables-before-functions"],
-		"newline-before-return": false,
-		"new-parens": true,
-		"no-angle-bracket-type-assertion": true,
-		"no-boolean-literal-compare": true,
-		"no-default-export": true,
-		"no-empty-interface": false,
-		"no-floating-promises": true,
-		"no-non-null-assertion": true,
-		"no-parameter-reassignment": true,
-		"no-redundant-jsdoc": true,
-		"no-return-await": true,
-		"no-string-throw": true,
-		"no-submodule-imports": false,
-		"no-unnecessary-type-assertion": true,
-		"no-unused-variable": [true, { "ignore-pattern": "^_\\d*" }],
-		"no-implicit-dependencies": [true, "dev"],
-		"number-literal-format": true,
-		"object-literal-sort-keys": false,
-		"object-literal-key-quotes": false,
-		"ordered-imports": [
-			true,
-			{
-				"grouped-imports": true
-			}
-		],
-		"prefer-const": true,
-		"prefer-for-of": true,
-		"prefer-function-over-method": true,
-		"promise-function-async": true,
-		"quotemark": [true, "single", "avoid-escape", "jsx-double"],
-		"restrict-plus-operands": true,
-		"semicolon": [true, "always"],
-		"space-before-function-paren": [
-			true,
-			{
-				"anonymous": "never",
-				"named": "never",
-				"method": "never",
-				"constructor": "never",
-				"asyncArrow": "always"
-			}
-		],
-		"space-within-parens": false,
-		"type-literal-delimiter": true,
-		"underscore-privates": true,
-		"variable-name": [true, "ban-keywords", "allow-pascal-case"],
-		"whitespace": [
-			true,
-			"check-branch",
-			"check-decl",
-			"check-operator",
-			"check-separator",
-			"check-rest-spread",
-			"check-type",
-			"check-typecast",
-			"check-preblock"
-		],
-		"jsx-alignment": true,
-		"jsx-boolean-value": true,
-		"jsx-curly-spacing": [true, "never"],
-		"jsx-no-lambda": true,
-		"jsx-no-multiline-js": false,
-		"jsx-no-string-ref": true,
-		"jsx-self-close": true,
-		"jsx-wrap-multiline": false,
-		"jsx-no-bind": false
-	},
-	"rulesDirectory": "lib"
+    "extends": ["tslint:latest", "tslint-react", "tslint-eslint-rules"],
+    "rules": {
+        "adjacent-overload-signatures": true,
+        "arrow-parens": [true, "ban-single-arg-parens"],
+        "arrow-return-shorthand": true,
+        "async-suffix": true,
+        "await-promise": true,
+        "binary-expression-operand-order": true,
+        "callable-types": true,
+        "class-name": true,
+        "completed-docs": [
+            true,
+            {
+                "functions": { "visibilities": ["exported"] },
+                "methods": { "locations": "instance", "privacies": ["public", "protected"] }
+            }
+        ],
+        "curly": true,
+        "eofline": true,
+        "encoding": true,
+        "import-spacing": true,
+        "indent": [true, "spaces", 4],
+        "interface-name": false,
+        "interface-over-type-literal": true,
+        "linebreak-style": [true, "LF"],
+        "max-classes-per-file": false,
+        "max-classes-per-file": [true, 1],
+        "max-line-length": false,
+        "max-file-line-count": [true, 500],
+        "member-access": true,
+        "member-ordering": [true, "public-before-private", "static-before-instance", "variables-before-functions"],
+        "newline-before-return": false,
+        "new-parens": true,
+        "no-angle-bracket-type-assertion": true,
+        "no-boolean-literal-compare": true,
+        "no-default-export": true,
+        "no-empty-interface": false,
+        "no-floating-promises": true,
+        "no-non-null-assertion": true,
+        "no-parameter-reassignment": true,
+        "no-redundant-jsdoc": true,
+        "no-return-await": true,
+        "no-string-throw": true,
+        "no-submodule-imports": false,
+        "no-unnecessary-type-assertion": true,
+        "no-unused-variable": [true, { "ignore-pattern": "^_\\d*" }],
+        "no-implicit-dependencies": [true, "dev"],
+        "number-literal-format": true,
+        "object-literal-sort-keys": false,
+        "object-literal-key-quotes": false,
+        "ordered-imports": [
+            true,
+            {
+                "grouped-imports": true
+            }
+        ],
+        "prefer-const": true,
+        "prefer-for-of": true,
+        "prefer-function-over-method": true,
+        "promise-function-async": true,
+        "quotemark": [true, "single", "avoid-escape", "jsx-double"],
+        "restrict-plus-operands": true,
+        "semicolon": [true, "always"],
+        "space-before-function-paren": [
+            true,
+            {
+                "anonymous": "never",
+                "named": "never",
+                "method": "never",
+                "constructor": "never",
+                "asyncArrow": "always"
+            }
+        ],
+        "space-within-parens": false,
+        "type-literal-delimiter": true,
+        "underscore-privates": true,
+        "variable-name": [true, "ban-keywords", "allow-pascal-case"],
+        "whitespace": [
+            true,
+            "check-branch",
+            "check-decl",
+            "check-operator",
+            "check-separator",
+            "check-rest-spread",
+            "check-type",
+            "check-typecast",
+            "check-preblock"
+        ],
+        "jsx-alignment": true,
+        "jsx-boolean-value": true,
+        "jsx-curly-spacing": [true, "never"],
+        "jsx-no-lambda": true,
+        "jsx-no-multiline-js": false,
+        "jsx-no-string-ref": true,
+        "jsx-self-close": true,
+        "jsx-wrap-multiline": false,
+        "jsx-no-bind": false
+    },
+    "rulesDirectory": "lib"
 }
diff --git a/packages/types/package.json b/packages/types/package.json
index a7df01bde..42a2be4e0 100644
--- a/packages/types/package.json
+++ b/packages/types/package.json
@@ -1,31 +1,31 @@
 {
-	"name": "@0xproject/types",
-	"version": "0.1.6",
-	"description": "0x types",
-	"main": "lib/index.js",
-	"types": "lib/index.d.ts",
-	"scripts": {
-		"build": "tsc",
-		"clean": "shx rm -rf lib",
-		"lint": "tslint --project . 'src/**/*.ts'"
-	},
-	"license": "Apache-2.0",
-	"repository": {
-		"type": "git",
-		"url": "https://github.com/0xProject/0x.js.git"
-	},
-	"bugs": {
-		"url": "https://github.com/0xProject/0x.js/issues"
-	},
-	"homepage": "https://github.com/0xProject/0x.js/packages/types/README.md",
-	"devDependencies": {
-		"@0xproject/tslint-config": "^0.4.4",
-		"shx": "^0.2.2",
-		"tslint": "5.8.0",
-		"typescript": "~2.6.1"
-	},
-	"dependencies": {
-		"@0xproject/utils": "^0.2.2",
-		"web3": "^0.20.0"
-	}
+    "name": "@0xproject/types",
+    "version": "0.1.6",
+    "description": "0x types",
+    "main": "lib/index.js",
+    "types": "lib/index.d.ts",
+    "scripts": {
+        "build": "tsc",
+        "clean": "shx rm -rf lib",
+        "lint": "tslint --project . 'src/**/*.ts'"
+    },
+    "license": "Apache-2.0",
+    "repository": {
+        "type": "git",
+        "url": "https://github.com/0xProject/0x.js.git"
+    },
+    "bugs": {
+        "url": "https://github.com/0xProject/0x.js/issues"
+    },
+    "homepage": "https://github.com/0xProject/0x.js/packages/types/README.md",
+    "devDependencies": {
+        "@0xproject/tslint-config": "^0.4.4",
+        "shx": "^0.2.2",
+        "tslint": "5.8.0",
+        "typescript": "~2.6.1"
+    },
+    "dependencies": {
+        "@0xproject/utils": "^0.2.2",
+        "web3": "^0.20.0"
+    }
 }
diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts
index f8d211052..9cf9bc7af 100644
--- a/packages/types/src/index.ts
+++ b/packages/types/src/index.ts
@@ -2,26 +2,26 @@ import { BigNumber } from '@0xproject/utils';
 import * as Web3 from 'web3';
 
 export interface TxData {
-	from?: string;
-	gas?: number;
-	gasPrice?: BigNumber;
-	nonce?: number;
+    from?: string;
+    gas?: number;
+    gasPrice?: BigNumber;
+    nonce?: number;
 }
 
 export interface TxDataPayable extends TxData {
-	value?: BigNumber;
+    value?: BigNumber;
 }
 
 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[];
+    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/packages/types/tsconfig.json b/packages/types/tsconfig.json
index fc88c962d..3d967d05f 100644
--- a/packages/types/tsconfig.json
+++ b/packages/types/tsconfig.json
@@ -1,7 +1,7 @@
 {
-	"extends": "../../tsconfig",
-	"compilerOptions": {
-		"outDir": "lib"
-	},
-	"include": ["./src/**/*", "../../node_modules/web3-typescript-typings/index.d.ts"]
+    "extends": "../../tsconfig",
+    "compilerOptions": {
+        "outDir": "lib"
+    },
+    "include": ["./src/**/*", "../../node_modules/web3-typescript-typings/index.d.ts"]
 }
diff --git a/packages/types/tslint.json b/packages/types/tslint.json
index e63054bfc..ffaefe83a 100644
--- a/packages/types/tslint.json
+++ b/packages/types/tslint.json
@@ -1,3 +1,3 @@
 {
-	"extends": ["@0xproject/tslint-config"]
+    "extends": ["@0xproject/tslint-config"]
 }
diff --git a/packages/utils/package.json b/packages/utils/package.json
index 7a5a10337..47a297859 100644
--- a/packages/utils/package.json
+++ b/packages/utils/package.json
@@ -1,34 +1,34 @@
 {
-	"name": "@0xproject/utils",
-	"version": "0.2.2",
-	"description": "0x TS utils",
-	"main": "lib/index.js",
-	"types": "lib/index.d.ts",
-	"scripts": {
-		"build": "tsc",
-		"clean": "shx rm -rf lib",
-		"lint": "tslint --project . 'src/**/*.ts'"
-	},
-	"license": "Apache-2.0",
-	"repository": {
-		"type": "git",
-		"url": "https://github.com/0xProject/0x.js.git"
-	},
-	"bugs": {
-		"url": "https://github.com/0xProject/0x.js/issues"
-	},
-	"homepage": "https://github.com/0xProject/0x.js/packages/utils/README.md",
-	"devDependencies": {
-		"@0xproject/tslint-config": "^0.4.4",
-		"@types/lodash": "^4.14.86",
-		"npm-run-all": "^4.1.2",
-		"shx": "^0.2.2",
-		"tslint": "5.8.0",
-		"typescript": "~2.6.1"
-	},
-	"dependencies": {
-		"bignumber.js": "~4.1.0",
-		"js-sha3": "^0.7.0",
-		"lodash": "^4.17.4"
-	}
+    "name": "@0xproject/utils",
+    "version": "0.2.2",
+    "description": "0x TS utils",
+    "main": "lib/index.js",
+    "types": "lib/index.d.ts",
+    "scripts": {
+        "build": "tsc",
+        "clean": "shx rm -rf lib",
+        "lint": "tslint --project . 'src/**/*.ts'"
+    },
+    "license": "Apache-2.0",
+    "repository": {
+        "type": "git",
+        "url": "https://github.com/0xProject/0x.js.git"
+    },
+    "bugs": {
+        "url": "https://github.com/0xProject/0x.js/issues"
+    },
+    "homepage": "https://github.com/0xProject/0x.js/packages/utils/README.md",
+    "devDependencies": {
+        "@0xproject/tslint-config": "^0.4.4",
+        "@types/lodash": "^4.14.86",
+        "npm-run-all": "^4.1.2",
+        "shx": "^0.2.2",
+        "tslint": "5.8.0",
+        "typescript": "~2.6.1"
+    },
+    "dependencies": {
+        "bignumber.js": "~4.1.0",
+        "js-sha3": "^0.7.0",
+        "lodash": "^4.17.4"
+    }
 }
diff --git a/packages/utils/src/address_utils.ts b/packages/utils/src/address_utils.ts
index 07042cb43..f94985441 100644
--- a/packages/utils/src/address_utils.ts
+++ b/packages/utils/src/address_utils.ts
@@ -4,33 +4,33 @@ const BASIC_ADDRESS_REGEX = /^(0x)?[0-9a-f]{40}$/i;
 const SAME_CASE_ADDRESS_REGEX = /^(0x)?([0-9a-f]{40}|[0-9A-F]{40})$/;
 
 export const addressUtils = {
-	isChecksumAddress(address: string): boolean {
-		// Check each case
-		const unprefixedAddress = address.replace('0x', '');
-		const addressHash = jsSHA3.keccak256(unprefixedAddress.toLowerCase());
+    isChecksumAddress(address: string): boolean {
+        // Check each case
+        const unprefixedAddress = address.replace('0x', '');
+        const addressHash = jsSHA3.keccak256(unprefixedAddress.toLowerCase());
 
-		for (let i = 0; i < 40; i++) {
-			// The nth letter should be uppercase if the nth digit of casemap is 1
-			if (
-				(parseInt(addressHash[i], 16) > 7 && unprefixedAddress[i].toUpperCase() !== unprefixedAddress[i]) ||
-				(parseInt(addressHash[i], 16) <= 7 && unprefixedAddress[i].toLowerCase() !== unprefixedAddress[i])
-			) {
-				return false;
-			}
-		}
-		return true;
-	},
-	isAddress(address: string): boolean {
-		if (!BASIC_ADDRESS_REGEX.test(address)) {
-			// Check if it has the basic requirements of an address
-			return false;
-		} else if (SAME_CASE_ADDRESS_REGEX.test(address)) {
-			// If it's all small caps or all all caps, return true
-			return true;
-		} else {
-			// Otherwise check each case
-			const isValidChecksummedAddress = addressUtils.isChecksumAddress(address);
-			return isValidChecksummedAddress;
-		}
-	},
+        for (let i = 0; i < 40; i++) {
+            // The nth letter should be uppercase if the nth digit of casemap is 1
+            if (
+                (parseInt(addressHash[i], 16) > 7 && unprefixedAddress[i].toUpperCase() !== unprefixedAddress[i]) ||
+                (parseInt(addressHash[i], 16) <= 7 && unprefixedAddress[i].toLowerCase() !== unprefixedAddress[i])
+            ) {
+                return false;
+            }
+        }
+        return true;
+    },
+    isAddress(address: string): boolean {
+        if (!BASIC_ADDRESS_REGEX.test(address)) {
+            // Check if it has the basic requirements of an address
+            return false;
+        } else if (SAME_CASE_ADDRESS_REGEX.test(address)) {
+            // If it's all small caps or all all caps, return true
+            return true;
+        } else {
+            // Otherwise check each case
+            const isValidChecksummedAddress = addressUtils.isChecksumAddress(address);
+            return isValidChecksummedAddress;
+        }
+    },
 };
diff --git a/packages/utils/src/class_utils.ts b/packages/utils/src/class_utils.ts
index 7fb011f91..04e60ee57 100644
--- a/packages/utils/src/class_utils.ts
+++ b/packages/utils/src/class_utils.ts
@@ -1,18 +1,18 @@
 import * as _ from 'lodash';
 
 export const classUtils = {
-	// This is useful for classes that have nested methods. Nested methods don't get bound out of the box.
-	bindAll(self: any, exclude: string[] = ['contructor'], thisArg?: any): void {
-		for (const key of Object.getOwnPropertyNames(self)) {
-			const val = self[key];
-			if (!_.includes(exclude, key)) {
-				if (_.isFunction(val)) {
-					self[key] = val.bind(thisArg || self);
-				} else if (_.isObject(val)) {
-					classUtils.bindAll(val, exclude, self);
-				}
-			}
-		}
-		return self;
-	},
+    // This is useful for classes that have nested methods. Nested methods don't get bound out of the box.
+    bindAll(self: any, exclude: string[] = ['contructor'], thisArg?: any): void {
+        for (const key of Object.getOwnPropertyNames(self)) {
+            const val = self[key];
+            if (!_.includes(exclude, key)) {
+                if (_.isFunction(val)) {
+                    self[key] = val.bind(thisArg || self);
+                } else if (_.isObject(val)) {
+                    classUtils.bindAll(val, exclude, self);
+                }
+            }
+        }
+        return self;
+    },
 };
diff --git a/packages/utils/src/configured_bignumber.ts b/packages/utils/src/configured_bignumber.ts
index d819e9365..e44c062c2 100644
--- a/packages/utils/src/configured_bignumber.ts
+++ b/packages/utils/src/configured_bignumber.ts
@@ -3,7 +3,7 @@ import { BigNumber } from 'bignumber.js';
 // 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,
+    EXPONENTIAL_AT: 1000,
 });
 
 export { BigNumber };
diff --git a/packages/utils/src/interval_utils.ts b/packages/utils/src/interval_utils.ts
index 65e51677b..ebecc7015 100644
--- a/packages/utils/src/interval_utils.ts
+++ b/packages/utils/src/interval_utils.ts
@@ -1,37 +1,37 @@
 import * as _ from 'lodash';
 
 export const intervalUtils = {
-	setAsyncExcludingInterval(fn: () => Promise<void>, intervalMs: number, onError: (err: Error) => void) {
-		let locked = false;
-		const intervalId = setInterval(async () => {
-			if (locked) {
-				return;
-			} else {
-				locked = true;
-				try {
-					await fn();
-				} catch (err) {
-					onError(err);
-				}
-				locked = false;
-			}
-		}, intervalMs);
-		return intervalId;
-	},
-	clearAsyncExcludingInterval(intervalId: NodeJS.Timer): void {
-		clearInterval(intervalId);
-	},
-	setInterval(fn: () => void, intervalMs: number, onError: (err: Error) => void) {
-		const intervalId = setInterval(() => {
-			try {
-				fn();
-			} catch (err) {
-				onError(err);
-			}
-		}, intervalMs);
-		return intervalId;
-	},
-	clearInterval(intervalId: NodeJS.Timer): void {
-		clearInterval(intervalId);
-	},
+    setAsyncExcludingInterval(fn: () => Promise<void>, intervalMs: number, onError: (err: Error) => void) {
+        let locked = false;
+        const intervalId = setInterval(async () => {
+            if (locked) {
+                return;
+            } else {
+                locked = true;
+                try {
+                    await fn();
+                } catch (err) {
+                    onError(err);
+                }
+                locked = false;
+            }
+        }, intervalMs);
+        return intervalId;
+    },
+    clearAsyncExcludingInterval(intervalId: NodeJS.Timer): void {
+        clearInterval(intervalId);
+    },
+    setInterval(fn: () => void, intervalMs: number, onError: (err: Error) => void) {
+        const intervalId = setInterval(() => {
+            try {
+                fn();
+            } catch (err) {
+                onError(err);
+            }
+        }, intervalMs);
+        return intervalId;
+    },
+    clearInterval(intervalId: NodeJS.Timer): void {
+        clearInterval(intervalId);
+    },
 };
diff --git a/packages/utils/src/promisify.ts b/packages/utils/src/promisify.ts
index 6b29664f9..29d626b61 100644
--- a/packages/utils/src/promisify.ts
+++ b/packages/utils/src/promisify.ts
@@ -7,13 +7,13 @@ import * as _ from 'lodash';
  */
 // HACK: This can't be properly typed without variadic kinds https://github.com/Microsoft/TypeScript/issues/5453
 export function promisify<T>(originalFn: (...args: any[]) => void, thisArg?: any): (...callArgs: any[]) => Promise<T> {
-	const promisifiedFunction = async (...callArgs: any[]): Promise<T> => {
-		return new Promise<T>((resolve, reject) => {
-			const callback = (err: Error | null, data?: T) => {
-				_.isNull(err) ? resolve(data) : reject(err);
-			};
-			originalFn.apply(thisArg, [...callArgs, callback]);
-		});
-	};
-	return promisifiedFunction;
+    const promisifiedFunction = async (...callArgs: any[]): Promise<T> => {
+        return new Promise<T>((resolve, reject) => {
+            const callback = (err: Error | null, data?: T) => {
+                _.isNull(err) ? resolve(data) : reject(err);
+            };
+            originalFn.apply(thisArg, [...callArgs, callback]);
+        });
+    };
+    return promisifiedFunction;
 }
diff --git a/packages/utils/tsconfig.json b/packages/utils/tsconfig.json
index fc88c962d..3d967d05f 100644
--- a/packages/utils/tsconfig.json
+++ b/packages/utils/tsconfig.json
@@ -1,7 +1,7 @@
 {
-	"extends": "../../tsconfig",
-	"compilerOptions": {
-		"outDir": "lib"
-	},
-	"include": ["./src/**/*", "../../node_modules/web3-typescript-typings/index.d.ts"]
+    "extends": "../../tsconfig",
+    "compilerOptions": {
+        "outDir": "lib"
+    },
+    "include": ["./src/**/*", "../../node_modules/web3-typescript-typings/index.d.ts"]
 }
diff --git a/packages/utils/tslint.json b/packages/utils/tslint.json
index e63054bfc..ffaefe83a 100644
--- a/packages/utils/tslint.json
+++ b/packages/utils/tslint.json
@@ -1,3 +1,3 @@
 {
-	"extends": ["@0xproject/tslint-config"]
+    "extends": ["@0xproject/tslint-config"]
 }
diff --git a/packages/web3-typescript-typings/index.d.ts b/packages/web3-typescript-typings/index.d.ts
index b610d0e48..cd34759ed 100644
--- a/packages/web3-typescript-typings/index.d.ts
+++ b/packages/web3-typescript-typings/index.d.ts
@@ -1,422 +1,422 @@
 declare module 'web3' {
-	import * as BigNumber from 'bignumber.js';
-
-	type MixedData = string | number | object | any[] | BigNumber.BigNumber;
-
-	class Web3 {
-		public static providers: typeof providers;
-		public currentProvider: Web3.Provider;
-
-		public eth: Web3.EthApi;
-		public personal: Web3.PersonalApi | undefined;
-		public version: Web3.VersionApi;
-		public net: Web3.NetApi;
-
-		public constructor(provider?: Web3.Provider);
-
-		public isConnected(): boolean;
-		public setProvider(provider: Web3.Provider): void;
-		public reset(keepIsSyncing: boolean): void;
-		public toHex(data: MixedData): string;
-		public toAscii(hex: string): string;
-		public fromAscii(ascii: string, padding?: number): string;
-		public toDecimal(hex: string): number;
-		public fromDecimal(value: number | string): string;
-		public fromWei(value: number | string, unit: Web3.Unit): string;
-		public fromWei(value: BigNumber.BigNumber, unit: Web3.Unit): BigNumber.BigNumber;
-		public toWei(amount: number | string, unit: Web3.Unit): string;
-		public toWei(amount: BigNumber.BigNumber, unit: Web3.Unit): BigNumber.BigNumber;
-		public toBigNumber(value: number | string): BigNumber.BigNumber;
-		public isAddress(address: string): boolean;
-		public isChecksumAddress(address: string): boolean;
-		public sha3(value: string, options?: Web3.Sha3Options): string;
-	}
-
-	namespace providers {
-		class HttpProvider implements Web3.Provider {
-			constructor(url?: string, timeout?: number, username?: string, password?: string);
-			public sendAsync(
-				payload: Web3.JSONRPCRequestPayload,
-				callback: (err: Error, result: Web3.JSONRPCResponsePayload) => void,
-			): void;
-		}
-	}
-
-	namespace Web3 {
-		type ContractAbi = AbiDefinition[];
-
-		type AbiDefinition = FunctionAbi | EventAbi;
-
-		type FunctionAbi = MethodAbi | ConstructorAbi | FallbackAbi;
-
-		enum AbiType {
-			Function = 'function',
-			Constructor = 'constructor',
-			Event = 'event',
-			Fallback = 'fallback',
-		}
-
-		type ConstructorStateMutability = 'nonpayable' | 'payable';
-		type StateMutability = 'pure' | 'view' | ConstructorStateMutability;
-
-		interface MethodAbi {
-			type: AbiType.Function;
-			name: string;
-			inputs: FunctionParameter[];
-			outputs: FunctionParameter[];
-			constant: boolean;
-			stateMutability: StateMutability;
-			payable: boolean;
-		}
-
-		interface ConstructorAbi {
-			type: AbiType.Constructor;
-			inputs: FunctionParameter[];
-			payable: boolean;
-			stateMutability: ConstructorStateMutability;
-		}
-
-		interface FallbackAbi {
-			type: AbiType.Fallback;
-			payable: boolean;
-		}
-
-		interface EventParameter {
-			name: string;
-			type: string;
-			indexed: boolean;
-		}
-
-		interface EventAbi {
-			type: AbiType.Event;
-			name: string;
-			inputs: EventParameter[];
-			anonymous: boolean;
-		}
-
-		interface FunctionParameter {
-			name: string;
-			type: string;
-		}
-
-		interface ContractInstance {
-			address: string;
-			abi: Web3.ContractAbi;
-			[name: string]: any;
-		}
-
-		interface Contract<A extends ContractInstance> {
-			at(address: string): A;
-			getData(...args: any[]): string;
-			'new'(...args: any[]): A;
-		}
-
-		interface FilterObject {
-			fromBlock?: number | string;
-			toBlock?: number | string;
-			address?: string;
-			topics?: LogTopic[];
-		}
-
-		type LogTopic = null | string | string[];
-
-		interface DecodedLogEntry<A> extends LogEntry {
-			event: string;
-			args: A;
-		}
-
-		interface DecodedLogEntryEvent<A> extends DecodedLogEntry<A> {
-			removed: boolean;
-		}
-
-		interface LogEntryEvent extends LogEntry {
-			removed: boolean;
-		}
-
-		interface FilterResult {
-			get(callback: () => void): void;
-			watch(callback: (err: Error, result: LogEntryEvent) => void): void;
-			stopWatching(callback?: () => void): void;
-		}
-
-		export interface JSONRPCRequestPayload {
-			params: any[];
-			method: string;
-			id: number;
-			jsonrpc: string;
-		}
-
-		export interface JSONRPCResponsePayload {
-			result: any;
-			id: number;
-			jsonrpc: string;
-		}
-
-		interface Provider {
-			sendAsync(
-				payload: JSONRPCRequestPayload,
-				callback: (err: Error, result: JSONRPCResponsePayload) => void,
-			): void;
-		}
-
-		interface Sha3Options {
-			encoding: 'hex';
-		}
-
-		interface EthApi {
-			coinbase: string;
-			mining: boolean;
-			hashrate: number;
-			gasPrice: BigNumber.BigNumber;
-			accounts: string[];
-			blockNumber: number;
-			defaultAccount?: string;
-			defaultBlock: Web3.BlockParam;
-			syncing: Web3.SyncingResult;
-			compile: {
-				solidity(sourceString: string, cb?: (err: Error, result: any) => void): object;
-			};
-			getMining(cd: (err: Error, mining: boolean) => void): void;
-			getHashrate(cd: (err: Error, hashrate: number) => void): void;
-			getGasPrice(cd: (err: Error, gasPrice: BigNumber.BigNumber) => void): void;
-			getAccounts(cd: (err: Error, accounts: string[]) => void): void;
-			getBlockNumber(callback: (err: Error, blockNumber: number) => void): void;
-			getSyncing(cd: (err: Error, syncing: Web3.SyncingResult) => void): void;
-			isSyncing(cb: (err: Error, isSyncing: boolean, syncingState: Web3.SyncingState) => void): Web3.IsSyncing;
-
-			getBlock(hashStringOrBlockNumber: string | Web3.BlockParam): Web3.BlockWithoutTransactionData;
-			getBlock(
-				hashStringOrBlockNumber: string | Web3.BlockParam,
-				callback: (err: Error, blockObj: Web3.BlockWithoutTransactionData) => void,
-			): void;
-			getBlock(
-				hashStringOrBlockNumber: string | Web3.BlockParam,
-				returnTransactionObjects: true,
-			): Web3.BlockWithTransactionData;
-			getBlock(
-				hashStringOrBlockNumber: string | Web3.BlockParam,
-				returnTransactionObjects: true,
-				callback: (err: Error, blockObj: Web3.BlockWithTransactionData) => void,
-			): void;
-
-			getBlockTransactionCount(hashStringOrBlockNumber: string | Web3.BlockParam): number;
-			getBlockTransactionCount(
-				hashStringOrBlockNumber: string | Web3.BlockParam,
-				callback: (err: Error, blockTransactionCount: number) => void,
-			): void;
-
-			// TODO returnTransactionObjects
-			getUncle(
-				hashStringOrBlockNumber: string | Web3.BlockParam,
-				uncleNumber: number,
-			): Web3.BlockWithoutTransactionData;
-			getUncle(
-				hashStringOrBlockNumber: string | Web3.BlockParam,
-				uncleNumber: number,
-				callback: (err: Error, uncle: Web3.BlockWithoutTransactionData) => void,
-			): void;
-
-			getTransaction(transactionHash: string): Web3.Transaction;
-			getTransaction(
-				transactionHash: string,
-				callback: (err: Error, transaction: Web3.Transaction) => void,
-			): void;
-
-			getTransactionFromBlock(
-				hashStringOrBlockNumber: string | Web3.BlockParam,
-				indexNumber: number,
-			): Web3.Transaction;
-			getTransactionFromBlock(
-				hashStringOrBlockNumber: string | Web3.BlockParam,
-				indexNumber: number,
-				callback: (err: Error, transaction: Web3.Transaction) => void,
-			): void;
-
-			contract(abi: Web3.AbiDefinition[]): Web3.Contract<any>;
-
-			// TODO block param
-			getBalance(addressHexString: string): BigNumber.BigNumber;
-			getBalance(addressHexString: string, callback: (err: Error, result: BigNumber.BigNumber) => void): void;
-
-			// TODO block param
-			getStorageAt(address: string, position: number): string;
-			getStorageAt(address: string, position: number, callback: (err: Error, storage: string) => void): void;
-
-			// TODO block param
-			getCode(addressHexString: string): string;
-			getCode(addressHexString: string, callback: (err: Error, code: string) => void): void;
-
-			filter(value: string | Web3.FilterObject): Web3.FilterResult;
-
-			sendTransaction(txData: Web3.TxData): string;
-			sendTransaction(txData: Web3.TxData, callback: (err: Error, value: string) => void): void;
-
-			sendRawTransaction(rawTxData: string): string;
-			sendRawTransaction(rawTxData: string, callback: (err: Error, value: string) => void): void;
-
-			sign(address: string, data: string): string;
-			sign(address: string, data: string, callback: (err: Error, signature: string) => void): void;
-
-			getTransactionReceipt(txHash: string): Web3.TransactionReceipt | null;
-			getTransactionReceipt(
-				txHash: string,
-				callback: (err: Error, receipt: Web3.TransactionReceipt | null) => void,
-			): void;
-
-			// TODO block param
-			call(callData: Web3.CallData): string;
-			call(callData: Web3.CallData, callback: (err: Error, result: string) => void): void;
-
-			estimateGas(callData: Web3.CallData): number;
-			estimateGas(callData: Web3.CallData, callback: (err: Error, gas: number) => void): void;
-
-			// TODO defaultBlock
-			getTransactionCount(address: string): number;
-			getTransactionCount(address: string, callback: (err: Error, count: number) => void): void;
-		}
-
-		interface VersionApi {
-			api: string;
-			network: string;
-			node: string;
-			ethereum: string;
-			whisper: string;
-			getNetwork(cd: (err: Error, networkId: string) => void): void;
-			getNode(cd: (err: Error, nodeVersion: string) => void): void;
-			getEthereum(cd: (err: Error, ethereum: string) => void): void;
-			getWhisper(cd: (err: Error, whisper: string) => void): void;
-		}
-
-		interface PersonalApi {
-			listAccounts: string[] | undefined;
-			newAccount(password?: string): string;
-			unlockAccount(address: string, password?: string, duration?: number): boolean;
-			lockAccount(address: string): boolean;
-			sign(message: string, account: string, password: string): string;
-			sign(hexMessage: string, account: string, callback: (error: Error, signature: string) => void): void;
-		}
-
-		interface NetApi {
-			listening: boolean;
-			peerCount: boolean;
-			getListening(cd: (err: Error, listening: boolean) => void): void;
-			getPeerCount(cd: (err: Error, peerCount: number) => void): void;
-		}
-
-		type BlockParam = number | 'earliest' | 'latest' | 'pending';
-
-		type Unit =
-			| 'kwei'
-			| 'ada'
-			| 'mwei'
-			| 'babbage'
-			| 'gwei'
-			| 'shannon'
-			| 'szabo'
-			| 'finney'
-			| 'ether'
-			| 'kether'
-			| 'grand'
-			| 'einstein'
-			| 'mether'
-			| 'gether'
-			| 'tether';
-
-		interface SyncingState {
-			startingBlock: number;
-			currentBlock: number;
-			highestBlock: number;
-		}
-		type SyncingResult = false | SyncingState;
-
-		interface IsSyncing {
-			addCallback(cb: (err: Error, isSyncing: boolean, syncingState: SyncingState) => void): void;
-			stopWatching(): void;
-		}
-
-		interface AbstractBlock {
-			number: number | null;
-			hash: string | null;
-			parentHash: string;
-			nonce: string | null;
-			sha3Uncles: string;
-			logsBloom: string | null;
-			transactionsRoot: string;
-			stateRoot: string;
-			miner: string;
-			difficulty: BigNumber.BigNumber;
-			totalDifficulty: BigNumber.BigNumber;
-			extraData: string;
-			size: number;
-			gasLimit: number;
-			gasUsed: number;
-			timestamp: number;
-			uncles: string[];
-		}
-		interface BlockWithoutTransactionData extends AbstractBlock {
-			transactions: string[];
-		}
-		interface BlockWithTransactionData extends AbstractBlock {
-			transactions: Transaction[];
-		}
-
-		interface Transaction {
-			hash: string;
-			nonce: number;
-			blockHash: string | null;
-			blockNumber: number | null;
-			transactionIndex: number | null;
-			from: string;
-			to: string | null;
-			value: BigNumber.BigNumber;
-			gasPrice: BigNumber.BigNumber;
-			gas: number;
-			input: string;
-		}
-
-		interface CallTxDataBase {
-			to?: string;
-			value?: number | string | BigNumber.BigNumber;
-			gas?: number | string | BigNumber.BigNumber;
-			gasPrice?: number | string | BigNumber.BigNumber;
-			data?: string;
-			nonce?: number;
-		}
-
-		interface TxData extends CallTxDataBase {
-			from: string;
-		}
-
-		interface CallData extends CallTxDataBase {
-			from?: string;
-		}
-
-		interface TransactionReceipt {
-			blockHash: string;
-			blockNumber: number;
-			transactionHash: string;
-			transactionIndex: number;
-			from: string;
-			to: string;
-			status: null | string | 0 | 1;
-			cumulativeGasUsed: number;
-			gasUsed: number;
-			contractAddress: string | null;
-			logs: LogEntry[];
-		}
-
-		interface LogEntry {
-			logIndex: number | null;
-			transactionIndex: number | null;
-			transactionHash: string;
-			blockHash: string | null;
-			blockNumber: number | null;
-			address: string;
-			data: string;
-			topics: string[];
-		}
-	}
-	/* tslint:disable */
-	export = Web3;
-	/* tslint:enable */
+    import * as BigNumber from 'bignumber.js';
+
+    type MixedData = string | number | object | any[] | BigNumber.BigNumber;
+
+    class Web3 {
+        public static providers: typeof providers;
+        public currentProvider: Web3.Provider;
+
+        public eth: Web3.EthApi;
+        public personal: Web3.PersonalApi | undefined;
+        public version: Web3.VersionApi;
+        public net: Web3.NetApi;
+
+        public constructor(provider?: Web3.Provider);
+
+        public isConnected(): boolean;
+        public setProvider(provider: Web3.Provider): void;
+        public reset(keepIsSyncing: boolean): void;
+        public toHex(data: MixedData): string;
+        public toAscii(hex: string): string;
+        public fromAscii(ascii: string, padding?: number): string;
+        public toDecimal(hex: string): number;
+        public fromDecimal(value: number | string): string;
+        public fromWei(value: number | string, unit: Web3.Unit): string;
+        public fromWei(value: BigNumber.BigNumber, unit: Web3.Unit): BigNumber.BigNumber;
+        public toWei(amount: number | string, unit: Web3.Unit): string;
+        public toWei(amount: BigNumber.BigNumber, unit: Web3.Unit): BigNumber.BigNumber;
+        public toBigNumber(value: number | string): BigNumber.BigNumber;
+        public isAddress(address: string): boolean;
+        public isChecksumAddress(address: string): boolean;
+        public sha3(value: string, options?: Web3.Sha3Options): string;
+    }
+
+    namespace providers {
+        class HttpProvider implements Web3.Provider {
+            constructor(url?: string, timeout?: number, username?: string, password?: string);
+            public sendAsync(
+                payload: Web3.JSONRPCRequestPayload,
+                callback: (err: Error, result: Web3.JSONRPCResponsePayload) => void,
+            ): void;
+        }
+    }
+
+    namespace Web3 {
+        type ContractAbi = AbiDefinition[];
+
+        type AbiDefinition = FunctionAbi | EventAbi;
+
+        type FunctionAbi = MethodAbi | ConstructorAbi | FallbackAbi;
+
+        enum AbiType {
+            Function = 'function',
+            Constructor = 'constructor',
+            Event = 'event',
+            Fallback = 'fallback',
+        }
+
+        type ConstructorStateMutability = 'nonpayable' | 'payable';
+        type StateMutability = 'pure' | 'view' | ConstructorStateMutability;
+
+        interface MethodAbi {
+            type: AbiType.Function;
+            name: string;
+            inputs: FunctionParameter[];
+            outputs: FunctionParameter[];
+            constant: boolean;
+            stateMutability: StateMutability;
+            payable: boolean;
+        }
+
+        interface ConstructorAbi {
+            type: AbiType.Constructor;
+            inputs: FunctionParameter[];
+            payable: boolean;
+            stateMutability: ConstructorStateMutability;
+        }
+
+        interface FallbackAbi {
+            type: AbiType.Fallback;
+            payable: boolean;
+        }
+
+        interface EventParameter {
+            name: string;
+            type: string;
+            indexed: boolean;
+        }
+
+        interface EventAbi {
+            type: AbiType.Event;
+            name: string;
+            inputs: EventParameter[];
+            anonymous: boolean;
+        }
+
+        interface FunctionParameter {
+            name: string;
+            type: string;
+        }
+
+        interface ContractInstance {
+            address: string;
+            abi: Web3.ContractAbi;
+            [name: string]: any;
+        }
+
+        interface Contract<A extends ContractInstance> {
+            at(address: string): A;
+            getData(...args: any[]): string;
+            'new'(...args: any[]): A;
+        }
+
+        interface FilterObject {
+            fromBlock?: number | string;
+            toBlock?: number | string;
+            address?: string;
+            topics?: LogTopic[];
+        }
+
+        type LogTopic = null | string | string[];
+
+        interface DecodedLogEntry<A> extends LogEntry {
+            event: string;
+            args: A;
+        }
+
+        interface DecodedLogEntryEvent<A> extends DecodedLogEntry<A> {
+            removed: boolean;
+        }
+
+        interface LogEntryEvent extends LogEntry {
+            removed: boolean;
+        }
+
+        interface FilterResult {
+            get(callback: () => void): void;
+            watch(callback: (err: Error, result: LogEntryEvent) => void): void;
+            stopWatching(callback?: () => void): void;
+        }
+
+        export interface JSONRPCRequestPayload {
+            params: any[];
+            method: string;
+            id: number;
+            jsonrpc: string;
+        }
+
+        export interface JSONRPCResponsePayload {
+            result: any;
+            id: number;
+            jsonrpc: string;
+        }
+
+        interface Provider {
+            sendAsync(
+                payload: JSONRPCRequestPayload,
+                callback: (err: Error, result: JSONRPCResponsePayload) => void,
+            ): void;
+        }
+
+        interface Sha3Options {
+            encoding: 'hex';
+        }
+
+        interface EthApi {
+            coinbase: string;
+            mining: boolean;
+            hashrate: number;
+            gasPrice: BigNumber.BigNumber;
+            accounts: string[];
+            blockNumber: number;
+            defaultAccount?: string;
+            defaultBlock: Web3.BlockParam;
+            syncing: Web3.SyncingResult;
+            compile: {
+                solidity(sourceString: string, cb?: (err: Error, result: any) => void): object;
+            };
+            getMining(cd: (err: Error, mining: boolean) => void): void;
+            getHashrate(cd: (err: Error, hashrate: number) => void): void;
+            getGasPrice(cd: (err: Error, gasPrice: BigNumber.BigNumber) => void): void;
+            getAccounts(cd: (err: Error, accounts: string[]) => void): void;
+            getBlockNumber(callback: (err: Error, blockNumber: number) => void): void;
+            getSyncing(cd: (err: Error, syncing: Web3.SyncingResult) => void): void;
+            isSyncing(cb: (err: Error, isSyncing: boolean, syncingState: Web3.SyncingState) => void): Web3.IsSyncing;
+
+            getBlock(hashStringOrBlockNumber: string | Web3.BlockParam): Web3.BlockWithoutTransactionData;
+            getBlock(
+                hashStringOrBlockNumber: string | Web3.BlockParam,
+                callback: (err: Error, blockObj: Web3.BlockWithoutTransactionData) => void,
+            ): void;
+            getBlock(
+                hashStringOrBlockNumber: string | Web3.BlockParam,
+                returnTransactionObjects: true,
+            ): Web3.BlockWithTransactionData;
+            getBlock(
+                hashStringOrBlockNumber: string | Web3.BlockParam,
+                returnTransactionObjects: true,
+                callback: (err: Error, blockObj: Web3.BlockWithTransactionData) => void,
+            ): void;
+
+            getBlockTransactionCount(hashStringOrBlockNumber: string | Web3.BlockParam): number;
+            getBlockTransactionCount(
+                hashStringOrBlockNumber: string | Web3.BlockParam,
+                callback: (err: Error, blockTransactionCount: number) => void,
+            ): void;
+
+            // TODO returnTransactionObjects
+            getUncle(
+                hashStringOrBlockNumber: string | Web3.BlockParam,
+                uncleNumber: number,
+            ): Web3.BlockWithoutTransactionData;
+            getUncle(
+                hashStringOrBlockNumber: string | Web3.BlockParam,
+                uncleNumber: number,
+                callback: (err: Error, uncle: Web3.BlockWithoutTransactionData) => void,
+            ): void;
+
+            getTransaction(transactionHash: string): Web3.Transaction;
+            getTransaction(
+                transactionHash: string,
+                callback: (err: Error, transaction: Web3.Transaction) => void,
+            ): void;
+
+            getTransactionFromBlock(
+                hashStringOrBlockNumber: string | Web3.BlockParam,
+                indexNumber: number,
+            ): Web3.Transaction;
+            getTransactionFromBlock(
+                hashStringOrBlockNumber: string | Web3.BlockParam,
+                indexNumber: number,
+                callback: (err: Error, transaction: Web3.Transaction) => void,
+            ): void;
+
+            contract(abi: Web3.AbiDefinition[]): Web3.Contract<any>;
+
+            // TODO block param
+            getBalance(addressHexString: string): BigNumber.BigNumber;
+            getBalance(addressHexString: string, callback: (err: Error, result: BigNumber.BigNumber) => void): void;
+
+            // TODO block param
+            getStorageAt(address: string, position: number): string;
+            getStorageAt(address: string, position: number, callback: (err: Error, storage: string) => void): void;
+
+            // TODO block param
+            getCode(addressHexString: string): string;
+            getCode(addressHexString: string, callback: (err: Error, code: string) => void): void;
+
+            filter(value: string | Web3.FilterObject): Web3.FilterResult;
+
+            sendTransaction(txData: Web3.TxData): string;
+            sendTransaction(txData: Web3.TxData, callback: (err: Error, value: string) => void): void;
+
+            sendRawTransaction(rawTxData: string): string;
+            sendRawTransaction(rawTxData: string, callback: (err: Error, value: string) => void): void;
+
+            sign(address: string, data: string): string;
+            sign(address: string, data: string, callback: (err: Error, signature: string) => void): void;
+
+            getTransactionReceipt(txHash: string): Web3.TransactionReceipt | null;
+            getTransactionReceipt(
+                txHash: string,
+                callback: (err: Error, receipt: Web3.TransactionReceipt | null) => void,
+            ): void;
+
+            // TODO block param
+            call(callData: Web3.CallData): string;
+            call(callData: Web3.CallData, callback: (err: Error, result: string) => void): void;
+
+            estimateGas(callData: Web3.CallData): number;
+            estimateGas(callData: Web3.CallData, callback: (err: Error, gas: number) => void): void;
+
+            // TODO defaultBlock
+            getTransactionCount(address: string): number;
+            getTransactionCount(address: string, callback: (err: Error, count: number) => void): void;
+        }
+
+        interface VersionApi {
+            api: string;
+            network: string;
+            node: string;
+            ethereum: string;
+            whisper: string;
+            getNetwork(cd: (err: Error, networkId: string) => void): void;
+            getNode(cd: (err: Error, nodeVersion: string) => void): void;
+            getEthereum(cd: (err: Error, ethereum: string) => void): void;
+            getWhisper(cd: (err: Error, whisper: string) => void): void;
+        }
+
+        interface PersonalApi {
+            listAccounts: string[] | undefined;
+            newAccount(password?: string): string;
+            unlockAccount(address: string, password?: string, duration?: number): boolean;
+            lockAccount(address: string): boolean;
+            sign(message: string, account: string, password: string): string;
+            sign(hexMessage: string, account: string, callback: (error: Error, signature: string) => void): void;
+        }
+
+        interface NetApi {
+            listening: boolean;
+            peerCount: boolean;
+            getListening(cd: (err: Error, listening: boolean) => void): void;
+            getPeerCount(cd: (err: Error, peerCount: number) => void): void;
+        }
+
+        type BlockParam = number | 'earliest' | 'latest' | 'pending';
+
+        type Unit =
+            | 'kwei'
+            | 'ada'
+            | 'mwei'
+            | 'babbage'
+            | 'gwei'
+            | 'shannon'
+            | 'szabo'
+            | 'finney'
+            | 'ether'
+            | 'kether'
+            | 'grand'
+            | 'einstein'
+            | 'mether'
+            | 'gether'
+            | 'tether';
+
+        interface SyncingState {
+            startingBlock: number;
+            currentBlock: number;
+            highestBlock: number;
+        }
+        type SyncingResult = false | SyncingState;
+
+        interface IsSyncing {
+            addCallback(cb: (err: Error, isSyncing: boolean, syncingState: SyncingState) => void): void;
+            stopWatching(): void;
+        }
+
+        interface AbstractBlock {
+            number: number | null;
+            hash: string | null;
+            parentHash: string;
+            nonce: string | null;
+            sha3Uncles: string;
+            logsBloom: string | null;
+            transactionsRoot: string;
+            stateRoot: string;
+            miner: string;
+            difficulty: BigNumber.BigNumber;
+            totalDifficulty: BigNumber.BigNumber;
+            extraData: string;
+            size: number;
+            gasLimit: number;
+            gasUsed: number;
+            timestamp: number;
+            uncles: string[];
+        }
+        interface BlockWithoutTransactionData extends AbstractBlock {
+            transactions: string[];
+        }
+        interface BlockWithTransactionData extends AbstractBlock {
+            transactions: Transaction[];
+        }
+
+        interface Transaction {
+            hash: string;
+            nonce: number;
+            blockHash: string | null;
+            blockNumber: number | null;
+            transactionIndex: number | null;
+            from: string;
+            to: string | null;
+            value: BigNumber.BigNumber;
+            gasPrice: BigNumber.BigNumber;
+            gas: number;
+            input: string;
+        }
+
+        interface CallTxDataBase {
+            to?: string;
+            value?: number | string | BigNumber.BigNumber;
+            gas?: number | string | BigNumber.BigNumber;
+            gasPrice?: number | string | BigNumber.BigNumber;
+            data?: string;
+            nonce?: number;
+        }
+
+        interface TxData extends CallTxDataBase {
+            from: string;
+        }
+
+        interface CallData extends CallTxDataBase {
+            from?: string;
+        }
+
+        interface TransactionReceipt {
+            blockHash: string;
+            blockNumber: number;
+            transactionHash: string;
+            transactionIndex: number;
+            from: string;
+            to: string;
+            status: null | string | 0 | 1;
+            cumulativeGasUsed: number;
+            gasUsed: number;
+            contractAddress: string | null;
+            logs: LogEntry[];
+        }
+
+        interface LogEntry {
+            logIndex: number | null;
+            transactionIndex: number | null;
+            transactionHash: string;
+            blockHash: string | null;
+            blockNumber: number | null;
+            address: string;
+            data: string;
+            topics: string[];
+        }
+    }
+    /* tslint:disable */
+    export = Web3;
+    /* tslint:enable */
 }
diff --git a/packages/web3-typescript-typings/package.json b/packages/web3-typescript-typings/package.json
index edfdd9701..e0e433c93 100644
--- a/packages/web3-typescript-typings/package.json
+++ b/packages/web3-typescript-typings/package.json
@@ -1,30 +1,30 @@
 {
-	"name": "web3-typescript-typings",
-	"version": "0.9.6",
-	"description": "Typescript type definitions for web3",
-	"main": "index.d.ts",
-	"types": "index.d.ts",
-	"scripts": {
-		"lint": "tslint index.d.ts"
-	},
-	"repository": {
-		"type": "git",
-		"url": "git+https://github.com/0xProject/0x.js.git"
-	},
-	"author": "Fabio Berger",
-	"contributors": ["Leonid Logvinov <logvinov.leon@gmail.com>"],
-	"license": "Apache-2.0",
-	"bugs": {
-		"url": "https://github.com/0xProject/0x.js/issues"
-	},
-	"homepage": "https://github.com/0xProject/0x.js/packages/web3-typescript-typings#readme",
-	"devDependencies": {
-		"@types/bignumber.js": "^4.0.2",
-		"tslint": "^5.5.0",
-		"tslint-config-0xproject": "^0.0.2",
-		"typescript": "~2.6.1"
-	},
-	"dependencies": {
-		"bignumber.js": "~4.1.0"
-	}
+    "name": "web3-typescript-typings",
+    "version": "0.9.6",
+    "description": "Typescript type definitions for web3",
+    "main": "index.d.ts",
+    "types": "index.d.ts",
+    "scripts": {
+        "lint": "tslint index.d.ts"
+    },
+    "repository": {
+        "type": "git",
+        "url": "git+https://github.com/0xProject/0x.js.git"
+    },
+    "author": "Fabio Berger",
+    "contributors": ["Leonid Logvinov <logvinov.leon@gmail.com>"],
+    "license": "Apache-2.0",
+    "bugs": {
+        "url": "https://github.com/0xProject/0x.js/issues"
+    },
+    "homepage": "https://github.com/0xProject/0x.js/packages/web3-typescript-typings#readme",
+    "devDependencies": {
+        "@types/bignumber.js": "^4.0.2",
+        "tslint": "^5.5.0",
+        "tslint-config-0xproject": "^0.0.2",
+        "typescript": "~2.6.1"
+    },
+    "dependencies": {
+        "bignumber.js": "~4.1.0"
+    }
 }
diff --git a/packages/web3-typescript-typings/tslint.json b/packages/web3-typescript-typings/tslint.json
index ef528b22e..9a93a1f74 100644
--- a/packages/web3-typescript-typings/tslint.json
+++ b/packages/web3-typescript-typings/tslint.json
@@ -1,3 +1,3 @@
 {
-	"extends": ["tslint-config-0xproject"]
+    "extends": ["tslint-config-0xproject"]
 }
diff --git a/packages/web3-wrapper/package.json b/packages/web3-wrapper/package.json
index d45480b35..6a65582f9 100644
--- a/packages/web3-wrapper/package.json
+++ b/packages/web3-wrapper/package.json
@@ -1,36 +1,36 @@
 {
-	"name": "@0xproject/web3-wrapper",
-	"version": "0.1.7",
-	"description": "Wraps around web3 and gives a nicer interface",
-	"main": "lib/index.js",
-	"types": "lib/index.d.ts",
-	"scripts": {
-		"build": "tsc",
-		"clean": "shx rm -rf lib",
-		"lint": "tslint --project . 'src/**/*.ts'"
-	},
-	"license": "Apache-2.0",
-	"repository": {
-		"type": "git",
-		"url": "https://github.com/0xProject/0x.js.git"
-	},
-	"bugs": {
-		"url": "https://github.com/0xProject/0x.js/issues"
-	},
-	"homepage": "https://github.com/0xProject/0x.js/packages/web3-wrapper/README.md",
-	"devDependencies": {
-		"@0xproject/tslint-config": "^0.4.4",
-		"@0xproject/types": "^0.1.6",
-		"@types/lodash": "^4.14.86",
-		"npm-run-all": "^4.1.2",
-		"shx": "^0.2.2",
-		"tslint": "5.8.0",
-		"typescript": "~2.6.1",
-		"web3-typescript-typings": "^0.9.6"
-	},
-	"dependencies": {
-		"@0xproject/utils": "^0.2.2",
-		"lodash": "^4.17.4",
-		"web3": "^0.20.0"
-	}
+    "name": "@0xproject/web3-wrapper",
+    "version": "0.1.7",
+    "description": "Wraps around web3 and gives a nicer interface",
+    "main": "lib/index.js",
+    "types": "lib/index.d.ts",
+    "scripts": {
+        "build": "tsc",
+        "clean": "shx rm -rf lib",
+        "lint": "tslint --project . 'src/**/*.ts'"
+    },
+    "license": "Apache-2.0",
+    "repository": {
+        "type": "git",
+        "url": "https://github.com/0xProject/0x.js.git"
+    },
+    "bugs": {
+        "url": "https://github.com/0xProject/0x.js/issues"
+    },
+    "homepage": "https://github.com/0xProject/0x.js/packages/web3-wrapper/README.md",
+    "devDependencies": {
+        "@0xproject/tslint-config": "^0.4.4",
+        "@0xproject/types": "^0.1.6",
+        "@types/lodash": "^4.14.86",
+        "npm-run-all": "^4.1.2",
+        "shx": "^0.2.2",
+        "tslint": "5.8.0",
+        "typescript": "~2.6.1",
+        "web3-typescript-typings": "^0.9.6"
+    },
+    "dependencies": {
+        "@0xproject/utils": "^0.2.2",
+        "lodash": "^4.17.4",
+        "web3": "^0.20.0"
+    }
 }
diff --git a/packages/web3-wrapper/src/index.ts b/packages/web3-wrapper/src/index.ts
index 859333448..c4826f2be 100644
--- a/packages/web3-wrapper/src/index.ts
+++ b/packages/web3-wrapper/src/index.ts
@@ -4,170 +4,170 @@ import * as _ from 'lodash';
 import * as Web3 from 'web3';
 
 interface RawLogEntry {
-	logIndex: string | null;
-	transactionIndex: string | null;
-	transactionHash: string;
-	blockHash: string | null;
-	blockNumber: string | null;
-	address: string;
-	data: string;
-	topics: string[];
+    logIndex: string | null;
+    transactionIndex: string | null;
+    transactionHash: string;
+    blockHash: string | null;
+    blockNumber: string | null;
+    address: string;
+    data: string;
+    topics: string[];
 }
 
 export class Web3Wrapper {
-	private _web3: Web3;
-	private _defaults: Partial<TxData>;
-	private _jsonRpcRequestId: number;
-	constructor(provider: Web3.Provider, defaults?: Partial<TxData>) {
-		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 getContractDefaults(): Partial<TxData> {
-		return this._defaults;
-	}
-	public setProvider(provider: Web3.Provider) {
-		this._web3.setProvider(provider);
-	}
-	public isAddress(address: string): boolean {
-		return this._web3.isAddress(address);
-	}
-	public async isSenderAddressAvailableAsync(senderAddress: string): Promise<boolean> {
-		const addresses = await this.getAvailableAddressesAsync();
-		return _.includes(addresses, senderAddress);
-	}
-	public async getNodeVersionAsync(): Promise<string> {
-		const nodeVersion = await promisify<string>(this._web3.version.getNode)();
-		return nodeVersion;
-	}
-	public async getNetworkIdAsync(): Promise<number> {
-		const networkIdStr = await promisify<string>(this._web3.version.getNetwork)();
-		const networkId = _.parseInt(networkIdStr);
-		return networkId;
-	}
-	public async getTransactionReceiptAsync(txHash: string): Promise<TransactionReceipt> {
-		const transactionReceipt = await promisify<TransactionReceipt>(this._web3.eth.getTransactionReceipt)(txHash);
-		if (!_.isNull(transactionReceipt)) {
-			transactionReceipt.status = this._normalizeTxReceiptStatus(transactionReceipt.status);
-		}
-		return transactionReceipt;
-	}
-	public getCurrentProvider(): Web3.Provider {
-		return this._web3.currentProvider;
-	}
-	public toWei(ethAmount: BigNumber): BigNumber {
-		const balanceWei = this._web3.toWei(ethAmount, 'ether');
-		return balanceWei;
-	}
-	public async getBalanceInWeiAsync(owner: string): Promise<BigNumber> {
-		let balanceInWei = await promisify<BigNumber>(this._web3.eth.getBalance)(owner);
-		// Rewrap in a new BigNumber
-		balanceInWei = new BigNumber(balanceInWei);
-		return balanceInWei;
-	}
-	public async doesContractExistAtAddressAsync(address: string): Promise<boolean> {
-		const code = await promisify<string>(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<string> {
-		const signData = await promisify<string>(this._web3.eth.sign)(address, message);
-		return signData;
-	}
-	public async getBlockNumberAsync(): Promise<number> {
-		const blockNumber = await promisify<number>(this._web3.eth.getBlockNumber)();
-		return blockNumber;
-	}
-	public async getBlockAsync(blockParam: string | Web3.BlockParam): Promise<Web3.BlockWithoutTransactionData> {
-		const block = await promisify<Web3.BlockWithoutTransactionData>(this._web3.eth.getBlock)(blockParam);
-		return block;
-	}
-	public async getBlockTimestampAsync(blockParam: string | Web3.BlockParam): Promise<number> {
-		const { timestamp } = await this.getBlockAsync(blockParam);
-		return timestamp;
-	}
-	public async getAvailableAddressesAsync(): Promise<string[]> {
-		const addresses = await promisify<string[]>(this._web3.eth.getAccounts)();
-		return addresses;
-	}
-	public async getLogsAsync(filter: Web3.FilterObject): Promise<Web3.LogEntry[]> {
-		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 rawLogs = await this._sendRawPayloadAsync<RawLogEntry[]>(payload);
-		const formattedLogs = _.map(rawLogs, this._formatLog.bind(this));
-		return formattedLogs;
-	}
-	public getContractFromAbi(abi: Web3.ContractAbi): Web3.Contract<any> {
-		const web3Contract = this._web3.eth.contract(abi);
-		return web3Contract;
-	}
-	public getContractInstance(abi: Web3.ContractAbi, address: string): Web3.ContractInstance {
-		const web3ContractInstance = this.getContractFromAbi(abi).at(address);
-		return web3ContractInstance;
-	}
-	public async estimateGasAsync(data: string): Promise<number> {
-		const gas = await promisify<number>(this._web3.eth.estimateGas)({ data });
-		return gas;
-	}
-	private async _sendRawPayloadAsync<A>(payload: Web3.JSONRPCRequestPayload): Promise<A> {
-		const sendAsync = this._web3.currentProvider.sendAsync.bind(this._web3.currentProvider);
-		const response = await promisify<Web3.JSONRPCResponsePayload>(sendAsync)(payload);
-		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;
-		}
-	}
-	private _formatLog(rawLog: RawLogEntry): Web3.LogEntry {
-		const formattedLog = {
-			...rawLog,
-			logIndex: this._hexToDecimal(rawLog.logIndex),
-			blockNumber: this._hexToDecimal(rawLog.blockNumber),
-			transactionIndex: this._hexToDecimal(rawLog.transactionIndex),
-		};
-		return formattedLog;
-	}
-	private _hexToDecimal(hex: string | null): number | null {
-		if (_.isNull(hex)) {
-			return null;
-		}
-		const decimal = this._web3.toDecimal(hex);
-		return decimal;
-	}
+    private _web3: Web3;
+    private _defaults: Partial<TxData>;
+    private _jsonRpcRequestId: number;
+    constructor(provider: Web3.Provider, defaults?: Partial<TxData>) {
+        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 getContractDefaults(): Partial<TxData> {
+        return this._defaults;
+    }
+    public setProvider(provider: Web3.Provider) {
+        this._web3.setProvider(provider);
+    }
+    public isAddress(address: string): boolean {
+        return this._web3.isAddress(address);
+    }
+    public async isSenderAddressAvailableAsync(senderAddress: string): Promise<boolean> {
+        const addresses = await this.getAvailableAddressesAsync();
+        return _.includes(addresses, senderAddress);
+    }
+    public async getNodeVersionAsync(): Promise<string> {
+        const nodeVersion = await promisify<string>(this._web3.version.getNode)();
+        return nodeVersion;
+    }
+    public async getNetworkIdAsync(): Promise<number> {
+        const networkIdStr = await promisify<string>(this._web3.version.getNetwork)();
+        const networkId = _.parseInt(networkIdStr);
+        return networkId;
+    }
+    public async getTransactionReceiptAsync(txHash: string): Promise<TransactionReceipt> {
+        const transactionReceipt = await promisify<TransactionReceipt>(this._web3.eth.getTransactionReceipt)(txHash);
+        if (!_.isNull(transactionReceipt)) {
+            transactionReceipt.status = this._normalizeTxReceiptStatus(transactionReceipt.status);
+        }
+        return transactionReceipt;
+    }
+    public getCurrentProvider(): Web3.Provider {
+        return this._web3.currentProvider;
+    }
+    public toWei(ethAmount: BigNumber): BigNumber {
+        const balanceWei = this._web3.toWei(ethAmount, 'ether');
+        return balanceWei;
+    }
+    public async getBalanceInWeiAsync(owner: string): Promise<BigNumber> {
+        let balanceInWei = await promisify<BigNumber>(this._web3.eth.getBalance)(owner);
+        // Rewrap in a new BigNumber
+        balanceInWei = new BigNumber(balanceInWei);
+        return balanceInWei;
+    }
+    public async doesContractExistAtAddressAsync(address: string): Promise<boolean> {
+        const code = await promisify<string>(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<string> {
+        const signData = await promisify<string>(this._web3.eth.sign)(address, message);
+        return signData;
+    }
+    public async getBlockNumberAsync(): Promise<number> {
+        const blockNumber = await promisify<number>(this._web3.eth.getBlockNumber)();
+        return blockNumber;
+    }
+    public async getBlockAsync(blockParam: string | Web3.BlockParam): Promise<Web3.BlockWithoutTransactionData> {
+        const block = await promisify<Web3.BlockWithoutTransactionData>(this._web3.eth.getBlock)(blockParam);
+        return block;
+    }
+    public async getBlockTimestampAsync(blockParam: string | Web3.BlockParam): Promise<number> {
+        const { timestamp } = await this.getBlockAsync(blockParam);
+        return timestamp;
+    }
+    public async getAvailableAddressesAsync(): Promise<string[]> {
+        const addresses = await promisify<string[]>(this._web3.eth.getAccounts)();
+        return addresses;
+    }
+    public async getLogsAsync(filter: Web3.FilterObject): Promise<Web3.LogEntry[]> {
+        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 rawLogs = await this._sendRawPayloadAsync<RawLogEntry[]>(payload);
+        const formattedLogs = _.map(rawLogs, this._formatLog.bind(this));
+        return formattedLogs;
+    }
+    public getContractFromAbi(abi: Web3.ContractAbi): Web3.Contract<any> {
+        const web3Contract = this._web3.eth.contract(abi);
+        return web3Contract;
+    }
+    public getContractInstance(abi: Web3.ContractAbi, address: string): Web3.ContractInstance {
+        const web3ContractInstance = this.getContractFromAbi(abi).at(address);
+        return web3ContractInstance;
+    }
+    public async estimateGasAsync(data: string): Promise<number> {
+        const gas = await promisify<number>(this._web3.eth.estimateGas)({ data });
+        return gas;
+    }
+    private async _sendRawPayloadAsync<A>(payload: Web3.JSONRPCRequestPayload): Promise<A> {
+        const sendAsync = this._web3.currentProvider.sendAsync.bind(this._web3.currentProvider);
+        const response = await promisify<Web3.JSONRPCResponsePayload>(sendAsync)(payload);
+        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;
+        }
+    }
+    private _formatLog(rawLog: RawLogEntry): Web3.LogEntry {
+        const formattedLog = {
+            ...rawLog,
+            logIndex: this._hexToDecimal(rawLog.logIndex),
+            blockNumber: this._hexToDecimal(rawLog.blockNumber),
+            transactionIndex: this._hexToDecimal(rawLog.transactionIndex),
+        };
+        return formattedLog;
+    }
+    private _hexToDecimal(hex: string | null): number | null {
+        if (_.isNull(hex)) {
+            return null;
+        }
+        const decimal = this._web3.toDecimal(hex);
+        return decimal;
+    }
 }
diff --git a/packages/web3-wrapper/tsconfig.json b/packages/web3-wrapper/tsconfig.json
index fc88c962d..3d967d05f 100644
--- a/packages/web3-wrapper/tsconfig.json
+++ b/packages/web3-wrapper/tsconfig.json
@@ -1,7 +1,7 @@
 {
-	"extends": "../../tsconfig",
-	"compilerOptions": {
-		"outDir": "lib"
-	},
-	"include": ["./src/**/*", "../../node_modules/web3-typescript-typings/index.d.ts"]
+    "extends": "../../tsconfig",
+    "compilerOptions": {
+        "outDir": "lib"
+    },
+    "include": ["./src/**/*", "../../node_modules/web3-typescript-typings/index.d.ts"]
 }
diff --git a/packages/web3-wrapper/tslint.json b/packages/web3-wrapper/tslint.json
index e63054bfc..ffaefe83a 100644
--- a/packages/web3-wrapper/tslint.json
+++ b/packages/web3-wrapper/tslint.json
@@ -1,3 +1,3 @@
 {
-	"extends": ["@0xproject/tslint-config"]
+    "extends": ["@0xproject/tslint-config"]
 }
diff --git a/packages/website/contracts/Mintable.json b/packages/website/contracts/Mintable.json
index eaadcf68f..dc46dc829 100644
--- a/packages/website/contracts/Mintable.json
+++ b/packages/website/contracts/Mintable.json
@@ -1,190 +1,190 @@
 {
-	"contract_name": "Mintable",
-	"abi": [
-		{
-			"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": true,
-			"inputs": [
-				{
-					"name": "_owner",
-					"type": "address"
-				}
-			],
-			"name": "balanceOf",
-			"outputs": [
-				{
-					"name": "",
-					"type": "uint256"
-				}
-			],
-			"payable": false,
-			"type": "function"
-		},
-		{
-			"constant": false,
-			"inputs": [
-				{
-					"name": "_value",
-					"type": "uint256"
-				}
-			],
-			"name": "mint",
-			"outputs": [],
-			"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": true,
-			"inputs": [
-				{
-					"name": "_owner",
-					"type": "address"
-				},
-				{
-					"name": "_spender",
-					"type": "address"
-				}
-			],
-			"name": "allowance",
-			"outputs": [
-				{
-					"name": "",
-					"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":
-		"0x6060604052341561000c57fe5b5b6105018061001c6000396000f300606060405236156100675763ffffffff60e060020a600035041663095ea7b3811461006957806318160ddd1461009c57806323b872dd146100be57806370a08231146100f7578063a0712d6814610125578063a9059cbb1461013a578063dd62ed3e1461016d575bfe5b341561007157fe5b610088600160a060020a03600435166024356101a1565b604080519115158252519081900360200190f35b34156100a457fe5b6100ac61020c565b60408051918252519081900360200190f35b34156100c657fe5b610088600160a060020a0360043581169060243516604435610212565b604080519115158252519081900360200190f35b34156100ff57fe5b6100ac600160a060020a0360043516610335565b60408051918252519081900360200190f35b341561012d57fe5b610138600435610354565b005b341561014257fe5b610088600160a060020a03600435166024356103bc565b604080519115158252519081900360200190f35b341561017557fe5b6100ac600160a060020a036004358116906024351661046e565b60408051918252519081900360200190f35b600160a060020a03338116600081815260016020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b60025481565b600160a060020a03808416600081815260016020908152604080832033909516835293815283822054928252819052918220548390108015906102555750828110155b801561027b5750600160a060020a03841660009081526020819052604090205483810110155b1561032757600160a060020a03808516600090815260208190526040808220805487019055918716815220805484900390556000198110156102e557600160a060020a03808616600090815260016020908152604080832033909416835292905220805484900390555b83600160a060020a031685600160a060020a03166000805160206104b6833981519152856040518082815260200191505060405180910390a36001915061032c565b600091505b5b509392505050565b600160a060020a0381166000908152602081905260409020545b919050565b68056bc75e2d6310000081111561036b5760006000fd5b600160a060020a03331660009081526020819052604090205461038f90829061049b565b600160a060020a0333166000908152602081905260409020556002546103b5908261049b565b6002555b50565b600160a060020a0333166000908152602081905260408120548290108015906103ff5750600160a060020a03831660009081526020819052604090205482810110155b1561045f57600160a060020a0333811660008181526020818152604080832080548890039055938716808352918490208054870190558351868152935191936000805160206104b6833981519152929081900390910190a3506001610206565b506000610206565b5b92915050565b600160a060020a038083166000908152600160209081526040808320938516835292905220545b92915050565b6000828201838110156104aa57fe5b8091505b50929150505600ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa165627a7a72305820998c8326b9629e063eb4867166e72c68a8c2e3ebca6a9d35ebc78c041c7aa47b0029",
-	"networks": {},
-	"schema_version": "0.0.5",
-	"updated_at": 1503413048892
+    "contract_name": "Mintable",
+    "abi": [
+        {
+            "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": true,
+            "inputs": [
+                {
+                    "name": "_owner",
+                    "type": "address"
+                }
+            ],
+            "name": "balanceOf",
+            "outputs": [
+                {
+                    "name": "",
+                    "type": "uint256"
+                }
+            ],
+            "payable": false,
+            "type": "function"
+        },
+        {
+            "constant": false,
+            "inputs": [
+                {
+                    "name": "_value",
+                    "type": "uint256"
+                }
+            ],
+            "name": "mint",
+            "outputs": [],
+            "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": true,
+            "inputs": [
+                {
+                    "name": "_owner",
+                    "type": "address"
+                },
+                {
+                    "name": "_spender",
+                    "type": "address"
+                }
+            ],
+            "name": "allowance",
+            "outputs": [
+                {
+                    "name": "",
+                    "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":
+        "0x6060604052341561000c57fe5b5b6105018061001c6000396000f300606060405236156100675763ffffffff60e060020a600035041663095ea7b3811461006957806318160ddd1461009c57806323b872dd146100be57806370a08231146100f7578063a0712d6814610125578063a9059cbb1461013a578063dd62ed3e1461016d575bfe5b341561007157fe5b610088600160a060020a03600435166024356101a1565b604080519115158252519081900360200190f35b34156100a457fe5b6100ac61020c565b60408051918252519081900360200190f35b34156100c657fe5b610088600160a060020a0360043581169060243516604435610212565b604080519115158252519081900360200190f35b34156100ff57fe5b6100ac600160a060020a0360043516610335565b60408051918252519081900360200190f35b341561012d57fe5b610138600435610354565b005b341561014257fe5b610088600160a060020a03600435166024356103bc565b604080519115158252519081900360200190f35b341561017557fe5b6100ac600160a060020a036004358116906024351661046e565b60408051918252519081900360200190f35b600160a060020a03338116600081815260016020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b60025481565b600160a060020a03808416600081815260016020908152604080832033909516835293815283822054928252819052918220548390108015906102555750828110155b801561027b5750600160a060020a03841660009081526020819052604090205483810110155b1561032757600160a060020a03808516600090815260208190526040808220805487019055918716815220805484900390556000198110156102e557600160a060020a03808616600090815260016020908152604080832033909416835292905220805484900390555b83600160a060020a031685600160a060020a03166000805160206104b6833981519152856040518082815260200191505060405180910390a36001915061032c565b600091505b5b509392505050565b600160a060020a0381166000908152602081905260409020545b919050565b68056bc75e2d6310000081111561036b5760006000fd5b600160a060020a03331660009081526020819052604090205461038f90829061049b565b600160a060020a0333166000908152602081905260409020556002546103b5908261049b565b6002555b50565b600160a060020a0333166000908152602081905260408120548290108015906103ff5750600160a060020a03831660009081526020819052604090205482810110155b1561045f57600160a060020a0333811660008181526020818152604080832080548890039055938716808352918490208054870190558351868152935191936000805160206104b6833981519152929081900390910190a3506001610206565b506000610206565b5b92915050565b600160a060020a038083166000908152600160209081526040808320938516835292905220545b92915050565b6000828201838110156104aa57fe5b8091505b50929150505600ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa165627a7a72305820998c8326b9629e063eb4867166e72c68a8c2e3ebca6a9d35ebc78c041c7aa47b0029",
+    "networks": {},
+    "schema_version": "0.0.5",
+    "updated_at": 1503413048892
 }
diff --git a/packages/website/md/docs/0xjs/async.md b/packages/website/md/docs/0xjs/async.md
index fa92e5bab..8abaef331 100644
--- a/packages/website/md/docs/0xjs/async.md
+++ b/packages/website/md/docs/0xjs/async.md
@@ -14,13 +14,13 @@ _Promise syntax:_
 
 ```javascript
 zeroEx
-	.getAvailableAddressesAsync()
-	.then(function(availableAddresses) {
-		console.log(availableAddresses);
-	})
-	.catch(function(error) {
-		console.log('Caught error: ', error);
-	});
+    .getAvailableAddressesAsync()
+    .then(function(availableAddresses) {
+        console.log(availableAddresses);
+    })
+    .catch(function(error) {
+        console.log('Caught error: ', error);
+    });
 ```
 
 As is the convention with promise-based libraries, if an error occurs, it is thrown. It is the callers responsibility to catch thrown errors and to handle them appropriately.
diff --git a/packages/website/package.json b/packages/website/package.json
index ac1bd2c13..6db74a20e 100644
--- a/packages/website/package.json
+++ b/packages/website/package.json
@@ -1,109 +1,109 @@
 {
-	"name": "@0xproject/website",
-	"version": "0.0.9",
-	"private": true,
-	"description": "Website and 0x portal dapp",
-	"scripts": {
-		"build": "NODE_ENV=production webpack; exit 0;",
-		"clean": "shx rm -f public/bundle*",
-		"lint": "tslint --project . 'ts/**/*.ts' 'ts/**/*.tsx'",
-		"dev": "webpack-dev-server --content-base public --https",
-		"update_contracts":
-			"for i in ${npm_package_config_artifacts}; do copyfiles -u 4 ../contracts/build/contracts/$i.json ../website/contracts; done;",
-		"deploy_staging":
-			"npm run build; aws s3 sync ./public/. s3://staging-0xproject --profile 0xproject --region us-east-1 --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers",
-		"deploy_live":
-			"npm run build; aws s3 sync ./public/. s3://0xproject.com --profile 0xproject --region us-east-1 --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers"
-	},
-	"config": {
-		"artifacts": "Mintable"
-	},
-	"author": "Fabio Berger",
-	"license": "Apache-2.0",
-	"dependencies": {
-		"0x.js": "^0.30.2",
-		"@0xproject/subproviders": "^0.3.3",
-		"@0xproject/utils": "^0.2.2",
-		"accounting": "^0.4.1",
-		"basscss": "^8.0.3",
-		"blockies": "^0.0.2",
-		"compare-versions": "^3.0.1",
-		"dateformat": "^2.0.0",
-		"deep-equal": "^1.0.1",
-		"dharma-loan-frame": "^0.0.12",
-		"ethereumjs-tx": "^1.3.3",
-		"ethereumjs-util": "^5.1.1",
-		"find-versions": "^2.0.0",
-		"is-mobile": "^0.2.2",
-		"jsonschema": "^1.2.0",
-		"ledgerco": "0xProject/ledger-node-js-api",
-		"less": "^2.7.2",
-		"lodash": "^4.17.4",
-		"material-ui": "^0.17.1",
-		"moment": "^2.18.1",
-		"query-string": "^5.0.1",
-		"react": "15.6.1",
-		"react-copy-to-clipboard": "^4.2.3",
-		"react-document-title": "^2.0.3",
-		"react-dom": "15.6.1",
-		"react-highlight": "^0.10.0",
-		"react-html5video": "^2.1.0",
-		"react-inlinesvg": "^0.5.5",
-		"react-markdown": "^2.5.0",
-		"react-recaptcha": "^2.3.2",
-		"react-redux": "^5.0.3",
-		"react-router-dom": "^4.1.1",
-		"react-router-hash-link": "^1.1.0",
-		"react-scroll": "^1.5.2",
-		"react-tap-event-plugin": "^2.0.1",
-		"react-tooltip": "^3.2.7",
-		"react-waypoint": "^7.0.4",
-		"redux": "^3.6.0",
-		"scroll-to-element": "^2.0.0",
-		"semver-sort": "0.0.4",
-		"thenby": "^1.2.3",
-		"truffle-contract": "2.0.1",
-		"tslint-config-0xproject": "^0.0.2",
-		"web3": "^0.20.0",
-		"web3-provider-engine": "^13.0.1",
-		"whatwg-fetch": "^2.0.3",
-		"xml-js": "^1.3.2"
-	},
-	"devDependencies": {
-		"@types/accounting": "^0.4.1",
-		"@types/dateformat": "^1.0.1",
-		"@types/deep-equal": "^1.0.0",
-		"@types/jsonschema": "^1.1.1",
-		"@types/lodash": "^4.14.86",
-		"@types/material-ui": "0.18.0",
-		"@types/moment": "^2.13.0",
-		"@types/node": "^8.0.53",
-		"@types/query-string": "^5.0.1",
-		"@types/react": "^15.0.15",
-		"@types/react-copy-to-clipboard": "^4.2.0",
-		"@types/react-dom": "^0.14.23",
-		"@types/react-redux": "^4.4.37",
-		"@types/react-router-dom": "^4.0.4",
-		"@types/react-scroll": "0.0.31",
-		"@types/react-tap-event-plugin": "0.0.30",
-		"@types/redux": "^3.6.0",
-		"awesome-typescript-loader": "^3.1.3",
-		"copy-webpack-plugin": "^4.0.1",
-		"copyfiles": "^1.2.0",
-		"css-loader": "0.23.x",
-		"exports-loader": "0.6.x",
-		"imports-loader": "0.6.x",
-		"json-loader": "^0.5.4",
-		"less-loader": "^2.2.3",
-		"raw-loader": "^0.5.1",
-		"shx": "^0.2.2",
-		"source-map-loader": "^0.1.6",
-		"style-loader": "0.13.x",
-		"tslint": "5.8.0",
-		"typescript": "~2.6.1",
-		"web3-typescript-typings": "^0.9.6",
-		"webpack": "^3.1.0",
-		"webpack-dev-middleware": "^1.10.0",
-		"webpack-dev-server": "^2.5.0"
-	}
+    "name": "@0xproject/website",
+    "version": "0.0.9",
+    "private": true,
+    "description": "Website and 0x portal dapp",
+    "scripts": {
+        "build": "NODE_ENV=production webpack; exit 0;",
+        "clean": "shx rm -f public/bundle*",
+        "lint": "tslint --project . 'ts/**/*.ts' 'ts/**/*.tsx'",
+        "dev": "webpack-dev-server --content-base public --https",
+        "update_contracts":
+            "for i in ${npm_package_config_artifacts}; do copyfiles -u 4 ../contracts/build/contracts/$i.json ../website/contracts; done;",
+        "deploy_staging":
+            "npm run build; aws s3 sync ./public/. s3://staging-0xproject --profile 0xproject --region us-east-1 --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers",
+        "deploy_live":
+            "npm run build; aws s3 sync ./public/. s3://0xproject.com --profile 0xproject --region us-east-1 --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers"
+    },
+    "config": {
+        "artifacts": "Mintable"
+    },
+    "author": "Fabio Berger",
+    "license": "Apache-2.0",
+    "dependencies": {
+        "0x.js": "^0.30.2",
+        "@0xproject/subproviders": "^0.3.3",
+        "@0xproject/utils": "^0.2.2",
+        "accounting": "^0.4.1",
+        "basscss": "^8.0.3",
+        "blockies": "^0.0.2",
+        "compare-versions": "^3.0.1",
+        "dateformat": "^2.0.0",
+        "deep-equal": "^1.0.1",
+        "dharma-loan-frame": "^0.0.12",
+        "ethereumjs-tx": "^1.3.3",
+        "ethereumjs-util": "^5.1.1",
+        "find-versions": "^2.0.0",
+        "is-mobile": "^0.2.2",
+        "jsonschema": "^1.2.0",
+        "ledgerco": "0xProject/ledger-node-js-api",
+        "less": "^2.7.2",
+        "lodash": "^4.17.4",
+        "material-ui": "^0.17.1",
+        "moment": "^2.18.1",
+        "query-string": "^5.0.1",
+        "react": "15.6.1",
+        "react-copy-to-clipboard": "^4.2.3",
+        "react-document-title": "^2.0.3",
+        "react-dom": "15.6.1",
+        "react-highlight": "^0.10.0",
+        "react-html5video": "^2.1.0",
+        "react-inlinesvg": "^0.5.5",
+        "react-markdown": "^2.5.0",
+        "react-recaptcha": "^2.3.2",
+        "react-redux": "^5.0.3",
+        "react-router-dom": "^4.1.1",
+        "react-router-hash-link": "^1.1.0",
+        "react-scroll": "^1.5.2",
+        "react-tap-event-plugin": "^2.0.1",
+        "react-tooltip": "^3.2.7",
+        "react-waypoint": "^7.0.4",
+        "redux": "^3.6.0",
+        "scroll-to-element": "^2.0.0",
+        "semver-sort": "0.0.4",
+        "thenby": "^1.2.3",
+        "truffle-contract": "2.0.1",
+        "tslint-config-0xproject": "^0.0.2",
+        "web3": "^0.20.0",
+        "web3-provider-engine": "^13.0.1",
+        "whatwg-fetch": "^2.0.3",
+        "xml-js": "^1.3.2"
+    },
+    "devDependencies": {
+        "@types/accounting": "^0.4.1",
+        "@types/dateformat": "^1.0.1",
+        "@types/deep-equal": "^1.0.0",
+        "@types/jsonschema": "^1.1.1",
+        "@types/lodash": "^4.14.86",
+        "@types/material-ui": "0.18.0",
+        "@types/moment": "^2.13.0",
+        "@types/node": "^8.0.53",
+        "@types/query-string": "^5.0.1",
+        "@types/react": "^15.0.15",
+        "@types/react-copy-to-clipboard": "^4.2.0",
+        "@types/react-dom": "^0.14.23",
+        "@types/react-redux": "^4.4.37",
+        "@types/react-router-dom": "^4.0.4",
+        "@types/react-scroll": "0.0.31",
+        "@types/react-tap-event-plugin": "0.0.30",
+        "@types/redux": "^3.6.0",
+        "awesome-typescript-loader": "^3.1.3",
+        "copy-webpack-plugin": "^4.0.1",
+        "copyfiles": "^1.2.0",
+        "css-loader": "0.23.x",
+        "exports-loader": "0.6.x",
+        "imports-loader": "0.6.x",
+        "json-loader": "^0.5.4",
+        "less-loader": "^2.2.3",
+        "raw-loader": "^0.5.1",
+        "shx": "^0.2.2",
+        "source-map-loader": "^0.1.6",
+        "style-loader": "0.13.x",
+        "tslint": "5.8.0",
+        "typescript": "~2.6.1",
+        "web3-typescript-typings": "^0.9.6",
+        "webpack": "^3.1.0",
+        "webpack-dev-middleware": "^1.10.0",
+        "webpack-dev-server": "^2.5.0"
+    }
 }
diff --git a/packages/website/ts/blockchain.ts b/packages/website/ts/blockchain.ts
index 711c3329d..5530701c0 100644
--- a/packages/website/ts/blockchain.ts
+++ b/packages/website/ts/blockchain.ts
@@ -1,25 +1,25 @@
 import {
-	BlockParam,
-	BlockRange,
-	DecodedLogEvent,
-	ExchangeContractEventArgs,
-	ExchangeEvents,
-	IndexedFilterValues,
-	LogCancelContractEventArgs,
-	LogFillContractEventArgs,
-	LogWithDecodedArgs,
-	Order,
-	SignedOrder,
-	Token as ZeroExToken,
-	TransactionReceiptWithDecodedLogs,
-	ZeroEx,
+    BlockParam,
+    BlockRange,
+    DecodedLogEvent,
+    ExchangeContractEventArgs,
+    ExchangeEvents,
+    IndexedFilterValues,
+    LogCancelContractEventArgs,
+    LogFillContractEventArgs,
+    LogWithDecodedArgs,
+    Order,
+    SignedOrder,
+    Token as ZeroExToken,
+    TransactionReceiptWithDecodedLogs,
+    ZeroEx,
 } from '0x.js';
 import {
-	InjectedWeb3Subprovider,
-	ledgerEthereumBrowserClientFactoryAsync,
-	LedgerSubprovider,
-	LedgerWalletSubprovider,
-	RedundantRPCSubprovider,
+    InjectedWeb3Subprovider,
+    ledgerEthereumBrowserClientFactoryAsync,
+    LedgerSubprovider,
+    LedgerWalletSubprovider,
+    RedundantRPCSubprovider,
 } from '@0xproject/subproviders';
 import { BigNumber, intervalUtils, promisify } from '@0xproject/utils';
 import * as _ from 'lodash';
@@ -31,16 +31,16 @@ import { trackedTokenStorage } from 'ts/local_storage/tracked_token_storage';
 import { tradeHistoryStorage } from 'ts/local_storage/trade_history_storage';
 import { Dispatcher } from 'ts/redux/dispatcher';
 import {
-	BlockchainCallErrs,
-	BlockchainErrs,
-	ContractInstance,
-	EtherscanLinkSuffixes,
-	ProviderType,
-	Side,
-	SignatureData,
-	Token,
-	TokenByAddress,
-	TokenStateByAddress,
+    BlockchainCallErrs,
+    BlockchainErrs,
+    ContractInstance,
+    EtherscanLinkSuffixes,
+    ProviderType,
+    Side,
+    SignatureData,
+    Token,
+    TokenByAddress,
+    TokenStateByAddress,
 } from 'ts/types';
 import { configs } from 'ts/utils/configs';
 import { constants } from 'ts/utils/constants';
@@ -56,727 +56,727 @@ import * as MintableArtifacts from '../contracts/Mintable.json';
 const BLOCK_NUMBER_BACK_TRACK = 50;
 
 export class Blockchain {
-	public networkId: number;
-	public nodeVersion: string;
-	private _zeroEx: ZeroEx;
-	private _dispatcher: Dispatcher;
-	private _web3Wrapper?: Web3Wrapper;
-	private _exchangeAddress: string;
-	private _userAddress: string;
-	private _cachedProvider: Web3.Provider;
-	private _ledgerSubprovider: LedgerWalletSubprovider;
-	private _zrxPollIntervalId: NodeJS.Timer;
-	private static async _onPageLoadAsync(): Promise<void> {
-		if (document.readyState === 'complete') {
-			return; // Already loaded
-		}
-		return new Promise<void>((resolve, reject) => {
-			window.onload = () => resolve();
-		});
-	}
-	private static _getNameGivenProvider(provider: Web3.Provider): string {
-		if (!_.isUndefined((provider as any).isMetaMask)) {
-			return constants.PROVIDER_NAME_METAMASK;
-		}
-
-		// HACK: We use the fact that Parity Signer's provider is an instance of their
-		// internal `Web3FrameProvider` class.
-		const isParitySigner = _.startsWith(provider.constructor.toString(), 'function Web3FrameProvider');
-		if (isParitySigner) {
-			return constants.PROVIDER_NAME_PARITY_SIGNER;
-		}
-
-		return constants.PROVIDER_NAME_GENERIC;
-	}
-	private static async _getProviderAsync(injectedWeb3: Web3, networkIdIfExists: number) {
-		const doesInjectedWeb3Exist = !_.isUndefined(injectedWeb3);
-		const publicNodeUrlsIfExistsForNetworkId = configs.PUBLIC_NODE_URLS_BY_NETWORK_ID[networkIdIfExists];
-		const isPublicNodeAvailableForNetworkId = !_.isUndefined(publicNodeUrlsIfExistsForNetworkId);
-
-		let provider;
-		if (doesInjectedWeb3Exist && isPublicNodeAvailableForNetworkId) {
-			// We catch all requests involving a users account and send it to the injectedWeb3
-			// instance. All other requests go to the public hosted node.
-			provider = new ProviderEngine();
-			provider.addProvider(new InjectedWeb3Subprovider(injectedWeb3));
-			provider.addProvider(new FilterSubprovider());
-			provider.addProvider(new RedundantRPCSubprovider(publicNodeUrlsIfExistsForNetworkId));
-			provider.start();
-		} else if (doesInjectedWeb3Exist) {
-			// Since no public node for this network, all requests go to injectedWeb3 instance
-			provider = injectedWeb3.currentProvider;
-		} else {
-			// If no injectedWeb3 instance, all requests fallback to our public hosted mainnet/testnet node
-			// We do this so that users can still browse the 0x Portal DApp even if they do not have web3
-			// injected into their browser.
-			provider = new ProviderEngine();
-			provider.addProvider(new FilterSubprovider());
-			const networkId = configs.IS_MAINNET_ENABLED ? constants.NETWORK_ID_MAINNET : constants.NETWORK_ID_TESTNET;
-			provider.addProvider(new RedundantRPCSubprovider(configs.PUBLIC_NODE_URLS_BY_NETWORK_ID[networkId]));
-			provider.start();
-		}
-
-		return provider;
-	}
-	constructor(dispatcher: Dispatcher, isSalePage: boolean = false) {
-		this._dispatcher = dispatcher;
-		this._userAddress = '';
-		// tslint:disable-next-line:no-floating-promises
-		this._onPageLoadInitFireAndForgetAsync();
-	}
-	public async networkIdUpdatedFireAndForgetAsync(newNetworkId: number) {
-		const isConnected = !_.isUndefined(newNetworkId);
-		if (!isConnected) {
-			this.networkId = newNetworkId;
-			this._dispatcher.encounteredBlockchainError(BlockchainErrs.DisconnectedFromEthereumNode);
-			this._dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
-		} else if (this.networkId !== newNetworkId) {
-			this.networkId = newNetworkId;
-			this._dispatcher.encounteredBlockchainError(BlockchainErrs.NoError);
-			await this._fetchTokenInformationAsync();
-			await this._rehydrateStoreWithContractEvents();
-		}
-	}
-	public async userAddressUpdatedFireAndForgetAsync(newUserAddress: string) {
-		if (this._userAddress !== newUserAddress) {
-			this._userAddress = newUserAddress;
-			await this._fetchTokenInformationAsync();
-			await this._rehydrateStoreWithContractEvents();
-		}
-	}
-	public async nodeVersionUpdatedFireAndForgetAsync(nodeVersion: string) {
-		if (this.nodeVersion !== nodeVersion) {
-			this.nodeVersion = nodeVersion;
-		}
-	}
-	public async isAddressInTokenRegistryAsync(tokenAddress: string): Promise<boolean> {
-		utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
-		// HACK: temporarily whitelist the new WETH token address `as if` they were
-		// already in the tokenRegistry.
-		// TODO: Remove this hack once we've updated the TokenRegistries
-		// Airtable task: https://airtable.com/tblFe0Q9JuKJPYbTn/viwsOG2Y97qdIeCIO/recv3VGmIorFzHBVz
-		if (configs.SHOULD_DEPRECATE_OLD_WETH_TOKEN && tokenAddress === configs.NEW_WRAPPED_ETHERS[this.networkId]) {
-			return true;
-		}
-		const tokenIfExists = await this._zeroEx.tokenRegistry.getTokenIfExistsAsync(tokenAddress);
-		return !_.isUndefined(tokenIfExists);
-	}
-	public getLedgerDerivationPathIfExists(): string {
-		if (_.isUndefined(this._ledgerSubprovider)) {
-			return undefined;
-		}
-		const path = this._ledgerSubprovider.getPath();
-		return path;
-	}
-	public updateLedgerDerivationPathIfExists(path: string) {
-		if (_.isUndefined(this._ledgerSubprovider)) {
-			return; // noop
-		}
-		this._ledgerSubprovider.setPath(path);
-	}
-	public updateLedgerDerivationIndex(pathIndex: number) {
-		if (_.isUndefined(this._ledgerSubprovider)) {
-			return; // noop
-		}
-		this._ledgerSubprovider.setPathIndex(pathIndex);
-	}
-	public async providerTypeUpdatedFireAndForgetAsync(providerType: ProviderType) {
-		utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
-		// Should actually be Web3.Provider|ProviderEngine union type but it causes issues
-		// later on in the logic.
-		let provider;
-		switch (providerType) {
-			case ProviderType.Ledger: {
-				const isU2FSupported = await utils.isU2FSupportedAsync();
-				if (!isU2FSupported) {
-					throw new Error('Cannot update providerType to LEDGER without U2F support');
-				}
-
-				// Cache injected provider so that we can switch the user back to it easily
-				this._cachedProvider = this._web3Wrapper.getProviderObj();
-
-				this._dispatcher.updateUserAddress(''); // Clear old userAddress
-
-				provider = new ProviderEngine();
-				const ledgerWalletConfigs = {
-					networkId: this.networkId,
-					ledgerEthereumClientFactoryAsync: ledgerEthereumBrowserClientFactoryAsync,
-				};
-				this._ledgerSubprovider = new LedgerSubprovider(ledgerWalletConfigs);
-				provider.addProvider(this._ledgerSubprovider);
-				provider.addProvider(new FilterSubprovider());
-				const networkId = configs.IS_MAINNET_ENABLED
-					? constants.NETWORK_ID_MAINNET
-					: constants.NETWORK_ID_TESTNET;
-				provider.addProvider(new RedundantRPCSubprovider(configs.PUBLIC_NODE_URLS_BY_NETWORK_ID[networkId]));
-				provider.start();
-				this._web3Wrapper.destroy();
-				const shouldPollUserAddress = false;
-				this._web3Wrapper = new Web3Wrapper(this._dispatcher, provider, this.networkId, shouldPollUserAddress);
-				this._zeroEx.setProvider(provider, networkId);
-				await this._postInstantiationOrUpdatingProviderZeroExAsync();
-				break;
-			}
-
-			case ProviderType.Injected: {
-				if (_.isUndefined(this._cachedProvider)) {
-					return; // Going from injected to injected, so we noop
-				}
-				provider = this._cachedProvider;
-				const shouldPollUserAddress = true;
-				this._web3Wrapper = new Web3Wrapper(this._dispatcher, provider, this.networkId, shouldPollUserAddress);
-				this._zeroEx.setProvider(provider, this.networkId);
-				await this._postInstantiationOrUpdatingProviderZeroExAsync();
-				delete this._ledgerSubprovider;
-				delete this._cachedProvider;
-				break;
-			}
-
-			default:
-				throw utils.spawnSwitchErr('providerType', providerType);
-		}
-
-		await this._fetchTokenInformationAsync();
-	}
-	public async setProxyAllowanceAsync(token: Token, amountInBaseUnits: BigNumber): Promise<void> {
-		utils.assert(this.isValidAddress(token.address), BlockchainCallErrs.TokenAddressIsInvalid);
-		utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
-		utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
-
-		const txHash = await this._zeroEx.token.setProxyAllowanceAsync(
-			token.address,
-			this._userAddress,
-			amountInBaseUnits,
-		);
-		await this._showEtherScanLinkAndAwaitTransactionMinedAsync(txHash);
-		const allowance = amountInBaseUnits;
-		this._dispatcher.replaceTokenAllowanceByAddress(token.address, allowance);
-	}
-	public async transferAsync(token: Token, toAddress: string, amountInBaseUnits: BigNumber): Promise<void> {
-		const txHash = await this._zeroEx.token.transferAsync(
-			token.address,
-			this._userAddress,
-			toAddress,
-			amountInBaseUnits,
-		);
-		await this._showEtherScanLinkAndAwaitTransactionMinedAsync(txHash);
-		const etherScanLinkIfExists = utils.getEtherScanLinkIfExists(txHash, this.networkId, EtherscanLinkSuffixes.Tx);
-		this._dispatcher.showFlashMessage(
-			React.createElement(TokenSendCompleted, {
-				etherScanLinkIfExists,
-				token,
-				toAddress,
-				amountInBaseUnits,
-			}),
-		);
-	}
-	public portalOrderToSignedOrder(
-		maker: string,
-		taker: string,
-		makerTokenAddress: string,
-		takerTokenAddress: string,
-		makerTokenAmount: BigNumber,
-		takerTokenAmount: BigNumber,
-		makerFee: BigNumber,
-		takerFee: BigNumber,
-		expirationUnixTimestampSec: BigNumber,
-		feeRecipient: string,
-		signatureData: SignatureData,
-		salt: BigNumber,
-	): SignedOrder {
-		const ecSignature = signatureData;
-		const exchangeContractAddress = this.getExchangeContractAddressIfExists();
-		const takerOrNullAddress = _.isEmpty(taker) ? constants.NULL_ADDRESS : taker;
-		const signedOrder = {
-			ecSignature,
-			exchangeContractAddress,
-			expirationUnixTimestampSec,
-			feeRecipient,
-			maker,
-			makerFee,
-			makerTokenAddress,
-			makerTokenAmount,
-			salt,
-			taker: takerOrNullAddress,
-			takerFee,
-			takerTokenAddress,
-			takerTokenAmount,
-		};
-		return signedOrder;
-	}
-	public async fillOrderAsync(signedOrder: SignedOrder, fillTakerTokenAmount: BigNumber): Promise<BigNumber> {
-		utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
-
-		const shouldThrowOnInsufficientBalanceOrAllowance = true;
-
-		const txHash = await this._zeroEx.exchange.fillOrderAsync(
-			signedOrder,
-			fillTakerTokenAmount,
-			shouldThrowOnInsufficientBalanceOrAllowance,
-			this._userAddress,
-		);
-		const receipt = await this._showEtherScanLinkAndAwaitTransactionMinedAsync(txHash);
-		const logs: Array<LogWithDecodedArgs<ExchangeContractEventArgs>> = receipt.logs as any;
-		this._zeroEx.exchange.throwLogErrorsAsErrors(logs);
-		const logFill = _.find(logs, { event: 'LogFill' });
-		const args = (logFill.args as any) as LogFillContractEventArgs;
-		const filledTakerTokenAmount = args.filledTakerTokenAmount;
-		return filledTakerTokenAmount;
-	}
-	public async cancelOrderAsync(signedOrder: SignedOrder, cancelTakerTokenAmount: BigNumber): Promise<BigNumber> {
-		const txHash = await this._zeroEx.exchange.cancelOrderAsync(signedOrder, cancelTakerTokenAmount);
-		const receipt = await this._showEtherScanLinkAndAwaitTransactionMinedAsync(txHash);
-		const logs: Array<LogWithDecodedArgs<ExchangeContractEventArgs>> = receipt.logs as any;
-		this._zeroEx.exchange.throwLogErrorsAsErrors(logs);
-		const logCancel = _.find(logs, { event: ExchangeEvents.LogCancel });
-		const args = (logCancel.args as any) as LogCancelContractEventArgs;
-		const cancelledTakerTokenAmount = args.cancelledTakerTokenAmount;
-		return cancelledTakerTokenAmount;
-	}
-	public async getUnavailableTakerAmountAsync(orderHash: string): Promise<BigNumber> {
-		utils.assert(ZeroEx.isValidOrderHash(orderHash), 'Must be valid orderHash');
-		utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
-		const unavailableTakerAmount = await this._zeroEx.exchange.getUnavailableTakerAmountAsync(orderHash);
-		return unavailableTakerAmount;
-	}
-	public getExchangeContractAddressIfExists() {
-		return this._exchangeAddress;
-	}
-	public async validateFillOrderThrowIfInvalidAsync(
-		signedOrder: SignedOrder,
-		fillTakerTokenAmount: BigNumber,
-		takerAddress: string,
-	): Promise<void> {
-		await this._zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(
-			signedOrder,
-			fillTakerTokenAmount,
-			takerAddress,
-		);
-	}
-	public async validateCancelOrderThrowIfInvalidAsync(
-		order: Order,
-		cancelTakerTokenAmount: BigNumber,
-	): Promise<void> {
-		await this._zeroEx.exchange.validateCancelOrderThrowIfInvalidAsync(order, cancelTakerTokenAmount);
-	}
-	public isValidAddress(address: string): boolean {
-		const lowercaseAddress = address.toLowerCase();
-		return this._web3Wrapper.isAddress(lowercaseAddress);
-	}
-	public async pollTokenBalanceAsync(token: Token) {
-		utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
-
-		const [currBalance] = await this.getTokenBalanceAndAllowanceAsync(this._userAddress, token.address);
-
-		this._zrxPollIntervalId = intervalUtils.setAsyncExcludingInterval(
-			async () => {
-				const [balance] = await this.getTokenBalanceAndAllowanceAsync(this._userAddress, token.address);
-				if (!balance.eq(currBalance)) {
-					this._dispatcher.replaceTokenBalanceByAddress(token.address, balance);
-					intervalUtils.clearAsyncExcludingInterval(this._zrxPollIntervalId);
-					delete this._zrxPollIntervalId;
-				}
-			},
-			5000,
-			(err: Error) => {
-				utils.consoleLog(`Polling tokenBalance failed: ${err}`);
-				intervalUtils.clearAsyncExcludingInterval(this._zrxPollIntervalId);
-				delete this._zrxPollIntervalId;
-			},
-		);
-	}
-	public async signOrderHashAsync(orderHash: string): Promise<SignatureData> {
-		utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
-		const makerAddress = this._userAddress;
-		// If makerAddress is undefined, this means they have a web3 instance injected into their browser
-		// but no account addresses associated with it.
-		if (_.isUndefined(makerAddress)) {
-			throw new Error('Tried to send a sign request but user has no associated addresses');
-		}
-		const ecSignature = await this._zeroEx.signOrderHashAsync(orderHash, makerAddress);
-		const signatureData = _.extend({}, ecSignature, {
-			hash: orderHash,
-		});
-		this._dispatcher.updateSignatureData(signatureData);
-		return signatureData;
-	}
-	public async mintTestTokensAsync(token: Token) {
-		utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
-
-		const mintableContract = await this._instantiateContractIfExistsAsync(MintableArtifacts, token.address);
-		await mintableContract.mint(constants.MINT_AMOUNT, {
-			from: this._userAddress,
-		});
-		const balanceDelta = constants.MINT_AMOUNT;
-		this._dispatcher.updateTokenBalanceByAddress(token.address, balanceDelta);
-	}
-	public async getBalanceInEthAsync(owner: string): Promise<BigNumber> {
-		const balance = await this._web3Wrapper.getBalanceInEthAsync(owner);
-		return balance;
-	}
-	public async convertEthToWrappedEthTokensAsync(etherTokenAddress: string, amount: BigNumber): Promise<void> {
-		utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
-		utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
-
-		const txHash = await this._zeroEx.etherToken.depositAsync(etherTokenAddress, amount, this._userAddress);
-		await this._showEtherScanLinkAndAwaitTransactionMinedAsync(txHash);
-	}
-	public async convertWrappedEthTokensToEthAsync(etherTokenAddress: string, amount: BigNumber): Promise<void> {
-		utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
-		utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
-
-		const txHash = await this._zeroEx.etherToken.withdrawAsync(etherTokenAddress, amount, this._userAddress);
-		await this._showEtherScanLinkAndAwaitTransactionMinedAsync(txHash);
-	}
-	public async doesContractExistAtAddressAsync(address: string) {
-		const doesContractExist = await this._web3Wrapper.doesContractExistAtAddressAsync(address);
-		return doesContractExist;
-	}
-	public async getCurrentUserTokenBalanceAndAllowanceAsync(tokenAddress: string): Promise<BigNumber[]> {
-		const tokenBalanceAndAllowance = await this.getTokenBalanceAndAllowanceAsync(this._userAddress, tokenAddress);
-		return tokenBalanceAndAllowance;
-	}
-	public async getTokenBalanceAndAllowanceAsync(ownerAddress: string, tokenAddress: string): Promise<BigNumber[]> {
-		utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
-
-		if (_.isEmpty(ownerAddress)) {
-			const zero = new BigNumber(0);
-			return [zero, zero];
-		}
-		let balance = new BigNumber(0);
-		let allowance = new BigNumber(0);
-		if (this._doesUserAddressExist()) {
-			balance = await this._zeroEx.token.getBalanceAsync(tokenAddress, ownerAddress);
-			allowance = await this._zeroEx.token.getProxyAllowanceAsync(tokenAddress, ownerAddress);
-		}
-		return [balance, allowance];
-	}
-	public async updateTokenBalancesAndAllowancesAsync(tokens: Token[]) {
-		const tokenStateByAddress: TokenStateByAddress = {};
-		for (const token of tokens) {
-			let balance = new BigNumber(0);
-			let allowance = new BigNumber(0);
-			if (this._doesUserAddressExist()) {
-				[balance, allowance] = await this.getTokenBalanceAndAllowanceAsync(this._userAddress, token.address);
-			}
-			const tokenState = {
-				balance,
-				allowance,
-			};
-			tokenStateByAddress[token.address] = tokenState;
-		}
-		this._dispatcher.updateTokenStateByAddress(tokenStateByAddress);
-	}
-	public async getUserAccountsAsync() {
-		utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
-		const userAccountsIfExists = await this._zeroEx.getAvailableAddressesAsync();
-		return userAccountsIfExists;
-	}
-	// HACK: When a user is using a Ledger, we simply dispatch the selected userAddress, which
-	// by-passes the web3Wrapper logic for updating the prevUserAddress. We therefore need to
-	// manually update it. This should only be called by the LedgerConfigDialog.
-	public updateWeb3WrapperPrevUserAddress(newUserAddress: string) {
-		this._web3Wrapper.updatePrevUserAddress(newUserAddress);
-	}
-	public destroy() {
-		intervalUtils.clearAsyncExcludingInterval(this._zrxPollIntervalId);
-		this._web3Wrapper.destroy();
-		this._stopWatchingExchangeLogFillEvents();
-	}
-	private async _showEtherScanLinkAndAwaitTransactionMinedAsync(
-		txHash: string,
-	): Promise<TransactionReceiptWithDecodedLogs> {
-		const etherScanLinkIfExists = utils.getEtherScanLinkIfExists(txHash, this.networkId, EtherscanLinkSuffixes.Tx);
-		this._dispatcher.showFlashMessage(
-			React.createElement(TransactionSubmitted, {
-				etherScanLinkIfExists,
-			}),
-		);
-		const receipt = await this._zeroEx.awaitTransactionMinedAsync(txHash);
-		return receipt;
-	}
-	private _doesUserAddressExist(): boolean {
-		return this._userAddress !== '';
-	}
-	private async _rehydrateStoreWithContractEvents() {
-		// Ensure we are only ever listening to one set of events
-		this._stopWatchingExchangeLogFillEvents();
-
-		if (!this._doesUserAddressExist()) {
-			return; // short-circuit
-		}
-
-		if (!_.isUndefined(this._zeroEx)) {
-			// Since we do not have an index on the `taker` address and want to show
-			// transactions where an account is either the `maker` or `taker`, we loop
-			// through all fill events, and filter/cache them client-side.
-			const filterIndexObj = {};
-			await this._startListeningForExchangeLogFillEventsAsync(filterIndexObj);
-		}
-	}
-	private async _startListeningForExchangeLogFillEventsAsync(indexFilterValues: IndexedFilterValues): Promise<void> {
-		utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
-		utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
-
-		// Fetch historical logs
-		await this._fetchHistoricalExchangeLogFillEventsAsync(indexFilterValues);
-
-		// Start a subscription for new logs
-		this._zeroEx.exchange.subscribe(
-			ExchangeEvents.LogFill,
-			indexFilterValues,
-			async (err: Error, decodedLogEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
-				if (err) {
-					// Note: it's not entirely clear from the documentation which
-					// errors will be thrown by `watch`. For now, let's log the error
-					// to rollbar and stop watching when one occurs
-					// tslint:disable-next-line:no-floating-promises
-					errorReporter.reportAsync(err); // fire and forget
-					return;
-				} else {
-					const decodedLog = decodedLogEvent.log;
-					if (!this._doesLogEventInvolveUser(decodedLog)) {
-						return; // We aren't interested in the fill event
-					}
-					this._updateLatestFillsBlockIfNeeded(decodedLog.blockNumber);
-					const fill = await this._convertDecodedLogToFillAsync(decodedLog);
-					if (decodedLogEvent.isRemoved) {
-						tradeHistoryStorage.removeFillFromUser(this._userAddress, this.networkId, fill);
-					} else {
-						tradeHistoryStorage.addFillToUser(this._userAddress, this.networkId, fill);
-					}
-				}
-			},
-		);
-	}
-	private async _fetchHistoricalExchangeLogFillEventsAsync(indexFilterValues: IndexedFilterValues) {
-		const fromBlock = tradeHistoryStorage.getFillsLatestBlock(this._userAddress, this.networkId);
-		const blockRange: BlockRange = {
-			fromBlock,
-			toBlock: 'latest' as BlockParam,
-		};
-		const decodedLogs = await this._zeroEx.exchange.getLogsAsync<LogFillContractEventArgs>(
-			ExchangeEvents.LogFill,
-			blockRange,
-			indexFilterValues,
-		);
-		for (const decodedLog of decodedLogs) {
-			if (!this._doesLogEventInvolveUser(decodedLog)) {
-				continue; // We aren't interested in the fill event
-			}
-			this._updateLatestFillsBlockIfNeeded(decodedLog.blockNumber);
-			const fill = await this._convertDecodedLogToFillAsync(decodedLog);
-			tradeHistoryStorage.addFillToUser(this._userAddress, this.networkId, fill);
-		}
-	}
-	private async _convertDecodedLogToFillAsync(decodedLog: LogWithDecodedArgs<LogFillContractEventArgs>) {
-		const args = decodedLog.args;
-		const blockTimestamp = await this._web3Wrapper.getBlockTimestampAsync(decodedLog.blockHash);
-		const fill = {
-			filledTakerTokenAmount: args.filledTakerTokenAmount,
-			filledMakerTokenAmount: args.filledMakerTokenAmount,
-			logIndex: decodedLog.logIndex,
-			maker: args.maker,
-			orderHash: args.orderHash,
-			taker: args.taker,
-			makerToken: args.makerToken,
-			takerToken: args.takerToken,
-			paidMakerFee: args.paidMakerFee,
-			paidTakerFee: args.paidTakerFee,
-			transactionHash: decodedLog.transactionHash,
-			blockTimestamp,
-		};
-		return fill;
-	}
-	private _doesLogEventInvolveUser(decodedLog: LogWithDecodedArgs<LogFillContractEventArgs>) {
-		const args = decodedLog.args;
-		const isUserMakerOrTaker = args.maker === this._userAddress || args.taker === this._userAddress;
-		return isUserMakerOrTaker;
-	}
-	private _updateLatestFillsBlockIfNeeded(blockNumber: number) {
-		const isBlockPending = _.isNull(blockNumber);
-		if (!isBlockPending) {
-			// Hack: I've observed the behavior where a client won't register certain fill events
-			// and lowering the cache blockNumber fixes the issue. As a quick fix for now, simply
-			// set the cached blockNumber 50 below the one returned. This way, upon refreshing, a user
-			// would still attempt to re-fetch events from the previous 50 blocks, but won't need to
-			// re-fetch all events in all blocks.
-			// TODO: Debug if this is a race condition, and apply a more precise fix
-			const blockNumberToSet =
-				blockNumber - BLOCK_NUMBER_BACK_TRACK < 0 ? 0 : blockNumber - BLOCK_NUMBER_BACK_TRACK;
-			tradeHistoryStorage.setFillsLatestBlock(this._userAddress, this.networkId, blockNumberToSet);
-		}
-	}
-	private _stopWatchingExchangeLogFillEvents(): void {
-		this._zeroEx.exchange.unsubscribeAll();
-	}
-	private async _getTokenRegistryTokensByAddressAsync(): Promise<TokenByAddress> {
-		utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
-		const tokenRegistryTokens = await this._zeroEx.tokenRegistry.getTokensAsync();
-
-		const tokenByAddress: TokenByAddress = {};
-		_.each(tokenRegistryTokens, (t: ZeroExToken, i: number) => {
-			// HACK: For now we have a hard-coded list of iconUrls for the dummyTokens
-			// TODO: Refactor this out and pull the iconUrl directly from the TokenRegistry
-			const iconUrl = configs.ICON_URL_BY_SYMBOL[t.symbol];
-			// HACK: Temporarily we hijack the WETH addresses fetched from the tokenRegistry
-			// so that we can take our time with actually updating it. This ensures that when
-			// we deploy the new WETH page, everyone will re-fill their trackedTokens with the
-			// new canonical WETH.
-			// TODO: Remove this hack once we've updated the TokenRegistries
-			// Airtable task: https://airtable.com/tblFe0Q9JuKJPYbTn/viwsOG2Y97qdIeCIO/recv3VGmIorFzHBVz
-			let address = t.address;
-			if (configs.SHOULD_DEPRECATE_OLD_WETH_TOKEN && t.symbol === 'WETH') {
-				const newEtherTokenAddressIfExists = configs.NEW_WRAPPED_ETHERS[this.networkId];
-				if (!_.isUndefined(newEtherTokenAddressIfExists)) {
-					address = newEtherTokenAddressIfExists;
-				}
-			}
-			const token: Token = {
-				iconUrl,
-				address,
-				name: t.name,
-				symbol: t.symbol,
-				decimals: t.decimals,
-				isTracked: false,
-				isRegistered: true,
-			};
-			tokenByAddress[token.address] = token;
-		});
-		return tokenByAddress;
-	}
-	private async _onPageLoadInitFireAndForgetAsync() {
-		await Blockchain._onPageLoadAsync(); // wait for page to load
-
-		// Hack: We need to know the networkId the injectedWeb3 is connected to (if it is defined) in
-		// order to properly instantiate the web3Wrapper. Since we must use the async call, we cannot
-		// retrieve it from within the web3Wrapper constructor. This is and should remain the only
-		// call to a web3 instance outside of web3Wrapper in the entire dapp.
-		// In addition, if the user has an injectedWeb3 instance that is disconnected from a backing
-		// Ethereum node, this call will throw. We need to handle this case gracefully
-		const injectedWeb3 = (window as any).web3;
-		let networkIdIfExists: number;
-		if (!_.isUndefined(injectedWeb3)) {
-			try {
-				networkIdIfExists = _.parseInt(await promisify<string>(injectedWeb3.version.getNetwork)());
-			} catch (err) {
-				// Ignore error and proceed with networkId undefined
-			}
-		}
-
-		const provider = await Blockchain._getProviderAsync(injectedWeb3, networkIdIfExists);
-		const networkId = !_.isUndefined(networkIdIfExists)
-			? networkIdIfExists
-			: configs.IS_MAINNET_ENABLED ? constants.NETWORK_ID_MAINNET : constants.NETWORK_ID_TESTNET;
-		const zeroExConfigs = {
-			networkId,
-		};
-		this._zeroEx = new ZeroEx(provider, zeroExConfigs);
-		this._updateProviderName(injectedWeb3);
-		const shouldPollUserAddress = true;
-		this._web3Wrapper = new Web3Wrapper(this._dispatcher, provider, networkId, shouldPollUserAddress);
-		await this._postInstantiationOrUpdatingProviderZeroExAsync();
-	}
-	// This method should always be run after instantiating or updating the provider
-	// of the ZeroEx instance.
-	private async _postInstantiationOrUpdatingProviderZeroExAsync() {
-		utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
-		this._exchangeAddress = this._zeroEx.exchange.getContractAddress();
-	}
-	private _updateProviderName(injectedWeb3: Web3) {
-		const doesInjectedWeb3Exist = !_.isUndefined(injectedWeb3);
-		const providerName = doesInjectedWeb3Exist
-			? Blockchain._getNameGivenProvider(injectedWeb3.currentProvider)
-			: constants.PROVIDER_NAME_PUBLIC;
-		this._dispatcher.updateInjectedProviderName(providerName);
-	}
-	private async _fetchTokenInformationAsync() {
-		utils.assert(
-			!_.isUndefined(this.networkId),
-			'Cannot call fetchTokenInformationAsync if disconnected from Ethereum node',
-		);
-
-		this._dispatcher.updateBlockchainIsLoaded(false);
-		this._dispatcher.clearTokenByAddress();
-
-		const tokenRegistryTokensByAddress = await this._getTokenRegistryTokensByAddressAsync();
-
-		// HACK: We need to fetch the userAddress here because otherwise we cannot save the
-		// tracked tokens in localStorage under the users address nor fetch the token
-		// balances and allowances and we need to do this in order not to trigger the blockchain
-		// loading dialog to show up twice. First to load the contracts, and second to load the
-		// balances and allowances.
-		this._userAddress = await this._web3Wrapper.getFirstAccountIfExistsAsync();
-		if (!_.isEmpty(this._userAddress)) {
-			this._dispatcher.updateUserAddress(this._userAddress);
-		}
-
-		let trackedTokensIfExists = trackedTokenStorage.getTrackedTokensIfExists(this._userAddress, this.networkId);
-		const tokenRegistryTokens = _.values(tokenRegistryTokensByAddress);
-		if (_.isUndefined(trackedTokensIfExists)) {
-			trackedTokensIfExists = _.map(configs.DEFAULT_TRACKED_TOKEN_SYMBOLS, symbol => {
-				const token = _.find(tokenRegistryTokens, t => t.symbol === symbol);
-				token.isTracked = true;
-				return token;
-			});
-			_.each(trackedTokensIfExists, token => {
-				trackedTokenStorage.addTrackedTokenToUser(this._userAddress, this.networkId, token);
-			});
-		} else {
-			// Properly set all tokenRegistry tokens `isTracked` to true if they are in the existing trackedTokens array
-			_.each(trackedTokensIfExists, trackedToken => {
-				if (!_.isUndefined(tokenRegistryTokensByAddress[trackedToken.address])) {
-					tokenRegistryTokensByAddress[trackedToken.address].isTracked = true;
-				}
-			});
-		}
-		const allTokens = _.uniq([...tokenRegistryTokens, ...trackedTokensIfExists]);
-		this._dispatcher.updateTokenByAddress(allTokens);
-
-		// Get balance/allowance for tracked tokens
-		await this.updateTokenBalancesAndAllowancesAsync(trackedTokensIfExists);
-
-		const mostPopularTradingPairTokens: Token[] = [
-			_.find(allTokens, { symbol: configs.DEFAULT_TRACKED_TOKEN_SYMBOLS[0] }),
-			_.find(allTokens, { symbol: configs.DEFAULT_TRACKED_TOKEN_SYMBOLS[1] }),
-		];
-		this._dispatcher.updateChosenAssetTokenAddress(Side.Deposit, mostPopularTradingPairTokens[0].address);
-		this._dispatcher.updateChosenAssetTokenAddress(Side.Receive, mostPopularTradingPairTokens[1].address);
-		this._dispatcher.updateBlockchainIsLoaded(true);
-	}
-	private async _instantiateContractIfExistsAsync(artifact: any, address?: string): Promise<ContractInstance> {
-		const c = await contract(artifact);
-		const providerObj = this._web3Wrapper.getProviderObj();
-		c.setProvider(providerObj);
-
-		const artifactNetworkConfigs = artifact.networks[this.networkId];
-		let contractAddress;
-		if (!_.isUndefined(address)) {
-			contractAddress = address;
-		} else if (!_.isUndefined(artifactNetworkConfigs)) {
-			contractAddress = artifactNetworkConfigs.address;
-		}
-
-		if (!_.isUndefined(contractAddress)) {
-			const doesContractExist = await this.doesContractExistAtAddressAsync(contractAddress);
-			if (!doesContractExist) {
-				utils.consoleLog(`Contract does not exist: ${artifact.contract_name} at ${contractAddress}`);
-				throw new Error(BlockchainCallErrs.ContractDoesNotExist);
-			}
-		}
-
-		try {
-			const contractInstance = _.isUndefined(address) ? await c.deployed() : await c.at(address);
-			return contractInstance;
-		} catch (err) {
-			const errMsg = `${err}`;
-			utils.consoleLog(`Notice: Error encountered: ${err} ${err.stack}`);
-			if (_.includes(errMsg, 'not been deployed to detected network')) {
-				throw new Error(BlockchainCallErrs.ContractDoesNotExist);
-			} else {
-				await errorReporter.reportAsync(err);
-				throw new Error(BlockchainCallErrs.UnhandledError);
-			}
-		}
-	}
+    public networkId: number;
+    public nodeVersion: string;
+    private _zeroEx: ZeroEx;
+    private _dispatcher: Dispatcher;
+    private _web3Wrapper?: Web3Wrapper;
+    private _exchangeAddress: string;
+    private _userAddress: string;
+    private _cachedProvider: Web3.Provider;
+    private _ledgerSubprovider: LedgerWalletSubprovider;
+    private _zrxPollIntervalId: NodeJS.Timer;
+    private static async _onPageLoadAsync(): Promise<void> {
+        if (document.readyState === 'complete') {
+            return; // Already loaded
+        }
+        return new Promise<void>((resolve, reject) => {
+            window.onload = () => resolve();
+        });
+    }
+    private static _getNameGivenProvider(provider: Web3.Provider): string {
+        if (!_.isUndefined((provider as any).isMetaMask)) {
+            return constants.PROVIDER_NAME_METAMASK;
+        }
+
+        // HACK: We use the fact that Parity Signer's provider is an instance of their
+        // internal `Web3FrameProvider` class.
+        const isParitySigner = _.startsWith(provider.constructor.toString(), 'function Web3FrameProvider');
+        if (isParitySigner) {
+            return constants.PROVIDER_NAME_PARITY_SIGNER;
+        }
+
+        return constants.PROVIDER_NAME_GENERIC;
+    }
+    private static async _getProviderAsync(injectedWeb3: Web3, networkIdIfExists: number) {
+        const doesInjectedWeb3Exist = !_.isUndefined(injectedWeb3);
+        const publicNodeUrlsIfExistsForNetworkId = configs.PUBLIC_NODE_URLS_BY_NETWORK_ID[networkIdIfExists];
+        const isPublicNodeAvailableForNetworkId = !_.isUndefined(publicNodeUrlsIfExistsForNetworkId);
+
+        let provider;
+        if (doesInjectedWeb3Exist && isPublicNodeAvailableForNetworkId) {
+            // We catch all requests involving a users account and send it to the injectedWeb3
+            // instance. All other requests go to the public hosted node.
+            provider = new ProviderEngine();
+            provider.addProvider(new InjectedWeb3Subprovider(injectedWeb3));
+            provider.addProvider(new FilterSubprovider());
+            provider.addProvider(new RedundantRPCSubprovider(publicNodeUrlsIfExistsForNetworkId));
+            provider.start();
+        } else if (doesInjectedWeb3Exist) {
+            // Since no public node for this network, all requests go to injectedWeb3 instance
+            provider = injectedWeb3.currentProvider;
+        } else {
+            // If no injectedWeb3 instance, all requests fallback to our public hosted mainnet/testnet node
+            // We do this so that users can still browse the 0x Portal DApp even if they do not have web3
+            // injected into their browser.
+            provider = new ProviderEngine();
+            provider.addProvider(new FilterSubprovider());
+            const networkId = configs.IS_MAINNET_ENABLED ? constants.NETWORK_ID_MAINNET : constants.NETWORK_ID_TESTNET;
+            provider.addProvider(new RedundantRPCSubprovider(configs.PUBLIC_NODE_URLS_BY_NETWORK_ID[networkId]));
+            provider.start();
+        }
+
+        return provider;
+    }
+    constructor(dispatcher: Dispatcher, isSalePage: boolean = false) {
+        this._dispatcher = dispatcher;
+        this._userAddress = '';
+        // tslint:disable-next-line:no-floating-promises
+        this._onPageLoadInitFireAndForgetAsync();
+    }
+    public async networkIdUpdatedFireAndForgetAsync(newNetworkId: number) {
+        const isConnected = !_.isUndefined(newNetworkId);
+        if (!isConnected) {
+            this.networkId = newNetworkId;
+            this._dispatcher.encounteredBlockchainError(BlockchainErrs.DisconnectedFromEthereumNode);
+            this._dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
+        } else if (this.networkId !== newNetworkId) {
+            this.networkId = newNetworkId;
+            this._dispatcher.encounteredBlockchainError(BlockchainErrs.NoError);
+            await this._fetchTokenInformationAsync();
+            await this._rehydrateStoreWithContractEvents();
+        }
+    }
+    public async userAddressUpdatedFireAndForgetAsync(newUserAddress: string) {
+        if (this._userAddress !== newUserAddress) {
+            this._userAddress = newUserAddress;
+            await this._fetchTokenInformationAsync();
+            await this._rehydrateStoreWithContractEvents();
+        }
+    }
+    public async nodeVersionUpdatedFireAndForgetAsync(nodeVersion: string) {
+        if (this.nodeVersion !== nodeVersion) {
+            this.nodeVersion = nodeVersion;
+        }
+    }
+    public async isAddressInTokenRegistryAsync(tokenAddress: string): Promise<boolean> {
+        utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
+        // HACK: temporarily whitelist the new WETH token address `as if` they were
+        // already in the tokenRegistry.
+        // TODO: Remove this hack once we've updated the TokenRegistries
+        // Airtable task: https://airtable.com/tblFe0Q9JuKJPYbTn/viwsOG2Y97qdIeCIO/recv3VGmIorFzHBVz
+        if (configs.SHOULD_DEPRECATE_OLD_WETH_TOKEN && tokenAddress === configs.NEW_WRAPPED_ETHERS[this.networkId]) {
+            return true;
+        }
+        const tokenIfExists = await this._zeroEx.tokenRegistry.getTokenIfExistsAsync(tokenAddress);
+        return !_.isUndefined(tokenIfExists);
+    }
+    public getLedgerDerivationPathIfExists(): string {
+        if (_.isUndefined(this._ledgerSubprovider)) {
+            return undefined;
+        }
+        const path = this._ledgerSubprovider.getPath();
+        return path;
+    }
+    public updateLedgerDerivationPathIfExists(path: string) {
+        if (_.isUndefined(this._ledgerSubprovider)) {
+            return; // noop
+        }
+        this._ledgerSubprovider.setPath(path);
+    }
+    public updateLedgerDerivationIndex(pathIndex: number) {
+        if (_.isUndefined(this._ledgerSubprovider)) {
+            return; // noop
+        }
+        this._ledgerSubprovider.setPathIndex(pathIndex);
+    }
+    public async providerTypeUpdatedFireAndForgetAsync(providerType: ProviderType) {
+        utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
+        // Should actually be Web3.Provider|ProviderEngine union type but it causes issues
+        // later on in the logic.
+        let provider;
+        switch (providerType) {
+            case ProviderType.Ledger: {
+                const isU2FSupported = await utils.isU2FSupportedAsync();
+                if (!isU2FSupported) {
+                    throw new Error('Cannot update providerType to LEDGER without U2F support');
+                }
+
+                // Cache injected provider so that we can switch the user back to it easily
+                this._cachedProvider = this._web3Wrapper.getProviderObj();
+
+                this._dispatcher.updateUserAddress(''); // Clear old userAddress
+
+                provider = new ProviderEngine();
+                const ledgerWalletConfigs = {
+                    networkId: this.networkId,
+                    ledgerEthereumClientFactoryAsync: ledgerEthereumBrowserClientFactoryAsync,
+                };
+                this._ledgerSubprovider = new LedgerSubprovider(ledgerWalletConfigs);
+                provider.addProvider(this._ledgerSubprovider);
+                provider.addProvider(new FilterSubprovider());
+                const networkId = configs.IS_MAINNET_ENABLED
+                    ? constants.NETWORK_ID_MAINNET
+                    : constants.NETWORK_ID_TESTNET;
+                provider.addProvider(new RedundantRPCSubprovider(configs.PUBLIC_NODE_URLS_BY_NETWORK_ID[networkId]));
+                provider.start();
+                this._web3Wrapper.destroy();
+                const shouldPollUserAddress = false;
+                this._web3Wrapper = new Web3Wrapper(this._dispatcher, provider, this.networkId, shouldPollUserAddress);
+                this._zeroEx.setProvider(provider, networkId);
+                await this._postInstantiationOrUpdatingProviderZeroExAsync();
+                break;
+            }
+
+            case ProviderType.Injected: {
+                if (_.isUndefined(this._cachedProvider)) {
+                    return; // Going from injected to injected, so we noop
+                }
+                provider = this._cachedProvider;
+                const shouldPollUserAddress = true;
+                this._web3Wrapper = new Web3Wrapper(this._dispatcher, provider, this.networkId, shouldPollUserAddress);
+                this._zeroEx.setProvider(provider, this.networkId);
+                await this._postInstantiationOrUpdatingProviderZeroExAsync();
+                delete this._ledgerSubprovider;
+                delete this._cachedProvider;
+                break;
+            }
+
+            default:
+                throw utils.spawnSwitchErr('providerType', providerType);
+        }
+
+        await this._fetchTokenInformationAsync();
+    }
+    public async setProxyAllowanceAsync(token: Token, amountInBaseUnits: BigNumber): Promise<void> {
+        utils.assert(this.isValidAddress(token.address), BlockchainCallErrs.TokenAddressIsInvalid);
+        utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
+        utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
+
+        const txHash = await this._zeroEx.token.setProxyAllowanceAsync(
+            token.address,
+            this._userAddress,
+            amountInBaseUnits,
+        );
+        await this._showEtherScanLinkAndAwaitTransactionMinedAsync(txHash);
+        const allowance = amountInBaseUnits;
+        this._dispatcher.replaceTokenAllowanceByAddress(token.address, allowance);
+    }
+    public async transferAsync(token: Token, toAddress: string, amountInBaseUnits: BigNumber): Promise<void> {
+        const txHash = await this._zeroEx.token.transferAsync(
+            token.address,
+            this._userAddress,
+            toAddress,
+            amountInBaseUnits,
+        );
+        await this._showEtherScanLinkAndAwaitTransactionMinedAsync(txHash);
+        const etherScanLinkIfExists = utils.getEtherScanLinkIfExists(txHash, this.networkId, EtherscanLinkSuffixes.Tx);
+        this._dispatcher.showFlashMessage(
+            React.createElement(TokenSendCompleted, {
+                etherScanLinkIfExists,
+                token,
+                toAddress,
+                amountInBaseUnits,
+            }),
+        );
+    }
+    public portalOrderToSignedOrder(
+        maker: string,
+        taker: string,
+        makerTokenAddress: string,
+        takerTokenAddress: string,
+        makerTokenAmount: BigNumber,
+        takerTokenAmount: BigNumber,
+        makerFee: BigNumber,
+        takerFee: BigNumber,
+        expirationUnixTimestampSec: BigNumber,
+        feeRecipient: string,
+        signatureData: SignatureData,
+        salt: BigNumber,
+    ): SignedOrder {
+        const ecSignature = signatureData;
+        const exchangeContractAddress = this.getExchangeContractAddressIfExists();
+        const takerOrNullAddress = _.isEmpty(taker) ? constants.NULL_ADDRESS : taker;
+        const signedOrder = {
+            ecSignature,
+            exchangeContractAddress,
+            expirationUnixTimestampSec,
+            feeRecipient,
+            maker,
+            makerFee,
+            makerTokenAddress,
+            makerTokenAmount,
+            salt,
+            taker: takerOrNullAddress,
+            takerFee,
+            takerTokenAddress,
+            takerTokenAmount,
+        };
+        return signedOrder;
+    }
+    public async fillOrderAsync(signedOrder: SignedOrder, fillTakerTokenAmount: BigNumber): Promise<BigNumber> {
+        utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
+
+        const shouldThrowOnInsufficientBalanceOrAllowance = true;
+
+        const txHash = await this._zeroEx.exchange.fillOrderAsync(
+            signedOrder,
+            fillTakerTokenAmount,
+            shouldThrowOnInsufficientBalanceOrAllowance,
+            this._userAddress,
+        );
+        const receipt = await this._showEtherScanLinkAndAwaitTransactionMinedAsync(txHash);
+        const logs: Array<LogWithDecodedArgs<ExchangeContractEventArgs>> = receipt.logs as any;
+        this._zeroEx.exchange.throwLogErrorsAsErrors(logs);
+        const logFill = _.find(logs, { event: 'LogFill' });
+        const args = (logFill.args as any) as LogFillContractEventArgs;
+        const filledTakerTokenAmount = args.filledTakerTokenAmount;
+        return filledTakerTokenAmount;
+    }
+    public async cancelOrderAsync(signedOrder: SignedOrder, cancelTakerTokenAmount: BigNumber): Promise<BigNumber> {
+        const txHash = await this._zeroEx.exchange.cancelOrderAsync(signedOrder, cancelTakerTokenAmount);
+        const receipt = await this._showEtherScanLinkAndAwaitTransactionMinedAsync(txHash);
+        const logs: Array<LogWithDecodedArgs<ExchangeContractEventArgs>> = receipt.logs as any;
+        this._zeroEx.exchange.throwLogErrorsAsErrors(logs);
+        const logCancel = _.find(logs, { event: ExchangeEvents.LogCancel });
+        const args = (logCancel.args as any) as LogCancelContractEventArgs;
+        const cancelledTakerTokenAmount = args.cancelledTakerTokenAmount;
+        return cancelledTakerTokenAmount;
+    }
+    public async getUnavailableTakerAmountAsync(orderHash: string): Promise<BigNumber> {
+        utils.assert(ZeroEx.isValidOrderHash(orderHash), 'Must be valid orderHash');
+        utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
+        const unavailableTakerAmount = await this._zeroEx.exchange.getUnavailableTakerAmountAsync(orderHash);
+        return unavailableTakerAmount;
+    }
+    public getExchangeContractAddressIfExists() {
+        return this._exchangeAddress;
+    }
+    public async validateFillOrderThrowIfInvalidAsync(
+        signedOrder: SignedOrder,
+        fillTakerTokenAmount: BigNumber,
+        takerAddress: string,
+    ): Promise<void> {
+        await this._zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(
+            signedOrder,
+            fillTakerTokenAmount,
+            takerAddress,
+        );
+    }
+    public async validateCancelOrderThrowIfInvalidAsync(
+        order: Order,
+        cancelTakerTokenAmount: BigNumber,
+    ): Promise<void> {
+        await this._zeroEx.exchange.validateCancelOrderThrowIfInvalidAsync(order, cancelTakerTokenAmount);
+    }
+    public isValidAddress(address: string): boolean {
+        const lowercaseAddress = address.toLowerCase();
+        return this._web3Wrapper.isAddress(lowercaseAddress);
+    }
+    public async pollTokenBalanceAsync(token: Token) {
+        utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
+
+        const [currBalance] = await this.getTokenBalanceAndAllowanceAsync(this._userAddress, token.address);
+
+        this._zrxPollIntervalId = intervalUtils.setAsyncExcludingInterval(
+            async () => {
+                const [balance] = await this.getTokenBalanceAndAllowanceAsync(this._userAddress, token.address);
+                if (!balance.eq(currBalance)) {
+                    this._dispatcher.replaceTokenBalanceByAddress(token.address, balance);
+                    intervalUtils.clearAsyncExcludingInterval(this._zrxPollIntervalId);
+                    delete this._zrxPollIntervalId;
+                }
+            },
+            5000,
+            (err: Error) => {
+                utils.consoleLog(`Polling tokenBalance failed: ${err}`);
+                intervalUtils.clearAsyncExcludingInterval(this._zrxPollIntervalId);
+                delete this._zrxPollIntervalId;
+            },
+        );
+    }
+    public async signOrderHashAsync(orderHash: string): Promise<SignatureData> {
+        utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
+        const makerAddress = this._userAddress;
+        // If makerAddress is undefined, this means they have a web3 instance injected into their browser
+        // but no account addresses associated with it.
+        if (_.isUndefined(makerAddress)) {
+            throw new Error('Tried to send a sign request but user has no associated addresses');
+        }
+        const ecSignature = await this._zeroEx.signOrderHashAsync(orderHash, makerAddress);
+        const signatureData = _.extend({}, ecSignature, {
+            hash: orderHash,
+        });
+        this._dispatcher.updateSignatureData(signatureData);
+        return signatureData;
+    }
+    public async mintTestTokensAsync(token: Token) {
+        utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
+
+        const mintableContract = await this._instantiateContractIfExistsAsync(MintableArtifacts, token.address);
+        await mintableContract.mint(constants.MINT_AMOUNT, {
+            from: this._userAddress,
+        });
+        const balanceDelta = constants.MINT_AMOUNT;
+        this._dispatcher.updateTokenBalanceByAddress(token.address, balanceDelta);
+    }
+    public async getBalanceInEthAsync(owner: string): Promise<BigNumber> {
+        const balance = await this._web3Wrapper.getBalanceInEthAsync(owner);
+        return balance;
+    }
+    public async convertEthToWrappedEthTokensAsync(etherTokenAddress: string, amount: BigNumber): Promise<void> {
+        utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
+        utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
+
+        const txHash = await this._zeroEx.etherToken.depositAsync(etherTokenAddress, amount, this._userAddress);
+        await this._showEtherScanLinkAndAwaitTransactionMinedAsync(txHash);
+    }
+    public async convertWrappedEthTokensToEthAsync(etherTokenAddress: string, amount: BigNumber): Promise<void> {
+        utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
+        utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
+
+        const txHash = await this._zeroEx.etherToken.withdrawAsync(etherTokenAddress, amount, this._userAddress);
+        await this._showEtherScanLinkAndAwaitTransactionMinedAsync(txHash);
+    }
+    public async doesContractExistAtAddressAsync(address: string) {
+        const doesContractExist = await this._web3Wrapper.doesContractExistAtAddressAsync(address);
+        return doesContractExist;
+    }
+    public async getCurrentUserTokenBalanceAndAllowanceAsync(tokenAddress: string): Promise<BigNumber[]> {
+        const tokenBalanceAndAllowance = await this.getTokenBalanceAndAllowanceAsync(this._userAddress, tokenAddress);
+        return tokenBalanceAndAllowance;
+    }
+    public async getTokenBalanceAndAllowanceAsync(ownerAddress: string, tokenAddress: string): Promise<BigNumber[]> {
+        utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
+
+        if (_.isEmpty(ownerAddress)) {
+            const zero = new BigNumber(0);
+            return [zero, zero];
+        }
+        let balance = new BigNumber(0);
+        let allowance = new BigNumber(0);
+        if (this._doesUserAddressExist()) {
+            balance = await this._zeroEx.token.getBalanceAsync(tokenAddress, ownerAddress);
+            allowance = await this._zeroEx.token.getProxyAllowanceAsync(tokenAddress, ownerAddress);
+        }
+        return [balance, allowance];
+    }
+    public async updateTokenBalancesAndAllowancesAsync(tokens: Token[]) {
+        const tokenStateByAddress: TokenStateByAddress = {};
+        for (const token of tokens) {
+            let balance = new BigNumber(0);
+            let allowance = new BigNumber(0);
+            if (this._doesUserAddressExist()) {
+                [balance, allowance] = await this.getTokenBalanceAndAllowanceAsync(this._userAddress, token.address);
+            }
+            const tokenState = {
+                balance,
+                allowance,
+            };
+            tokenStateByAddress[token.address] = tokenState;
+        }
+        this._dispatcher.updateTokenStateByAddress(tokenStateByAddress);
+    }
+    public async getUserAccountsAsync() {
+        utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
+        const userAccountsIfExists = await this._zeroEx.getAvailableAddressesAsync();
+        return userAccountsIfExists;
+    }
+    // HACK: When a user is using a Ledger, we simply dispatch the selected userAddress, which
+    // by-passes the web3Wrapper logic for updating the prevUserAddress. We therefore need to
+    // manually update it. This should only be called by the LedgerConfigDialog.
+    public updateWeb3WrapperPrevUserAddress(newUserAddress: string) {
+        this._web3Wrapper.updatePrevUserAddress(newUserAddress);
+    }
+    public destroy() {
+        intervalUtils.clearAsyncExcludingInterval(this._zrxPollIntervalId);
+        this._web3Wrapper.destroy();
+        this._stopWatchingExchangeLogFillEvents();
+    }
+    private async _showEtherScanLinkAndAwaitTransactionMinedAsync(
+        txHash: string,
+    ): Promise<TransactionReceiptWithDecodedLogs> {
+        const etherScanLinkIfExists = utils.getEtherScanLinkIfExists(txHash, this.networkId, EtherscanLinkSuffixes.Tx);
+        this._dispatcher.showFlashMessage(
+            React.createElement(TransactionSubmitted, {
+                etherScanLinkIfExists,
+            }),
+        );
+        const receipt = await this._zeroEx.awaitTransactionMinedAsync(txHash);
+        return receipt;
+    }
+    private _doesUserAddressExist(): boolean {
+        return this._userAddress !== '';
+    }
+    private async _rehydrateStoreWithContractEvents() {
+        // Ensure we are only ever listening to one set of events
+        this._stopWatchingExchangeLogFillEvents();
+
+        if (!this._doesUserAddressExist()) {
+            return; // short-circuit
+        }
+
+        if (!_.isUndefined(this._zeroEx)) {
+            // Since we do not have an index on the `taker` address and want to show
+            // transactions where an account is either the `maker` or `taker`, we loop
+            // through all fill events, and filter/cache them client-side.
+            const filterIndexObj = {};
+            await this._startListeningForExchangeLogFillEventsAsync(filterIndexObj);
+        }
+    }
+    private async _startListeningForExchangeLogFillEventsAsync(indexFilterValues: IndexedFilterValues): Promise<void> {
+        utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
+        utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
+
+        // Fetch historical logs
+        await this._fetchHistoricalExchangeLogFillEventsAsync(indexFilterValues);
+
+        // Start a subscription for new logs
+        this._zeroEx.exchange.subscribe(
+            ExchangeEvents.LogFill,
+            indexFilterValues,
+            async (err: Error, decodedLogEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
+                if (err) {
+                    // Note: it's not entirely clear from the documentation which
+                    // errors will be thrown by `watch`. For now, let's log the error
+                    // to rollbar and stop watching when one occurs
+                    // tslint:disable-next-line:no-floating-promises
+                    errorReporter.reportAsync(err); // fire and forget
+                    return;
+                } else {
+                    const decodedLog = decodedLogEvent.log;
+                    if (!this._doesLogEventInvolveUser(decodedLog)) {
+                        return; // We aren't interested in the fill event
+                    }
+                    this._updateLatestFillsBlockIfNeeded(decodedLog.blockNumber);
+                    const fill = await this._convertDecodedLogToFillAsync(decodedLog);
+                    if (decodedLogEvent.isRemoved) {
+                        tradeHistoryStorage.removeFillFromUser(this._userAddress, this.networkId, fill);
+                    } else {
+                        tradeHistoryStorage.addFillToUser(this._userAddress, this.networkId, fill);
+                    }
+                }
+            },
+        );
+    }
+    private async _fetchHistoricalExchangeLogFillEventsAsync(indexFilterValues: IndexedFilterValues) {
+        const fromBlock = tradeHistoryStorage.getFillsLatestBlock(this._userAddress, this.networkId);
+        const blockRange: BlockRange = {
+            fromBlock,
+            toBlock: 'latest' as BlockParam,
+        };
+        const decodedLogs = await this._zeroEx.exchange.getLogsAsync<LogFillContractEventArgs>(
+            ExchangeEvents.LogFill,
+            blockRange,
+            indexFilterValues,
+        );
+        for (const decodedLog of decodedLogs) {
+            if (!this._doesLogEventInvolveUser(decodedLog)) {
+                continue; // We aren't interested in the fill event
+            }
+            this._updateLatestFillsBlockIfNeeded(decodedLog.blockNumber);
+            const fill = await this._convertDecodedLogToFillAsync(decodedLog);
+            tradeHistoryStorage.addFillToUser(this._userAddress, this.networkId, fill);
+        }
+    }
+    private async _convertDecodedLogToFillAsync(decodedLog: LogWithDecodedArgs<LogFillContractEventArgs>) {
+        const args = decodedLog.args;
+        const blockTimestamp = await this._web3Wrapper.getBlockTimestampAsync(decodedLog.blockHash);
+        const fill = {
+            filledTakerTokenAmount: args.filledTakerTokenAmount,
+            filledMakerTokenAmount: args.filledMakerTokenAmount,
+            logIndex: decodedLog.logIndex,
+            maker: args.maker,
+            orderHash: args.orderHash,
+            taker: args.taker,
+            makerToken: args.makerToken,
+            takerToken: args.takerToken,
+            paidMakerFee: args.paidMakerFee,
+            paidTakerFee: args.paidTakerFee,
+            transactionHash: decodedLog.transactionHash,
+            blockTimestamp,
+        };
+        return fill;
+    }
+    private _doesLogEventInvolveUser(decodedLog: LogWithDecodedArgs<LogFillContractEventArgs>) {
+        const args = decodedLog.args;
+        const isUserMakerOrTaker = args.maker === this._userAddress || args.taker === this._userAddress;
+        return isUserMakerOrTaker;
+    }
+    private _updateLatestFillsBlockIfNeeded(blockNumber: number) {
+        const isBlockPending = _.isNull(blockNumber);
+        if (!isBlockPending) {
+            // Hack: I've observed the behavior where a client won't register certain fill events
+            // and lowering the cache blockNumber fixes the issue. As a quick fix for now, simply
+            // set the cached blockNumber 50 below the one returned. This way, upon refreshing, a user
+            // would still attempt to re-fetch events from the previous 50 blocks, but won't need to
+            // re-fetch all events in all blocks.
+            // TODO: Debug if this is a race condition, and apply a more precise fix
+            const blockNumberToSet =
+                blockNumber - BLOCK_NUMBER_BACK_TRACK < 0 ? 0 : blockNumber - BLOCK_NUMBER_BACK_TRACK;
+            tradeHistoryStorage.setFillsLatestBlock(this._userAddress, this.networkId, blockNumberToSet);
+        }
+    }
+    private _stopWatchingExchangeLogFillEvents(): void {
+        this._zeroEx.exchange.unsubscribeAll();
+    }
+    private async _getTokenRegistryTokensByAddressAsync(): Promise<TokenByAddress> {
+        utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
+        const tokenRegistryTokens = await this._zeroEx.tokenRegistry.getTokensAsync();
+
+        const tokenByAddress: TokenByAddress = {};
+        _.each(tokenRegistryTokens, (t: ZeroExToken, i: number) => {
+            // HACK: For now we have a hard-coded list of iconUrls for the dummyTokens
+            // TODO: Refactor this out and pull the iconUrl directly from the TokenRegistry
+            const iconUrl = configs.ICON_URL_BY_SYMBOL[t.symbol];
+            // HACK: Temporarily we hijack the WETH addresses fetched from the tokenRegistry
+            // so that we can take our time with actually updating it. This ensures that when
+            // we deploy the new WETH page, everyone will re-fill their trackedTokens with the
+            // new canonical WETH.
+            // TODO: Remove this hack once we've updated the TokenRegistries
+            // Airtable task: https://airtable.com/tblFe0Q9JuKJPYbTn/viwsOG2Y97qdIeCIO/recv3VGmIorFzHBVz
+            let address = t.address;
+            if (configs.SHOULD_DEPRECATE_OLD_WETH_TOKEN && t.symbol === 'WETH') {
+                const newEtherTokenAddressIfExists = configs.NEW_WRAPPED_ETHERS[this.networkId];
+                if (!_.isUndefined(newEtherTokenAddressIfExists)) {
+                    address = newEtherTokenAddressIfExists;
+                }
+            }
+            const token: Token = {
+                iconUrl,
+                address,
+                name: t.name,
+                symbol: t.symbol,
+                decimals: t.decimals,
+                isTracked: false,
+                isRegistered: true,
+            };
+            tokenByAddress[token.address] = token;
+        });
+        return tokenByAddress;
+    }
+    private async _onPageLoadInitFireAndForgetAsync() {
+        await Blockchain._onPageLoadAsync(); // wait for page to load
+
+        // Hack: We need to know the networkId the injectedWeb3 is connected to (if it is defined) in
+        // order to properly instantiate the web3Wrapper. Since we must use the async call, we cannot
+        // retrieve it from within the web3Wrapper constructor. This is and should remain the only
+        // call to a web3 instance outside of web3Wrapper in the entire dapp.
+        // In addition, if the user has an injectedWeb3 instance that is disconnected from a backing
+        // Ethereum node, this call will throw. We need to handle this case gracefully
+        const injectedWeb3 = (window as any).web3;
+        let networkIdIfExists: number;
+        if (!_.isUndefined(injectedWeb3)) {
+            try {
+                networkIdIfExists = _.parseInt(await promisify<string>(injectedWeb3.version.getNetwork)());
+            } catch (err) {
+                // Ignore error and proceed with networkId undefined
+            }
+        }
+
+        const provider = await Blockchain._getProviderAsync(injectedWeb3, networkIdIfExists);
+        const networkId = !_.isUndefined(networkIdIfExists)
+            ? networkIdIfExists
+            : configs.IS_MAINNET_ENABLED ? constants.NETWORK_ID_MAINNET : constants.NETWORK_ID_TESTNET;
+        const zeroExConfigs = {
+            networkId,
+        };
+        this._zeroEx = new ZeroEx(provider, zeroExConfigs);
+        this._updateProviderName(injectedWeb3);
+        const shouldPollUserAddress = true;
+        this._web3Wrapper = new Web3Wrapper(this._dispatcher, provider, networkId, shouldPollUserAddress);
+        await this._postInstantiationOrUpdatingProviderZeroExAsync();
+    }
+    // This method should always be run after instantiating or updating the provider
+    // of the ZeroEx instance.
+    private async _postInstantiationOrUpdatingProviderZeroExAsync() {
+        utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
+        this._exchangeAddress = this._zeroEx.exchange.getContractAddress();
+    }
+    private _updateProviderName(injectedWeb3: Web3) {
+        const doesInjectedWeb3Exist = !_.isUndefined(injectedWeb3);
+        const providerName = doesInjectedWeb3Exist
+            ? Blockchain._getNameGivenProvider(injectedWeb3.currentProvider)
+            : constants.PROVIDER_NAME_PUBLIC;
+        this._dispatcher.updateInjectedProviderName(providerName);
+    }
+    private async _fetchTokenInformationAsync() {
+        utils.assert(
+            !_.isUndefined(this.networkId),
+            'Cannot call fetchTokenInformationAsync if disconnected from Ethereum node',
+        );
+
+        this._dispatcher.updateBlockchainIsLoaded(false);
+        this._dispatcher.clearTokenByAddress();
+
+        const tokenRegistryTokensByAddress = await this._getTokenRegistryTokensByAddressAsync();
+
+        // HACK: We need to fetch the userAddress here because otherwise we cannot save the
+        // tracked tokens in localStorage under the users address nor fetch the token
+        // balances and allowances and we need to do this in order not to trigger the blockchain
+        // loading dialog to show up twice. First to load the contracts, and second to load the
+        // balances and allowances.
+        this._userAddress = await this._web3Wrapper.getFirstAccountIfExistsAsync();
+        if (!_.isEmpty(this._userAddress)) {
+            this._dispatcher.updateUserAddress(this._userAddress);
+        }
+
+        let trackedTokensIfExists = trackedTokenStorage.getTrackedTokensIfExists(this._userAddress, this.networkId);
+        const tokenRegistryTokens = _.values(tokenRegistryTokensByAddress);
+        if (_.isUndefined(trackedTokensIfExists)) {
+            trackedTokensIfExists = _.map(configs.DEFAULT_TRACKED_TOKEN_SYMBOLS, symbol => {
+                const token = _.find(tokenRegistryTokens, t => t.symbol === symbol);
+                token.isTracked = true;
+                return token;
+            });
+            _.each(trackedTokensIfExists, token => {
+                trackedTokenStorage.addTrackedTokenToUser(this._userAddress, this.networkId, token);
+            });
+        } else {
+            // Properly set all tokenRegistry tokens `isTracked` to true if they are in the existing trackedTokens array
+            _.each(trackedTokensIfExists, trackedToken => {
+                if (!_.isUndefined(tokenRegistryTokensByAddress[trackedToken.address])) {
+                    tokenRegistryTokensByAddress[trackedToken.address].isTracked = true;
+                }
+            });
+        }
+        const allTokens = _.uniq([...tokenRegistryTokens, ...trackedTokensIfExists]);
+        this._dispatcher.updateTokenByAddress(allTokens);
+
+        // Get balance/allowance for tracked tokens
+        await this.updateTokenBalancesAndAllowancesAsync(trackedTokensIfExists);
+
+        const mostPopularTradingPairTokens: Token[] = [
+            _.find(allTokens, { symbol: configs.DEFAULT_TRACKED_TOKEN_SYMBOLS[0] }),
+            _.find(allTokens, { symbol: configs.DEFAULT_TRACKED_TOKEN_SYMBOLS[1] }),
+        ];
+        this._dispatcher.updateChosenAssetTokenAddress(Side.Deposit, mostPopularTradingPairTokens[0].address);
+        this._dispatcher.updateChosenAssetTokenAddress(Side.Receive, mostPopularTradingPairTokens[1].address);
+        this._dispatcher.updateBlockchainIsLoaded(true);
+    }
+    private async _instantiateContractIfExistsAsync(artifact: any, address?: string): Promise<ContractInstance> {
+        const c = await contract(artifact);
+        const providerObj = this._web3Wrapper.getProviderObj();
+        c.setProvider(providerObj);
+
+        const artifactNetworkConfigs = artifact.networks[this.networkId];
+        let contractAddress;
+        if (!_.isUndefined(address)) {
+            contractAddress = address;
+        } else if (!_.isUndefined(artifactNetworkConfigs)) {
+            contractAddress = artifactNetworkConfigs.address;
+        }
+
+        if (!_.isUndefined(contractAddress)) {
+            const doesContractExist = await this.doesContractExistAtAddressAsync(contractAddress);
+            if (!doesContractExist) {
+                utils.consoleLog(`Contract does not exist: ${artifact.contract_name} at ${contractAddress}`);
+                throw new Error(BlockchainCallErrs.ContractDoesNotExist);
+            }
+        }
+
+        try {
+            const contractInstance = _.isUndefined(address) ? await c.deployed() : await c.at(address);
+            return contractInstance;
+        } catch (err) {
+            const errMsg = `${err}`;
+            utils.consoleLog(`Notice: Error encountered: ${err} ${err.stack}`);
+            if (_.includes(errMsg, 'not been deployed to detected network')) {
+                throw new Error(BlockchainCallErrs.ContractDoesNotExist);
+            } else {
+                await errorReporter.reportAsync(err);
+                throw new Error(BlockchainCallErrs.UnhandledError);
+            }
+        }
+    }
 } // tslint:disable:max-file-line-count
diff --git a/packages/website/ts/components/dialogs/blockchain_err_dialog.tsx b/packages/website/ts/components/dialogs/blockchain_err_dialog.tsx
index e0f61a29b..f555ca6b1 100644
--- a/packages/website/ts/components/dialogs/blockchain_err_dialog.tsx
+++ b/packages/website/ts/components/dialogs/blockchain_err_dialog.tsx
@@ -9,150 +9,150 @@ import { configs } from 'ts/utils/configs';
 import { constants } from 'ts/utils/constants';
 
 interface BlockchainErrDialogProps {
-	blockchain: Blockchain;
-	blockchainErr: BlockchainErrs;
-	isOpen: boolean;
-	userAddress: string;
-	toggleDialogFn: (isOpen: boolean) => void;
-	networkId: number;
+    blockchain: Blockchain;
+    blockchainErr: BlockchainErrs;
+    isOpen: boolean;
+    userAddress: string;
+    toggleDialogFn: (isOpen: boolean) => void;
+    networkId: number;
 }
 
 export class BlockchainErrDialog extends React.Component<BlockchainErrDialogProps, undefined> {
-	public render() {
-		const dialogActions = [
-			<FlatButton
-				key="blockchainErrOk"
-				label="Ok"
-				primary={true}
-				onTouchTap={this.props.toggleDialogFn.bind(this.props.toggleDialogFn, false)}
-			/>,
-		];
+    public render() {
+        const dialogActions = [
+            <FlatButton
+                key="blockchainErrOk"
+                label="Ok"
+                primary={true}
+                onTouchTap={this.props.toggleDialogFn.bind(this.props.toggleDialogFn, false)}
+            />,
+        ];
 
-		const hasWalletAddress = this.props.userAddress !== '';
-		return (
-			<Dialog
-				title={this._getTitle(hasWalletAddress)}
-				titleStyle={{ fontWeight: 100 }}
-				actions={dialogActions}
-				open={this.props.isOpen}
-				contentStyle={{ width: 400 }}
-				onRequestClose={this.props.toggleDialogFn.bind(this.props.toggleDialogFn, false)}
-				autoScrollBodyContent={true}
-			>
-				<div className="pt2" style={{ color: colors.grey700 }}>
-					{this._renderExplanation(hasWalletAddress)}
-				</div>
-			</Dialog>
-		);
-	}
-	private _getTitle(hasWalletAddress: boolean) {
-		if (this.props.blockchainErr === BlockchainErrs.AContractNotDeployedOnNetwork) {
-			return '0x smart contracts not found';
-		} else if (!hasWalletAddress) {
-			return 'Enable wallet communication';
-		} else if (this.props.blockchainErr === BlockchainErrs.DisconnectedFromEthereumNode) {
-			return 'Disconnected from Ethereum network';
-		} else {
-			return 'Unexpected error';
-		}
-	}
-	private _renderExplanation(hasWalletAddress: boolean) {
-		if (this.props.blockchainErr === BlockchainErrs.AContractNotDeployedOnNetwork) {
-			return this._renderContractsNotDeployedExplanation();
-		} else if (!hasWalletAddress) {
-			return this._renderNoWalletFoundExplanation();
-		} else if (this.props.blockchainErr === BlockchainErrs.DisconnectedFromEthereumNode) {
-			return this._renderDisconnectedFromNode();
-		} else {
-			return this._renderUnexpectedErrorExplanation();
-		}
-	}
-	private _renderDisconnectedFromNode() {
-		return (
-			<div>
-				You were disconnected from the backing Ethereum node. If using{' '}
-				<a href={constants.URL_METAMASK_CHROME_STORE} target="_blank">
-					Metamask
-				</a>{' '}
-				or{' '}
-				<a href={constants.URL_MIST_DOWNLOAD} target="_blank">
-					Mist
-				</a>{' '}
-				try refreshing the page. If using a locally hosted Ethereum node, make sure it's still running.
-			</div>
-		);
-	}
-	private _renderUnexpectedErrorExplanation() {
-		return <div>We encountered an unexpected error. Please try refreshing the page.</div>;
-	}
-	private _renderNoWalletFoundExplanation() {
-		return (
-			<div>
-				<div>
-					We were unable to access an Ethereum wallet you control. In order to interact with the 0x portal
-					dApp, we need a way to interact with one of your Ethereum wallets. There are two easy ways you can
-					enable us to do that:
-				</div>
-				<h4>1. Metamask chrome extension</h4>
-				<div>
-					You can install the{' '}
-					<a href={constants.URL_METAMASK_CHROME_STORE} target="_blank">
-						Metamask
-					</a>{' '}
-					Chrome extension Ethereum wallet. Once installed and set up, refresh this page.
-					<div className="pt1">
-						<span className="bold">Note:</span> If you already have Metamask installed, make sure it is
-						unlocked.
-					</div>
-				</div>
-				<h4>Parity Signer</h4>
-				<div>
-					The{' '}
-					<a href={constants.URL_PARITY_CHROME_STORE} target="_blank">
-						Parity Signer Chrome extension
-					</a>{' '}
-					lets you connect to a locally running Parity node. Make sure you have started your local Parity node
-					with {configs.IS_MAINNET_ENABLED && '`parity ui` or'} `parity --chain kovan ui` in order to connect
-					to {configs.IS_MAINNET_ENABLED ? 'mainnet or Kovan respectively.' : 'Kovan.'}
-				</div>
-				<div className="pt2">
-					<span className="bold">Note:</span> If you have done one of the above steps and are still seeing
-					this message, we might still be unable to retrieve an Ethereum address by calling
-					`web3.eth.accounts`. Make sure you have created at least one Ethereum address.
-				</div>
-			</div>
-		);
-	}
-	private _renderContractsNotDeployedExplanation() {
-		return (
-			<div>
-				<div>
-					The 0x smart contracts are not deployed on the Ethereum network you are currently connected to
-					(network Id: {this.props.networkId}). In order to use the 0x portal dApp, please connect to the{' '}
-					{constants.TESTNET_NAME} testnet (network Id: {constants.NETWORK_ID_TESTNET})
-					{configs.IS_MAINNET_ENABLED
-						? ` or ${constants.MAINNET_NAME} (network Id: ${constants.NETWORK_ID_MAINNET}).`
-						: `.`}
-				</div>
-				<h4>Metamask</h4>
-				<div>
-					If you are using{' '}
-					<a href={constants.URL_METAMASK_CHROME_STORE} target="_blank">
-						Metamask
-					</a>, you can switch networks in the top left corner of the extension popover.
-				</div>
-				<h4>Parity Signer</h4>
-				<div>
-					If using the{' '}
-					<a href={constants.URL_PARITY_CHROME_STORE} target="_blank">
-						Parity Signer Chrome extension
-					</a>, make sure to start your local Parity node with{' '}
-					{configs.IS_MAINNET_ENABLED
-						? '`parity ui` or `parity --chain Kovan ui` in order to connect to mainnet \
+        const hasWalletAddress = this.props.userAddress !== '';
+        return (
+            <Dialog
+                title={this._getTitle(hasWalletAddress)}
+                titleStyle={{ fontWeight: 100 }}
+                actions={dialogActions}
+                open={this.props.isOpen}
+                contentStyle={{ width: 400 }}
+                onRequestClose={this.props.toggleDialogFn.bind(this.props.toggleDialogFn, false)}
+                autoScrollBodyContent={true}
+            >
+                <div className="pt2" style={{ color: colors.grey700 }}>
+                    {this._renderExplanation(hasWalletAddress)}
+                </div>
+            </Dialog>
+        );
+    }
+    private _getTitle(hasWalletAddress: boolean) {
+        if (this.props.blockchainErr === BlockchainErrs.AContractNotDeployedOnNetwork) {
+            return '0x smart contracts not found';
+        } else if (!hasWalletAddress) {
+            return 'Enable wallet communication';
+        } else if (this.props.blockchainErr === BlockchainErrs.DisconnectedFromEthereumNode) {
+            return 'Disconnected from Ethereum network';
+        } else {
+            return 'Unexpected error';
+        }
+    }
+    private _renderExplanation(hasWalletAddress: boolean) {
+        if (this.props.blockchainErr === BlockchainErrs.AContractNotDeployedOnNetwork) {
+            return this._renderContractsNotDeployedExplanation();
+        } else if (!hasWalletAddress) {
+            return this._renderNoWalletFoundExplanation();
+        } else if (this.props.blockchainErr === BlockchainErrs.DisconnectedFromEthereumNode) {
+            return this._renderDisconnectedFromNode();
+        } else {
+            return this._renderUnexpectedErrorExplanation();
+        }
+    }
+    private _renderDisconnectedFromNode() {
+        return (
+            <div>
+                You were disconnected from the backing Ethereum node. If using{' '}
+                <a href={constants.URL_METAMASK_CHROME_STORE} target="_blank">
+                    Metamask
+                </a>{' '}
+                or{' '}
+                <a href={constants.URL_MIST_DOWNLOAD} target="_blank">
+                    Mist
+                </a>{' '}
+                try refreshing the page. If using a locally hosted Ethereum node, make sure it's still running.
+            </div>
+        );
+    }
+    private _renderUnexpectedErrorExplanation() {
+        return <div>We encountered an unexpected error. Please try refreshing the page.</div>;
+    }
+    private _renderNoWalletFoundExplanation() {
+        return (
+            <div>
+                <div>
+                    We were unable to access an Ethereum wallet you control. In order to interact with the 0x portal
+                    dApp, we need a way to interact with one of your Ethereum wallets. There are two easy ways you can
+                    enable us to do that:
+                </div>
+                <h4>1. Metamask chrome extension</h4>
+                <div>
+                    You can install the{' '}
+                    <a href={constants.URL_METAMASK_CHROME_STORE} target="_blank">
+                        Metamask
+                    </a>{' '}
+                    Chrome extension Ethereum wallet. Once installed and set up, refresh this page.
+                    <div className="pt1">
+                        <span className="bold">Note:</span> If you already have Metamask installed, make sure it is
+                        unlocked.
+                    </div>
+                </div>
+                <h4>Parity Signer</h4>
+                <div>
+                    The{' '}
+                    <a href={constants.URL_PARITY_CHROME_STORE} target="_blank">
+                        Parity Signer Chrome extension
+                    </a>{' '}
+                    lets you connect to a locally running Parity node. Make sure you have started your local Parity node
+                    with {configs.IS_MAINNET_ENABLED && '`parity ui` or'} `parity --chain kovan ui` in order to connect
+                    to {configs.IS_MAINNET_ENABLED ? 'mainnet or Kovan respectively.' : 'Kovan.'}
+                </div>
+                <div className="pt2">
+                    <span className="bold">Note:</span> If you have done one of the above steps and are still seeing
+                    this message, we might still be unable to retrieve an Ethereum address by calling
+                    `web3.eth.accounts`. Make sure you have created at least one Ethereum address.
+                </div>
+            </div>
+        );
+    }
+    private _renderContractsNotDeployedExplanation() {
+        return (
+            <div>
+                <div>
+                    The 0x smart contracts are not deployed on the Ethereum network you are currently connected to
+                    (network Id: {this.props.networkId}). In order to use the 0x portal dApp, please connect to the{' '}
+                    {constants.TESTNET_NAME} testnet (network Id: {constants.NETWORK_ID_TESTNET})
+                    {configs.IS_MAINNET_ENABLED
+                        ? ` or ${constants.MAINNET_NAME} (network Id: ${constants.NETWORK_ID_MAINNET}).`
+                        : `.`}
+                </div>
+                <h4>Metamask</h4>
+                <div>
+                    If you are using{' '}
+                    <a href={constants.URL_METAMASK_CHROME_STORE} target="_blank">
+                        Metamask
+                    </a>, you can switch networks in the top left corner of the extension popover.
+                </div>
+                <h4>Parity Signer</h4>
+                <div>
+                    If using the{' '}
+                    <a href={constants.URL_PARITY_CHROME_STORE} target="_blank">
+                        Parity Signer Chrome extension
+                    </a>, make sure to start your local Parity node with{' '}
+                    {configs.IS_MAINNET_ENABLED
+                        ? '`parity ui` or `parity --chain Kovan ui` in order to connect to mainnet \
                          or Kovan respectively.'
-						: '`parity --chain kovan ui` in order to connect to Kovan.'}
-				</div>
-			</div>
-		);
-	}
+                        : '`parity --chain kovan ui` in order to connect to Kovan.'}
+                </div>
+            </div>
+        );
+    }
 }
diff --git a/packages/website/ts/components/dialogs/eth_weth_conversion_dialog.tsx b/packages/website/ts/components/dialogs/eth_weth_conversion_dialog.tsx
index 45ba5cc9e..661cc1d8c 100644
--- a/packages/website/ts/components/dialogs/eth_weth_conversion_dialog.tsx
+++ b/packages/website/ts/components/dialogs/eth_weth_conversion_dialog.tsx
@@ -8,156 +8,156 @@ import { Side, Token, TokenState } from 'ts/types';
 import { colors } from 'ts/utils/colors';
 
 interface EthWethConversionDialogProps {
-	direction: Side;
-	onComplete: (direction: Side, value: BigNumber) => void;
-	onCancelled: () => void;
-	isOpen: boolean;
-	token: Token;
-	tokenState: TokenState;
-	etherBalance: BigNumber;
+    direction: Side;
+    onComplete: (direction: Side, value: BigNumber) => void;
+    onCancelled: () => void;
+    isOpen: boolean;
+    token: Token;
+    tokenState: TokenState;
+    etherBalance: BigNumber;
 }
 
 interface EthWethConversionDialogState {
-	value?: BigNumber;
-	shouldShowIncompleteErrs: boolean;
-	hasErrors: boolean;
+    value?: BigNumber;
+    shouldShowIncompleteErrs: boolean;
+    hasErrors: boolean;
 }
 
 export class EthWethConversionDialog extends React.Component<
-	EthWethConversionDialogProps,
-	EthWethConversionDialogState
+    EthWethConversionDialogProps,
+    EthWethConversionDialogState
 > {
-	constructor() {
-		super();
-		this.state = {
-			shouldShowIncompleteErrs: false,
-			hasErrors: false,
-		};
-	}
-	public render() {
-		const convertDialogActions = [
-			<FlatButton key="cancel" label="Cancel" onTouchTap={this._onCancel.bind(this)} />,
-			<FlatButton key="convert" label="Convert" primary={true} onTouchTap={this._onConvertClick.bind(this)} />,
-		];
-		const title = this.props.direction === Side.Deposit ? 'Wrap ETH' : 'Unwrap WETH';
-		return (
-			<Dialog
-				title={title}
-				titleStyle={{ fontWeight: 100 }}
-				actions={convertDialogActions}
-				contentStyle={{ width: 448 }}
-				open={this.props.isOpen}
-			>
-				{this._renderConversionDialogBody()}
-			</Dialog>
-		);
-	}
-	private _renderConversionDialogBody() {
-		const explanation =
-			this.props.direction === Side.Deposit
-				? 'Convert your Ether into a tokenized, tradable form.'
-				: "Convert your Wrapped Ether back into it's native form.";
-		const isWrappedVersion = this.props.direction === Side.Receive;
-		return (
-			<div>
-				<div className="pb2">{explanation}</div>
-				<div className="mx-auto" style={{ maxWidth: 312 }}>
-					<div className="flex">
-						{this._renderCurrency(isWrappedVersion)}
-						<div style={{ paddingTop: 68 }}>
-							<i style={{ fontSize: 28, color: colors.darkBlue }} className="zmdi zmdi-arrow-right" />
-						</div>
-						{this._renderCurrency(!isWrappedVersion)}
-					</div>
-					<div className="pt2 mx-auto" style={{ width: 245 }}>
-						{this.props.direction === Side.Receive ? (
-							<TokenAmountInput
-								token={this.props.token}
-								tokenState={this.props.tokenState}
-								shouldShowIncompleteErrs={this.state.shouldShowIncompleteErrs}
-								shouldCheckBalance={true}
-								shouldCheckAllowance={false}
-								onChange={this._onValueChange.bind(this)}
-								amount={this.state.value}
-								onVisitBalancesPageClick={this.props.onCancelled}
-							/>
-						) : (
-							<EthAmountInput
-								balance={this.props.etherBalance}
-								amount={this.state.value}
-								onChange={this._onValueChange.bind(this)}
-								shouldCheckBalance={true}
-								shouldShowIncompleteErrs={this.state.shouldShowIncompleteErrs}
-								onVisitBalancesPageClick={this.props.onCancelled}
-							/>
-						)}
-						<div className="pt1" style={{ fontSize: 12 }}>
-							<div className="left">1 ETH = 1 WETH</div>
-							{this.props.direction === Side.Receive && (
-								<div
-									className="right"
-									onClick={this._onMaxClick.bind(this)}
-									style={{
-										color: colors.darkBlue,
-										textDecoration: 'underline',
-										cursor: 'pointer',
-									}}
-								>
-									Max
-								</div>
-							)}
-						</div>
-					</div>
-				</div>
-			</div>
-		);
-	}
-	private _renderCurrency(isWrappedVersion: boolean) {
-		const name = isWrappedVersion ? 'Wrapped Ether' : 'Ether';
-		const iconUrl = isWrappedVersion ? '/images/token_icons/ether_erc20.png' : '/images/ether.png';
-		const symbol = isWrappedVersion ? 'WETH' : 'ETH';
-		return (
-			<div className="mx-auto pt2">
-				<div className="center" style={{ color: colors.darkBlue }}>
-					{name}
-				</div>
-				<div className="center py2">
-					<img src={iconUrl} style={{ width: 60 }} />
-				</div>
-				<div className="center" style={{ fontSize: 12 }}>
-					({symbol})
-				</div>
-			</div>
-		);
-	}
-	private _onMaxClick() {
-		this.setState({
-			value: this.props.tokenState.balance,
-		});
-	}
-	private _onValueChange(isValid: boolean, amount?: BigNumber) {
-		this.setState({
-			value: amount,
-			hasErrors: !isValid,
-		});
-	}
-	private _onConvertClick() {
-		if (this.state.hasErrors) {
-			this.setState({
-				shouldShowIncompleteErrs: true,
-			});
-		} else {
-			const value = this.state.value;
-			this.setState({
-				value: undefined,
-			});
-			this.props.onComplete(this.props.direction, value);
-		}
-	}
-	private _onCancel() {
-		this.setState({
-			value: undefined,
-		});
-		this.props.onCancelled();
-	}
+    constructor() {
+        super();
+        this.state = {
+            shouldShowIncompleteErrs: false,
+            hasErrors: false,
+        };
+    }
+    public render() {
+        const convertDialogActions = [
+            <FlatButton key="cancel" label="Cancel" onTouchTap={this._onCancel.bind(this)} />,
+            <FlatButton key="convert" label="Convert" primary={true} onTouchTap={this._onConvertClick.bind(this)} />,
+        ];
+        const title = this.props.direction === Side.Deposit ? 'Wrap ETH' : 'Unwrap WETH';
+        return (
+            <Dialog
+                title={title}
+                titleStyle={{ fontWeight: 100 }}
+                actions={convertDialogActions}
+                contentStyle={{ width: 448 }}
+                open={this.props.isOpen}
+            >
+                {this._renderConversionDialogBody()}
+            </Dialog>
+        );
+    }
+    private _renderConversionDialogBody() {
+        const explanation =
+            this.props.direction === Side.Deposit
+                ? 'Convert your Ether into a tokenized, tradable form.'
+                : "Convert your Wrapped Ether back into it's native form.";
+        const isWrappedVersion = this.props.direction === Side.Receive;
+        return (
+            <div>
+                <div className="pb2">{explanation}</div>
+                <div className="mx-auto" style={{ maxWidth: 312 }}>
+                    <div className="flex">
+                        {this._renderCurrency(isWrappedVersion)}
+                        <div style={{ paddingTop: 68 }}>
+                            <i style={{ fontSize: 28, color: colors.darkBlue }} className="zmdi zmdi-arrow-right" />
+                        </div>
+                        {this._renderCurrency(!isWrappedVersion)}
+                    </div>
+                    <div className="pt2 mx-auto" style={{ width: 245 }}>
+                        {this.props.direction === Side.Receive ? (
+                            <TokenAmountInput
+                                token={this.props.token}
+                                tokenState={this.props.tokenState}
+                                shouldShowIncompleteErrs={this.state.shouldShowIncompleteErrs}
+                                shouldCheckBalance={true}
+                                shouldCheckAllowance={false}
+                                onChange={this._onValueChange.bind(this)}
+                                amount={this.state.value}
+                                onVisitBalancesPageClick={this.props.onCancelled}
+                            />
+                        ) : (
+                            <EthAmountInput
+                                balance={this.props.etherBalance}
+                                amount={this.state.value}
+                                onChange={this._onValueChange.bind(this)}
+                                shouldCheckBalance={true}
+                                shouldShowIncompleteErrs={this.state.shouldShowIncompleteErrs}
+                                onVisitBalancesPageClick={this.props.onCancelled}
+                            />
+                        )}
+                        <div className="pt1" style={{ fontSize: 12 }}>
+                            <div className="left">1 ETH = 1 WETH</div>
+                            {this.props.direction === Side.Receive && (
+                                <div
+                                    className="right"
+                                    onClick={this._onMaxClick.bind(this)}
+                                    style={{
+                                        color: colors.darkBlue,
+                                        textDecoration: 'underline',
+                                        cursor: 'pointer',
+                                    }}
+                                >
+                                    Max
+                                </div>
+                            )}
+                        </div>
+                    </div>
+                </div>
+            </div>
+        );
+    }
+    private _renderCurrency(isWrappedVersion: boolean) {
+        const name = isWrappedVersion ? 'Wrapped Ether' : 'Ether';
+        const iconUrl = isWrappedVersion ? '/images/token_icons/ether_erc20.png' : '/images/ether.png';
+        const symbol = isWrappedVersion ? 'WETH' : 'ETH';
+        return (
+            <div className="mx-auto pt2">
+                <div className="center" style={{ color: colors.darkBlue }}>
+                    {name}
+                </div>
+                <div className="center py2">
+                    <img src={iconUrl} style={{ width: 60 }} />
+                </div>
+                <div className="center" style={{ fontSize: 12 }}>
+                    ({symbol})
+                </div>
+            </div>
+        );
+    }
+    private _onMaxClick() {
+        this.setState({
+            value: this.props.tokenState.balance,
+        });
+    }
+    private _onValueChange(isValid: boolean, amount?: BigNumber) {
+        this.setState({
+            value: amount,
+            hasErrors: !isValid,
+        });
+    }
+    private _onConvertClick() {
+        if (this.state.hasErrors) {
+            this.setState({
+                shouldShowIncompleteErrs: true,
+            });
+        } else {
+            const value = this.state.value;
+            this.setState({
+                value: undefined,
+            });
+            this.props.onComplete(this.props.direction, value);
+        }
+    }
+    private _onCancel() {
+        this.setState({
+            value: undefined,
+        });
+        this.props.onCancelled();
+    }
 }
diff --git a/packages/website/ts/components/dialogs/ledger_config_dialog.tsx b/packages/website/ts/components/dialogs/ledger_config_dialog.tsx
index 8b7760a1a..60db93c52 100644
--- a/packages/website/ts/components/dialogs/ledger_config_dialog.tsx
+++ b/packages/website/ts/components/dialogs/ledger_config_dialog.tsx
@@ -17,245 +17,245 @@ import { utils } from 'ts/utils/utils';
 const VALID_ETHEREUM_DERIVATION_PATH_PREFIX = `44'/60'`;
 
 enum LedgerSteps {
-	CONNECT,
-	SELECT_ADDRESS,
+    CONNECT,
+    SELECT_ADDRESS,
 }
 
 interface LedgerConfigDialogProps {
-	isOpen: boolean;
-	toggleDialogFn: (isOpen: boolean) => void;
-	dispatcher: Dispatcher;
-	blockchain: Blockchain;
-	networkId: number;
+    isOpen: boolean;
+    toggleDialogFn: (isOpen: boolean) => void;
+    dispatcher: Dispatcher;
+    blockchain: Blockchain;
+    networkId: number;
 }
 
 interface LedgerConfigDialogState {
-	didConnectFail: boolean;
-	stepIndex: LedgerSteps;
-	userAddresses: string[];
-	addressBalances: BigNumber[];
-	derivationPath: string;
-	derivationErrMsg: string;
+    didConnectFail: boolean;
+    stepIndex: LedgerSteps;
+    userAddresses: string[];
+    addressBalances: BigNumber[];
+    derivationPath: string;
+    derivationErrMsg: string;
 }
 
 export class LedgerConfigDialog extends React.Component<LedgerConfigDialogProps, LedgerConfigDialogState> {
-	constructor(props: LedgerConfigDialogProps) {
-		super(props);
-		this.state = {
-			didConnectFail: false,
-			stepIndex: LedgerSteps.CONNECT,
-			userAddresses: [],
-			addressBalances: [],
-			derivationPath: configs.DEFAULT_DERIVATION_PATH,
-			derivationErrMsg: '',
-		};
-	}
-	public render() {
-		const dialogActions = [
-			<FlatButton key="ledgerConnectCancel" label="Cancel" onTouchTap={this._onClose.bind(this)} />,
-		];
-		const dialogTitle =
-			this.state.stepIndex === LedgerSteps.CONNECT ? 'Connect to your Ledger' : 'Select desired address';
-		return (
-			<Dialog
-				title={dialogTitle}
-				titleStyle={{ fontWeight: 100 }}
-				actions={dialogActions}
-				open={this.props.isOpen}
-				onRequestClose={this._onClose.bind(this)}
-				autoScrollBodyContent={true}
-				bodyStyle={{ paddingBottom: 0 }}
-			>
-				<div style={{ color: colors.grey700, paddingTop: 1 }}>
-					{this.state.stepIndex === LedgerSteps.CONNECT && this._renderConnectStep()}
-					{this.state.stepIndex === LedgerSteps.SELECT_ADDRESS && this._renderSelectAddressStep()}
-				</div>
-			</Dialog>
-		);
-	}
-	private _renderConnectStep() {
-		return (
-			<div>
-				<div className="h4 pt3">Follow these instructions before proceeding:</div>
-				<ol>
-					<li className="pb1">Connect your Ledger Nano S & Open the Ethereum application</li>
-					<li className="pb1">Verify that Browser Support is enabled in Settings</li>
-					<li className="pb1">
-						If no Browser Support is found in settings, verify that you have{' '}
-						<a href="https://www.ledgerwallet.com/apps/manager" target="_blank">
-							Firmware >1.2
-						</a>
-					</li>
-				</ol>
-				<div className="center pb3">
-					<LifeCycleRaisedButton
-						isPrimary={true}
-						labelReady="Connect to Ledger"
-						labelLoading="Connecting..."
-						labelComplete="Connected!"
-						onClickAsyncFn={this._onConnectLedgerClickAsync.bind(this, true)}
-					/>
-					{this.state.didConnectFail && (
-						<div className="pt2 left-align" style={{ color: colors.red200 }}>
-							Failed to connect. Follow the instructions and try again.
-						</div>
-					)}
-				</div>
-			</div>
-		);
-	}
-	private _renderSelectAddressStep() {
-		return (
-			<div>
-				<div>
-					<Table bodyStyle={{ height: 300 }} onRowSelection={this._onAddressSelected.bind(this)}>
-						<TableHeader displaySelectAll={false}>
-							<TableRow>
-								<TableHeaderColumn colSpan={2}>Address</TableHeaderColumn>
-								<TableHeaderColumn>Balance</TableHeaderColumn>
-							</TableRow>
-						</TableHeader>
-						<TableBody>{this._renderAddressTableRows()}</TableBody>
-					</Table>
-				</div>
-				<div className="flex pt2" style={{ height: 100 }}>
-					<div className="overflow-hidden" style={{ width: 180 }}>
-						<TextField
-							floatingLabelFixed={true}
-							floatingLabelStyle={{ color: colors.grey }}
-							floatingLabelText="Update path derivation (advanced)"
-							value={this.state.derivationPath}
-							errorText={this.state.derivationErrMsg}
-							onChange={this._onDerivationPathChanged.bind(this)}
-						/>
-					</div>
-					<div className="pl2" style={{ paddingTop: 28 }}>
-						<LifeCycleRaisedButton
-							labelReady="Update"
-							labelLoading="Updating..."
-							labelComplete="Updated!"
-							onClickAsyncFn={this._onFetchAddressesForDerivationPathAsync.bind(this)}
-						/>
-					</div>
-				</div>
-			</div>
-		);
-	}
-	private _renderAddressTableRows() {
-		const rows = _.map(this.state.userAddresses, (userAddress: string, i: number) => {
-			const balance = this.state.addressBalances[i];
-			const addressTooltipId = `address-${userAddress}`;
-			const balanceTooltipId = `balance-${userAddress}`;
-			const networkName = constants.NETWORK_NAME_BY_ID[this.props.networkId];
-			// We specifically prefix kovan ETH.
-			// TODO: We should probably add prefixes for all networks
-			const isKovanNetwork = networkName === 'Kovan';
-			const balanceString = `${balance.toString()} ${isKovanNetwork ? 'Kovan ' : ''}ETH`;
-			return (
-				<TableRow key={userAddress} style={{ height: 40 }}>
-					<TableRowColumn colSpan={2}>
-						<div data-tip={true} data-for={addressTooltipId}>
-							{userAddress}
-						</div>
-						<ReactTooltip id={addressTooltipId}>{userAddress}</ReactTooltip>
-					</TableRowColumn>
-					<TableRowColumn>
-						<div data-tip={true} data-for={balanceTooltipId}>
-							{balanceString}
-						</div>
-						<ReactTooltip id={balanceTooltipId}>{balanceString}</ReactTooltip>
-					</TableRowColumn>
-				</TableRow>
-			);
-		});
-		return rows;
-	}
-	private _onClose() {
-		this.setState({
-			didConnectFail: false,
-		});
-		const isOpen = false;
-		this.props.toggleDialogFn(isOpen);
-	}
-	private _onAddressSelected(selectedRowIndexes: number[]) {
-		const selectedRowIndex = selectedRowIndexes[0];
-		this.props.blockchain.updateLedgerDerivationIndex(selectedRowIndex);
-		const selectedAddress = this.state.userAddresses[selectedRowIndex];
-		const selectAddressBalance = this.state.addressBalances[selectedRowIndex];
-		this.props.dispatcher.updateUserAddress(selectedAddress);
-		this.props.blockchain.updateWeb3WrapperPrevUserAddress(selectedAddress);
-		this.props.dispatcher.updateUserEtherBalance(selectAddressBalance);
-		this.setState({
-			stepIndex: LedgerSteps.CONNECT,
-		});
-		const isOpen = false;
-		this.props.toggleDialogFn(isOpen);
-	}
-	private async _onFetchAddressesForDerivationPathAsync(): Promise<boolean> {
-		const currentlySetPath = this.props.blockchain.getLedgerDerivationPathIfExists();
-		let didSucceed;
-		if (currentlySetPath === this.state.derivationPath) {
-			didSucceed = true;
-			return didSucceed;
-		}
-		this.props.blockchain.updateLedgerDerivationPathIfExists(this.state.derivationPath);
-		didSucceed = await this._fetchAddressesAndBalancesAsync();
-		if (!didSucceed) {
-			this.setState({
-				derivationErrMsg: 'Failed to connect to Ledger.',
-			});
-		}
-		return didSucceed;
-	}
-	private async _fetchAddressesAndBalancesAsync() {
-		let userAddresses: string[];
-		const addressBalances: BigNumber[] = [];
-		try {
-			userAddresses = await this._getUserAddressesAsync();
-			for (const address of userAddresses) {
-				const balance = await this.props.blockchain.getBalanceInEthAsync(address);
-				addressBalances.push(balance);
-			}
-		} catch (err) {
-			utils.consoleLog(`Ledger error: ${JSON.stringify(err)}`);
-			this.setState({
-				didConnectFail: true,
-			});
-			return false;
-		}
-		this.setState({
-			userAddresses,
-			addressBalances,
-		});
-		return true;
-	}
-	private _onDerivationPathChanged(e: any, derivationPath: string) {
-		let derivationErrMsg = '';
-		if (!_.startsWith(derivationPath, VALID_ETHEREUM_DERIVATION_PATH_PREFIX)) {
-			derivationErrMsg = 'Must be valid Ethereum path.';
-		}
+    constructor(props: LedgerConfigDialogProps) {
+        super(props);
+        this.state = {
+            didConnectFail: false,
+            stepIndex: LedgerSteps.CONNECT,
+            userAddresses: [],
+            addressBalances: [],
+            derivationPath: configs.DEFAULT_DERIVATION_PATH,
+            derivationErrMsg: '',
+        };
+    }
+    public render() {
+        const dialogActions = [
+            <FlatButton key="ledgerConnectCancel" label="Cancel" onTouchTap={this._onClose.bind(this)} />,
+        ];
+        const dialogTitle =
+            this.state.stepIndex === LedgerSteps.CONNECT ? 'Connect to your Ledger' : 'Select desired address';
+        return (
+            <Dialog
+                title={dialogTitle}
+                titleStyle={{ fontWeight: 100 }}
+                actions={dialogActions}
+                open={this.props.isOpen}
+                onRequestClose={this._onClose.bind(this)}
+                autoScrollBodyContent={true}
+                bodyStyle={{ paddingBottom: 0 }}
+            >
+                <div style={{ color: colors.grey700, paddingTop: 1 }}>
+                    {this.state.stepIndex === LedgerSteps.CONNECT && this._renderConnectStep()}
+                    {this.state.stepIndex === LedgerSteps.SELECT_ADDRESS && this._renderSelectAddressStep()}
+                </div>
+            </Dialog>
+        );
+    }
+    private _renderConnectStep() {
+        return (
+            <div>
+                <div className="h4 pt3">Follow these instructions before proceeding:</div>
+                <ol>
+                    <li className="pb1">Connect your Ledger Nano S & Open the Ethereum application</li>
+                    <li className="pb1">Verify that Browser Support is enabled in Settings</li>
+                    <li className="pb1">
+                        If no Browser Support is found in settings, verify that you have{' '}
+                        <a href="https://www.ledgerwallet.com/apps/manager" target="_blank">
+                            Firmware >1.2
+                        </a>
+                    </li>
+                </ol>
+                <div className="center pb3">
+                    <LifeCycleRaisedButton
+                        isPrimary={true}
+                        labelReady="Connect to Ledger"
+                        labelLoading="Connecting..."
+                        labelComplete="Connected!"
+                        onClickAsyncFn={this._onConnectLedgerClickAsync.bind(this, true)}
+                    />
+                    {this.state.didConnectFail && (
+                        <div className="pt2 left-align" style={{ color: colors.red200 }}>
+                            Failed to connect. Follow the instructions and try again.
+                        </div>
+                    )}
+                </div>
+            </div>
+        );
+    }
+    private _renderSelectAddressStep() {
+        return (
+            <div>
+                <div>
+                    <Table bodyStyle={{ height: 300 }} onRowSelection={this._onAddressSelected.bind(this)}>
+                        <TableHeader displaySelectAll={false}>
+                            <TableRow>
+                                <TableHeaderColumn colSpan={2}>Address</TableHeaderColumn>
+                                <TableHeaderColumn>Balance</TableHeaderColumn>
+                            </TableRow>
+                        </TableHeader>
+                        <TableBody>{this._renderAddressTableRows()}</TableBody>
+                    </Table>
+                </div>
+                <div className="flex pt2" style={{ height: 100 }}>
+                    <div className="overflow-hidden" style={{ width: 180 }}>
+                        <TextField
+                            floatingLabelFixed={true}
+                            floatingLabelStyle={{ color: colors.grey }}
+                            floatingLabelText="Update path derivation (advanced)"
+                            value={this.state.derivationPath}
+                            errorText={this.state.derivationErrMsg}
+                            onChange={this._onDerivationPathChanged.bind(this)}
+                        />
+                    </div>
+                    <div className="pl2" style={{ paddingTop: 28 }}>
+                        <LifeCycleRaisedButton
+                            labelReady="Update"
+                            labelLoading="Updating..."
+                            labelComplete="Updated!"
+                            onClickAsyncFn={this._onFetchAddressesForDerivationPathAsync.bind(this)}
+                        />
+                    </div>
+                </div>
+            </div>
+        );
+    }
+    private _renderAddressTableRows() {
+        const rows = _.map(this.state.userAddresses, (userAddress: string, i: number) => {
+            const balance = this.state.addressBalances[i];
+            const addressTooltipId = `address-${userAddress}`;
+            const balanceTooltipId = `balance-${userAddress}`;
+            const networkName = constants.NETWORK_NAME_BY_ID[this.props.networkId];
+            // We specifically prefix kovan ETH.
+            // TODO: We should probably add prefixes for all networks
+            const isKovanNetwork = networkName === 'Kovan';
+            const balanceString = `${balance.toString()} ${isKovanNetwork ? 'Kovan ' : ''}ETH`;
+            return (
+                <TableRow key={userAddress} style={{ height: 40 }}>
+                    <TableRowColumn colSpan={2}>
+                        <div data-tip={true} data-for={addressTooltipId}>
+                            {userAddress}
+                        </div>
+                        <ReactTooltip id={addressTooltipId}>{userAddress}</ReactTooltip>
+                    </TableRowColumn>
+                    <TableRowColumn>
+                        <div data-tip={true} data-for={balanceTooltipId}>
+                            {balanceString}
+                        </div>
+                        <ReactTooltip id={balanceTooltipId}>{balanceString}</ReactTooltip>
+                    </TableRowColumn>
+                </TableRow>
+            );
+        });
+        return rows;
+    }
+    private _onClose() {
+        this.setState({
+            didConnectFail: false,
+        });
+        const isOpen = false;
+        this.props.toggleDialogFn(isOpen);
+    }
+    private _onAddressSelected(selectedRowIndexes: number[]) {
+        const selectedRowIndex = selectedRowIndexes[0];
+        this.props.blockchain.updateLedgerDerivationIndex(selectedRowIndex);
+        const selectedAddress = this.state.userAddresses[selectedRowIndex];
+        const selectAddressBalance = this.state.addressBalances[selectedRowIndex];
+        this.props.dispatcher.updateUserAddress(selectedAddress);
+        this.props.blockchain.updateWeb3WrapperPrevUserAddress(selectedAddress);
+        this.props.dispatcher.updateUserEtherBalance(selectAddressBalance);
+        this.setState({
+            stepIndex: LedgerSteps.CONNECT,
+        });
+        const isOpen = false;
+        this.props.toggleDialogFn(isOpen);
+    }
+    private async _onFetchAddressesForDerivationPathAsync(): Promise<boolean> {
+        const currentlySetPath = this.props.blockchain.getLedgerDerivationPathIfExists();
+        let didSucceed;
+        if (currentlySetPath === this.state.derivationPath) {
+            didSucceed = true;
+            return didSucceed;
+        }
+        this.props.blockchain.updateLedgerDerivationPathIfExists(this.state.derivationPath);
+        didSucceed = await this._fetchAddressesAndBalancesAsync();
+        if (!didSucceed) {
+            this.setState({
+                derivationErrMsg: 'Failed to connect to Ledger.',
+            });
+        }
+        return didSucceed;
+    }
+    private async _fetchAddressesAndBalancesAsync() {
+        let userAddresses: string[];
+        const addressBalances: BigNumber[] = [];
+        try {
+            userAddresses = await this._getUserAddressesAsync();
+            for (const address of userAddresses) {
+                const balance = await this.props.blockchain.getBalanceInEthAsync(address);
+                addressBalances.push(balance);
+            }
+        } catch (err) {
+            utils.consoleLog(`Ledger error: ${JSON.stringify(err)}`);
+            this.setState({
+                didConnectFail: true,
+            });
+            return false;
+        }
+        this.setState({
+            userAddresses,
+            addressBalances,
+        });
+        return true;
+    }
+    private _onDerivationPathChanged(e: any, derivationPath: string) {
+        let derivationErrMsg = '';
+        if (!_.startsWith(derivationPath, VALID_ETHEREUM_DERIVATION_PATH_PREFIX)) {
+            derivationErrMsg = 'Must be valid Ethereum path.';
+        }
 
-		this.setState({
-			derivationPath,
-			derivationErrMsg,
-		});
-	}
-	private async _onConnectLedgerClickAsync() {
-		const didSucceed = await this._fetchAddressesAndBalancesAsync();
-		if (didSucceed) {
-			this.setState({
-				stepIndex: LedgerSteps.SELECT_ADDRESS,
-			});
-		}
-		return didSucceed;
-	}
-	private async _getUserAddressesAsync(): Promise<string[]> {
-		let userAddresses: string[];
-		userAddresses = await this.props.blockchain.getUserAccountsAsync();
+        this.setState({
+            derivationPath,
+            derivationErrMsg,
+        });
+    }
+    private async _onConnectLedgerClickAsync() {
+        const didSucceed = await this._fetchAddressesAndBalancesAsync();
+        if (didSucceed) {
+            this.setState({
+                stepIndex: LedgerSteps.SELECT_ADDRESS,
+            });
+        }
+        return didSucceed;
+    }
+    private async _getUserAddressesAsync(): Promise<string[]> {
+        let userAddresses: string[];
+        userAddresses = await this.props.blockchain.getUserAccountsAsync();
 
-		if (_.isEmpty(userAddresses)) {
-			throw new Error('No addresses retrieved.');
-		}
-		return userAddresses;
-	}
+        if (_.isEmpty(userAddresses)) {
+            throw new Error('No addresses retrieved.');
+        }
+        return userAddresses;
+    }
 }
diff --git a/packages/website/ts/components/dialogs/portal_disclaimer_dialog.tsx b/packages/website/ts/components/dialogs/portal_disclaimer_dialog.tsx
index 1c5efc978..3ecc454a0 100644
--- a/packages/website/ts/components/dialogs/portal_disclaimer_dialog.tsx
+++ b/packages/website/ts/components/dialogs/portal_disclaimer_dialog.tsx
@@ -4,33 +4,33 @@ import * as React from 'react';
 import { colors } from 'ts/utils/colors';
 
 interface PortalDisclaimerDialogProps {
-	isOpen: boolean;
-	onToggleDialog: () => void;
+    isOpen: boolean;
+    onToggleDialog: () => void;
 }
 
 export function PortalDisclaimerDialog(props: PortalDisclaimerDialogProps) {
-	return (
-		<Dialog
-			title="0x Portal Disclaimer"
-			titleStyle={{ fontWeight: 100 }}
-			actions={[<FlatButton key="portalAgree" label="I Agree" onTouchTap={props.onToggleDialog} />]}
-			open={props.isOpen}
-			onRequestClose={props.onToggleDialog}
-			autoScrollBodyContent={true}
-			modal={true}
-		>
-			<div className="pt2" style={{ color: colors.grey700 }}>
-				<div>
-					0x Portal is a free software-based tool intended to help users to buy and sell ERC20-compatible
-					blockchain tokens through the 0x protocol on a purely peer-to-peer basis. 0x portal is not a
-					regulated marketplace, exchange or intermediary of any kind, and therefore, you should only use 0x
-					portal to exchange tokens that are not securities, commodity interests, or any other form of
-					regulated instrument. 0x has not attempted to screen or otherwise limit the tokens that you may
-					enter in 0x Portal. By clicking “I Agree” below, you understand that you are solely responsible for
-					using 0x Portal and buying and selling tokens using 0x Portal in compliance with all applicable laws
-					and regulations.
-				</div>
-			</div>
-		</Dialog>
-	);
+    return (
+        <Dialog
+            title="0x Portal Disclaimer"
+            titleStyle={{ fontWeight: 100 }}
+            actions={[<FlatButton key="portalAgree" label="I Agree" onTouchTap={props.onToggleDialog} />]}
+            open={props.isOpen}
+            onRequestClose={props.onToggleDialog}
+            autoScrollBodyContent={true}
+            modal={true}
+        >
+            <div className="pt2" style={{ color: colors.grey700 }}>
+                <div>
+                    0x Portal is a free software-based tool intended to help users to buy and sell ERC20-compatible
+                    blockchain tokens through the 0x protocol on a purely peer-to-peer basis. 0x portal is not a
+                    regulated marketplace, exchange or intermediary of any kind, and therefore, you should only use 0x
+                    portal to exchange tokens that are not securities, commodity interests, or any other form of
+                    regulated instrument. 0x has not attempted to screen or otherwise limit the tokens that you may
+                    enter in 0x Portal. By clicking “I Agree” below, you understand that you are solely responsible for
+                    using 0x Portal and buying and selling tokens using 0x Portal in compliance with all applicable laws
+                    and regulations.
+                </div>
+            </div>
+        </Dialog>
+    );
 }
diff --git a/packages/website/ts/components/dialogs/send_dialog.tsx b/packages/website/ts/components/dialogs/send_dialog.tsx
index b9022cd9b..b3dbce598 100644
--- a/packages/website/ts/components/dialogs/send_dialog.tsx
+++ b/packages/website/ts/components/dialogs/send_dialog.tsx
@@ -8,110 +8,110 @@ import { TokenAmountInput } from 'ts/components/inputs/token_amount_input';
 import { Token, TokenState } from 'ts/types';
 
 interface SendDialogProps {
-	onComplete: (recipient: string, value: BigNumber) => void;
-	onCancelled: () => void;
-	isOpen: boolean;
-	token: Token;
-	tokenState: TokenState;
+    onComplete: (recipient: string, value: BigNumber) => void;
+    onCancelled: () => void;
+    isOpen: boolean;
+    token: Token;
+    tokenState: TokenState;
 }
 
 interface SendDialogState {
-	value?: BigNumber;
-	recipient: string;
-	shouldShowIncompleteErrs: boolean;
-	isAmountValid: boolean;
+    value?: BigNumber;
+    recipient: string;
+    shouldShowIncompleteErrs: boolean;
+    isAmountValid: boolean;
 }
 
 export class SendDialog extends React.Component<SendDialogProps, SendDialogState> {
-	constructor() {
-		super();
-		this.state = {
-			recipient: '',
-			shouldShowIncompleteErrs: false,
-			isAmountValid: false,
-		};
-	}
-	public render() {
-		const transferDialogActions = [
-			<FlatButton key="cancelTransfer" label="Cancel" onTouchTap={this._onCancel.bind(this)} />,
-			<FlatButton
-				key="sendTransfer"
-				disabled={this._hasErrors()}
-				label="Send"
-				primary={true}
-				onTouchTap={this._onSendClick.bind(this)}
-			/>,
-		];
-		return (
-			<Dialog
-				title="I want to send"
-				titleStyle={{ fontWeight: 100 }}
-				actions={transferDialogActions}
-				open={this.props.isOpen}
-			>
-				{this._renderSendDialogBody()}
-			</Dialog>
-		);
-	}
-	private _renderSendDialogBody() {
-		return (
-			<div className="mx-auto" style={{ maxWidth: 300 }}>
-				<div style={{ height: 80 }}>
-					<AddressInput
-						initialAddress={this.state.recipient}
-						updateAddress={this._onRecipientChange.bind(this)}
-						isRequired={true}
-						label={'Recipient address'}
-						hintText={'Address'}
-					/>
-				</div>
-				<TokenAmountInput
-					label="Amount to send"
-					token={this.props.token}
-					tokenState={this.props.tokenState}
-					shouldShowIncompleteErrs={this.state.shouldShowIncompleteErrs}
-					shouldCheckBalance={true}
-					shouldCheckAllowance={false}
-					onChange={this._onValueChange.bind(this)}
-					amount={this.state.value}
-					onVisitBalancesPageClick={this.props.onCancelled}
-				/>
-			</div>
-		);
-	}
-	private _onRecipientChange(recipient?: string) {
-		this.setState({
-			shouldShowIncompleteErrs: false,
-			recipient,
-		});
-	}
-	private _onValueChange(isValid: boolean, amount?: BigNumber) {
-		this.setState({
-			isAmountValid: isValid,
-			value: amount,
-		});
-	}
-	private _onSendClick() {
-		if (this._hasErrors()) {
-			this.setState({
-				shouldShowIncompleteErrs: true,
-			});
-		} else {
-			const value = this.state.value;
-			this.setState({
-				recipient: undefined,
-				value: undefined,
-			});
-			this.props.onComplete(this.state.recipient, value);
-		}
-	}
-	private _onCancel() {
-		this.setState({
-			value: undefined,
-		});
-		this.props.onCancelled();
-	}
-	private _hasErrors() {
-		return _.isUndefined(this.state.recipient) || _.isUndefined(this.state.value) || !this.state.isAmountValid;
-	}
+    constructor() {
+        super();
+        this.state = {
+            recipient: '',
+            shouldShowIncompleteErrs: false,
+            isAmountValid: false,
+        };
+    }
+    public render() {
+        const transferDialogActions = [
+            <FlatButton key="cancelTransfer" label="Cancel" onTouchTap={this._onCancel.bind(this)} />,
+            <FlatButton
+                key="sendTransfer"
+                disabled={this._hasErrors()}
+                label="Send"
+                primary={true}
+                onTouchTap={this._onSendClick.bind(this)}
+            />,
+        ];
+        return (
+            <Dialog
+                title="I want to send"
+                titleStyle={{ fontWeight: 100 }}
+                actions={transferDialogActions}
+                open={this.props.isOpen}
+            >
+                {this._renderSendDialogBody()}
+            </Dialog>
+        );
+    }
+    private _renderSendDialogBody() {
+        return (
+            <div className="mx-auto" style={{ maxWidth: 300 }}>
+                <div style={{ height: 80 }}>
+                    <AddressInput
+                        initialAddress={this.state.recipient}
+                        updateAddress={this._onRecipientChange.bind(this)}
+                        isRequired={true}
+                        label={'Recipient address'}
+                        hintText={'Address'}
+                    />
+                </div>
+                <TokenAmountInput
+                    label="Amount to send"
+                    token={this.props.token}
+                    tokenState={this.props.tokenState}
+                    shouldShowIncompleteErrs={this.state.shouldShowIncompleteErrs}
+                    shouldCheckBalance={true}
+                    shouldCheckAllowance={false}
+                    onChange={this._onValueChange.bind(this)}
+                    amount={this.state.value}
+                    onVisitBalancesPageClick={this.props.onCancelled}
+                />
+            </div>
+        );
+    }
+    private _onRecipientChange(recipient?: string) {
+        this.setState({
+            shouldShowIncompleteErrs: false,
+            recipient,
+        });
+    }
+    private _onValueChange(isValid: boolean, amount?: BigNumber) {
+        this.setState({
+            isAmountValid: isValid,
+            value: amount,
+        });
+    }
+    private _onSendClick() {
+        if (this._hasErrors()) {
+            this.setState({
+                shouldShowIncompleteErrs: true,
+            });
+        } else {
+            const value = this.state.value;
+            this.setState({
+                recipient: undefined,
+                value: undefined,
+            });
+            this.props.onComplete(this.state.recipient, value);
+        }
+    }
+    private _onCancel() {
+        this.setState({
+            value: undefined,
+        });
+        this.props.onCancelled();
+    }
+    private _hasErrors() {
+        return _.isUndefined(this.state.recipient) || _.isUndefined(this.state.value) || !this.state.isAmountValid;
+    }
 }
diff --git a/packages/website/ts/components/dialogs/track_token_confirmation_dialog.tsx b/packages/website/ts/components/dialogs/track_token_confirmation_dialog.tsx
index b1804e95c..3f29d46f8 100644
--- a/packages/website/ts/components/dialogs/track_token_confirmation_dialog.tsx
+++ b/packages/website/ts/components/dialogs/track_token_confirmation_dialog.tsx
@@ -9,94 +9,94 @@ import { Dispatcher } from 'ts/redux/dispatcher';
 import { Token, TokenByAddress } from 'ts/types';
 
 interface TrackTokenConfirmationDialogProps {
-	tokens: Token[];
-	tokenByAddress: TokenByAddress;
-	isOpen: boolean;
-	onToggleDialog: (didConfirmTokenTracking: boolean) => void;
-	dispatcher: Dispatcher;
-	networkId: number;
-	blockchain: Blockchain;
-	userAddress: string;
+    tokens: Token[];
+    tokenByAddress: TokenByAddress;
+    isOpen: boolean;
+    onToggleDialog: (didConfirmTokenTracking: boolean) => void;
+    dispatcher: Dispatcher;
+    networkId: number;
+    blockchain: Blockchain;
+    userAddress: string;
 }
 
 interface TrackTokenConfirmationDialogState {
-	isAddingTokenToTracked: boolean;
+    isAddingTokenToTracked: boolean;
 }
 
 export class TrackTokenConfirmationDialog extends React.Component<
-	TrackTokenConfirmationDialogProps,
-	TrackTokenConfirmationDialogState
+    TrackTokenConfirmationDialogProps,
+    TrackTokenConfirmationDialogState
 > {
-	constructor(props: TrackTokenConfirmationDialogProps) {
-		super(props);
-		this.state = {
-			isAddingTokenToTracked: false,
-		};
-	}
-	public render() {
-		const tokens = this.props.tokens;
-		return (
-			<Dialog
-				title="Tracking confirmation"
-				titleStyle={{ fontWeight: 100 }}
-				actions={[
-					<FlatButton
-						key="trackNo"
-						label="No"
-						onTouchTap={this._onTrackConfirmationRespondedAsync.bind(this, false)}
-					/>,
-					<FlatButton
-						key="trackYes"
-						label="Yes"
-						onTouchTap={this._onTrackConfirmationRespondedAsync.bind(this, true)}
-					/>,
-				]}
-				open={this.props.isOpen}
-				onRequestClose={this.props.onToggleDialog.bind(this, false)}
-				autoScrollBodyContent={true}
-			>
-				<div className="pt2">
-					<TrackTokenConfirmation
-						tokens={tokens}
-						networkId={this.props.networkId}
-						tokenByAddress={this.props.tokenByAddress}
-						isAddingTokenToTracked={this.state.isAddingTokenToTracked}
-					/>
-				</div>
-			</Dialog>
-		);
-	}
-	private async _onTrackConfirmationRespondedAsync(didUserAcceptTracking: boolean) {
-		if (!didUserAcceptTracking) {
-			this.props.onToggleDialog(didUserAcceptTracking);
-			return;
-		}
-		this.setState({
-			isAddingTokenToTracked: true,
-		});
-		for (const token of this.props.tokens) {
-			const newTokenEntry = {
-				...token,
-			};
+    constructor(props: TrackTokenConfirmationDialogProps) {
+        super(props);
+        this.state = {
+            isAddingTokenToTracked: false,
+        };
+    }
+    public render() {
+        const tokens = this.props.tokens;
+        return (
+            <Dialog
+                title="Tracking confirmation"
+                titleStyle={{ fontWeight: 100 }}
+                actions={[
+                    <FlatButton
+                        key="trackNo"
+                        label="No"
+                        onTouchTap={this._onTrackConfirmationRespondedAsync.bind(this, false)}
+                    />,
+                    <FlatButton
+                        key="trackYes"
+                        label="Yes"
+                        onTouchTap={this._onTrackConfirmationRespondedAsync.bind(this, true)}
+                    />,
+                ]}
+                open={this.props.isOpen}
+                onRequestClose={this.props.onToggleDialog.bind(this, false)}
+                autoScrollBodyContent={true}
+            >
+                <div className="pt2">
+                    <TrackTokenConfirmation
+                        tokens={tokens}
+                        networkId={this.props.networkId}
+                        tokenByAddress={this.props.tokenByAddress}
+                        isAddingTokenToTracked={this.state.isAddingTokenToTracked}
+                    />
+                </div>
+            </Dialog>
+        );
+    }
+    private async _onTrackConfirmationRespondedAsync(didUserAcceptTracking: boolean) {
+        if (!didUserAcceptTracking) {
+            this.props.onToggleDialog(didUserAcceptTracking);
+            return;
+        }
+        this.setState({
+            isAddingTokenToTracked: true,
+        });
+        for (const token of this.props.tokens) {
+            const newTokenEntry = {
+                ...token,
+            };
 
-			newTokenEntry.isTracked = true;
-			trackedTokenStorage.addTrackedTokenToUser(this.props.userAddress, this.props.networkId, newTokenEntry);
-			this.props.dispatcher.updateTokenByAddress([newTokenEntry]);
+            newTokenEntry.isTracked = true;
+            trackedTokenStorage.addTrackedTokenToUser(this.props.userAddress, this.props.networkId, newTokenEntry);
+            this.props.dispatcher.updateTokenByAddress([newTokenEntry]);
 
-			const [balance, allowance] = await this.props.blockchain.getCurrentUserTokenBalanceAndAllowanceAsync(
-				token.address,
-			);
-			this.props.dispatcher.updateTokenStateByAddress({
-				[token.address]: {
-					balance,
-					allowance,
-				},
-			});
-		}
+            const [balance, allowance] = await this.props.blockchain.getCurrentUserTokenBalanceAndAllowanceAsync(
+                token.address,
+            );
+            this.props.dispatcher.updateTokenStateByAddress({
+                [token.address]: {
+                    balance,
+                    allowance,
+                },
+            });
+        }
 
-		this.setState({
-			isAddingTokenToTracked: false,
-		});
-		this.props.onToggleDialog(didUserAcceptTracking);
-	}
+        this.setState({
+            isAddingTokenToTracked: false,
+        });
+        this.props.onToggleDialog(didUserAcceptTracking);
+    }
 }
diff --git a/packages/website/ts/components/dialogs/u2f_not_supported_dialog.tsx b/packages/website/ts/components/dialogs/u2f_not_supported_dialog.tsx
index 2ea51d07b..098e3e26d 100644
--- a/packages/website/ts/components/dialogs/u2f_not_supported_dialog.tsx
+++ b/packages/website/ts/components/dialogs/u2f_not_supported_dialog.tsx
@@ -5,42 +5,42 @@ import { colors } from 'ts/utils/colors';
 import { constants } from 'ts/utils/constants';
 
 interface U2fNotSupportedDialogProps {
-	isOpen: boolean;
-	onToggleDialog: () => void;
+    isOpen: boolean;
+    onToggleDialog: () => void;
 }
 
 export function U2fNotSupportedDialog(props: U2fNotSupportedDialogProps) {
-	return (
-		<Dialog
-			title="U2F Not Supported"
-			titleStyle={{ fontWeight: 100 }}
-			actions={[<FlatButton key="u2fNo" label="Ok" onTouchTap={props.onToggleDialog.bind(this)} />]}
-			open={props.isOpen}
-			onRequestClose={props.onToggleDialog.bind(this)}
-			autoScrollBodyContent={true}
-		>
-			<div className="pt2" style={{ color: colors.grey700 }}>
-				<div>
-					It looks like your browser does not support U2F connections required for us to communicate with your
-					hardware wallet. Please use a browser that supports U2F connections and try again.
-				</div>
-				<div>
-					<ul>
-						<li className="pb1">Chrome version 38 or later</li>
-						<li className="pb1">Opera version 40 of later</li>
-						<li>
-							Firefox with{' '}
-							<a
-								href={constants.URL_FIREFOX_U2F_ADDON}
-								target="_blank"
-								style={{ textDecoration: 'underline' }}
-							>
-								this extension
-							</a>.
-						</li>
-					</ul>
-				</div>
-			</div>
-		</Dialog>
-	);
+    return (
+        <Dialog
+            title="U2F Not Supported"
+            titleStyle={{ fontWeight: 100 }}
+            actions={[<FlatButton key="u2fNo" label="Ok" onTouchTap={props.onToggleDialog.bind(this)} />]}
+            open={props.isOpen}
+            onRequestClose={props.onToggleDialog.bind(this)}
+            autoScrollBodyContent={true}
+        >
+            <div className="pt2" style={{ color: colors.grey700 }}>
+                <div>
+                    It looks like your browser does not support U2F connections required for us to communicate with your
+                    hardware wallet. Please use a browser that supports U2F connections and try again.
+                </div>
+                <div>
+                    <ul>
+                        <li className="pb1">Chrome version 38 or later</li>
+                        <li className="pb1">Opera version 40 of later</li>
+                        <li>
+                            Firefox with{' '}
+                            <a
+                                href={constants.URL_FIREFOX_U2F_ADDON}
+                                target="_blank"
+                                style={{ textDecoration: 'underline' }}
+                            >
+                                this extension
+                            </a>.
+                        </li>
+                    </ul>
+                </div>
+            </div>
+        </Dialog>
+    );
 }
diff --git a/packages/website/ts/components/dialogs/wrapped_eth_section_notice_dialog.tsx b/packages/website/ts/components/dialogs/wrapped_eth_section_notice_dialog.tsx
index 98436eb50..9e91ff12d 100644
--- a/packages/website/ts/components/dialogs/wrapped_eth_section_notice_dialog.tsx
+++ b/packages/website/ts/components/dialogs/wrapped_eth_section_notice_dialog.tsx
@@ -4,30 +4,30 @@ import { colors } from 'material-ui/styles';
 import * as React from 'react';
 
 interface WrappedEthSectionNoticeDialogProps {
-	isOpen: boolean;
-	onToggleDialog: () => void;
+    isOpen: boolean;
+    onToggleDialog: () => void;
 }
 
 export function WrappedEthSectionNoticeDialog(props: WrappedEthSectionNoticeDialogProps) {
-	return (
-		<Dialog
-			title="Dedicated Wrapped Ether Section"
-			titleStyle={{ fontWeight: 100 }}
-			actions={[
-				<FlatButton key="acknowledgeWrapEthSection" label="Sounds good" onTouchTap={props.onToggleDialog} />,
-			]}
-			open={props.isOpen}
-			onRequestClose={props.onToggleDialog}
-			autoScrollBodyContent={true}
-			modal={true}
-		>
-			<div className="pt2" style={{ color: colors.grey700 }}>
-				<div>
-					We have recently updated the Wrapped Ether token (WETH) used by 0x Portal. Don't worry, unwrapping
-					Ether tied to the old Wrapped Ether token can be done at any time by clicking on the "Wrap ETH"
-					section in the menu to the left.
-				</div>
-			</div>
-		</Dialog>
-	);
+    return (
+        <Dialog
+            title="Dedicated Wrapped Ether Section"
+            titleStyle={{ fontWeight: 100 }}
+            actions={[
+                <FlatButton key="acknowledgeWrapEthSection" label="Sounds good" onTouchTap={props.onToggleDialog} />,
+            ]}
+            open={props.isOpen}
+            onRequestClose={props.onToggleDialog}
+            autoScrollBodyContent={true}
+            modal={true}
+        >
+            <div className="pt2" style={{ color: colors.grey700 }}>
+                <div>
+                    We have recently updated the Wrapped Ether token (WETH) used by 0x Portal. Don't worry, unwrapping
+                    Ether tied to the old Wrapped Ether token can be done at any time by clicking on the "Wrap ETH"
+                    section in the menu to the left.
+                </div>
+            </div>
+        </Dialog>
+    );
 }
diff --git a/packages/website/ts/components/eth_weth_conversion_button.tsx b/packages/website/ts/components/eth_weth_conversion_button.tsx
index af1b33eef..300e71f1f 100644
--- a/packages/website/ts/components/eth_weth_conversion_button.tsx
+++ b/packages/website/ts/components/eth_weth_conversion_button.tsx
@@ -12,115 +12,115 @@ import { errorReporter } from 'ts/utils/error_reporter';
 import { utils } from 'ts/utils/utils';
 
 interface EthWethConversionButtonProps {
-	direction: Side;
-	ethToken: Token;
-	ethTokenState: TokenState;
-	dispatcher: Dispatcher;
-	blockchain: Blockchain;
-	userEtherBalance: BigNumber;
-	isOutdatedWrappedEther: boolean;
-	onConversionSuccessful?: () => void;
-	isDisabled?: boolean;
+    direction: Side;
+    ethToken: Token;
+    ethTokenState: TokenState;
+    dispatcher: Dispatcher;
+    blockchain: Blockchain;
+    userEtherBalance: BigNumber;
+    isOutdatedWrappedEther: boolean;
+    onConversionSuccessful?: () => void;
+    isDisabled?: boolean;
 }
 
 interface EthWethConversionButtonState {
-	isEthConversionDialogVisible: boolean;
-	isEthConversionHappening: boolean;
+    isEthConversionDialogVisible: boolean;
+    isEthConversionHappening: boolean;
 }
 
 export class EthWethConversionButton extends React.Component<
-	EthWethConversionButtonProps,
-	EthWethConversionButtonState
+    EthWethConversionButtonProps,
+    EthWethConversionButtonState
 > {
-	public static defaultProps: Partial<EthWethConversionButtonProps> = {
-		isDisabled: false,
-		onConversionSuccessful: _.noop,
-	};
-	public constructor(props: EthWethConversionButtonProps) {
-		super(props);
-		this.state = {
-			isEthConversionDialogVisible: false,
-			isEthConversionHappening: false,
-		};
-	}
-	public render() {
-		const labelStyle = this.state.isEthConversionHappening ? { fontSize: 10 } : {};
-		let callToActionLabel;
-		let inProgressLabel;
-		if (this.props.direction === Side.Deposit) {
-			callToActionLabel = 'Wrap';
-			inProgressLabel = 'Wrapping...';
-		} else {
-			callToActionLabel = 'Unwrap';
-			inProgressLabel = 'Unwrapping...';
-		}
-		return (
-			<div>
-				<RaisedButton
-					style={{ width: '100%' }}
-					labelStyle={labelStyle}
-					disabled={this.props.isDisabled || this.state.isEthConversionHappening}
-					label={this.state.isEthConversionHappening ? inProgressLabel : callToActionLabel}
-					onClick={this._toggleConversionDialog.bind(this)}
-				/>
-				<EthWethConversionDialog
-					direction={this.props.direction}
-					isOpen={this.state.isEthConversionDialogVisible}
-					onComplete={this._onConversionAmountSelectedAsync.bind(this)}
-					onCancelled={this._toggleConversionDialog.bind(this)}
-					etherBalance={this.props.userEtherBalance}
-					token={this.props.ethToken}
-					tokenState={this.props.ethTokenState}
-				/>
-			</div>
-		);
-	}
-	private _toggleConversionDialog() {
-		this.setState({
-			isEthConversionDialogVisible: !this.state.isEthConversionDialogVisible,
-		});
-	}
-	private async _onConversionAmountSelectedAsync(direction: Side, value: BigNumber) {
-		this.setState({
-			isEthConversionHappening: true,
-		});
-		this._toggleConversionDialog();
-		const token = this.props.ethToken;
-		const tokenState = this.props.ethTokenState;
-		let balance = tokenState.balance;
-		try {
-			if (direction === Side.Deposit) {
-				await this.props.blockchain.convertEthToWrappedEthTokensAsync(token.address, value);
-				const ethAmount = ZeroEx.toUnitAmount(value, constants.DECIMAL_PLACES_ETH);
-				this.props.dispatcher.showFlashMessage(`Successfully wrapped ${ethAmount.toString()} ETH to WETH`);
-				balance = balance.plus(value);
-			} else {
-				await this.props.blockchain.convertWrappedEthTokensToEthAsync(token.address, value);
-				const tokenAmount = ZeroEx.toUnitAmount(value, token.decimals);
-				this.props.dispatcher.showFlashMessage(`Successfully unwrapped ${tokenAmount.toString()} WETH to ETH`);
-				balance = balance.minus(value);
-			}
-			if (!this.props.isOutdatedWrappedEther) {
-				this.props.dispatcher.replaceTokenBalanceByAddress(token.address, balance);
-			}
-			this.props.onConversionSuccessful();
-		} catch (err) {
-			const errMsg = `${err}`;
-			if (_.includes(errMsg, BlockchainCallErrs.UserHasNoAssociatedAddresses)) {
-				this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
-			} else if (!_.includes(errMsg, 'User denied transaction')) {
-				utils.consoleLog(`Unexpected error encountered: ${err}`);
-				utils.consoleLog(err.stack);
-				const errorMsg =
-					direction === Side.Deposit
-						? 'Failed to wrap your ETH. Please try again.'
-						: 'Failed to unwrap your WETH. Please try again.';
-				this.props.dispatcher.showFlashMessage(errorMsg);
-				await errorReporter.reportAsync(err);
-			}
-		}
-		this.setState({
-			isEthConversionHappening: false,
-		});
-	}
+    public static defaultProps: Partial<EthWethConversionButtonProps> = {
+        isDisabled: false,
+        onConversionSuccessful: _.noop,
+    };
+    public constructor(props: EthWethConversionButtonProps) {
+        super(props);
+        this.state = {
+            isEthConversionDialogVisible: false,
+            isEthConversionHappening: false,
+        };
+    }
+    public render() {
+        const labelStyle = this.state.isEthConversionHappening ? { fontSize: 10 } : {};
+        let callToActionLabel;
+        let inProgressLabel;
+        if (this.props.direction === Side.Deposit) {
+            callToActionLabel = 'Wrap';
+            inProgressLabel = 'Wrapping...';
+        } else {
+            callToActionLabel = 'Unwrap';
+            inProgressLabel = 'Unwrapping...';
+        }
+        return (
+            <div>
+                <RaisedButton
+                    style={{ width: '100%' }}
+                    labelStyle={labelStyle}
+                    disabled={this.props.isDisabled || this.state.isEthConversionHappening}
+                    label={this.state.isEthConversionHappening ? inProgressLabel : callToActionLabel}
+                    onClick={this._toggleConversionDialog.bind(this)}
+                />
+                <EthWethConversionDialog
+                    direction={this.props.direction}
+                    isOpen={this.state.isEthConversionDialogVisible}
+                    onComplete={this._onConversionAmountSelectedAsync.bind(this)}
+                    onCancelled={this._toggleConversionDialog.bind(this)}
+                    etherBalance={this.props.userEtherBalance}
+                    token={this.props.ethToken}
+                    tokenState={this.props.ethTokenState}
+                />
+            </div>
+        );
+    }
+    private _toggleConversionDialog() {
+        this.setState({
+            isEthConversionDialogVisible: !this.state.isEthConversionDialogVisible,
+        });
+    }
+    private async _onConversionAmountSelectedAsync(direction: Side, value: BigNumber) {
+        this.setState({
+            isEthConversionHappening: true,
+        });
+        this._toggleConversionDialog();
+        const token = this.props.ethToken;
+        const tokenState = this.props.ethTokenState;
+        let balance = tokenState.balance;
+        try {
+            if (direction === Side.Deposit) {
+                await this.props.blockchain.convertEthToWrappedEthTokensAsync(token.address, value);
+                const ethAmount = ZeroEx.toUnitAmount(value, constants.DECIMAL_PLACES_ETH);
+                this.props.dispatcher.showFlashMessage(`Successfully wrapped ${ethAmount.toString()} ETH to WETH`);
+                balance = balance.plus(value);
+            } else {
+                await this.props.blockchain.convertWrappedEthTokensToEthAsync(token.address, value);
+                const tokenAmount = ZeroEx.toUnitAmount(value, token.decimals);
+                this.props.dispatcher.showFlashMessage(`Successfully unwrapped ${tokenAmount.toString()} WETH to ETH`);
+                balance = balance.minus(value);
+            }
+            if (!this.props.isOutdatedWrappedEther) {
+                this.props.dispatcher.replaceTokenBalanceByAddress(token.address, balance);
+            }
+            this.props.onConversionSuccessful();
+        } catch (err) {
+            const errMsg = `${err}`;
+            if (_.includes(errMsg, BlockchainCallErrs.UserHasNoAssociatedAddresses)) {
+                this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
+            } else if (!_.includes(errMsg, 'User denied transaction')) {
+                utils.consoleLog(`Unexpected error encountered: ${err}`);
+                utils.consoleLog(err.stack);
+                const errorMsg =
+                    direction === Side.Deposit
+                        ? 'Failed to wrap your ETH. Please try again.'
+                        : 'Failed to unwrap your WETH. Please try again.';
+                this.props.dispatcher.showFlashMessage(errorMsg);
+                await errorReporter.reportAsync(err);
+            }
+        }
+        this.setState({
+            isEthConversionHappening: false,
+        });
+    }
 }
diff --git a/packages/website/ts/components/eth_wrappers.tsx b/packages/website/ts/components/eth_wrappers.tsx
index 1593d51f0..d074ec787 100644
--- a/packages/website/ts/components/eth_wrappers.tsx
+++ b/packages/website/ts/components/eth_wrappers.tsx
@@ -10,13 +10,13 @@ import { Blockchain } from 'ts/blockchain';
 import { EthWethConversionButton } from 'ts/components/eth_weth_conversion_button';
 import { Dispatcher } from 'ts/redux/dispatcher';
 import {
-	EtherscanLinkSuffixes,
-	OutdatedWrappedEtherByNetworkId,
-	Side,
-	Token,
-	TokenByAddress,
-	TokenState,
-	TokenStateByAddress,
+    EtherscanLinkSuffixes,
+    OutdatedWrappedEtherByNetworkId,
+    Side,
+    Token,
+    TokenByAddress,
+    TokenState,
+    TokenStateByAddress,
 } from 'ts/types';
 import { colors } from 'ts/utils/colors';
 import { configs } from 'ts/utils/configs';
@@ -30,345 +30,345 @@ const ETHER_ICON_PATH = '/images/ether.png';
 const OUTDATED_WETH_ICON_PATH = '/images/wrapped_eth_gray.png';
 
 interface OutdatedWETHAddressToIsStateLoaded {
-	[address: string]: boolean;
+    [address: string]: boolean;
 }
 interface OutdatedWETHStateByAddress {
-	[address: string]: TokenState;
+    [address: string]: TokenState;
 }
 
 interface EthWrappersProps {
-	networkId: number;
-	blockchain: Blockchain;
-	dispatcher: Dispatcher;
-	tokenByAddress: TokenByAddress;
-	tokenStateByAddress: TokenStateByAddress;
-	userAddress: string;
-	userEtherBalance: BigNumber;
+    networkId: number;
+    blockchain: Blockchain;
+    dispatcher: Dispatcher;
+    tokenByAddress: TokenByAddress;
+    tokenStateByAddress: TokenStateByAddress;
+    userAddress: string;
+    userEtherBalance: BigNumber;
 }
 
 interface EthWrappersState {
-	outdatedWETHAddressToIsStateLoaded: OutdatedWETHAddressToIsStateLoaded;
-	outdatedWETHStateByAddress: OutdatedWETHStateByAddress;
+    outdatedWETHAddressToIsStateLoaded: OutdatedWETHAddressToIsStateLoaded;
+    outdatedWETHStateByAddress: OutdatedWETHStateByAddress;
 }
 
 export class EthWrappers extends React.Component<EthWrappersProps, EthWrappersState> {
-	constructor(props: EthWrappersProps) {
-		super(props);
-		const outdatedWETHAddresses = this._getOutdatedWETHAddresses();
-		const outdatedWETHAddressToIsStateLoaded: OutdatedWETHAddressToIsStateLoaded = {};
-		const outdatedWETHStateByAddress: OutdatedWETHStateByAddress = {};
-		_.each(outdatedWETHAddresses, outdatedWETHAddress => {
-			outdatedWETHAddressToIsStateLoaded[outdatedWETHAddress] = false;
-			outdatedWETHStateByAddress[outdatedWETHAddress] = {
-				balance: new BigNumber(0),
-				allowance: new BigNumber(0),
-			};
-		});
-		this.state = {
-			outdatedWETHAddressToIsStateLoaded,
-			outdatedWETHStateByAddress,
-		};
-	}
-	public componentDidMount() {
-		window.scrollTo(0, 0);
-		// tslint:disable-next-line:no-floating-promises
-		this._fetchOutdatedWETHStateAsync();
-	}
-	public render() {
-		const tokens = _.values(this.props.tokenByAddress);
-		const etherToken = _.find(tokens, { symbol: 'WETH' });
-		const etherTokenState = this.props.tokenStateByAddress[etherToken.address];
-		const wethBalance = ZeroEx.toUnitAmount(etherTokenState.balance, constants.DECIMAL_PLACES_ETH);
-		const isBidirectional = true;
-		const etherscanUrl = utils.getEtherScanLinkIfExists(
-			etherToken.address,
-			this.props.networkId,
-			EtherscanLinkSuffixes.Address,
-		);
-		const tokenLabel = this._renderToken('Wrapped Ether', etherToken.address, configs.ICON_URL_BY_SYMBOL.WETH);
-		return (
-			<div className="clearfix lg-px4 md-px4 sm-px2" style={{ minHeight: 600 }}>
-				<div className="relative">
-					<h3>ETH Wrapper</h3>
-					<div className="absolute" style={{ top: 0, right: 0 }}>
-						<a target="_blank" href={constants.URL_WETH_IO} style={{ color: colors.grey }}>
-							<div className="flex">
-								<div>About Wrapped ETH</div>
-								<div className="pl1">
-									<i className="zmdi zmdi-open-in-new" />
-								</div>
-							</div>
-						</a>
-					</div>
-				</div>
-				<Divider />
-				<div>
-					<div className="py2">Wrap ETH into an ERC20-compliant Ether token. 1 ETH = 1 WETH.</div>
-					<div>
-						<Table selectable={false} style={{ backgroundColor: colors.grey50 }}>
-							<TableHeader displaySelectAll={false} adjustForCheckbox={false}>
-								<TableRow>
-									<TableHeaderColumn>ETH Token</TableHeaderColumn>
-									<TableHeaderColumn>Balance</TableHeaderColumn>
-									<TableHeaderColumn className="center">
-										{this._renderActionColumnTitle(isBidirectional)}
-									</TableHeaderColumn>
-								</TableRow>
-							</TableHeader>
-							<TableBody displayRowCheckbox={false}>
-								<TableRow key="ETH">
-									<TableRowColumn className="py1">
-										<div className="flex">
-											<img
-												style={{
-													width: ICON_DIMENSION,
-													height: ICON_DIMENSION,
-												}}
-												src={ETHER_ICON_PATH}
-											/>
-											<div className="ml2 sm-hide xs-hide" style={{ marginTop: 12 }}>
-												ETH
-											</div>
-										</div>
-									</TableRowColumn>
-									<TableRowColumn>
-										{this.props.userEtherBalance.toFixed(PRECISION)} ETH
-									</TableRowColumn>
-									<TableRowColumn>
-										<EthWethConversionButton
-											isOutdatedWrappedEther={false}
-											direction={Side.Deposit}
-											ethToken={etherToken}
-											ethTokenState={etherTokenState}
-											dispatcher={this.props.dispatcher}
-											blockchain={this.props.blockchain}
-											userEtherBalance={this.props.userEtherBalance}
-										/>
-									</TableRowColumn>
-								</TableRow>
-								<TableRow key="WETH">
-									<TableRowColumn className="py1">
-										{this._renderTokenLink(tokenLabel, etherscanUrl)}
-									</TableRowColumn>
-									<TableRowColumn>{wethBalance.toFixed(PRECISION)} WETH</TableRowColumn>
-									<TableRowColumn>
-										<EthWethConversionButton
-											isOutdatedWrappedEther={false}
-											direction={Side.Receive}
-											ethToken={etherToken}
-											ethTokenState={etherTokenState}
-											dispatcher={this.props.dispatcher}
-											blockchain={this.props.blockchain}
-											userEtherBalance={this.props.userEtherBalance}
-										/>
-									</TableRowColumn>
-								</TableRow>
-							</TableBody>
-						</Table>
-					</div>
-				</div>
-				<div>
-					<h4>Outdated WETH</h4>
-					<Divider />
-					<div className="pt2" style={{ lineHeight: 1.5 }}>
-						The{' '}
-						<a href="https://blog.0xproject.com/canonical-weth-a9aa7d0279dd" target="_blank">
-							canonical WETH
-						</a>{' '}
-						contract is updated when necessary. Unwrap outdated WETH in order to
 retrieve your ETH and move
-						it to the updated WETH token.
-					</div>
-					<div>
-						<Table selectable={false} style={{ backgroundColor: colors.grey50 }}>
-							<TableHeader displaySelectAll={false} adjustForCheckbox={false}>
-								<TableRow>
-									<TableHeaderColumn>WETH Version</TableHeaderColumn>
-									<TableHeaderColumn>Balance</TableHeaderColumn>
-									<TableHeaderColumn className="center">
-										{this._renderActionColumnTitle(!isBidirectional)}
-									</TableHeaderColumn>
-								</TableRow>
-							</TableHeader>
-							<TableBody displayRowCheckbox={false}>
-								{this._renderOutdatedWeths(etherToken, etherTokenState)}
-							</TableBody>
-						</Table>
-					</div>
-				</div>
-			</div>
-		);
-	}
-	private _renderActionColumnTitle(isBidirectional: boolean) {
-		let iconClass = 'zmdi-long-arrow-right';
-		let leftSymbol = 'WETH';
-		let rightSymbol = 'ETH';
-		if (isBidirectional) {
-			iconClass = 'zmdi-swap';
-			leftSymbol = 'ETH';
-			rightSymbol = 'WETH';
-		}
-		return (
-			<div className="flex mx-auto" style={{ width: 85 }}>
-				<div style={{ paddingTop: 3 }}>{leftSymbol}</div>
-				<div className="px1">
-					<i style={{ fontSize: 18 }} className={`zmdi ${iconClass}`} />
-				</div>
-				<div style={{ paddingTop: 3 }}>{rightSymbol}</div>
-			</div>
-		);
-	}
-	private _renderOutdatedWeths(etherToken: Token, etherTokenState: TokenState) {
-		const rows = _.map(
-			configs.OUTDATED_WRAPPED_ETHERS,
-			(outdatedWETHByNetworkId: OutdatedWrappedEtherByNetworkId) => {
-				const outdatedWETHIfExists = outdatedWETHByNetworkId[this.props.networkId];
-				if (_.isUndefined(outdatedWETHIfExists)) {
-					return null; // noop
-				}
-				const timestampMsRange = outdatedWETHIfExists.timestampMsRange;
-				let dateRange: string;
-				if (!_.isUndefined(timestampMsRange)) {
-					const startMoment = moment(timestampMsRange.startTimestampMs);
-					const endMoment = moment(timestampMsRange.endTimestampMs);
-					dateRange = `${startMoment.format(DATE_FORMAT)}-${endMoment.format(DATE_FORMAT)}`;
-				} else {
-					dateRange = '-';
-				}
-				const outdatedEtherToken = {
-					...etherToken,
-					address: outdatedWETHIfExists.address,
-				};
-				const isStateLoaded = this.state.outdatedWETHAddressToIsStateLoaded[outdatedWETHIfExists.address];
-				const outdatedEtherTokenState = this.state.outdatedWETHStateByAddress[outdatedWETHIfExists.address];
-				const balanceInEthIfExists = isStateLoaded
-					? ZeroEx.toUnitAmount(outdatedEtherTokenState.balance, constants.DECIMAL_PLACES_ETH).toFixed(
-							PRECISION,
-						)
-					: undefined;
-				const onConversionSuccessful = this._onOutdatedConversionSuccessfulAsync.bind(
-					this,
-					outdatedWETHIfExists.address,
-				);
-				const etherscanUrl = utils.getEtherScanLinkIfExists(
-					outdatedWETHIfExists.address,
-					this.props.networkId,
-					EtherscanLinkSuffixes.Address,
-				);
-				const tokenLabel = this._renderToken(dateRange, outdatedEtherToken.address, OUTDATED_WETH_ICON_PATH);
-				return (
-					<TableRow key={`weth-${outdatedWETHIfExists.address}`}>
-						<TableRowColumn className="py1">
-							{this._renderTokenLink(tokenLabel, etherscanUrl)}
-						</TableRowColumn>
-						<TableRowColumn>
-							{isStateLoaded ? (
-								`${balanceInEthIfExists} WETH`
-							) : (
-								<i className="zmdi zmdi-spinner zmdi-hc-spin" />
-							)}
-						</TableRowColumn>
-						<TableRowColumn>
-							<EthWethConversionButton
-								isDisabled={!isStateLoaded}
-								isOutdatedWrappedEther={true}
-								direction={Side.Receive}
-								ethToken={outdatedEtherToken}
-								ethTokenState={outdatedEtherTokenState}
-								dispatcher={this.props.dispatcher}
-								blockchain={this.props.blockchain}
-								userEtherBalance={this.props.userEtherBalance}
-								onConversionSuccessful={onConversionSuccessful}
-							/>
-						</TableRowColumn>
-					</TableRow>
-				);
-			},
-		);
-		return rows;
-	}
-	private _renderTokenLink(tokenLabel: React.ReactNode, etherscanUrl: string) {
-		return (
-			<span>
-				{_.isUndefined(etherscanUrl) ? (
-					tokenLabel
-				) : (
-					<a href={etherscanUrl} target="_blank" style={{ textDecoration: 'none' }}>
-						{tokenLabel}
-					</a>
-				)}
-			</span>
-		);
-	}
-	private _renderToken(name: string, address: string, imgPath: string) {
-		const tooltipId = `tooltip-${address}`;
-		return (
-			<div className="flex">
-				<img style={{ width: ICON_DIMENSION, height: ICON_DIMENSION }} src={imgPath} />
-				<div className="ml2 sm-hide xs-hide" style={{ marginTop: 12 }}>
-					<span data-tip={true} data-for={tooltipId}>
-						{name}
-					</span>
-					<ReactTooltip id={tooltipId}>{address}</ReactTooltip>
-				</div>
-			</div>
-		);
-	}
-	private async _onOutdatedConversionSuccessfulAsync(outdatedWETHAddress: string) {
-		this.setState({
-			outdatedWETHAddressToIsStateLoaded: {
-				...this.state.outdatedWETHAddressToIsStateLoaded,
-				[outdatedWETHAddress]: false,
-			},
-		});
-		const [balance, allowance] = await this.props.blockchain.getTokenBalanceAndAllowanceAsync(
-			this.props.userAddress,
-			outdatedWETHAddress,
-		);
-		this.setState({
-			outdatedWETHAddressToIsStateLoaded: {
-				...this.state.outdatedWETHAddressToIsStateLoaded,
-				[outdatedWETHAddress]: true,
-			},
-			outdatedWETHStateByAddress: {
-				...this.state.outdatedWETHStateByAddress,
-				[outdatedWETHAddress]: {
-					balance,
-					allowance,
-				},
-			},
-		});
-	}
-	private async _fetchOutdatedWETHStateAsync() {
-		const outdatedWETHAddresses = this._getOutdatedWETHAddresses();
-		const outdatedWETHAddressToIsStateLoaded: OutdatedWETHAddressToIsStateLoaded = {};
-		const outdatedWETHStateByAddress: OutdatedWETHStateByAddress = {};
-		for (const address of outdatedWETHAddresses) {
-			const [balance, allowance] = await this.props.blockchain.getTokenBalanceAndAllowanceAsync(
-				this.props.userAddress,
-				address,
-			);
-			outdatedWETHStateByAddress[address] = {
-				balance,
-				allowance,
-			};
-			outdatedWETHAddressToIsStateLoaded[address] = true;
-		}
-		this.setState({
-			outdatedWETHStateByAddress,
-			outdatedWETHAddressToIsStateLoaded,
-		});
-	}
-	private _getOutdatedWETHAddresses(): string[] {
-		const outdatedWETHAddresses = _.compact(
-			_.map(configs.OUTDATED_WRAPPED_ETHERS, outdatedWrappedEtherByNetwork => {
-				const outdatedWrappedEtherIfExists = outdatedWrappedEtherByNetwork[this.props.networkId];
-				if (_.isUndefined(outdatedWrappedEtherIfExists)) {
-					return undefined;
-				}
-				const address = outdatedWrappedEtherIfExists.address;
-				return address;
-			}),
-		);
-		return outdatedWETHAddresses;
-	}
+    constructor(props: EthWrappersProps) {
+        super(props);
+        const outdatedWETHAddresses = this._getOutdatedWETHAddresses();
+        const outdatedWETHAddressToIsStateLoaded: OutdatedWETHAddressToIsStateLoaded = {};
+        const outdatedWETHStateByAddress: OutdatedWETHStateByAddress = {};
+        _.each(outdatedWETHAddresses, outdatedWETHAddress => {
+            outdatedWETHAddressToIsStateLoaded[outdatedWETHAddress] = false;
+            outdatedWETHStateByAddress[outdatedWETHAddress] = {
+                balance: new BigNumber(0),
+                allowance: new BigNumber(0),
+            };
+        });
+        this.state = {
+            outdatedWETHAddressToIsStateLoaded,
+            outdatedWETHStateByAddress,
+        };
+    }
+    public componentDidMount() {
+        window.scrollTo(0, 0);
+        // tslint:disable-next-line:no-floating-promises
+        this._fetchOutdatedWETHStateAsync();
+    }
+    public render() {
+        const tokens = _.values(this.props.tokenByAddress);
+        const etherToken = _.find(tokens, { symbol: 'WETH' });
+        const etherTokenState = this.props.tokenStateByAddress[etherToken.address];
+        const wethBalance = ZeroEx.toUnitAmount(etherTokenState.balance, constants.DECIMAL_PLACES_ETH);
+        const isBidirectional = true;
+        const etherscanUrl = utils.getEtherScanLinkIfExists(
+            etherToken.address,
+            this.props.networkId,
+            EtherscanLinkSuffixes.Address,
+        );
+        const tokenLabel = this._renderToken('Wrapped Ether', etherToken.address, configs.ICON_URL_BY_SYMBOL.WETH);
+        return (
+            <div className="clearfix lg-px4 md-px4 sm-px2" style={{ minHeight: 600 }}>
+                <div className="relative">
+                    <h3>ETH Wrapper</h3>
+                    <div className="absolute" style={{ top: 0, right: 0 }}>
+                        <a target="_blank" href={constants.URL_WETH_IO} style={{ color: colors.grey }}>
+                            <div className="flex">
+                                <div>About Wrapped ETH</div>
+                                <div className="pl1">
+                                    <i className="zmdi zmdi-open-in-new" />
+                                </div>
+                            </div>
+                        </a>
+                    </div>
+                </div>
+                <Divider />
+                <div>
+                    <div className="py2">Wrap ETH into an ERC20-compliant Ether token. 1 ETH = 1 WETH.</div>
+                    <div>
+                        <Table selectable={false} style={{ backgroundColor: colors.grey50 }}>
+                            <TableHeader displaySelectAll={false} adjustForCheckbox={false}>
+                                <TableRow>
+                                    <TableHeaderColumn>ETH Token</TableHeaderColumn>
+                                    <TableHeaderColumn>Balance</TableHeaderColumn>
+                                    <TableHeaderColumn className="center">
+                                        {this._renderActionColumnTitle(isBidirectional)}
+                                    </TableHeaderColumn>
+                                </TableRow>
+                            </TableHeader>
+                            <TableBody displayRowCheckbox={false}>
+                                <TableRow key="ETH">
+                                    <TableRowColumn className="py1">
+                                        <div className="flex">
+                                            <img
+                                                style={{
+                                                    width: ICON_DIMENSION,
+                                                    height: ICON_DIMENSION,
+                                                }}
+                                                src={ETHER_ICON_PATH}
+                                            />
+                                            <div className="ml2 sm-hide xs-hide" style={{ marginTop: 12 }}>
+                                                ETH
+                                            </div>
+                                        </div>
+                                    </TableRowColumn>
+                                    <TableRowColumn>
+                                        {this.props.userEtherBalance.toFixed(PRECISION)} ETH
+                                    </TableRowColumn>
+                                    <TableRowColumn>
+                                        <EthWethConversionButton
+                                            isOutdatedWrappedEther={false}
+                                            direction={Side.Deposit}
+                                            ethToken={etherToken}
+                                            ethTokenState={etherTokenState}
+                                            dispatcher={this.props.dispatcher}
+                                            blockchain={this.props.blockchain}
+                                            userEtherBalance={this.props.userEtherBalance}
+                                        />
+                                    </TableRowColumn>
+                                </TableRow>
+                                <TableRow key="WETH">
+                                    <TableRowColumn className="py1">
+                                        {this._renderTokenLink(tokenLabel, etherscanUrl)}
+                                    </TableRowColumn>
+                                    <TableRowColumn>{wethBalance.toFixed(PRECISION)} WETH</TableRowColumn>
+                                    <TableRowColumn>
+                                        <EthWethConversionButton
+                                            isOutdatedWrappedEther={false}
+                                            direction={Side.Receive}
+                                            ethToken={etherToken}
+                                            ethTokenState={etherTokenState}
+                                            dispatcher={this.props.dispatcher}
+                                            blockchain={this.props.blockchain}
+                                            userEtherBalance={this.props.userEtherBalance}
+                                        />
+                                    </TableRowColumn>
+                                </TableRow>
+                            </TableBody>
+                        </Table>
+                    </div>
+                </div>
+                <div>
+                    <h4>Outdated WETH</h4>
+                    <Divider />
+                    <div className="pt2" style={{ lineHeight: 1.5 }}>
+                        The{' '}
+                        <a href="https://blog.0xproject.com/canonical-weth-a9aa7d0279dd" target="_blank">
+                            canonical WETH
+                        </a>{' '}
+                        contract is updated when necessary. Unwrap outdated WETH in order to
 retrieve your ETH and move
+                        it to the updated WETH token.
+                    </div>
+                    <div>
+                        <Table selectable={false} style={{ backgroundColor: colors.grey50 }}>
+                            <TableHeader displaySelectAll={false} adjustForCheckbox={false}>
+                                <TableRow>
+                                    <TableHeaderColumn>WETH Version</TableHeaderColumn>
+                                    <TableHeaderColumn>Balance</TableHeaderColumn>
+                                    <TableHeaderColumn className="center">
+                                        {this._renderActionColumnTitle(!isBidirectional)}
+                                    </TableHeaderColumn>
+                                </TableRow>
+                            </TableHeader>
+                            <TableBody displayRowCheckbox={false}>
+                                {this._renderOutdatedWeths(etherToken, etherTokenState)}
+                            </TableBody>
+                        </Table>
+                    </div>
+                </div>
+            </div>
+        );
+    }
+    private _renderActionColumnTitle(isBidirectional: boolean) {
+        let iconClass = 'zmdi-long-arrow-right';
+        let leftSymbol = 'WETH';
+        let rightSymbol = 'ETH';
+        if (isBidirectional) {
+            iconClass = 'zmdi-swap';
+            leftSymbol = 'ETH';
+            rightSymbol = 'WETH';
+        }
+        return (
+            <div className="flex mx-auto" style={{ width: 85 }}>
+                <div style={{ paddingTop: 3 }}>{leftSymbol}</div>
+                <div className="px1">
+                    <i style={{ fontSize: 18 }} className={`zmdi ${iconClass}`} />
+                </div>
+                <div style={{ paddingTop: 3 }}>{rightSymbol}</div>
+            </div>
+        );
+    }
+    private _renderOutdatedWeths(etherToken: Token, etherTokenState: TokenState) {
+        const rows = _.map(
+            configs.OUTDATED_WRAPPED_ETHERS,
+            (outdatedWETHByNetworkId: OutdatedWrappedEtherByNetworkId) => {
+                const outdatedWETHIfExists = outdatedWETHByNetworkId[this.props.networkId];
+                if (_.isUndefined(outdatedWETHIfExists)) {
+                    return null; // noop
+                }
+                const timestampMsRange = outdatedWETHIfExists.timestampMsRange;
+                let dateRange: string;
+                if (!_.isUndefined(timestampMsRange)) {
+                    const startMoment = moment(timestampMsRange.startTimestampMs);
+                    const endMoment = moment(timestampMsRange.endTimestampMs);
+                    dateRange = `${startMoment.format(DATE_FORMAT)}-${endMoment.format(DATE_FORMAT)}`;
+                } else {
+                    dateRange = '-';
+                }
+                const outdatedEtherToken = {
+                    ...etherToken,
+                    address: outdatedWETHIfExists.address,
+                };
+                const isStateLoaded = this.state.outdatedWETHAddressToIsStateLoaded[outdatedWETHIfExists.address];
+                const outdatedEtherTokenState = this.state.outdatedWETHStateByAddress[outdatedWETHIfExists.address];
+                const balanceInEthIfExists = isStateLoaded
+                    ? ZeroEx.toUnitAmount(outdatedEtherTokenState.balance, constants.DECIMAL_PLACES_ETH).toFixed(
+                          PRECISION,
+                      )
+                    : undefined;
+                const onConversionSuccessful = this._onOutdatedConversionSuccessfulAsync.bind(
+                    this,
+                    outdatedWETHIfExists.address,
+                );
+                const etherscanUrl = utils.getEtherScanLinkIfExists(
+                    outdatedWETHIfExists.address,
+                    this.props.networkId,
+                    EtherscanLinkSuffixes.Address,
+                );
+                const tokenLabel = this._renderToken(dateRange, outdatedEtherToken.address, OUTDATED_WETH_ICON_PATH);
+                return (
+                    <TableRow key={`weth-${outdatedWETHIfExists.address}`}>
+                        <TableRowColumn className="py1">
+                            {this._renderTokenLink(tokenLabel, etherscanUrl)}
+                        </TableRowColumn>
+                        <TableRowColumn>
+                            {isStateLoaded ? (
+                                `${balanceInEthIfExists} WETH`
+                            ) : (
+                                <i className="zmdi zmdi-spinner zmdi-hc-spin" />
+                            )}
+                        </TableRowColumn>
+                        <TableRowColumn>
+                            <EthWethConversionButton
+                                isDisabled={!isStateLoaded}
+                                isOutdatedWrappedEther={true}
+                                direction={Side.Receive}
+                                ethToken={outdatedEtherToken}
+                                ethTokenState={outdatedEtherTokenState}
+                                dispatcher={this.props.dispatcher}
+                                blockchain={this.props.blockchain}
+                                userEtherBalance={this.props.userEtherBalance}
+                                onConversionSuccessful={onConversionSuccessful}
+                            />
+                        </TableRowColumn>
+                    </TableRow>
+                );
+            },
+        );
+        return rows;
+    }
+    private _renderTokenLink(tokenLabel: React.ReactNode, etherscanUrl: string) {
+        return (
+            <span>
+                {_.isUndefined(etherscanUrl) ? (
+                    tokenLabel
+                ) : (
+                    <a href={etherscanUrl} target="_blank" style={{ textDecoration: 'none' }}>
+                        {tokenLabel}
+                    </a>
+                )}
+            </span>
+        );
+    }
+    private _renderToken(name: string, address: string, imgPath: string) {
+        const tooltipId = `tooltip-${address}`;
+        return (
+            <div className="flex">
+                <img style={{ width: ICON_DIMENSION, height: ICON_DIMENSION }} src={imgPath} />
+                <div className="ml2 sm-hide xs-hide" style={{ marginTop: 12 }}>
+                    <span data-tip={true} data-for={tooltipId}>
+                        {name}
+                    </span>
+                    <ReactTooltip id={tooltipId}>{address}</ReactTooltip>
+                </div>
+            </div>
+        );
+    }
+    private async _onOutdatedConversionSuccessfulAsync(outdatedWETHAddress: string) {
+        this.setState({
+            outdatedWETHAddressToIsStateLoaded: {
+                ...this.state.outdatedWETHAddressToIsStateLoaded,
+                [outdatedWETHAddress]: false,
+            },
+        });
+        const [balance, allowance] = await this.props.blockchain.getTokenBalanceAndAllowanceAsync(
+            this.props.userAddress,
+            outdatedWETHAddress,
+        );
+        this.setState({
+            outdatedWETHAddressToIsStateLoaded: {
+                ...this.state.outdatedWETHAddressToIsStateLoaded,
+                [outdatedWETHAddress]: true,
+            },
+            outdatedWETHStateByAddress: {
+                ...this.state.outdatedWETHStateByAddress,
+                [outdatedWETHAddress]: {
+                    balance,
+                    allowance,
+                },
+            },
+        });
+    }
+    private async _fetchOutdatedWETHStateAsync() {
+        const outdatedWETHAddresses = this._getOutdatedWETHAddresses();
+        const outdatedWETHAddressToIsStateLoaded: OutdatedWETHAddressToIsStateLoaded = {};
+        const outdatedWETHStateByAddress: OutdatedWETHStateByAddress = {};
+        for (const address of outdatedWETHAddresses) {
+            const [balance, allowance] = await this.props.blockchain.getTokenBalanceAndAllowanceAsync(
+                this.props.userAddress,
+                address,
+            );
+            outdatedWETHStateByAddress[address] = {
+                balance,
+                allowance,
+            };
+            outdatedWETHAddressToIsStateLoaded[address] = true;
+        }
+        this.setState({
+            outdatedWETHStateByAddress,
+            outdatedWETHAddressToIsStateLoaded,
+        });
+    }
+    private _getOutdatedWETHAddresses(): string[] {
+        const outdatedWETHAddresses = _.compact(
+            _.map(configs.OUTDATED_WRAPPED_ETHERS, outdatedWrappedEtherByNetwork => {
+                const outdatedWrappedEtherIfExists = outdatedWrappedEtherByNetwork[this.props.networkId];
+                if (_.isUndefined(outdatedWrappedEtherIfExists)) {
+                    return undefined;
+                }
+                const address = outdatedWrappedEtherIfExists.address;
+                return address;
+            }),
+        );
+        return outdatedWETHAddresses;
+    }
 } // tslint:disable:max-file-line-count
diff --git a/packages/website/ts/components/fill_order.tsx b/packages/website/ts/components/fill_order.tsx
index 249ee419e..1a150e9ee 100644
--- a/packages/website/ts/components/fill_order.tsx
+++ b/packages/website/ts/components/fill_order.tsx
@@ -26,665 +26,665 @@ import { errorReporter } from 'ts/utils/error_reporter';
 import { utils } from 'ts/utils/utils';
 
 interface FillOrderProps {
-	blockchain: Blockchain;
-	blockchainErr: BlockchainErrs;
-	orderFillAmount: BigNumber;
-	isOrderInUrl: boolean;
-	networkId: number;
-	userAddress: string;
-	tokenByAddress: TokenByAddress;
-	tokenStateByAddress: TokenStateByAddress;
-	initialOrder: Order;
-	dispatcher: Dispatcher;
+    blockchain: Blockchain;
+    blockchainErr: BlockchainErrs;
+    orderFillAmount: BigNumber;
+    isOrderInUrl: boolean;
+    networkId: number;
+    userAddress: string;
+    tokenByAddress: TokenByAddress;
+    tokenStateByAddress: TokenStateByAddress;
+    initialOrder: Order;
+    dispatcher: Dispatcher;
 }
 
 interface FillOrderState {
-	didOrderValidationRun: boolean;
-	areAllInvolvedTokensTracked: boolean;
-	globalErrMsg: string;
-	orderJSON: string;
-	orderJSONErrMsg: string;
-	parsedOrder: Order;
-	didFillOrderSucceed: boolean;
-	didCancelOrderSucceed: boolean;
-	unavailableTakerAmount: BigNumber;
-	isMakerTokenAddressInRegistry: boolean;
-	isTakerTokenAddressInRegistry: boolean;
-	isFillWarningDialogOpen: boolean;
-	isFilling: boolean;
-	isCancelling: boolean;
-	isConfirmingTokenTracking: boolean;
-	tokensToTrack: Token[];
+    didOrderValidationRun: boolean;
+    areAllInvolvedTokensTracked: boolean;
+    globalErrMsg: string;
+    orderJSON: string;
+    orderJSONErrMsg: string;
+    parsedOrder: Order;
+    didFillOrderSucceed: boolean;
+    didCancelOrderSucceed: boolean;
+    unavailableTakerAmount: BigNumber;
+    isMakerTokenAddressInRegistry: boolean;
+    isTakerTokenAddressInRegistry: boolean;
+    isFillWarningDialogOpen: boolean;
+    isFilling: boolean;
+    isCancelling: boolean;
+    isConfirmingTokenTracking: boolean;
+    tokensToTrack: Token[];
 }
 
 export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
-	private _validator: SchemaValidator;
-	constructor(props: FillOrderProps) {
-		super(props);
-		this.state = {
-			globalErrMsg: '',
-			didOrderValidationRun: false,
-			areAllInvolvedTokensTracked: false,
-			didFillOrderSucceed: false,
-			didCancelOrderSucceed: false,
-			orderJSON: _.isUndefined(this.props.initialOrder) ? '' : JSON.stringify(this.props.initialOrder),
-			orderJSONErrMsg: '',
-			parsedOrder: this.props.initialOrder,
-			unavailableTakerAmount: new BigNumber(0),
-			isMakerTokenAddressInRegistry: false,
-			isTakerTokenAddressInRegistry: false,
-			isFillWarningDialogOpen: false,
-			isFilling: false,
-			isCancelling: false,
-			isConfirmingTokenTracking: false,
-			tokensToTrack: [],
-		};
-		this._validator = new SchemaValidator();
-	}
-	public componentWillMount() {
-		if (!_.isEmpty(this.state.orderJSON)) {
-			// tslint:disable-next-line:no-floating-promises
-			this._validateFillOrderFireAndForgetAsync(this.state.orderJSON);
-		}
-	}
-	public componentDidMount() {
-		window.scrollTo(0, 0);
-	}
-	public render() {
-		return (
-			<div className="clearfix lg-px4 md-px4 sm-px2" style={{ minHeight: 600 }}>
-				<h3>Fill an order</h3>
-				<Divider />
-				<div>
-					{!this.props.isOrderInUrl && (
-						<div>
-							<div className="pt2 pb2">Paste an order JSON snippet below to begin</div>
-							<div className="pb2">Order JSON</div>
-							<FillOrderJSON
-								blockchain={this.props.blockchain}
-								tokenByAddress={this.props.tokenByAddress}
-								networkId={this.props.networkId}
-								orderJSON={this.state.orderJSON}
-								onFillOrderJSONChanged={this._onFillOrderJSONChanged.bind(this)}
-							/>
-							{this._renderOrderJsonNotices()}
-						</div>
-					)}
-					<div>
-						{!_.isUndefined(this.state.parsedOrder) &&
-							this.state.didOrderValidationRun &&
-							this.state.areAllInvolvedTokensTracked &&
-							this._renderVisualOrder()}
-					</div>
-					{this.props.isOrderInUrl && (
-						<div className="pt2">
-							<Card
-								style={{
-									boxShadow: 'none',
-									backgroundColor: 'none',
-									border: '1px solid #eceaea',
-								}}
-							>
-								<CardHeader title="Order JSON" actAsExpander={true} showExpandableButton={true} />
-								<CardText expandable={true}>
-									<FillOrderJSON
-										blockchain={this.props.blockchain}
-										tokenByAddress={this.props.tokenByAddress}
-										networkId={this.props.networkId}
-										orderJSON={this.state.orderJSON}
-										onFillOrderJSONChanged={this._onFillOrderJSONChanged.bind(this)}
-									/>
-								</CardText>
-							</Card>
-							{this._renderOrderJsonNotices()}
-						</div>
-					)}
-				</div>
-				<FillWarningDialog
-					isOpen={this.state.isFillWarningDialogOpen}
-					onToggleDialog={this._onFillWarningClosed.bind(this)}
-				/>
-				<TrackTokenConfirmationDialog
-					userAddress={this.props.userAddress}
-					networkId={this.props.networkId}
-					blockchain={this.props.blockchain}
-					tokenByAddress={this.props.tokenByAddress}
-					dispatcher={this.props.dispatcher}
-					tokens={this.state.tokensToTrack}
-					isOpen={this.state.isConfirmingTokenTracking}
-					onToggleDialog={this._onToggleTrackConfirmDialog.bind(this)}
-				/>
-			</div>
-		);
-	}
-	private _renderOrderJsonNotices() {
-		return (
-			<div>
-				{!_.isUndefined(this.props.initialOrder) &&
-					!this.state.didOrderValidationRun && (
-						<div className="pt2">
-							<span className="pr1">
-								<i className="zmdi zmdi-spinner zmdi-hc-spin" />
-							</span>
-							<span>Validating order...</span>
-						</div>
-					)}
-				{!_.isEmpty(this.state.orderJSONErrMsg) && (
-					<Alert type={AlertTypes.ERROR} message={this.state.orderJSONErrMsg} />
-				)}
-			</div>
-		);
-	}
-	private _renderVisualOrder() {
-		const takerTokenAddress = this.state.parsedOrder.taker.token.address;
-		const takerToken = this.props.tokenByAddress[takerTokenAddress];
-		const orderTakerAmount = new BigNumber(this.state.parsedOrder.taker.amount);
-		const orderMakerAmount = new BigNumber(this.state.parsedOrder.maker.amount);
-		const takerAssetToken = {
-			amount: orderTakerAmount.minus(this.state.unavailableTakerAmount),
-			symbol: takerToken.symbol,
-		};
-		const fillToken = this.props.tokenByAddress[takerToken.address];
-		const fillTokenState = this.props.tokenStateByAddress[takerToken.address];
-		const makerTokenAddress = this.state.parsedOrder.maker.token.address;
-		const makerToken = this.props.tokenByAddress[makerTokenAddress];
-		const makerAssetToken = {
-			amount: orderMakerAmount.times(takerAssetToken.amount).div(orderTakerAmount),
-			symbol: makerToken.symbol,
-		};
-		const fillAssetToken = {
-			amount: this.props.orderFillAmount,
-			symbol: takerToken.symbol,
-		};
-		const orderTaker = !_.isEmpty(this.state.parsedOrder.taker.address)
-			? this.state.parsedOrder.taker.address
-			: this.props.userAddress;
-		const parsedOrderExpiration = new BigNumber(this.state.parsedOrder.expiration);
-		const exchangeRate = orderMakerAmount.div(orderTakerAmount);
+    private _validator: SchemaValidator;
+    constructor(props: FillOrderProps) {
+        super(props);
+        this.state = {
+            globalErrMsg: '',
+            didOrderValidationRun: false,
+            areAllInvolvedTokensTracked: false,
+            didFillOrderSucceed: false,
+            didCancelOrderSucceed: false,
+            orderJSON: _.isUndefined(this.props.initialOrder) ? '' : JSON.stringify(this.props.initialOrder),
+            orderJSONErrMsg: '',
+            parsedOrder: this.props.initialOrder,
+            unavailableTakerAmount: new BigNumber(0),
+            isMakerTokenAddressInRegistry: false,
+            isTakerTokenAddressInRegistry: false,
+            isFillWarningDialogOpen: false,
+            isFilling: false,
+            isCancelling: false,
+            isConfirmingTokenTracking: false,
+            tokensToTrack: [],
+        };
+        this._validator = new SchemaValidator();
+    }
+    public componentWillMount() {
+        if (!_.isEmpty(this.state.orderJSON)) {
+            // tslint:disable-next-line:no-floating-promises
+            this._validateFillOrderFireAndForgetAsync(this.state.orderJSON);
+        }
+    }
+    public componentDidMount() {
+        window.scrollTo(0, 0);
+    }
+    public render() {
+        return (
+            <div className="clearfix lg-px4 md-px4 sm-px2" style={{ minHeight: 600 }}>
+                <h3>Fill an order</h3>
+                <Divider />
+                <div>
+                    {!this.props.isOrderInUrl && (
+                        <div>
+                            <div className="pt2 pb2">Paste an order JSON snippet below to begin</div>
+                            <div className="pb2">Order JSON</div>
+                            <FillOrderJSON
+                                blockchain={this.props.blockchain}
+                                tokenByAddress={this.props.tokenByAddress}
+                                networkId={this.props.networkId}
+                                orderJSON={this.state.orderJSON}
+                                onFillOrderJSONChanged={this._onFillOrderJSONChanged.bind(this)}
+                            />
+                            {this._renderOrderJsonNotices()}
+                        </div>
+                    )}
+                    <div>
+                        {!_.isUndefined(this.state.parsedOrder) &&
+                            this.state.didOrderValidationRun &&
+                            this.state.areAllInvolvedTokensTracked &&
+                            this._renderVisualOrder()}
+                    </div>
+                    {this.props.isOrderInUrl && (
+                        <div className="pt2">
+                            <Card
+                                style={{
+                                    boxShadow: 'none',
+                                    backgroundColor: 'none',
+                                    border: '1px solid #eceaea',
+                                }}
+                            >
+                                <CardHeader title="Order JSON" actAsExpander={true} showExpandableButton={true} />
+                                <CardText expandable={true}>
+                                    <FillOrderJSON
+                                        blockchain={this.props.blockchain}
+                                        tokenByAddress={this.props.tokenByAddress}
+                                        networkId={this.props.networkId}
+                                        orderJSON={this.state.orderJSON}
+                                        onFillOrderJSONChanged={this._onFillOrderJSONChanged.bind(this)}
+                                    />
+                                </CardText>
+                            </Card>
+                            {this._renderOrderJsonNotices()}
+                        </div>
+                    )}
+                </div>
+                <FillWarningDialog
+                    isOpen={this.state.isFillWarningDialogOpen}
+                    onToggleDialog={this._onFillWarningClosed.bind(this)}
+                />
+                <TrackTokenConfirmationDialog
+                    userAddress={this.props.userAddress}
+                    networkId={this.props.networkId}
+                    blockchain={this.props.blockchain}
+                    tokenByAddress={this.props.tokenByAddress}
+                    dispatcher={this.props.dispatcher}
+                    tokens={this.state.tokensToTrack}
+                    isOpen={this.state.isConfirmingTokenTracking}
+                    onToggleDialog={this._onToggleTrackConfirmDialog.bind(this)}
+                />
+            </div>
+        );
+    }
+    private _renderOrderJsonNotices() {
+        return (
+            <div>
+                {!_.isUndefined(this.props.initialOrder) &&
+                    !this.state.didOrderValidationRun && (
+                        <div className="pt2">
+                            <span className="pr1">
+                                <i className="zmdi zmdi-spinner zmdi-hc-spin" />
+                            </span>
+                            <span>Validating order...</span>
+                        </div>
+                    )}
+                {!_.isEmpty(this.state.orderJSONErrMsg) && (
+                    <Alert type={AlertTypes.ERROR} message={this.state.orderJSONErrMsg} />
+                )}
+            </div>
+        );
+    }
+    private _renderVisualOrder() {
+        const takerTokenAddress = this.state.parsedOrder.taker.token.address;
+        const takerToken = this.props.tokenByAddress[takerTokenAddress];
+        const orderTakerAmount = new BigNumber(this.state.parsedOrder.taker.amount);
+        const orderMakerAmount = new BigNumber(this.state.parsedOrder.maker.amount);
+        const takerAssetToken = {
+            amount: orderTakerAmount.minus(this.state.unavailableTakerAmount),
+            symbol: takerToken.symbol,
+        };
+        const fillToken = this.props.tokenByAddress[takerToken.address];
+        const fillTokenState = this.props.tokenStateByAddress[takerToken.address];
+        const makerTokenAddress = this.state.parsedOrder.maker.token.address;
+        const makerToken = this.props.tokenByAddress[makerTokenAddress];
+        const makerAssetToken = {
+            amount: orderMakerAmount.times(takerAssetToken.amount).div(orderTakerAmount),
+            symbol: makerToken.symbol,
+        };
+        const fillAssetToken = {
+            amount: this.props.orderFillAmount,
+            symbol: takerToken.symbol,
+        };
+        const orderTaker = !_.isEmpty(this.state.parsedOrder.taker.address)
+            ? this.state.parsedOrder.taker.address
+            : this.props.userAddress;
+        const parsedOrderExpiration = new BigNumber(this.state.parsedOrder.expiration);
+        const exchangeRate = orderMakerAmount.div(orderTakerAmount);
 
-		let orderReceiveAmount = 0;
-		if (!_.isUndefined(this.props.orderFillAmount)) {
-			const orderReceiveAmountBigNumber = exchangeRate.mul(this.props.orderFillAmount);
-			orderReceiveAmount = this._formatCurrencyAmount(orderReceiveAmountBigNumber, makerToken.decimals);
-		}
-		const isUserMaker =
-			!_.isUndefined(this.state.parsedOrder) && this.state.parsedOrder.maker.address === this.props.userAddress;
-		const expiryDate = utils.convertToReadableDateTimeFromUnixTimestamp(parsedOrderExpiration);
-		return (
-			<div className="pt3 pb1">
-				<div className="clearfix pb2" style={{ width: '100%' }}>
-					<div className="inline left">Order details</div>
-					<div className="inline right" style={{ minWidth: 208 }}>
-						<div className="col col-4 pl2" style={{ color: colors.grey }}>
-							Maker:
-						</div>
-						<div className="col col-2 pr1">
-							<Identicon address={this.state.parsedOrder.maker.address} diameter={23} />
-						</div>
-						<div className="col col-6">
-							<EthereumAddress
-								address={this.state.parsedOrder.maker.address}
-								networkId={this.props.networkId}
-							/>
-						</div>
-					</div>
-				</div>
-				<div className="lg-px4 md-px4 sm-px0">
-					<div className="lg-px4 md-px4 sm-px1 pt1">
-						<VisualOrder
-							orderTakerAddress={orderTaker}
-							orderMakerAddress={this.state.parsedOrder.maker.address}
-							makerAssetToken={makerAssetToken}
-							takerAssetToken={takerAssetToken}
-							tokenByAddress={this.props.tokenByAddress}
-							makerToken={makerToken}
-							takerToken={takerToken}
-							networkId={this.props.networkId}
-							isMakerTokenAddressInRegistry={this.state.isMakerTokenAddressInRegistry}
-							isTakerTokenAddressInRegistry={this.state.isTakerTokenAddressInRegistry}
-						/>
-						<div className="center pt3 pb2">Expires: {expiryDate} UTC</div>
-					</div>
-				</div>
-				{!isUserMaker && (
-					<div className="clearfix mx-auto relative" style={{ width: 235, height: 108 }}>
-						<TokenAmountInput
-							label="Fill amount"
-							onChange={this._onFillAmountChange.bind(this)}
-							shouldShowIncompleteErrs={false}
-							token={fillToken}
-							tokenState={fillTokenState}
-							amount={fillAssetToken.amount}
-							shouldCheckBalance={true}
-							shouldCheckAllowance={true}
-						/>
-						<div
-							className="absolute sm-hide xs-hide"
-							style={{
-								color: colors.grey400,
-								right: -247,
-								top: 39,
-								width: 242,
-							}}
-						>
-							= {accounting.formatNumber(orderReceiveAmount, 6)} {makerToken.symbol}
-						</div>
-					</div>
-				)}
-				<div>
-					{isUserMaker ? (
-						<div>
-							<RaisedButton
-								style={{ width: '100%' }}
-								disabled={this.state.isCancelling}
-								label={this.state.isCancelling ? 'Cancelling order...' : 'Cancel order'}
-								onClick={this._onCancelOrderClickFireAndForgetAsync.bind(this)}
-							/>
-							{this.state.didCancelOrderSucceed && (
-								<Alert type={AlertTypes.SUCCESS} message={this._renderCancelSuccessMsg()} />
-							)}
-						</div>
-					) : (
-						<div>
-							<RaisedButton
-								style={{ width: '100%' }}
-								disabled={this.state.isFilling}
-								label={this.state.isFilling ? 'Filling order...' : 'Fill order'}
-								onClick={this._onFillOrderClick.bind(this)}
-							/>
-							{!_.isEmpty(this.state.globalErrMsg) && (
-								<Alert type={AlertTypes.ERROR} message={this.state.globalErrMsg} />
-							)}
-							{this.state.didFillOrderSucceed && (
-								<Alert type={AlertTypes.SUCCESS} message={this._renderFillSuccessMsg()} />
-							)}
-						</div>
-					)}
-				</div>
-			</div>
-		);
-	}
-	private _renderFillSuccessMsg() {
-		return (
-			<div>
-				Order successfully filled. See the trade details in your{' '}
-				<Link to={`${WebsitePaths.Portal}/trades`} style={{ color: colors.white }}>
-					trade history
-				</Link>
-			</div>
-		);
-	}
-	private _renderCancelSuccessMsg() {
-		return <div>Order successfully cancelled.</div>;
-	}
-	private _onFillOrderClick() {
-		if (!this.state.isMakerTokenAddressInRegistry || !this.state.isTakerTokenAddressInRegistry) {
-			this.setState({
-				isFillWarningDialogOpen: true,
-			});
-		} else {
-			// tslint:disable-next-line:no-floating-promises
-			this._onFillOrderClickFireAndForgetAsync();
-		}
-	}
-	private _onFillWarningClosed(didUserCancel: boolean) {
-		this.setState({
-			isFillWarningDialogOpen: false,
-		});
-		if (!didUserCancel) {
-			// tslint:disable-next-line:no-floating-promises
-			this._onFillOrderClickFireAndForgetAsync();
-		}
-	}
-	private _onFillAmountChange(isValid: boolean, amount?: BigNumber) {
-		this.props.dispatcher.updateOrderFillAmount(amount);
-	}
-	private _onFillOrderJSONChanged(event: any) {
-		const orderJSON = event.target.value;
-		this.setState({
-			didOrderValidationRun: _.isEmpty(orderJSON) && _.isEmpty(this.state.orderJSONErrMsg),
-			didFillOrderSucceed: false,
-		});
-		// tslint:disable-next-line:no-floating-promises
-		this._validateFillOrderFireAndForgetAsync(orderJSON);
-	}
-	private async _checkForUntrackedTokensAndAskToAdd() {
-		if (!_.isEmpty(this.state.orderJSONErrMsg)) {
-			return;
-		}
+        let orderReceiveAmount = 0;
+        if (!_.isUndefined(this.props.orderFillAmount)) {
+            const orderReceiveAmountBigNumber = exchangeRate.mul(this.props.orderFillAmount);
+            orderReceiveAmount = this._formatCurrencyAmount(orderReceiveAmountBigNumber, makerToken.decimals);
+        }
+        const isUserMaker =
+            !_.isUndefined(this.state.parsedOrder) && this.state.parsedOrder.maker.address === this.props.userAddress;
+        const expiryDate = utils.convertToReadableDateTimeFromUnixTimestamp(parsedOrderExpiration);
+        return (
+            <div className="pt3 pb1">
+                <div className="clearfix pb2" style={{ width: '100%' }}>
+                    <div className="inline left">Order details</div>
+                    <div className="inline right" style={{ minWidth: 208 }}>
+                        <div className="col col-4 pl2" style={{ color: colors.grey }}>
+                            Maker:
+                        </div>
+                        <div className="col col-2 pr1">
+                            <Identicon address={this.state.parsedOrder.maker.address} diameter={23} />
+                        </div>
+                        <div className="col col-6">
+                            <EthereumAddress
+                                address={this.state.parsedOrder.maker.address}
+                                networkId={this.props.networkId}
+                            />
+                        </div>
+                    </div>
+                </div>
+                <div className="lg-px4 md-px4 sm-px0">
+                    <div className="lg-px4 md-px4 sm-px1 pt1">
+                        <VisualOrder
+                            orderTakerAddress={orderTaker}
+                            orderMakerAddress={this.state.parsedOrder.maker.address}
+                            makerAssetToken={makerAssetToken}
+                            takerAssetToken={takerAssetToken}
+                            tokenByAddress={this.props.tokenByAddress}
+                            makerToken={makerToken}
+                            takerToken={takerToken}
+                            networkId={this.props.networkId}
+                            isMakerTokenAddressInRegistry={this.state.isMakerTokenAddressInRegistry}
+                            isTakerTokenAddressInRegistry={this.state.isTakerTokenAddressInRegistry}
+                        />
+                        <div className="center pt3 pb2">Expires: {expiryDate} UTC</div>
+                    </div>
+                </div>
+                {!isUserMaker && (
+                    <div className="clearfix mx-auto relative" style={{ width: 235, height: 108 }}>
+                        <TokenAmountInput
+                            label="Fill amount"
+                            onChange={this._onFillAmountChange.bind(this)}
+                            shouldShowIncompleteErrs={false}
+                            token={fillToken}
+                            tokenState={fillTokenState}
+                            amount={fillAssetToken.amount}
+                            shouldCheckBalance={true}
+                            shouldCheckAllowance={true}
+                        />
+                        <div
+                            className="absolute sm-hide xs-hide"
+                            style={{
+                                color: colors.grey400,
+                                right: -247,
+                                top: 39,
+                                width: 242,
+                            }}
+                        >
+                            = {accounting.formatNumber(orderReceiveAmount, 6)} {makerToken.symbol}
+                        </div>
+                    </div>
+                )}
+                <div>
+                    {isUserMaker ? (
+                        <div>
+                            <RaisedButton
+                                style={{ width: '100%' }}
+                                disabled={this.state.isCancelling}
+                                label={this.state.isCancelling ? 'Cancelling order...' : 'Cancel order'}
+                                onClick={this._onCancelOrderClickFireAndForgetAsync.bind(this)}
+                            />
+                            {this.state.didCancelOrderSucceed && (
+                                <Alert type={AlertTypes.SUCCESS} message={this._renderCancelSuccessMsg()} />
+                            )}
+                        </div>
+                    ) : (
+                        <div>
+                            <RaisedButton
+                                style={{ width: '100%' }}
+                                disabled={this.state.isFilling}
+                                label={this.state.isFilling ? 'Filling order...' : 'Fill order'}
+                                onClick={this._onFillOrderClick.bind(this)}
+                            />
+                            {!_.isEmpty(this.state.globalErrMsg) && (
+                                <Alert type={AlertTypes.ERROR} message={this.state.globalErrMsg} />
+                            )}
+                            {this.state.didFillOrderSucceed && (
+                                <Alert type={AlertTypes.SUCCESS} message={this._renderFillSuccessMsg()} />
+                            )}
+                        </div>
+                    )}
+                </div>
+            </div>
+        );
+    }
+    private _renderFillSuccessMsg() {
+        return (
+            <div>
+                Order successfully filled. See the trade details in your{' '}
+                <Link to={`${WebsitePaths.Portal}/trades`} style={{ color: colors.white }}>
+                    trade history
+                </Link>
+            </div>
+        );
+    }
+    private _renderCancelSuccessMsg() {
+        return <div>Order successfully cancelled.</div>;
+    }
+    private _onFillOrderClick() {
+        if (!this.state.isMakerTokenAddressInRegistry || !this.state.isTakerTokenAddressInRegistry) {
+            this.setState({
+                isFillWarningDialogOpen: true,
+            });
+        } else {
+            // tslint:disable-next-line:no-floating-promises
+            this._onFillOrderClickFireAndForgetAsync();
+        }
+    }
+    private _onFillWarningClosed(didUserCancel: boolean) {
+        this.setState({
+            isFillWarningDialogOpen: false,
+        });
+        if (!didUserCancel) {
+            // tslint:disable-next-line:no-floating-promises
+            this._onFillOrderClickFireAndForgetAsync();
+        }
+    }
+    private _onFillAmountChange(isValid: boolean, amount?: BigNumber) {
+        this.props.dispatcher.updateOrderFillAmount(amount);
+    }
+    private _onFillOrderJSONChanged(event: any) {
+        const orderJSON = event.target.value;
+        this.setState({
+            didOrderValidationRun: _.isEmpty(orderJSON) && _.isEmpty(this.state.orderJSONErrMsg),
+            didFillOrderSucceed: false,
+        });
+        // tslint:disable-next-line:no-floating-promises
+        this._validateFillOrderFireAndForgetAsync(orderJSON);
+    }
+    private async _checkForUntrackedTokensAndAskToAdd() {
+        if (!_.isEmpty(this.state.orderJSONErrMsg)) {
+            return;
+        }
 
-		const makerTokenIfExists = this.props.tokenByAddress[this.state.parsedOrder.maker.token.address];
-		const takerTokenIfExists = this.props.tokenByAddress[this.state.parsedOrder.taker.token.address];
+        const makerTokenIfExists = this.props.tokenByAddress[this.state.parsedOrder.maker.token.address];
+        const takerTokenIfExists = this.props.tokenByAddress[this.state.parsedOrder.taker.token.address];
 
-		const tokensToTrack = [];
-		const isUnseenMakerToken = _.isUndefined(makerTokenIfExists);
-		const isMakerTokenTracked = !_.isUndefined(makerTokenIfExists) && makerTokenIfExists.isTracked;
-		if (isUnseenMakerToken) {
-			tokensToTrack.push({
-				...this.state.parsedOrder.maker.token,
-				iconUrl: undefined,
-				isTracked: false,
-				isRegistered: false,
-			});
-		} else if (!isMakerTokenTracked) {
-			tokensToTrack.push(makerTokenIfExists);
-		}
-		const isUnseenTakerToken = _.isUndefined(takerTokenIfExists);
-		const isTakerTokenTracked = !_.isUndefined(takerTokenIfExists) && takerTokenIfExists.isTracked;
-		if (isUnseenTakerToken) {
-			tokensToTrack.push({
-				...this.state.parsedOrder.taker.token,
-				iconUrl: undefined,
-				isTracked: false,
-				isRegistered: false,
-			});
-		} else if (!isTakerTokenTracked) {
-			tokensToTrack.push(takerTokenIfExists);
-		}
-		if (!_.isEmpty(tokensToTrack)) {
-			this.setState({
-				isConfirmingTokenTracking: true,
-				tokensToTrack,
-			});
-		} else {
-			this.setState({
-				areAllInvolvedTokensTracked: true,
-			});
-		}
-	}
-	private async _validateFillOrderFireAndForgetAsync(orderJSON: string) {
-		let orderJSONErrMsg = '';
-		let parsedOrder: Order;
-		try {
-			const order = JSON.parse(orderJSON);
-			const validationResult = this._validator.validate(order, orderSchema);
-			if (validationResult.errors.length > 0) {
-				orderJSONErrMsg = 'Submitted order JSON is not a valid order';
-				utils.consoleLog(`Unexpected order JSON validation error: ${validationResult.errors.join(', ')}`);
-				return;
-			}
-			parsedOrder = order;
+        const tokensToTrack = [];
+        const isUnseenMakerToken = _.isUndefined(makerTokenIfExists);
+        const isMakerTokenTracked = !_.isUndefined(makerTokenIfExists) && makerTokenIfExists.isTracked;
+        if (isUnseenMakerToken) {
+            tokensToTrack.push({
+                ...this.state.parsedOrder.maker.token,
+                iconUrl: undefined,
+                isTracked: false,
+                isRegistered: false,
+            });
+        } else if (!isMakerTokenTracked) {
+            tokensToTrack.push(makerTokenIfExists);
+        }
+        const isUnseenTakerToken = _.isUndefined(takerTokenIfExists);
+        const isTakerTokenTracked = !_.isUndefined(takerTokenIfExists) && takerTokenIfExists.isTracked;
+        if (isUnseenTakerToken) {
+            tokensToTrack.push({
+                ...this.state.parsedOrder.taker.token,
+                iconUrl: undefined,
+                isTracked: false,
+                isRegistered: false,
+            });
+        } else if (!isTakerTokenTracked) {
+            tokensToTrack.push(takerTokenIfExists);
+        }
+        if (!_.isEmpty(tokensToTrack)) {
+            this.setState({
+                isConfirmingTokenTracking: true,
+                tokensToTrack,
+            });
+        } else {
+            this.setState({
+                areAllInvolvedTokensTracked: true,
+            });
+        }
+    }
+    private async _validateFillOrderFireAndForgetAsync(orderJSON: string) {
+        let orderJSONErrMsg = '';
+        let parsedOrder: Order;
+        try {
+            const order = JSON.parse(orderJSON);
+            const validationResult = this._validator.validate(order, orderSchema);
+            if (validationResult.errors.length > 0) {
+                orderJSONErrMsg = 'Submitted order JSON is not a valid order';
+                utils.consoleLog(`Unexpected order JSON validation error: ${validationResult.errors.join(', ')}`);
+                return;
+            }
+            parsedOrder = order;
 
-			const exchangeContractAddr = this.props.blockchain.getExchangeContractAddressIfExists();
-			const makerAmount = new BigNumber(parsedOrder.maker.amount);
-			const takerAmount = new BigNumber(parsedOrder.taker.amount);
-			const expiration = new BigNumber(parsedOrder.expiration);
-			const salt = new BigNumber(parsedOrder.salt);
-			const parsedMakerFee = new BigNumber(parsedOrder.maker.feeAmount);
-			const parsedTakerFee = new BigNumber(parsedOrder.taker.feeAmount);
+            const exchangeContractAddr = this.props.blockchain.getExchangeContractAddressIfExists();
+            const makerAmount = new BigNumber(parsedOrder.maker.amount);
+            const takerAmount = new BigNumber(parsedOrder.taker.amount);
+            const expiration = new BigNumber(parsedOrder.expiration);
+            const salt = new BigNumber(parsedOrder.salt);
+            const parsedMakerFee = new BigNumber(parsedOrder.maker.feeAmount);
+            const parsedTakerFee = new BigNumber(parsedOrder.taker.feeAmount);
 
-			const zeroExOrder: ZeroExOrder = {
-				exchangeContractAddress: parsedOrder.exchangeContract,
-				expirationUnixTimestampSec: expiration,
-				feeRecipient: parsedOrder.feeRecipient,
-				maker: parsedOrder.maker.address,
-				makerFee: parsedMakerFee,
-				makerTokenAddress: parsedOrder.maker.token.address,
-				makerTokenAmount: makerAmount,
-				salt,
-				taker: _.isEmpty(parsedOrder.taker.address) ? constants.NULL_ADDRESS : parsedOrder.taker.address,
-				takerFee: parsedTakerFee,
-				takerTokenAddress: parsedOrder.taker.token.address,
-				takerTokenAmount: takerAmount,
-			};
-			const orderHash = ZeroEx.getOrderHashHex(zeroExOrder);
+            const zeroExOrder: ZeroExOrder = {
+                exchangeContractAddress: parsedOrder.exchangeContract,
+                expirationUnixTimestampSec: expiration,
+                feeRecipient: parsedOrder.feeRecipient,
+                maker: parsedOrder.maker.address,
+                makerFee: parsedMakerFee,
+                makerTokenAddress: parsedOrder.maker.token.address,
+                makerTokenAmount: makerAmount,
+                salt,
+                taker: _.isEmpty(parsedOrder.taker.address) ? constants.NULL_ADDRESS : parsedOrder.taker.address,
+                takerFee: parsedTakerFee,
+                takerTokenAddress: parsedOrder.taker.token.address,
+                takerTokenAmount: takerAmount,
+            };
+            const orderHash = ZeroEx.getOrderHashHex(zeroExOrder);
 
-			const signature = parsedOrder.signature;
-			const isValidSignature = ZeroEx.isValidSignature(signature.hash, signature, parsedOrder.maker.address);
-			if (this.props.networkId !== parsedOrder.networkId) {
-				orderJSONErrMsg = `This order was made on another Ethereum network
+            const signature = parsedOrder.signature;
+            const isValidSignature = ZeroEx.isValidSignature(signature.hash, signature, parsedOrder.maker.address);
+            if (this.props.networkId !== parsedOrder.networkId) {
+                orderJSONErrMsg = `This order was made on another Ethereum network
                                    (id: ${parsedOrder.networkId}). Connect to this network to fill.`;
-				parsedOrder = undefined;
-			} else if (exchangeContractAddr !== parsedOrder.exchangeContract) {
-				orderJSONErrMsg = 'This order was made using a deprecated 0x Exchange contract.';
-				parsedOrder = undefined;
-			} else if (orderHash !== signature.hash) {
-				orderJSONErrMsg = 'Order hash does not match supplied plaintext values';
-				parsedOrder = undefined;
-			} else if (!isValidSignature) {
-				orderJSONErrMsg = 'Order signature is invalid';
-				parsedOrder = undefined;
-			} else {
-				// Update user supplied order cache so that if they navigate away from fill view
-				// e.g to set a token allowance, when they come back, the fill order persists
-				this.props.dispatcher.updateUserSuppliedOrderCache(parsedOrder);
-			}
-		} catch (err) {
-			utils.consoleLog(`Validate order err: ${err}`);
-			if (!_.isEmpty(orderJSON)) {
-				orderJSONErrMsg = 'Submitted order JSON is not valid JSON';
-			}
-			this.setState({
-				didOrderValidationRun: true,
-				orderJSON,
-				orderJSONErrMsg,
-				parsedOrder,
-			});
-			return;
-		}
+                parsedOrder = undefined;
+            } else if (exchangeContractAddr !== parsedOrder.exchangeContract) {
+                orderJSONErrMsg = 'This order was made using a deprecated 0x Exchange contract.';
+                parsedOrder = undefined;
+            } else if (orderHash !== signature.hash) {
+                orderJSONErrMsg = 'Order hash does not match supplied plaintext values';
+                parsedOrder = undefined;
+            } else if (!isValidSignature) {
+                orderJSONErrMsg = 'Order signature is invalid';
+                parsedOrder = undefined;
+            } else {
+                // Update user supplied order cache so that if they navigate away from fill view
+                // e.g to set a token allowance, when they come back, the fill order persists
+                this.props.dispatcher.updateUserSuppliedOrderCache(parsedOrder);
+            }
+        } catch (err) {
+            utils.consoleLog(`Validate order err: ${err}`);
+            if (!_.isEmpty(orderJSON)) {
+                orderJSONErrMsg = 'Submitted order JSON is not valid JSON';
+            }
+            this.setState({
+                didOrderValidationRun: true,
+                orderJSON,
+                orderJSONErrMsg,
+                parsedOrder,
+            });
+            return;
+        }
 
-		let unavailableTakerAmount = new BigNumber(0);
-		if (!_.isEmpty(orderJSONErrMsg)) {
-			// Clear cache entry if user updates orderJSON to invalid entry
-			this.props.dispatcher.updateUserSuppliedOrderCache(undefined);
-		} else {
-			const orderHash = parsedOrder.signature.hash;
-			unavailableTakerAmount = await this.props.blockchain.getUnavailableTakerAmountAsync(orderHash);
-			const isMakerTokenAddressInRegistry = await this.props.blockchain.isAddressInTokenRegistryAsync(
-				parsedOrder.maker.token.address,
-			);
-			const isTakerTokenAddressInRegistry = await this.props.blockchain.isAddressInTokenRegistryAsync(
-				parsedOrder.taker.token.address,
-			);
-			this.setState({
-				isMakerTokenAddressInRegistry,
-				isTakerTokenAddressInRegistry,
-			});
-		}
+        let unavailableTakerAmount = new BigNumber(0);
+        if (!_.isEmpty(orderJSONErrMsg)) {
+            // Clear cache entry if user updates orderJSON to invalid entry
+            this.props.dispatcher.updateUserSuppliedOrderCache(undefined);
+        } else {
+            const orderHash = parsedOrder.signature.hash;
+            unavailableTakerAmount = await this.props.blockchain.getUnavailableTakerAmountAsync(orderHash);
+            const isMakerTokenAddressInRegistry = await this.props.blockchain.isAddressInTokenRegistryAsync(
+                parsedOrder.maker.token.address,
+            );
+            const isTakerTokenAddressInRegistry = await this.props.blockchain.isAddressInTokenRegistryAsync(
+                parsedOrder.taker.token.address,
+            );
+            this.setState({
+                isMakerTokenAddressInRegistry,
+                isTakerTokenAddressInRegistry,
+            });
+        }
 
-		this.setState({
-			didOrderValidationRun: true,
-			orderJSON,
-			orderJSONErrMsg,
-			parsedOrder,
-			unavailableTakerAmount,
-		});
+        this.setState({
+            didOrderValidationRun: true,
+            orderJSON,
+            orderJSONErrMsg,
+            parsedOrder,
+            unavailableTakerAmount,
+        });
 
-		await this._checkForUntrackedTokensAndAskToAdd();
-	}
-	private async _onFillOrderClickFireAndForgetAsync(): Promise<void> {
-		if (this.props.blockchainErr !== BlockchainErrs.NoError || _.isEmpty(this.props.userAddress)) {
-			this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
-			return;
-		}
+        await this._checkForUntrackedTokensAndAskToAdd();
+    }
+    private async _onFillOrderClickFireAndForgetAsync(): Promise<void> {
+        if (this.props.blockchainErr !== BlockchainErrs.NoError || _.isEmpty(this.props.userAddress)) {
+            this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
+            return;
+        }
 
-		this.setState({
-			isFilling: true,
-			didFillOrderSucceed: false,
-		});
+        this.setState({
+            isFilling: true,
+            didFillOrderSucceed: false,
+        });
 
-		const parsedOrder = this.state.parsedOrder;
-		const takerFillAmount = this.props.orderFillAmount;
+        const parsedOrder = this.state.parsedOrder;
+        const takerFillAmount = this.props.orderFillAmount;
 
-		if (_.isUndefined(this.props.userAddress)) {
-			this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
-			this.setState({
-				isFilling: false,
-			});
-			return;
-		}
-		let globalErrMsg = '';
+        if (_.isUndefined(this.props.userAddress)) {
+            this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
+            this.setState({
+                isFilling: false,
+            });
+            return;
+        }
+        let globalErrMsg = '';
 
-		if (_.isUndefined(takerFillAmount)) {
-			globalErrMsg = 'You must specify a fill amount';
-		}
+        if (_.isUndefined(takerFillAmount)) {
+            globalErrMsg = 'You must specify a fill amount';
+        }
 
-		const signedOrder = this.props.blockchain.portalOrderToSignedOrder(
-			parsedOrder.maker.address,
-			parsedOrder.taker.address,
-			parsedOrder.maker.token.address,
-			parsedOrder.taker.token.address,
-			new BigNumber(parsedOrder.maker.amount),
-			new BigNumber(parsedOrder.taker.amount),
-			new BigNumber(parsedOrder.maker.feeAmount),
-			new BigNumber(parsedOrder.taker.feeAmount),
-			new BigNumber(this.state.parsedOrder.expiration),
-			parsedOrder.feeRecipient,
-			parsedOrder.signature,
-			new BigNumber(parsedOrder.salt),
-		);
-		if (_.isEmpty(globalErrMsg)) {
-			try {
-				await this.props.blockchain.validateFillOrderThrowIfInvalidAsync(
-					signedOrder,
-					takerFillAmount,
-					this.props.userAddress,
-				);
-			} catch (err) {
-				globalErrMsg = utils.zeroExErrToHumanReadableErrMsg(err.message, parsedOrder.taker.address);
-			}
-		}
-		if (!_.isEmpty(globalErrMsg)) {
-			this.setState({
-				isFilling: false,
-				globalErrMsg,
-			});
-			return;
-		}
-		try {
-			const orderFilledAmount: BigNumber = await this.props.blockchain.fillOrderAsync(
-				signedOrder,
-				this.props.orderFillAmount,
-			);
-			// After fill completes, let's update the token balances
-			const makerToken = this.props.tokenByAddress[parsedOrder.maker.token.address];
-			const takerToken = this.props.tokenByAddress[parsedOrder.taker.token.address];
-			const tokens = [makerToken, takerToken];
-			await this.props.blockchain.updateTokenBalancesAndAllowancesAsync(tokens);
-			this.setState({
-				isFilling: false,
-				didFillOrderSucceed: true,
-				globalErrMsg: '',
-				unavailableTakerAmount: this.state.unavailableTakerAmount.plus(orderFilledAmount),
-			});
-			return;
-		} catch (err) {
-			this.setState({
-				isFilling: false,
-			});
-			const errMsg = `${err}`;
-			if (_.includes(errMsg, 'User denied transaction signature')) {
-				return;
-			}
-			globalErrMsg = 'Failed to fill order, please refresh and try again';
-			utils.consoleLog(`${err}`);
-			this.setState({
-				globalErrMsg,
-			});
-			await errorReporter.reportAsync(err);
-			return;
-		}
-	}
-	private async _onCancelOrderClickFireAndForgetAsync(): Promise<void> {
-		if (this.props.blockchainErr !== BlockchainErrs.NoError || _.isEmpty(this.props.userAddress)) {
-			this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
-			return;
-		}
+        const signedOrder = this.props.blockchain.portalOrderToSignedOrder(
+            parsedOrder.maker.address,
+            parsedOrder.taker.address,
+            parsedOrder.maker.token.address,
+            parsedOrder.taker.token.address,
+            new BigNumber(parsedOrder.maker.amount),
+            new BigNumber(parsedOrder.taker.amount),
+            new BigNumber(parsedOrder.maker.feeAmount),
+            new BigNumber(parsedOrder.taker.feeAmount),
+            new BigNumber(this.state.parsedOrder.expiration),
+            parsedOrder.feeRecipient,
+            parsedOrder.signature,
+            new BigNumber(parsedOrder.salt),
+        );
+        if (_.isEmpty(globalErrMsg)) {
+            try {
+                await this.props.blockchain.validateFillOrderThrowIfInvalidAsync(
+                    signedOrder,
+                    takerFillAmount,
+                    this.props.userAddress,
+                );
+            } catch (err) {
+                globalErrMsg = utils.zeroExErrToHumanReadableErrMsg(err.message, parsedOrder.taker.address);
+            }
+        }
+        if (!_.isEmpty(globalErrMsg)) {
+            this.setState({
+                isFilling: false,
+                globalErrMsg,
+            });
+            return;
+        }
+        try {
+            const orderFilledAmount: BigNumber = await this.props.blockchain.fillOrderAsync(
+                signedOrder,
+                this.props.orderFillAmount,
+            );
+            // After fill completes, let's update the token balances
+            const makerToken = this.props.tokenByAddress[parsedOrder.maker.token.address];
+            const takerToken = this.props.tokenByAddress[parsedOrder.taker.token.address];
+            const tokens = [makerToken, takerToken];
+            await this.props.blockchain.updateTokenBalancesAndAllowancesAsync(tokens);
+            this.setState({
+                isFilling: false,
+                didFillOrderSucceed: true,
+                globalErrMsg: '',
+                unavailableTakerAmount: this.state.unavailableTakerAmount.plus(orderFilledAmount),
+            });
+            return;
+        } catch (err) {
+            this.setState({
+                isFilling: false,
+            });
+            const errMsg = `${err}`;
+            if (_.includes(errMsg, 'User denied transaction signature')) {
+                return;
+            }
+            globalErrMsg = 'Failed to fill order, please refresh and try again';
+            utils.consoleLog(`${err}`);
+            this.setState({
+                globalErrMsg,
+            });
+            await errorReporter.reportAsync(err);
+            return;
+        }
+    }
+    private async _onCancelOrderClickFireAndForgetAsync(): Promise<void> {
+        if (this.props.blockchainErr !== BlockchainErrs.NoError || _.isEmpty(this.props.userAddress)) {
+            this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
+            return;
+        }
 
-		this.setState({
-			isCancelling: true,
-			didCancelOrderSucceed: false,
-		});
+        this.setState({
+            isCancelling: true,
+            didCancelOrderSucceed: false,
+        });
 
-		const parsedOrder = this.state.parsedOrder;
-		const orderHash = parsedOrder.signature.hash;
-		const takerAddress = this.props.userAddress;
+        const parsedOrder = this.state.parsedOrder;
+        const orderHash = parsedOrder.signature.hash;
+        const takerAddress = this.props.userAddress;
 
-		if (_.isUndefined(takerAddress)) {
-			this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
-			this.setState({
-				isFilling: false,
-			});
-			return;
-		}
-		let globalErrMsg = '';
+        if (_.isUndefined(takerAddress)) {
+            this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
+            this.setState({
+                isFilling: false,
+            });
+            return;
+        }
+        let globalErrMsg = '';
 
-		const takerTokenAmount = new BigNumber(parsedOrder.taker.amount);
+        const takerTokenAmount = new BigNumber(parsedOrder.taker.amount);
 
-		const signedOrder = this.props.blockchain.portalOrderToSignedOrder(
-			parsedOrder.maker.address,
-			parsedOrder.taker.address,
-			parsedOrder.maker.token.address,
-			parsedOrder.taker.token.address,
-			new BigNumber(parsedOrder.maker.amount),
-			takerTokenAmount,
-			new BigNumber(parsedOrder.maker.feeAmount),
-			new BigNumber(parsedOrder.taker.feeAmount),
-			new BigNumber(this.state.parsedOrder.expiration),
-			parsedOrder.feeRecipient,
-			parsedOrder.signature,
-			new BigNumber(parsedOrder.salt),
-		);
-		const unavailableTakerAmount = await this.props.blockchain.getUnavailableTakerAmountAsync(orderHash);
-		const availableTakerTokenAmount = takerTokenAmount.minus(unavailableTakerAmount);
-		try {
-			await this.props.blockchain.validateCancelOrderThrowIfInvalidAsync(signedOrder, availableTakerTokenAmount);
-		} catch (err) {
-			globalErrMsg = utils.zeroExErrToHumanReadableErrMsg(err.message, parsedOrder.taker.address);
-		}
-		if (!_.isEmpty(globalErrMsg)) {
-			this.setState({
-				isCancelling: false,
-				globalErrMsg,
-			});
-			return;
-		}
-		try {
-			await this.props.blockchain.cancelOrderAsync(signedOrder, availableTakerTokenAmount);
-			this.setState({
-				isCancelling: false,
-				didCancelOrderSucceed: true,
-				globalErrMsg: '',
-				unavailableTakerAmount: takerTokenAmount,
-			});
-			return;
-		} catch (err) {
-			this.setState({
-				isCancelling: false,
-			});
-			const errMsg = `${err}`;
-			if (_.includes(errMsg, 'User denied transaction signature')) {
-				return;
-			}
-			globalErrMsg = 'Failed to cancel order, please refresh and try again';
-			utils.consoleLog(`${err}`);
-			this.setState({
-				globalErrMsg,
-			});
-			await errorReporter.reportAsync(err);
-			return;
-		}
-	}
-	private _formatCurrencyAmount(amount: BigNumber, decimals: number): number {
-		const unitAmount = ZeroEx.toUnitAmount(amount, decimals);
-		const roundedUnitAmount = Math.round(unitAmount.toNumber() * 100000) / 100000;
-		return roundedUnitAmount;
-	}
-	private _onToggleTrackConfirmDialog(didConfirmTokenTracking: boolean) {
-		if (!didConfirmTokenTracking) {
-			this.setState({
-				orderJSON: '',
-				orderJSONErrMsg: '',
-				parsedOrder: undefined,
-			});
-		} else {
-			this.setState({
-				areAllInvolvedTokensTracked: true,
-			});
-		}
-		this.setState({
-			isConfirmingTokenTracking: !this.state.isConfirmingTokenTracking,
-			tokensToTrack: [],
-		});
-	}
+        const signedOrder = this.props.blockchain.portalOrderToSignedOrder(
+            parsedOrder.maker.address,
+            parsedOrder.taker.address,
+            parsedOrder.maker.token.address,
+            parsedOrder.taker.token.address,
+            new BigNumber(parsedOrder.maker.amount),
+            takerTokenAmount,
+            new BigNumber(parsedOrder.maker.feeAmount),
+            new BigNumber(parsedOrder.taker.feeAmount),
+            new BigNumber(this.state.parsedOrder.expiration),
+            parsedOrder.feeRecipient,
+            parsedOrder.signature,
+            new BigNumber(parsedOrder.salt),
+        );
+        const unavailableTakerAmount = await this.props.blockchain.getUnavailableTakerAmountAsync(orderHash);
+        const availableTakerTokenAmount = takerTokenAmount.minus(unavailableTakerAmount);
+        try {
+            await this.props.blockchain.validateCancelOrderThrowIfInvalidAsync(signedOrder, availableTakerTokenAmount);
+        } catch (err) {
+            globalErrMsg = utils.zeroExErrToHumanReadableErrMsg(err.message, parsedOrder.taker.address);
+        }
+        if (!_.isEmpty(globalErrMsg)) {
+            this.setState({
+                isCancelling: false,
+                globalErrMsg,
+            });
+            return;
+        }
+        try {
+            await this.props.blockchain.cancelOrderAsync(signedOrder, availableTakerTokenAmount);
+            this.setState({
+                isCancelling: false,
+                didCancelOrderSucceed: true,
+                globalErrMsg: '',
+                unavailableTakerAmount: takerTokenAmount,
+            });
+            return;
+        } catch (err) {
+            this.setState({
+                isCancelling: false,
+            });
+            const errMsg = `${err}`;
+            if (_.includes(errMsg, 'User denied transaction signature')) {
+                return;
+            }
+            globalErrMsg = 'Failed to cancel order, please refresh and try again';
+            utils.consoleLog(`${err}`);
+            this.setState({
+                globalErrMsg,
+            });
+            await errorReporter.reportAsync(err);
+            return;
+        }
+    }
+    private _formatCurrencyAmount(amount: BigNumber, decimals: number): number {
+        const unitAmount = ZeroEx.toUnitAmount(amount, decimals);
+        const roundedUnitAmount = Math.round(unitAmount.toNumber() * 100000) / 100000;
+        return roundedUnitAmount;
+    }
+    private _onToggleTrackConfirmDialog(didConfirmTokenTracking: boolean) {
+        if (!didConfirmTokenTracking) {
+            this.setState({
+                orderJSON: '',
+                orderJSONErrMsg: '',
+                parsedOrder: undefined,
+            });
+        } else {
+            this.setState({
+                areAllInvolvedTokensTracked: true,
+            });
+        }
+        this.setState({
+            isConfirmingTokenTracking: !this.state.isConfirmingTokenTracking,
+            tokensToTrack: [],
+        });
+    }
 } // tslint:disable:max-file-line-count
diff --git a/packages/website/ts/components/fill_order_json.tsx b/packages/website/ts/components/fill_order_json.tsx
index 3446b8a39..f8e43481a 100644
--- a/packages/website/ts/components/fill_order_json.tsx
+++ b/packages/website/ts/components/fill_order_json.tsx
@@ -10,71 +10,71 @@ import { constants } from 'ts/utils/constants';
 import { utils } from 'ts/utils/utils';
 
 interface FillOrderJSONProps {
-	blockchain: Blockchain;
-	tokenByAddress: TokenByAddress;
-	networkId: number;
-	orderJSON: string;
-	onFillOrderJSONChanged: (event: any) => void;
+    blockchain: Blockchain;
+    tokenByAddress: TokenByAddress;
+    networkId: number;
+    orderJSON: string;
+    onFillOrderJSONChanged: (event: any) => void;
 }
 
 interface FillOrderJSONState {}
 
 export class FillOrderJSON extends React.Component<FillOrderJSONProps, FillOrderJSONState> {
-	public render() {
-		const tokenAddresses = _.keys(this.props.tokenByAddress);
-		const exchangeContract = this.props.blockchain.getExchangeContractAddressIfExists();
-		const hintSideToAssetToken = {
-			[Side.Deposit]: {
-				amount: new BigNumber(35),
-				address: tokenAddresses[0],
-			},
-			[Side.Receive]: {
-				amount: new BigNumber(89),
-				address: tokenAddresses[1],
-			},
-		};
-		const hintOrderExpiryTimestamp = utils.initialOrderExpiryUnixTimestampSec();
-		const hintSignatureData = {
-			hash: '0xf965a9978a0381ab58f5a2408ad967c...',
-			r: '0xf01103f759e2289a28593eaf22e5820032...',
-			s: '937862111edcba395f8a9e0cc1b2c5e12320...',
-			v: 27,
-		};
-		const hintSalt = ZeroEx.generatePseudoRandomSalt();
-		const feeRecipient = constants.NULL_ADDRESS;
-		const hintOrder = utils.generateOrder(
-			this.props.networkId,
-			exchangeContract,
-			hintSideToAssetToken,
-			hintOrderExpiryTimestamp,
-			'',
-			'',
-			constants.MAKER_FEE,
-			constants.TAKER_FEE,
-			feeRecipient,
-			hintSignatureData,
-			this.props.tokenByAddress,
-			hintSalt,
-		);
-		const hintOrderJSON = `${JSON.stringify(hintOrder, null, '\t').substring(0, 500)}...`;
-		return (
-			<div>
-				<Paper className="p1 overflow-hidden" style={{ height: 164 }}>
-					<TextField
-						id="orderJSON"
-						hintStyle={{ bottom: 0, top: 0 }}
-						fullWidth={true}
-						value={this.props.orderJSON}
-						onChange={this.props.onFillOrderJSONChanged.bind(this)}
-						hintText={hintOrderJSON}
-						multiLine={true}
-						rows={6}
-						rowsMax={6}
-						underlineStyle={{ display: 'none' }}
-						textareaStyle={{ marginTop: 0 }}
-					/>
-				</Paper>
-			</div>
-		);
-	}
+    public render() {
+        const tokenAddresses = _.keys(this.props.tokenByAddress);
+        const exchangeContract = this.props.blockchain.getExchangeContractAddressIfExists();
+        const hintSideToAssetToken = {
+            [Side.Deposit]: {
+                amount: new BigNumber(35),
+                address: tokenAddresses[0],
+            },
+            [Side.Receive]: {
+                amount: new BigNumber(89),
+                address: tokenAddresses[1],
+            },
+        };
+        const hintOrderExpiryTimestamp = utils.initialOrderExpiryUnixTimestampSec();
+        const hintSignatureData = {
+            hash: '0xf965a9978a0381ab58f5a2408ad967c...',
+            r: '0xf01103f759e2289a28593eaf22e5820032...',
+            s: '937862111edcba395f8a9e0cc1b2c5e12320...',
+            v: 27,
+        };
+        const hintSalt = ZeroEx.generatePseudoRandomSalt();
+        const feeRecipient = constants.NULL_ADDRESS;
+        const hintOrder = utils.generateOrder(
+            this.props.networkId,
+            exchangeContract,
+            hintSideToAssetToken,
+            hintOrderExpiryTimestamp,
+            '',
+            '',
+            constants.MAKER_FEE,
+            constants.TAKER_FEE,
+            feeRecipient,
+            hintSignatureData,
+            this.props.tokenByAddress,
+            hintSalt,
+        );
+        const hintOrderJSON = `${JSON.stringify(hintOrder, null, '\t').substring(0, 500)}...`;
+        return (
+            <div>
+                <Paper className="p1 overflow-hidden" style={{ height: 164 }}>
+                    <TextField
+                        id="orderJSON"
+                        hintStyle={{ bottom: 0, top: 0 }}
+                        fullWidth={true}
+                        value={this.props.orderJSON}
+                        onChange={this.props.onFillOrderJSONChanged.bind(this)}
+                        hintText={hintOrderJSON}
+                        multiLine={true}
+                        rows={6}
+                        rowsMax={6}
+                        underlineStyle={{ display: 'none' }}
+                        textareaStyle={{ marginTop: 0 }}
+                    />
+                </Paper>
+            </div>
+        );
+    }
 }
diff --git a/packages/website/ts/components/fill_warning_dialog.tsx b/packages/website/ts/components/fill_warning_dialog.tsx
index 40b04723d..165d21b34 100644
--- a/packages/website/ts/components/fill_warning_dialog.tsx
+++ b/packages/website/ts/components/fill_warning_dialog.tsx
@@ -4,42 +4,42 @@ import * as React from 'react';
 import { colors } from 'ts/utils/colors';
 
 interface FillWarningDialogProps {
-	isOpen: boolean;
-	onToggleDialog: (didUserCancel: boolean) => void;
+    isOpen: boolean;
+    onToggleDialog: (didUserCancel: boolean) => void;
 }
 
 export function FillWarningDialog(props: FillWarningDialogProps) {
-	const didCancel = true;
-	return (
-		<Dialog
-			title="Warning"
-			titleStyle={{ fontWeight: 100, color: colors.red500 }}
-			actions={[
-				<FlatButton
-					key="fillWarningCancel"
-					label="Cancel"
-					onTouchTap={props.onToggleDialog.bind(this, didCancel)}
-				/>,
-				<FlatButton
-					key="fillWarningContinue"
-					label="Fill Order"
-					onTouchTap={props.onToggleDialog.bind(this, !didCancel)}
-				/>,
-			]}
-			open={props.isOpen}
-			onRequestClose={props.onToggleDialog.bind(this)}
-			autoScrollBodyContent={true}
-			modal={true}
-		>
-			<div className="pt2" style={{ color: colors.grey700 }}>
-				<div>
-					At least one of the tokens in this order was not found in the token registry smart contract and may
-					be counterfeit. It is your responsibility to verify the token addresses on Etherscan (
-					<a href="https://0xproject.com/wiki#Verifying-Custom-Tokens" target="_blank">
-						See this how-to guide
-					</a>) before filling an order. <b>This action may result in the loss of funds</b>.
-				</div>
-			</div>
-		</Dialog>
-	);
+    const didCancel = true;
+    return (
+        <Dialog
+            title="Warning"
+            titleStyle={{ fontWeight: 100, color: colors.red500 }}
+            actions={[
+                <FlatButton
+                    key="fillWarningCancel"
+                    label="Cancel"
+                    onTouchTap={props.onToggleDialog.bind(this, didCancel)}
+                />,
+                <FlatButton
+                    key="fillWarningContinue"
+                    label="Fill Order"
+                    onTouchTap={props.onToggleDialog.bind(this, !didCancel)}
+                />,
+            ]}
+            open={props.isOpen}
+            onRequestClose={props.onToggleDialog.bind(this)}
+            autoScrollBodyContent={true}
+            modal={true}
+        >
+            <div className="pt2" style={{ color: colors.grey700 }}>
+                <div>
+                    At least one of the tokens in this order was not found in the token registry smart contract and may
+                    be counterfeit. It is your responsibility to verify the token addresses on Etherscan (
+                    <a href="https://0xproject.com/wiki#Verifying-Custom-Tokens" target="_blank">
+                        See this how-to guide
+                    </a>) before filling an order. <b>This action may result in the loss of funds</b>.
+                </div>
+            </div>
+        </Dialog>
+    );
 }
diff --git a/packages/website/ts/components/flash_messages/token_send_completed.tsx b/packages/website/ts/components/flash_messages/token_send_completed.tsx
index 07fca1ddc..18f371624 100644
--- a/packages/website/ts/components/flash_messages/token_send_completed.tsx
+++ b/packages/website/ts/components/flash_messages/token_send_completed.tsx
@@ -7,28 +7,28 @@ import { colors } from 'ts/utils/colors';
 import { utils } from 'ts/utils/utils';
 
 interface TokenSendCompletedProps {
-	etherScanLinkIfExists?: string;
-	token: Token;
-	toAddress: string;
-	amountInBaseUnits: BigNumber;
+    etherScanLinkIfExists?: string;
+    token: Token;
+    toAddress: string;
+    amountInBaseUnits: BigNumber;
 }
 
 interface TokenSendCompletedState {}
 
 export class TokenSendCompleted extends React.Component<TokenSendCompletedProps, TokenSendCompletedState> {
-	public render() {
-		const etherScanLink = !_.isUndefined(this.props.etherScanLinkIfExists) && (
-			<a style={{ color: colors.white }} href={`${this.props.etherScanLinkIfExists}`} target="_blank">
-				Verify on Etherscan
-			</a>
-		);
-		const amountInUnits = ZeroEx.toUnitAmount(this.props.amountInBaseUnits, this.props.token.decimals);
-		const truncatedAddress = utils.getAddressBeginAndEnd(this.props.toAddress);
-		return (
-			<div>
-				{`Sent ${amountInUnits} ${this.props.token.symbol} to ${truncatedAddress}: `}
-				{etherScanLink}
-			</div>
-		);
-	}
+    public render() {
+        const etherScanLink = !_.isUndefined(this.props.etherScanLinkIfExists) && (
+            <a style={{ color: colors.white }} href={`${this.props.etherScanLinkIfExists}`} target="_blank">
+                Verify on Etherscan
+            </a>
+        );
+        const amountInUnits = ZeroEx.toUnitAmount(this.props.amountInBaseUnits, this.props.token.decimals);
+        const truncatedAddress = utils.getAddressBeginAndEnd(this.props.toAddress);
+        return (
+            <div>
+                {`Sent ${amountInUnits} ${this.props.token.symbol} to ${truncatedAddress}: `}
+                {etherScanLink}
+            </div>
+        );
+    }
 }
diff --git a/packages/website/ts/components/flash_messages/transaction_submitted.tsx b/packages/website/ts/components/flash_messages/transaction_submitted.tsx
index 14464b923..862e382dd 100644
--- a/packages/website/ts/components/flash_messages/transaction_submitted.tsx
+++ b/packages/website/ts/components/flash_messages/transaction_submitted.tsx
@@ -3,24 +3,24 @@ import * as React from 'react';
 import { colors } from 'ts/utils/colors';
 
 interface TransactionSubmittedProps {
-	etherScanLinkIfExists?: string;
+    etherScanLinkIfExists?: string;
 }
 
 interface TransactionSubmittedState {}
 
 export class TransactionSubmitted extends React.Component<TransactionSubmittedProps, TransactionSubmittedState> {
-	public render() {
-		if (_.isUndefined(this.props.etherScanLinkIfExists)) {
-			return <div>Transaction submitted to the network</div>;
-		} else {
-			return (
-				<div>
-					Transaction submitted to the network:{' '}
-					<a style={{ color: colors.white }} href={`${this.props.etherScanLinkIfExists}`} target="_blank">
-						Verify on Etherscan
-					</a>
-				</div>
-			);
-		}
-	}
+    public render() {
+        if (_.isUndefined(this.props.etherScanLinkIfExists)) {
+            return <div>Transaction submitted to the network</div>;
+        } else {
+            return (
+                <div>
+                    Transaction submitted to the network:{' '}
+                    <a style={{ color: colors.white }} href={`${this.props.etherScanLinkIfExists}`} target="_blank">
+                        Verify on Etherscan
+                    </a>
+                </div>
+            );
+        }
+    }
 }
diff --git a/packages/website/ts/components/footer.tsx b/packages/website/ts/components/footer.tsx
index 3a342591c..a0f1a0c96 100644
--- a/packages/website/ts/components/footer.tsx
+++ b/packages/website/ts/components/footer.tsx
@@ -6,106 +6,106 @@ import { colors } from 'ts/utils/colors';
 import { constants } from 'ts/utils/constants';
 
 interface MenuItemsBySection {
-	[sectionName: string]: FooterMenuItem[];
+    [sectionName: string]: FooterMenuItem[];
 }
 
 interface FooterMenuItem {
-	title: string;
-	path?: string;
-	isExternal?: boolean;
+    title: string;
+    path?: string;
+    isExternal?: boolean;
 }
 
 enum Sections {
-	Documentation = 'Documentation',
-	Community = 'Community',
-	Organization = 'Organization',
+    Documentation = 'Documentation',
+    Community = 'Community',
+    Organization = 'Organization',
 }
 
 const ICON_DIMENSION = 16;
 const menuItemsBySection: MenuItemsBySection = {
-	Documentation: [
-		{
-			title: '0x.js',
-			path: WebsitePaths.ZeroExJs,
-		},
-		{
-			title: '0x Smart Contracts',
-			path: WebsitePaths.SmartContracts,
-		},
-		{
-			title: '0x Connect',
-			path: WebsitePaths.Connect,
-		},
-		{
-			title: 'Whitepaper',
-			path: WebsitePaths.Whitepaper,
-			isExternal: true,
-		},
-		{
-			title: 'Wiki',
-			path: WebsitePaths.Wiki,
-		},
-		{
-			title: 'FAQ',
-			path: WebsitePaths.FAQ,
-		},
-	],
-	Community: [
-		{
-			title: 'Rocket.chat',
-			isExternal: true,
-			path: constants.URL_ZEROEX_CHAT,
-		},
-		{
-			title: 'Blog',
-			isExternal: true,
-			path: constants.URL_BLOG,
-		},
-		{
-			title: 'Twitter',
-			isExternal: true,
-			path: constants.URL_TWITTER,
-		},
-		{
-			title: 'Reddit',
-			isExternal: true,
-			path: constants.URL_REDDIT,
-		},
-		{
-			title: 'Forum',
-			isExternal: true,
-			path: constants.URL_DISCOURSE_FORUM,
-		},
-	],
-	Organization: [
-		{
-			title: 'About',
-			isExternal: false,
-			path: WebsitePaths.About,
-		},
-		{
-			title: 'Careers',
-			isExternal: true,
-			path: constants.URL_ANGELLIST,
-		},
-		{
-			title: 'Contact',
-			isExternal: true,
-			path: 'mailto:team@0xproject.com',
-		},
-	],
+    Documentation: [
+        {
+            title: '0x.js',
+            path: WebsitePaths.ZeroExJs,
+        },
+        {
+            title: '0x Smart Contracts',
+            path: WebsitePaths.SmartContracts,
+        },
+        {
+            title: '0x Connect',
+            path: WebsitePaths.Connect,
+        },
+        {
+            title: 'Whitepaper',
+            path: WebsitePaths.Whitepaper,
+            isExternal: true,
+        },
+        {
+            title: 'Wiki',
+            path: WebsitePaths.Wiki,
+        },
+        {
+            title: 'FAQ',
+            path: WebsitePaths.FAQ,
+        },
+    ],
+    Community: [
+        {
+            title: 'Rocket.chat',
+            isExternal: true,
+            path: constants.URL_ZEROEX_CHAT,
+        },
+        {
+            title: 'Blog',
+            isExternal: true,
+            path: constants.URL_BLOG,
+        },
+        {
+            title: 'Twitter',
+            isExternal: true,
+            path: constants.URL_TWITTER,
+        },
+        {
+            title: 'Reddit',
+            isExternal: true,
+            path: constants.URL_REDDIT,
+        },
+        {
+            title: 'Forum',
+            isExternal: true,
+            path: constants.URL_DISCOURSE_FORUM,
+        },
+    ],
+    Organization: [
+        {
+            title: 'About',
+            isExternal: false,
+            path: WebsitePaths.About,
+        },
+        {
+            title: 'Careers',
+            isExternal: true,
+            path: constants.URL_ANGELLIST,
+        },
+        {
+            title: 'Contact',
+            isExternal: true,
+            path: 'mailto:team@0xproject.com',
+        },
+    ],
 };
 const linkStyle = {
-	color: colors.white,
-	cursor: 'pointer',
+    color: colors.white,
+    cursor: 'pointer',
 };
 
 const titleToIcon: { [title: string]: string } = {
-	'Rocket.chat': 'rocketchat.png',
-	Blog: 'medium.png',
-	Twitter: 'twitter.png',
-	Reddit: 'reddit.png',
-	Forum: 'discourse.png',
+    'Rocket.chat': 'rocketchat.png',
+    Blog: 'medium.png',
+    Twitter: 'twitter.png',
+    Reddit: 'reddit.png',
+    Forum: 'discourse.png',
 };
 
 export interface FooterProps {}
@@ -113,100 +113,100 @@ export interface FooterProps {}
 interface FooterState {}
 
 export class Footer extends React.Component<FooterProps, FooterState> {
-	public render() {
-		return (
-			<div className="relative pb4 pt2" style={{ backgroundColor: colors.darkerGrey }}>
-				<div className="mx-auto max-width-4 md-px2 lg-px0 py4 clearfix" style={{ color: colors.white }}>
-					<div className="col lg-col-4 md-col-4 col-12 left">
-						<div className="sm-mx-auto" style={{ width: 148 }}>
-							<div>
-								<img src="/images/protocol_logo_white.png" height="30" />
-							</div>
-							<div
-								style={{
-									fontSize: 11,
-									color: colors.grey,
-									paddingLeft: 37,
-									paddingTop: 2,
-								}}
-							>
-								© ZeroEx, Intl.
-							</div>
-						</div>
-					</div>
-					<div className="col lg-col-8 md-col-8 col-12 lg-pl4 md-pl4">
-						<div className="col lg-col-4 md-col-4 col-12">
-							<div className="lg-right md-right sm-center">
-								{this._renderHeader(Sections.Documentation)}
-								{_.map(menuItemsBySection[Sections.Documentation], this._renderMenuItem.bind(this))}
-							</div>
-						</div>
-						<div className="col lg-col-4 md-col-4 col-12 lg-pr2 md-pr2">
-							<div className="lg-right md-right sm-center">
-								{this._renderHeader(Sections.Community)}
-								{_.map(menuItemsBySection[Sections.Community], this._renderMenuItem.bind(this))}
-							</div>
-						</div>
-						<div className="col lg-col-4 md-col-4 col-12">
-							<div className="lg-right md-right sm-center">
-								{this._renderHeader(Sections.Organization)}
-								{_.map(menuItemsBySection[Sections.Organization], this._renderMenuItem.bind(this))}
-							</div>
-						</div>
-					</div>
-				</div>
-			</div>
-		);
-	}
-	private _renderIcon(fileName: string) {
-		return (
-			<div style={{ height: ICON_DIMENSION, width: ICON_DIMENSION }}>
-				<img src={`/images/social/${fileName}`} style={{ width: ICON_DIMENSION }} />
-			</div>
-		);
-	}
-	private _renderMenuItem(item: FooterMenuItem) {
-		const iconIfExists = titleToIcon[item.title];
-		return (
-			<div key={item.title} className="sm-center" style={{ fontSize: 13, paddingTop: 25 }}>
-				{item.isExternal ? (
-					<a className="text-decoration-none" style={linkStyle} target="_blank" href={item.path}>
-						{!_.isUndefined(iconIfExists) ? (
-							<div className="sm-mx-auto" style={{ width: 65 }}>
-								<div className="flex">
-									<div className="pr1">{this._renderIcon(iconIfExists)}</div>
-									<div>{item.title}</div>
-								</div>
-							</div>
-						) : (
-							item.title
-						)}
-					</a>
-				) : (
-					<Link to={item.path} style={linkStyle} className="text-decoration-none">
-						<div>
-							{!_.isUndefined(iconIfExists) && (
-								<div className="pr1">{this._renderIcon(iconIfExists)}</div>
-							)}
-							{item.title}
-						</div>
-					</Link>
-				)}
-			</div>
-		);
-	}
-	private _renderHeader(title: string) {
-		const headerStyle = {
-			textTransform: 'uppercase',
-			color: colors.grey400,
-			letterSpacing: 2,
-			fontFamily: 'Roboto Mono',
-			fontSize: 13,
-		};
-		return (
-			<div className="lg-pb2 md-pb2 sm-pt4" style={headerStyle}>
-				{title}
-			</div>
-		);
-	}
+    public render() {
+        return (
+            <div className="relative pb4 pt2" style={{ backgroundColor: colors.darkerGrey }}>
+                <div className="mx-auto max-width-4 md-px2 lg-px0 py4 clearfix" style={{ color: colors.white }}>
+                    <div className="col lg-col-4 md-col-4 col-12 left">
+                        <div className="sm-mx-auto" style={{ width: 148 }}>
+                            <div>
+                                <img src="/images/protocol_logo_white.png" height="30" />
+                            </div>
+                            <div
+                                style={{
+                                    fontSize: 11,
+                                    color: colors.grey,
+                                    paddingLeft: 37,
+                                    paddingTop: 2,
+                                }}
+                            >
+                                © ZeroEx, Intl.
+                            </div>
+                        </div>
+                    </div>
+                    <div className="col lg-col-8 md-col-8 col-12 lg-pl4 md-pl4">
+                        <div className="col lg-col-4 md-col-4 col-12">
+                            <div className="lg-right md-right sm-center">
+                                {this._renderHeader(Sections.Documentation)}
+                                {_.map(menuItemsBySection[Sections.Documentation], this._renderMenuItem.bind(this))}
+                            </div>
+                        </div>
+                        <div className="col lg-col-4 md-col-4 col-12 lg-pr2 md-pr2">
+                            <div className="lg-right md-right sm-center">
+                                {this._renderHeader(Sections.Community)}
+                                {_.map(menuItemsBySection[Sections.Community], this._renderMenuItem.bind(this))}
+                            </div>
+                        </div>
+                        <div className="col lg-col-4 md-col-4 col-12">
+                            <div className="lg-right md-right sm-center">
+                                {this._renderHeader(Sections.Organization)}
+                                {_.map(menuItemsBySection[Sections.Organization], this._renderMenuItem.bind(this))}
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        );
+    }
+    private _renderIcon(fileName: string) {
+        return (
+            <div style={{ height: ICON_DIMENSION, width: ICON_DIMENSION }}>
+                <img src={`/images/social/${fileName}`} style={{ width: ICON_DIMENSION }} />
+            </div>
+        );
+    }
+    private _renderMenuItem(item: FooterMenuItem) {
+        const iconIfExists = titleToIcon[item.title];
+        return (
+            <div key={item.title} className="sm-center" style={{ fontSize: 13, paddingTop: 25 }}>
+                {item.isExternal ? (
+                    <a className="text-decoration-none" style={linkStyle} target="_blank" href={item.path}>
+                        {!_.isUndefined(iconIfExists) ? (
+                            <div className="sm-mx-auto" style={{ width: 65 }}>
+                                <div className="flex">
+                                    <div className="pr1">{this._renderIcon(iconIfExists)}</div>
+                                    <div>{item.title}</div>
+                                </div>
+                            </div>
+                        ) : (
+                            item.title
+                        )}
+                    </a>
+                ) : (
+                    <Link to={item.path} style={linkStyle} className="text-decoration-none">
+                        <div>
+                            {!_.isUndefined(iconIfExists) && (
+                                <div className="pr1">{this._renderIcon(iconIfExists)}</div>
+                            )}
+                            {item.title}
+                        </div>
+                    </Link>
+                )}
+            </div>
+        );
+    }
+    private _renderHeader(title: string) {
+        const headerStyle = {
+            textTransform: 'uppercase',
+            color: colors.grey400,
+            letterSpacing: 2,
+            fontFamily: 'Roboto Mono',
+            fontSize: 13,
+        };
+        return (
+            <div className="lg-pb2 md-pb2 sm-pt4" style={headerStyle}>
+                {title}
+            </div>
+        );
+    }
 }
diff --git a/packages/website/ts/components/generate_order/asset_picker.tsx b/packages/website/ts/components/generate_order/asset_picker.tsx
index 5eed2fabf..df7d87cfd 100644
--- a/packages/website/ts/components/generate_order/asset_picker.tsx
+++ b/packages/website/ts/components/generate_order/asset_picker.tsx
@@ -13,264 +13,264 @@ import { DialogConfigs, Token, TokenByAddress, TokenState, TokenVisibility } fro
 const TOKEN_ICON_DIMENSION = 100;
 const TILE_DIMENSION = 146;
 enum AssetViews {
-	ASSET_PICKER = 'ASSET_PICKER',
-	NEW_TOKEN_FORM = 'NEW_TOKEN_FORM',
-	CONFIRM_TRACK_TOKEN = 'CONFIRM_TRACK_TOKEN',
+    ASSET_PICKER = 'ASSET_PICKER',
+    NEW_TOKEN_FORM = 'NEW_TOKEN_FORM',
+    CONFIRM_TRACK_TOKEN = 'CONFIRM_TRACK_TOKEN',
 }
 
 interface AssetPickerProps {
-	userAddress: string;
-	blockchain: Blockchain;
-	dispatcher: Dispatcher;
-	networkId: number;
-	isOpen: boolean;
-	currentTokenAddress: string;
-	onTokenChosen: (tokenAddress: string) => void;
-	tokenByAddress: TokenByAddress;
-	tokenVisibility?: TokenVisibility;
+    userAddress: string;
+    blockchain: Blockchain;
+    dispatcher: Dispatcher;
+    networkId: number;
+    isOpen: boolean;
+    currentTokenAddress: string;
+    onTokenChosen: (tokenAddress: string) => void;
+    tokenByAddress: TokenByAddress;
+    tokenVisibility?: TokenVisibility;
 }
 
 interface AssetPickerState {
-	assetView: AssetViews;
-	hoveredAddress: string | undefined;
-	chosenTrackTokenAddress: string;
-	isAddingTokenToTracked: boolean;
+    assetView: AssetViews;
+    hoveredAddress: string | undefined;
+    chosenTrackTokenAddress: string;
+    isAddingTokenToTracked: boolean;
 }
 
 export class AssetPicker extends React.Component<AssetPickerProps, AssetPickerState> {
-	public static defaultProps: Partial<AssetPickerProps> = {
-		tokenVisibility: TokenVisibility.ALL,
-	};
-	private _dialogConfigsByAssetView: { [assetView: string]: DialogConfigs };
-	constructor(props: AssetPickerProps) {
-		super(props);
-		this.state = {
-			assetView: AssetViews.ASSET_PICKER,
-			hoveredAddress: undefined,
-			chosenTrackTokenAddress: undefined,
-			isAddingTokenToTracked: false,
-		};
-		this._dialogConfigsByAssetView = {
-			[AssetViews.ASSET_PICKER]: {
-				title: 'Select token',
-				isModal: false,
-				actions: [],
-			},
-			[AssetViews.NEW_TOKEN_FORM]: {
-				title: 'Add an ERC20 token',
-				isModal: false,
-				actions: [],
-			},
-			[AssetViews.CONFIRM_TRACK_TOKEN]: {
-				title: 'Tracking confirmation',
-				isModal: true,
-				actions: [
-					<FlatButton
-						key="noTracking"
-						label="No"
-						onTouchTap={this._onTrackConfirmationRespondedAsync.bind(this, false)}
-					/>,
-					<FlatButton
-						key="yesTrack"
-						label="Yes"
-						onTouchTap={this._onTrackConfirmationRespondedAsync.bind(this, true)}
-					/>,
-				],
-			},
-		};
-	}
-	public render() {
-		const dialogConfigs: DialogConfigs = this._dialogConfigsByAssetView[this.state.assetView];
-		return (
-			<Dialog
-				title={dialogConfigs.title}
-				titleStyle={{ fontWeight: 100 }}
-				modal={dialogConfigs.isModal}
-				open={this.props.isOpen}
-				actions={dialogConfigs.actions}
-				onRequestClose={this._onCloseDialog.bind(this)}
-			>
-				{this.state.assetView === AssetViews.ASSET_PICKER && this._renderAssetPicker()}
-				{this.state.assetView === AssetViews.NEW_TOKEN_FORM && (
-					<NewTokenForm
-						blockchain={this.props.blockchain}
-						onNewTokenSubmitted={this._onNewTokenSubmitted.bind(this)}
-						tokenByAddress={this.props.tokenByAddress}
-					/>
-				)}
-				{this.state.assetView === AssetViews.CONFIRM_TRACK_TOKEN && this._renderConfirmTrackToken()}
-			</Dialog>
-		);
-	}
-	private _renderConfirmTrackToken() {
-		const token = this.props.tokenByAddress[this.state.chosenTrackTokenAddress];
-		return (
-			<TrackTokenConfirmation
-				tokens={[token]}
-				tokenByAddress={this.props.tokenByAddress}
-				networkId={this.props.networkId}
-				isAddingTokenToTracked={this.state.isAddingTokenToTracked}
-			/>
-		);
-	}
-	private _renderAssetPicker() {
-		return (
-			<div
-				className="clearfix flex flex-wrap"
-				style={{
-					overflowY: 'auto',
-					maxWidth: 720,
-					maxHeight: 356,
-					marginBottom: 10,
-				}}
-			>
-				{this._renderGridTiles()}
-			</div>
-		);
-	}
-	private _renderGridTiles() {
-		let isHovered;
-		let tileStyles;
-		const gridTiles = _.map(this.props.tokenByAddress, (token: Token, address: string) => {
-			if (
-				(this.props.tokenVisibility === TokenVisibility.TRACKED && !token.isTracked) ||
-				(this.props.tokenVisibility === TokenVisibility.UNTRACKED && token.isTracked)
-			) {
-				return null; // Skip
-			}
-			isHovered = this.state.hoveredAddress === address;
-			tileStyles = {
-				cursor: 'pointer',
-				opacity: isHovered ? 0.6 : 1,
-			};
-			return (
-				<div
-					key={address}
-					style={{
-						width: TILE_DIMENSION,
-						height: TILE_DIMENSION,
-						...tileStyles,
-					}}
-					className="p2 mx-auto"
-					onClick={this._onChooseToken.bind(this, address)}
-					onMouseEnter={this._onToggleHover.bind(this, address, true)}
-					onMouseLeave={this._onToggleHover.bind(this, address, false)}
-				>
-					<div className="p1 center">
-						<TokenIcon token={token} diameter={TOKEN_ICON_DIMENSION} />
-					</div>
-					<div className="center">{token.name}</div>
-				</div>
-			);
-		});
-		const otherTokenKey = 'otherToken';
-		isHovered = this.state.hoveredAddress === otherTokenKey;
-		tileStyles = {
-			cursor: 'pointer',
-			opacity: isHovered ? 0.6 : 1,
-		};
-		if (this.props.tokenVisibility !== TokenVisibility.TRACKED) {
-			gridTiles.push(
-				<div
-					key={otherTokenKey}
-					style={{
-						width: TILE_DIMENSION,
-						height: TILE_DIMENSION,
-						...tileStyles,
-					}}
-					className="p2 mx-auto"
-					onClick={this._onCustomAssetChosen.bind(this)}
-					onMouseEnter={this._onToggleHover.bind(this, otherTokenKey, true)}
-					onMouseLeave={this._onToggleHover.bind(this, otherTokenKey, false)}
-				>
-					<div className="p1 center">
-						<i
-							style={{ fontSize: 105, paddingLeft: 1, paddingRight: 1 }}
-							className="zmdi zmdi-plus-circle"
-						/>
-					</div>
-					<div className="center">Other ERC20 Token</div>
-				</div>,
-			);
-		}
-		return gridTiles;
-	}
-	private _onToggleHover(address: string, isHovered: boolean) {
-		const hoveredAddress = isHovered ? address : undefined;
-		this.setState({
-			hoveredAddress,
-		});
-	}
-	private _onCloseDialog() {
-		this.setState({
-			assetView: AssetViews.ASSET_PICKER,
-		});
-		this.props.onTokenChosen(this.props.currentTokenAddress);
-	}
-	private _onChooseToken(tokenAddress: string) {
-		const token = this.props.tokenByAddress[tokenAddress];
-		if (token.isTracked) {
-			this.props.onTokenChosen(tokenAddress);
-		} else {
-			this.setState({
-				assetView: AssetViews.CONFIRM_TRACK_TOKEN,
-				chosenTrackTokenAddress: tokenAddress,
-			});
-		}
-	}
-	private _onCustomAssetChosen() {
-		this.setState({
-			assetView: AssetViews.NEW_TOKEN_FORM,
-		});
-	}
-	private _onNewTokenSubmitted(newToken: Token, newTokenState: TokenState) {
-		this.props.dispatcher.updateTokenStateByAddress({
-			[newToken.address]: newTokenState,
-		});
-		trackedTokenStorage.addTrackedTokenToUser(this.props.userAddress, this.props.networkId, newToken);
-		this.props.dispatcher.addTokenToTokenByAddress(newToken);
-		this.setState({
-			assetView: AssetViews.ASSET_PICKER,
-		});
-		this.props.onTokenChosen(newToken.address);
-	}
-	private async _onTrackConfirmationRespondedAsync(didUserAcceptTracking: boolean) {
-		if (!didUserAcceptTracking) {
-			this.setState({
-				isAddingTokenToTracked: false,
-				assetView: AssetViews.ASSET_PICKER,
-				chosenTrackTokenAddress: undefined,
-			});
-			this._onCloseDialog();
-			return;
-		}
-		this.setState({
-			isAddingTokenToTracked: true,
-		});
-		const tokenAddress = this.state.chosenTrackTokenAddress;
-		const token = this.props.tokenByAddress[tokenAddress];
-		const newTokenEntry = {
-			...token,
-		};
+    public static defaultProps: Partial<AssetPickerProps> = {
+        tokenVisibility: TokenVisibility.ALL,
+    };
+    private _dialogConfigsByAssetView: { [assetView: string]: DialogConfigs };
+    constructor(props: AssetPickerProps) {
+        super(props);
+        this.state = {
+            assetView: AssetViews.ASSET_PICKER,
+            hoveredAddress: undefined,
+            chosenTrackTokenAddress: undefined,
+            isAddingTokenToTracked: false,
+        };
+        this._dialogConfigsByAssetView = {
+            [AssetViews.ASSET_PICKER]: {
+                title: 'Select token',
+                isModal: false,
+                actions: [],
+            },
+            [AssetViews.NEW_TOKEN_FORM]: {
+                title: 'Add an ERC20 token',
+                isModal: false,
+                actions: [],
+            },
+            [AssetViews.CONFIRM_TRACK_TOKEN]: {
+                title: 'Tracking confirmation',
+                isModal: true,
+                actions: [
+                    <FlatButton
+                        key="noTracking"
+                        label="No"
+                        onTouchTap={this._onTrackConfirmationRespondedAsync.bind(this, false)}
+                    />,
+                    <FlatButton
+                        key="yesTrack"
+                        label="Yes"
+                        onTouchTap={this._onTrackConfirmationRespondedAsync.bind(this, true)}
+                    />,
+                ],
+            },
+        };
+    }
+    public render() {
+        const dialogConfigs: DialogConfigs = this._dialogConfigsByAssetView[this.state.assetView];
+        return (
+            <Dialog
+                title={dialogConfigs.title}
+                titleStyle={{ fontWeight: 100 }}
+                modal={dialogConfigs.isModal}
+                open={this.props.isOpen}
+                actions={dialogConfigs.actions}
+                onRequestClose={this._onCloseDialog.bind(this)}
+            >
+                {this.state.assetView === AssetViews.ASSET_PICKER && this._renderAssetPicker()}
+                {this.state.assetView === AssetViews.NEW_TOKEN_FORM && (
+                    <NewTokenForm
+                        blockchain={this.props.blockchain}
+                        onNewTokenSubmitted={this._onNewTokenSubmitted.bind(this)}
+                        tokenByAddress={this.props.tokenByAddress}
+                    />
+                )}
+                {this.state.assetView === AssetViews.CONFIRM_TRACK_TOKEN && this._renderConfirmTrackToken()}
+            </Dialog>
+        );
+    }
+    private _renderConfirmTrackToken() {
+        const token = this.props.tokenByAddress[this.state.chosenTrackTokenAddress];
+        return (
+            <TrackTokenConfirmation
+                tokens={[token]}
+                tokenByAddress={this.props.tokenByAddress}
+                networkId={this.props.networkId}
+                isAddingTokenToTracked={this.state.isAddingTokenToTracked}
+            />
+        );
+    }
+    private _renderAssetPicker() {
+        return (
+            <div
+                className="clearfix flex flex-wrap"
+                style={{
+                    overflowY: 'auto',
+                    maxWidth: 720,
+                    maxHeight: 356,
+                    marginBottom: 10,
+                }}
+            >
+                {this._renderGridTiles()}
+            </div>
+        );
+    }
+    private _renderGridTiles() {
+        let isHovered;
+        let tileStyles;
+        const gridTiles = _.map(this.props.tokenByAddress, (token: Token, address: string) => {
+            if (
+                (this.props.tokenVisibility === TokenVisibility.TRACKED && !token.isTracked) ||
+                (this.props.tokenVisibility === TokenVisibility.UNTRACKED && token.isTracked)
+            ) {
+                return null; // Skip
+            }
+            isHovered = this.state.hoveredAddress === address;
+            tileStyles = {
+                cursor: 'pointer',
+                opacity: isHovered ? 0.6 : 1,
+            };
+            return (
+                <div
+                    key={address}
+                    style={{
+                        width: TILE_DIMENSION,
+                        height: TILE_DIMENSION,
+                        ...tileStyles,
+                    }}
+                    className="p2 mx-auto"
+                    onClick={this._onChooseToken.bind(this, address)}
+                    onMouseEnter={this._onToggleHover.bind(this, address, true)}
+                    onMouseLeave={this._onToggleHover.bind(this, address, false)}
+                >
+                    <div className="p1 center">
+                        <TokenIcon token={token} diameter={TOKEN_ICON_DIMENSION} />
+                    </div>
+                    <div className="center">{token.name}</div>
+                </div>
+            );
+        });
+        const otherTokenKey = 'otherToken';
+        isHovered = this.state.hoveredAddress === otherTokenKey;
+        tileStyles = {
+            cursor: 'pointer',
+            opacity: isHovered ? 0.6 : 1,
+        };
+        if (this.props.tokenVisibility !== TokenVisibility.TRACKED) {
+            gridTiles.push(
+                <div
+                    key={otherTokenKey}
+                    style={{
+                        width: TILE_DIMENSION,
+                        height: TILE_DIMENSION,
+                        ...tileStyles,
+                    }}
+                    className="p2 mx-auto"
+                    onClick={this._onCustomAssetChosen.bind(this)}
+                    onMouseEnter={this._onToggleHover.bind(this, otherTokenKey, true)}
+                    onMouseLeave={this._onToggleHover.bind(this, otherTokenKey, false)}
+                >
+                    <div className="p1 center">
+                        <i
+                            style={{ fontSize: 105, paddingLeft: 1, paddingRight: 1 }}
+                            className="zmdi zmdi-plus-circle"
+                        />
+                    </div>
+                    <div className="center">Other ERC20 Token</div>
+                </div>,
+            );
+        }
+        return gridTiles;
+    }
+    private _onToggleHover(address: string, isHovered: boolean) {
+        const hoveredAddress = isHovered ? address : undefined;
+        this.setState({
+            hoveredAddress,
+        });
+    }
+    private _onCloseDialog() {
+        this.setState({
+            assetView: AssetViews.ASSET_PICKER,
+        });
+        this.props.onTokenChosen(this.props.currentTokenAddress);
+    }
+    private _onChooseToken(tokenAddress: string) {
+        const token = this.props.tokenByAddress[tokenAddress];
+        if (token.isTracked) {
+            this.props.onTokenChosen(tokenAddress);
+        } else {
+            this.setState({
+                assetView: AssetViews.CONFIRM_TRACK_TOKEN,
+                chosenTrackTokenAddress: tokenAddress,
+            });
+        }
+    }
+    private _onCustomAssetChosen() {
+        this.setState({
+            assetView: AssetViews.NEW_TOKEN_FORM,
+        });
+    }
+    private _onNewTokenSubmitted(newToken: Token, newTokenState: TokenState) {
+        this.props.dispatcher.updateTokenStateByAddress({
+            [newToken.address]: newTokenState,
+        });
+        trackedTokenStorage.addTrackedTokenToUser(this.props.userAddress, this.props.networkId, newToken);
+        this.props.dispatcher.addTokenToTokenByAddress(newToken);
+        this.setState({
+            assetView: AssetViews.ASSET_PICKER,
+        });
+        this.props.onTokenChosen(newToken.address);
+    }
+    private async _onTrackConfirmationRespondedAsync(didUserAcceptTracking: boolean) {
+        if (!didUserAcceptTracking) {
+            this.setState({
+                isAddingTokenToTracked: false,
+                assetView: AssetViews.ASSET_PICKER,
+                chosenTrackTokenAddress: undefined,
+            });
+            this._onCloseDialog();
+            return;
+        }
+        this.setState({
+            isAddingTokenToTracked: true,
+        });
+        const tokenAddress = this.state.chosenTrackTokenAddress;
+        const token = this.props.tokenByAddress[tokenAddress];
+        const newTokenEntry = {
+            ...token,
+        };
 
-		newTokenEntry.isTracked = true;
-		trackedTokenStorage.addTrackedTokenToUser(this.props.userAddress, this.props.networkId, newTokenEntry);
+        newTokenEntry.isTracked = true;
+        trackedTokenStorage.addTrackedTokenToUser(this.props.userAddress, this.props.networkId, newTokenEntry);
 
-		const [balance, allowance] = await this.props.blockchain.getCurrentUserTokenBalanceAndAllowanceAsync(
-			token.address,
-		);
-		this.props.dispatcher.updateTokenStateByAddress({
-			[token.address]: {
-				balance,
-				allowance,
-			},
-		});
-		this.props.dispatcher.updateTokenByAddress([newTokenEntry]);
-		this.setState({
-			isAddingTokenToTracked: false,
-			assetView: AssetViews.ASSET_PICKER,
-			chosenTrackTokenAddress: undefined,
-		});
-		this.props.onTokenChosen(tokenAddress);
-	}
+        const [balance, allowance] = await this.props.blockchain.getCurrentUserTokenBalanceAndAllowanceAsync(
+            token.address,
+        );
+        this.props.dispatcher.updateTokenStateByAddress({
+            [token.address]: {
+                balance,
+                allowance,
+            },
+        });
+        this.props.dispatcher.updateTokenByAddress([newTokenEntry]);
+        this.setState({
+            isAddingTokenToTracked: false,
+            assetView: AssetViews.ASSET_PICKER,
+            chosenTrackTokenAddress: undefined,
+        });
+        this.props.onTokenChosen(tokenAddress);
+    }
 }
diff --git a/packages/website/ts/components/generate_order/generate_order_form.tsx b/packages/website/ts/components/generate_order/generate_order_form.tsx
index b10b2d609..3ae0d48a7 100644
--- a/packages/website/ts/components/generate_order/generate_order_form.tsx
+++ b/packages/website/ts/components/generate_order/generate_order_form.tsx
@@ -19,335 +19,335 @@ import { Dispatcher } from 'ts/redux/dispatcher';
 import { orderSchema } from 'ts/schemas/order_schema';
 import { SchemaValidator } from 'ts/schemas/validator';
 import {
-	AlertTypes,
-	BlockchainErrs,
-	HashData,
-	Side,
-	SideToAssetToken,
-	SignatureData,
-	Token,
-	TokenByAddress,
-	TokenStateByAddress,
+    AlertTypes,
+    BlockchainErrs,
+    HashData,
+    Side,
+    SideToAssetToken,
+    SignatureData,
+    Token,
+    TokenByAddress,
+    TokenStateByAddress,
 } from 'ts/types';
 import { colors } from 'ts/utils/colors';
 import { errorReporter } from 'ts/utils/error_reporter';
 import { utils } from 'ts/utils/utils';
 
 enum SigningState {
-	UNSIGNED,
-	SIGNING,
-	SIGNED,
+    UNSIGNED,
+    SIGNING,
+    SIGNED,
 }
 
 interface GenerateOrderFormProps {
-	blockchain: Blockchain;
-	blockchainErr: BlockchainErrs;
-	blockchainIsLoaded: boolean;
-	dispatcher: Dispatcher;
-	hashData: HashData;
-	orderExpiryTimestamp: BigNumber;
-	networkId: number;
-	userAddress: string;
-	orderSignatureData: SignatureData;
-	orderTakerAddress: string;
-	orderSalt: BigNumber;
-	sideToAssetToken: SideToAssetToken;
-	tokenByAddress: TokenByAddress;
-	tokenStateByAddress: TokenStateByAddress;
+    blockchain: Blockchain;
+    blockchainErr: BlockchainErrs;
+    blockchainIsLoaded: boolean;
+    dispatcher: Dispatcher;
+    hashData: HashData;
+    orderExpiryTimestamp: BigNumber;
+    networkId: number;
+    userAddress: string;
+    orderSignatureData: SignatureData;
+    orderTakerAddress: string;
+    orderSalt: BigNumber;
+    sideToAssetToken: SideToAssetToken;
+    tokenByAddress: TokenByAddress;
+    tokenStateByAddress: TokenStateByAddress;
 }
 
 interface GenerateOrderFormState {
-	globalErrMsg: string;
-	shouldShowIncompleteErrs: boolean;
-	signingState: SigningState;
+    globalErrMsg: string;
+    shouldShowIncompleteErrs: boolean;
+    signingState: SigningState;
 }
 
 export class GenerateOrderForm extends React.Component<GenerateOrderFormProps, GenerateOrderFormState> {
-	private _validator: SchemaValidator;
-	constructor(props: GenerateOrderFormProps) {
-		super(props);
-		this.state = {
-			globalErrMsg: '',
-			shouldShowIncompleteErrs: false,
-			signingState: SigningState.UNSIGNED,
-		};
-		this._validator = new SchemaValidator();
-	}
-	public componentDidMount() {
-		window.scrollTo(0, 0);
-	}
-	public render() {
-		const dispatcher = this.props.dispatcher;
-		const depositTokenAddress = this.props.sideToAssetToken[Side.Deposit].address;
-		const depositToken = this.props.tokenByAddress[depositTokenAddress];
-		const depositTokenState = this.props.tokenStateByAddress[depositTokenAddress];
-		const receiveTokenAddress = this.props.sideToAssetToken[Side.Receive].address;
-		const receiveToken = this.props.tokenByAddress[receiveTokenAddress];
-		const receiveTokenState = this.props.tokenStateByAddress[receiveTokenAddress];
-		const takerExplanation =
-			'If a taker is specified, only they are<br> \
+    private _validator: SchemaValidator;
+    constructor(props: GenerateOrderFormProps) {
+        super(props);
+        this.state = {
+            globalErrMsg: '',
+            shouldShowIncompleteErrs: false,
+            signingState: SigningState.UNSIGNED,
+        };
+        this._validator = new SchemaValidator();
+    }
+    public componentDidMount() {
+        window.scrollTo(0, 0);
+    }
+    public render() {
+        const dispatcher = this.props.dispatcher;
+        const depositTokenAddress = this.props.sideToAssetToken[Side.Deposit].address;
+        const depositToken = this.props.tokenByAddress[depositTokenAddress];
+        const depositTokenState = this.props.tokenStateByAddress[depositTokenAddress];
+        const receiveTokenAddress = this.props.sideToAssetToken[Side.Receive].address;
+        const receiveToken = this.props.tokenByAddress[receiveTokenAddress];
+        const receiveTokenState = this.props.tokenStateByAddress[receiveTokenAddress];
+        const takerExplanation =
+            'If a taker is specified, only they are<br> \
                                   allowed to fill this order. If no taker is<br> \
                                   specified, anyone is able to fill it.';
-		const exchangeContractIfExists = this.props.blockchain.getExchangeContractAddressIfExists();
-		return (
-			<div className="clearfix mb2 lg-px4 md-px4 sm-px2">
-				<h3>Generate an order</h3>
-				<Divider />
-				<div className="mx-auto" style={{ maxWidth: 580 }}>
-					<div className="pt3">
-						<div className="mx-auto clearfix">
-							<div className="lg-col md-col lg-col-5 md-col-5 sm-col sm-col-5 sm-pb2">
-								<TokenInput
-									userAddress={this.props.userAddress}
-									blockchain={this.props.blockchain}
-									blockchainErr={this.props.blockchainErr}
-									dispatcher={this.props.dispatcher}
-									label="Selling"
-									side={Side.Deposit}
-									networkId={this.props.networkId}
-									assetToken={this.props.sideToAssetToken[Side.Deposit]}
-									updateChosenAssetToken={dispatcher.updateChosenAssetToken.bind(dispatcher)}
-									tokenByAddress={this.props.tokenByAddress}
-								/>
-								<TokenAmountInput
-									label="Sell amount"
-									token={depositToken}
-									tokenState={depositTokenState}
-									amount={this.props.sideToAssetToken[Side.Deposit].amount}
-									onChange={this._onTokenAmountChange.bind(this, depositToken, Side.Deposit)}
-									shouldShowIncompleteErrs={this.state.shouldShowIncompleteErrs}
-									shouldCheckBalance={true}
-									shouldCheckAllowance={true}
-								/>
-							</div>
-							<div className="lg-col md-col lg-col-2 md-col-2 sm-col sm-col-2 xs-hide">
-								<div className="p1">
-									<SwapIcon swapTokensFn={dispatcher.swapAssetTokenSymbols.bind(dispatcher)} />
-								</div>
-							</div>
-							<div className="lg-col md-col lg-col-5 md-col-5 sm-col sm-col-5 sm-pb2">
-								<TokenInput
-									userAddress={this.props.userAddress}
-									blockchain={this.props.blockchain}
-									blockchainErr={this.props.blockchainErr}
-									dispatcher={this.props.dispatcher}
-									label="Buying"
-									side={Side.Receive}
-									networkId={this.props.networkId}
-									assetToken={this.props.sideToAssetToken[Side.Receive]}
-									updateChosenAssetToken={dispatcher.updateChosenAssetToken.bind(dispatcher)}
-									tokenByAddress={this.props.tokenByAddress}
-								/>
-								<TokenAmountInput
-									label="Receive amount"
-									token={receiveToken}
-									tokenState={receiveTokenState}
-									amount={this.props.sideToAssetToken[Side.Receive].amount}
-									onChange={this._onTokenAmountChange.bind(this, receiveToken, Side.Receive)}
-									shouldShowIncompleteErrs={this.state.shouldShowIncompleteErrs}
-									shouldCheckBalance={false}
-									shouldCheckAllowance={false}
-								/>
-							</div>
-						</div>
-					</div>
-					<div className="pt1 sm-pb2 lg-px4 md-px4">
-						<div className="lg-px3 md-px3">
-							<div style={{ fontSize: 12, color: colors.grey }}>Expiration</div>
-							<ExpirationInput
-								orderExpiryTimestamp={this.props.orderExpiryTimestamp}
-								updateOrderExpiry={dispatcher.updateOrderExpiry.bind(dispatcher)}
-							/>
-						</div>
-					</div>
-					<div className="pt1 flex mx-auto">
-						<IdenticonAddressInput
-							label="Taker"
-							initialAddress={this.props.orderTakerAddress}
-							updateOrderAddress={this._updateOrderAddress.bind(this)}
-						/>
-						<div className="pt3">
-							<div className="pl1">
-								<HelpTooltip explanation={takerExplanation} />
-							</div>
-						</div>
-					</div>
-					<div>
-						<HashInput
-							blockchain={this.props.blockchain}
-							blockchainIsLoaded={this.props.blockchainIsLoaded}
-							hashData={this.props.hashData}
-							label="Order Hash"
-						/>
-					</div>
-					<div className="pt2">
-						<div className="center">
-							<LifeCycleRaisedButton
-								labelReady="Sign hash"
-								labelLoading="Signing..."
-								labelComplete="Hash signed!"
-								onClickAsyncFn={this._onSignClickedAsync.bind(this)}
-							/>
-						</div>
-						{this.state.globalErrMsg !== '' && (
-							<Alert type={AlertTypes.ERROR} message={this.state.globalErrMsg} />
-						)}
-					</div>
-				</div>
-				<Dialog
-					title="Order JSON"
-					titleStyle={{ fontWeight: 100 }}
-					modal={false}
-					open={this.state.signingState === SigningState.SIGNED}
-					onRequestClose={this._onCloseOrderJSONDialog.bind(this)}
-				>
-					<OrderJSON
-						exchangeContractIfExists={exchangeContractIfExists}
-						orderExpiryTimestamp={this.props.orderExpiryTimestamp}
-						orderSignatureData={this.props.orderSignatureData}
-						orderTakerAddress={this.props.orderTakerAddress}
-						orderMakerAddress={this.props.userAddress}
-						orderSalt={this.props.orderSalt}
-						orderMakerFee={this.props.hashData.makerFee}
-						orderTakerFee={this.props.hashData.takerFee}
-						orderFeeRecipient={this.props.hashData.feeRecipientAddress}
-						networkId={this.props.networkId}
-						sideToAssetToken={this.props.sideToAssetToken}
-						tokenByAddress={this.props.tokenByAddress}
-					/>
-				</Dialog>
-			</div>
-		);
-	}
-	private _onTokenAmountChange(token: Token, side: Side, isValid: boolean, amount?: BigNumber) {
-		this.props.dispatcher.updateChosenAssetToken(side, {
-			address: token.address,
-			amount,
-		});
-	}
-	private _onCloseOrderJSONDialog() {
-		// Upon closing the order JSON dialog, we update the orderSalt stored in the Redux store
-		// with a new value so that if a user signs the identical order again, the newly signed
-		// orderHash will not collide with the previously generated orderHash.
-		this.props.dispatcher.updateOrderSalt(ZeroEx.generatePseudoRandomSalt());
-		this.setState({
-			signingState: SigningState.UNSIGNED,
-		});
-	}
-	private async _onSignClickedAsync(): Promise<boolean> {
-		if (this.props.blockchainErr !== BlockchainErrs.NoError) {
-			this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
-			return false;
-		}
+        const exchangeContractIfExists = this.props.blockchain.getExchangeContractAddressIfExists();
+        return (
+            <div className="clearfix mb2 lg-px4 md-px4 sm-px2">
+                <h3>Generate an order</h3>
+                <Divider />
+                <div className="mx-auto" style={{ maxWidth: 580 }}>
+                    <div className="pt3">
+                        <div className="mx-auto clearfix">
+                            <div className="lg-col md-col lg-col-5 md-col-5 sm-col sm-col-5 sm-pb2">
+                                <TokenInput
+                                    userAddress={this.props.userAddress}
+                                    blockchain={this.props.blockchain}
+                                    blockchainErr={this.props.blockchainErr}
+                                    dispatcher={this.props.dispatcher}
+                                    label="Selling"
+                                    side={Side.Deposit}
+                                    networkId={this.props.networkId}
+                                    assetToken={this.props.sideToAssetToken[Side.Deposit]}
+                                    updateChosenAssetToken={dispatcher.updateChosenAssetToken.bind(dispatcher)}
+                                    tokenByAddress={this.props.tokenByAddress}
+                                />
+                                <TokenAmountInput
+                                    label="Sell amount"
+                                    token={depositToken}
+                                    tokenState={depositTokenState}
+                                    amount={this.props.sideToAssetToken[Side.Deposit].amount}
+                                    onChange={this._onTokenAmountChange.bind(this, depositToken, Side.Deposit)}
+                                    shouldShowIncompleteErrs={this.state.shouldShowIncompleteErrs}
+                                    shouldCheckBalance={true}
+                                    shouldCheckAllowance={true}
+                                />
+                            </div>
+                            <div className="lg-col md-col lg-col-2 md-col-2 sm-col sm-col-2 xs-hide">
+                                <div className="p1">
+                                    <SwapIcon swapTokensFn={dispatcher.swapAssetTokenSymbols.bind(dispatcher)} />
+                                </div>
+                            </div>
+                            <div className="lg-col md-col lg-col-5 md-col-5 sm-col sm-col-5 sm-pb2">
+                                <TokenInput
+                                    userAddress={this.props.userAddress}
+                                    blockchain={this.props.blockchain}
+                                    blockchainErr={this.props.blockchainErr}
+                                    dispatcher={this.props.dispatcher}
+                                    label="Buying"
+                                    side={Side.Receive}
+                                    networkId={this.props.networkId}
+                                    assetToken={this.props.sideToAssetToken[Side.Receive]}
+                                    updateChosenAssetToken={dispatcher.updateChosenAssetToken.bind(dispatcher)}
+                                    tokenByAddress={this.props.tokenByAddress}
+                                />
+                                <TokenAmountInput
+                                    label="Receive amount"
+                                    token={receiveToken}
+                                    tokenState={receiveTokenState}
+                                    amount={this.props.sideToAssetToken[Side.Receive].amount}
+                                    onChange={this._onTokenAmountChange.bind(this, receiveToken, Side.Receive)}
+                                    shouldShowIncompleteErrs={this.state.shouldShowIncompleteErrs}
+                                    shouldCheckBalance={false}
+                                    shouldCheckAllowance={false}
+                                />
+                            </div>
+                        </div>
+                    </div>
+                    <div className="pt1 sm-pb2 lg-px4 md-px4">
+                        <div className="lg-px3 md-px3">
+                            <div style={{ fontSize: 12, color: colors.grey }}>Expiration</div>
+                            <ExpirationInput
+                                orderExpiryTimestamp={this.props.orderExpiryTimestamp}
+                                updateOrderExpiry={dispatcher.updateOrderExpiry.bind(dispatcher)}
+                            />
+                        </div>
+                    </div>
+                    <div className="pt1 flex mx-auto">
+                        <IdenticonAddressInput
+                            label="Taker"
+                            initialAddress={this.props.orderTakerAddress}
+                            updateOrderAddress={this._updateOrderAddress.bind(this)}
+                        />
+                        <div className="pt3">
+                            <div className="pl1">
+                                <HelpTooltip explanation={takerExplanation} />
+                            </div>
+                        </div>
+                    </div>
+                    <div>
+                        <HashInput
+                            blockchain={this.props.blockchain}
+                            blockchainIsLoaded={this.props.blockchainIsLoaded}
+                            hashData={this.props.hashData}
+                            label="Order Hash"
+                        />
+                    </div>
+                    <div className="pt2">
+                        <div className="center">
+                            <LifeCycleRaisedButton
+                                labelReady="Sign hash"
+                                labelLoading="Signing..."
+                                labelComplete="Hash signed!"
+                                onClickAsyncFn={this._onSignClickedAsync.bind(this)}
+                            />
+                        </div>
+                        {this.state.globalErrMsg !== '' && (
+                            <Alert type={AlertTypes.ERROR} message={this.state.globalErrMsg} />
+                        )}
+                    </div>
+                </div>
+                <Dialog
+                    title="Order JSON"
+                    titleStyle={{ fontWeight: 100 }}
+                    modal={false}
+                    open={this.state.signingState === SigningState.SIGNED}
+                    onRequestClose={this._onCloseOrderJSONDialog.bind(this)}
+                >
+                    <OrderJSON
+                        exchangeContractIfExists={exchangeContractIfExists}
+                        orderExpiryTimestamp={this.props.orderExpiryTimestamp}
+                        orderSignatureData={this.props.orderSignatureData}
+                        orderTakerAddress={this.props.orderTakerAddress}
+                        orderMakerAddress={this.props.userAddress}
+                        orderSalt={this.props.orderSalt}
+                        orderMakerFee={this.props.hashData.makerFee}
+                        orderTakerFee={this.props.hashData.takerFee}
+                        orderFeeRecipient={this.props.hashData.feeRecipientAddress}
+                        networkId={this.props.networkId}
+                        sideToAssetToken={this.props.sideToAssetToken}
+                        tokenByAddress={this.props.tokenByAddress}
+                    />
+                </Dialog>
+            </div>
+        );
+    }
+    private _onTokenAmountChange(token: Token, side: Side, isValid: boolean, amount?: BigNumber) {
+        this.props.dispatcher.updateChosenAssetToken(side, {
+            address: token.address,
+            amount,
+        });
+    }
+    private _onCloseOrderJSONDialog() {
+        // Upon closing the order JSON dialog, we update the orderSalt stored in the Redux store
+        // with a new value so that if a user signs the identical order again, the newly signed
+        // orderHash will not collide with the previously generated orderHash.
+        this.props.dispatcher.updateOrderSalt(ZeroEx.generatePseudoRandomSalt());
+        this.setState({
+            signingState: SigningState.UNSIGNED,
+        });
+    }
+    private async _onSignClickedAsync(): Promise<boolean> {
+        if (this.props.blockchainErr !== BlockchainErrs.NoError) {
+            this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
+            return false;
+        }
 
-		// Check if all required inputs were supplied
-		const debitToken = this.props.sideToAssetToken[Side.Deposit];
-		const debitBalance = this.props.tokenStateByAddress[debitToken.address].balance;
-		const debitAllowance = this.props.tokenStateByAddress[debitToken.address].allowance;
-		const receiveAmount = this.props.sideToAssetToken[Side.Receive].amount;
-		if (
-			!_.isUndefined(debitToken.amount) &&
-			!_.isUndefined(receiveAmount) &&
-			debitToken.amount.gt(0) &&
-			receiveAmount.gt(0) &&
-			this.props.userAddress !== '' &&
-			debitBalance.gte(debitToken.amount) &&
-			debitAllowance.gte(debitToken.amount)
-		) {
-			const didSignSuccessfully = await this._signTransactionAsync();
-			if (didSignSuccessfully) {
-				this.setState({
-					globalErrMsg: '',
-					shouldShowIncompleteErrs: false,
-				});
-			}
-			return didSignSuccessfully;
-		} else {
-			let globalErrMsg = 'You must fix the above errors in order to generate a valid order';
-			if (this.props.userAddress === '') {
-				globalErrMsg = 'You must enable wallet communication';
-				this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
-			}
-			this.setState({
-				globalErrMsg,
-				shouldShowIncompleteErrs: true,
-			});
-			return false;
-		}
-	}
-	private async _signTransactionAsync(): Promise<boolean> {
-		this.setState({
-			signingState: SigningState.SIGNING,
-		});
-		const exchangeContractAddr = this.props.blockchain.getExchangeContractAddressIfExists();
-		if (_.isUndefined(exchangeContractAddr)) {
-			this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
-			this.setState({
-				signingState: SigningState.UNSIGNED,
-			});
-			return false;
-		}
-		const hashData = this.props.hashData;
+        // Check if all required inputs were supplied
+        const debitToken = this.props.sideToAssetToken[Side.Deposit];
+        const debitBalance = this.props.tokenStateByAddress[debitToken.address].balance;
+        const debitAllowance = this.props.tokenStateByAddress[debitToken.address].allowance;
+        const receiveAmount = this.props.sideToAssetToken[Side.Receive].amount;
+        if (
+            !_.isUndefined(debitToken.amount) &&
+            !_.isUndefined(receiveAmount) &&
+            debitToken.amount.gt(0) &&
+            receiveAmount.gt(0) &&
+            this.props.userAddress !== '' &&
+            debitBalance.gte(debitToken.amount) &&
+            debitAllowance.gte(debitToken.amount)
+        ) {
+            const didSignSuccessfully = await this._signTransactionAsync();
+            if (didSignSuccessfully) {
+                this.setState({
+                    globalErrMsg: '',
+                    shouldShowIncompleteErrs: false,
+                });
+            }
+            return didSignSuccessfully;
+        } else {
+            let globalErrMsg = 'You must fix the above errors in order to generate a valid order';
+            if (this.props.userAddress === '') {
+                globalErrMsg = 'You must enable wallet communication';
+                this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
+            }
+            this.setState({
+                globalErrMsg,
+                shouldShowIncompleteErrs: true,
+            });
+            return false;
+        }
+    }
+    private async _signTransactionAsync(): Promise<boolean> {
+        this.setState({
+            signingState: SigningState.SIGNING,
+        });
+        const exchangeContractAddr = this.props.blockchain.getExchangeContractAddressIfExists();
+        if (_.isUndefined(exchangeContractAddr)) {
+            this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
+            this.setState({
+                signingState: SigningState.UNSIGNED,
+            });
+            return false;
+        }
+        const hashData = this.props.hashData;
 
-		const zeroExOrder: Order = {
-			exchangeContractAddress: exchangeContractAddr,
-			expirationUnixTimestampSec: hashData.orderExpiryTimestamp,
-			feeRecipient: hashData.feeRecipientAddress,
-			maker: hashData.orderMakerAddress,
-			makerFee: hashData.makerFee,
-			makerTokenAddress: hashData.depositTokenContractAddr,
-			makerTokenAmount: hashData.depositAmount,
-			salt: hashData.orderSalt,
-			taker: hashData.orderTakerAddress,
-			takerFee: hashData.takerFee,
-			takerTokenAddress: hashData.receiveTokenContractAddr,
-			takerTokenAmount: hashData.receiveAmount,
-		};
-		const orderHash = ZeroEx.getOrderHashHex(zeroExOrder);
+        const zeroExOrder: Order = {
+            exchangeContractAddress: exchangeContractAddr,
+            expirationUnixTimestampSec: hashData.orderExpiryTimestamp,
+            feeRecipient: hashData.feeRecipientAddress,
+            maker: hashData.orderMakerAddress,
+            makerFee: hashData.makerFee,
+            makerTokenAddress: hashData.depositTokenContractAddr,
+            makerTokenAmount: hashData.depositAmount,
+            salt: hashData.orderSalt,
+            taker: hashData.orderTakerAddress,
+            takerFee: hashData.takerFee,
+            takerTokenAddress: hashData.receiveTokenContractAddr,
+            takerTokenAmount: hashData.receiveAmount,
+        };
+        const orderHash = ZeroEx.getOrderHashHex(zeroExOrder);
 
-		let globalErrMsg = '';
-		try {
-			const signatureData = await this.props.blockchain.signOrderHashAsync(orderHash);
-			const order = utils.generateOrder(
-				this.props.networkId,
-				exchangeContractAddr,
-				this.props.sideToAssetToken,
-				hashData.orderExpiryTimestamp,
-				this.props.orderTakerAddress,
-				this.props.userAddress,
-				hashData.makerFee,
-				hashData.takerFee,
-				hashData.feeRecipientAddress,
-				signatureData,
-				this.props.tokenByAddress,
-				hashData.orderSalt,
-			);
-			const validationResult = this._validator.validate(order, orderSchema);
-			if (validationResult.errors.length > 0) {
-				globalErrMsg = 'Order signing failed. Please refresh and try again';
-				utils.consoleLog(`Unexpected error occured: Order validation failed:
+        let globalErrMsg = '';
+        try {
+            const signatureData = await this.props.blockchain.signOrderHashAsync(orderHash);
+            const order = utils.generateOrder(
+                this.props.networkId,
+                exchangeContractAddr,
+                this.props.sideToAssetToken,
+                hashData.orderExpiryTimestamp,
+                this.props.orderTakerAddress,
+                this.props.userAddress,
+                hashData.makerFee,
+                hashData.takerFee,
+                hashData.feeRecipientAddress,
+                signatureData,
+                this.props.tokenByAddress,
+                hashData.orderSalt,
+            );
+            const validationResult = this._validator.validate(order, orderSchema);
+            if (validationResult.errors.length > 0) {
+                globalErrMsg = 'Order signing failed. Please refresh and try again';
+                utils.consoleLog(`Unexpected error occured: Order validation failed:
                                   ${validationResult.errors}`);
-			}
-		} catch (err) {
-			const errMsg = `${err}`;
-			if (utils.didUserDenyWeb3Request(errMsg)) {
-				globalErrMsg = 'User denied sign request';
-			} else {
-				globalErrMsg = 'An unexpected error occured. Please try refreshing the page';
-				utils.consoleLog(`Unexpected error occured: ${err}`);
-				utils.consoleLog(err.stack);
-				await errorReporter.reportAsync(err);
-			}
-		}
-		this.setState({
-			signingState: globalErrMsg === '' ? SigningState.SIGNED : SigningState.UNSIGNED,
-			globalErrMsg,
-		});
-		return globalErrMsg === '';
-	}
-	private _updateOrderAddress(address?: string): void {
-		if (!_.isUndefined(address)) {
-			this.props.dispatcher.updateOrderTakerAddress(address);
-		}
-	}
+            }
+        } catch (err) {
+            const errMsg = `${err}`;
+            if (utils.didUserDenyWeb3Request(errMsg)) {
+                globalErrMsg = 'User denied sign request';
+            } else {
+                globalErrMsg = 'An unexpected error occured. Please try refreshing the page';
+                utils.consoleLog(`Unexpected error occured: ${err}`);
+                utils.consoleLog(err.stack);
+                await errorReporter.reportAsync(err);
+            }
+        }
+        this.setState({
+            signingState: globalErrMsg === '' ? SigningState.SIGNED : SigningState.UNSIGNED,
+            globalErrMsg,
+        });
+        return globalErrMsg === '';
+    }
+    private _updateOrderAddress(address?: string): void {
+        if (!_.isUndefined(address)) {
+            this.props.dispatcher.updateOrderTakerAddress(address);
+        }
+    }
 }
diff --git a/packages/website/ts/components/generate_order/new_token_form.tsx b/packages/website/ts/components/generate_order/new_token_form.tsx
index d61aac92a..63645be9a 100644
--- a/packages/website/ts/components/generate_order/new_token_form.tsx
+++ b/packages/website/ts/components/generate_order/new_token_form.tsx
@@ -11,227 +11,227 @@ import { AlertTypes, Token, TokenByAddress, TokenState } from 'ts/types';
 import { colors } from 'ts/utils/colors';
 
 interface NewTokenFormProps {
-	blockchain: Blockchain;
-	tokenByAddress: TokenByAddress;
-	onNewTokenSubmitted: (token: Token, tokenState: TokenState) => void;
+    blockchain: Blockchain;
+    tokenByAddress: TokenByAddress;
+    onNewTokenSubmitted: (token: Token, tokenState: TokenState) => void;
 }
 
 interface NewTokenFormState {
-	globalErrMsg: string;
-	name: string;
-	nameErrText: string;
-	symbol: string;
-	symbolErrText: string;
-	address: string;
-	shouldShowAddressIncompleteErr: boolean;
-	decimals: string;
-	decimalsErrText: string;
+    globalErrMsg: string;
+    name: string;
+    nameErrText: string;
+    symbol: string;
+    symbolErrText: string;
+    address: string;
+    shouldShowAddressIncompleteErr: boolean;
+    decimals: string;
+    decimalsErrText: string;
 }
 
 export class NewTokenForm extends React.Component<NewTokenFormProps, NewTokenFormState> {
-	constructor(props: NewTokenFormProps) {
-		super(props);
-		this.state = {
-			address: '',
-			globalErrMsg: '',
-			name: '',
-			nameErrText: '',
-			shouldShowAddressIncompleteErr: false,
-			symbol: '',
-			symbolErrText: '',
-			decimals: '18',
-			decimalsErrText: '',
-		};
-	}
-	public render() {
-		return (
-			<div className="mx-auto pb2" style={{ width: 256 }}>
-				<div>
-					<TextField
-						floatingLabelFixed={true}
-						floatingLabelStyle={{ color: colors.grey }}
-						floatingLabelText={<RequiredLabel label="Name" />}
-						value={this.state.name}
-						errorText={this.state.nameErrText}
-						onChange={this._onTokenNameChanged.bind(this)}
-					/>
-				</div>
-				<div>
-					<TextField
-						floatingLabelFixed={true}
-						floatingLabelStyle={{ color: colors.grey }}
-						floatingLabelText={<RequiredLabel label="Symbol" />}
-						value={this.state.symbol}
-						errorText={this.state.symbolErrText}
-						onChange={this._onTokenSymbolChanged.bind(this)}
-					/>
-				</div>
-				<div>
-					<AddressInput
-						isRequired={true}
-						label="Contract address"
-						initialAddress=""
-						shouldShowIncompleteErrs={this.state.shouldShowAddressIncompleteErr}
-						updateAddress={this._onTokenAddressChanged.bind(this)}
-					/>
-				</div>
-				<div>
-					<TextField
-						floatingLabelFixed={true}
-						floatingLabelStyle={{ color: colors.grey }}
-						floatingLabelText={<RequiredLabel label="Decimals" />}
-						value={this.state.decimals}
-						errorText={this.state.decimalsErrText}
-						onChange={this._onTokenDecimalsChanged.bind(this)}
-					/>
-				</div>
-				<div className="pt2 mx-auto" style={{ width: 120 }}>
-					<LifeCycleRaisedButton
-						labelReady="Add"
-						labelLoading="Adding..."
-						labelComplete="Added!"
-						onClickAsyncFn={this._onAddNewTokenClickAsync.bind(this)}
-					/>
-				</div>
-				{this.state.globalErrMsg !== '' && <Alert type={AlertTypes.ERROR} message={this.state.globalErrMsg} />}
-			</div>
-		);
-	}
-	private async _onAddNewTokenClickAsync() {
-		// Trigger validation of name and symbol
-		this._onTokenNameChanged(undefined, this.state.name);
-		this._onTokenSymbolChanged(undefined, this.state.symbol);
-		this._onTokenDecimalsChanged(undefined, this.state.decimals);
+    constructor(props: NewTokenFormProps) {
+        super(props);
+        this.state = {
+            address: '',
+            globalErrMsg: '',
+            name: '',
+            nameErrText: '',
+            shouldShowAddressIncompleteErr: false,
+            symbol: '',
+            symbolErrText: '',
+            decimals: '18',
+            decimalsErrText: '',
+        };
+    }
+    public render() {
+        return (
+            <div className="mx-auto pb2" style={{ width: 256 }}>
+                <div>
+                    <TextField
+                        floatingLabelFixed={true}
+                        floatingLabelStyle={{ color: colors.grey }}
+                        floatingLabelText={<RequiredLabel label="Name" />}
+                        value={this.state.name}
+                        errorText={this.state.nameErrText}
+                        onChange={this._onTokenNameChanged.bind(this)}
+                    />
+                </div>
+                <div>
+                    <TextField
+                        floatingLabelFixed={true}
+                        floatingLabelStyle={{ color: colors.grey }}
+                        floatingLabelText={<RequiredLabel label="Symbol" />}
+                        value={this.state.symbol}
+                        errorText={this.state.symbolErrText}
+                        onChange={this._onTokenSymbolChanged.bind(this)}
+                    />
+                </div>
+                <div>
+                    <AddressInput
+                        isRequired={true}
+                        label="Contract address"
+                        initialAddress=""
+                        shouldShowIncompleteErrs={this.state.shouldShowAddressIncompleteErr}
+                        updateAddress={this._onTokenAddressChanged.bind(this)}
+                    />
+                </div>
+                <div>
+                    <TextField
+                        floatingLabelFixed={true}
+                        floatingLabelStyle={{ color: colors.grey }}
+                        floatingLabelText={<RequiredLabel label="Decimals" />}
+                        value={this.state.decimals}
+                        errorText={this.state.decimalsErrText}
+                        onChange={this._onTokenDecimalsChanged.bind(this)}
+                    />
+                </div>
+                <div className="pt2 mx-auto" style={{ width: 120 }}>
+                    <LifeCycleRaisedButton
+                        labelReady="Add"
+                        labelLoading="Adding..."
+                        labelComplete="Added!"
+                        onClickAsyncFn={this._onAddNewTokenClickAsync.bind(this)}
+                    />
+                </div>
+                {this.state.globalErrMsg !== '' && <Alert type={AlertTypes.ERROR} message={this.state.globalErrMsg} />}
+            </div>
+        );
+    }
+    private async _onAddNewTokenClickAsync() {
+        // Trigger validation of name and symbol
+        this._onTokenNameChanged(undefined, this.state.name);
+        this._onTokenSymbolChanged(undefined, this.state.symbol);
+        this._onTokenDecimalsChanged(undefined, this.state.decimals);
 
-		const isAddressIncomplete = this.state.address === '';
-		let doesContractExist = false;
-		if (!isAddressIncomplete) {
-			doesContractExist = await this.props.blockchain.doesContractExistAtAddressAsync(this.state.address);
-		}
+        const isAddressIncomplete = this.state.address === '';
+        let doesContractExist = false;
+        if (!isAddressIncomplete) {
+            doesContractExist = await this.props.blockchain.doesContractExistAtAddressAsync(this.state.address);
+        }
 
-		let hasBalanceAllowanceErr = false;
-		let balance = new BigNumber(0);
-		let allowance = new BigNumber(0);
-		if (doesContractExist) {
-			try {
-				[balance, allowance] = await this.props.blockchain.getCurrentUserTokenBalanceAndAllowanceAsync(
-					this.state.address,
-				);
-			} catch (err) {
-				hasBalanceAllowanceErr = true;
-			}
-		}
+        let hasBalanceAllowanceErr = false;
+        let balance = new BigNumber(0);
+        let allowance = new BigNumber(0);
+        if (doesContractExist) {
+            try {
+                [balance, allowance] = await this.props.blockchain.getCurrentUserTokenBalanceAndAllowanceAsync(
+                    this.state.address,
+                );
+            } catch (err) {
+                hasBalanceAllowanceErr = true;
+            }
+        }
 
-		let globalErrMsg = '';
-		if (
-			this.state.nameErrText !== '' ||
-			this.state.symbolErrText !== '' ||
-			this.state.decimalsErrText !== '' ||
-			isAddressIncomplete
-		) {
-			globalErrMsg = 'Please fix the above issues';
-		} else if (!doesContractExist) {
-			globalErrMsg = 'No contract found at supplied address';
-		} else if (hasBalanceAllowanceErr) {
-			globalErrMsg = 'Unsuccessful call to `balanceOf` and/or `allowance` on supplied contract address';
-		} else if (!isAddressIncomplete && !_.isUndefined(this.props.tokenByAddress[this.state.address])) {
-			globalErrMsg = 'A token already exists with this address';
-		}
+        let globalErrMsg = '';
+        if (
+            this.state.nameErrText !== '' ||
+            this.state.symbolErrText !== '' ||
+            this.state.decimalsErrText !== '' ||
+            isAddressIncomplete
+        ) {
+            globalErrMsg = 'Please fix the above issues';
+        } else if (!doesContractExist) {
+            globalErrMsg = 'No contract found at supplied address';
+        } else if (hasBalanceAllowanceErr) {
+            globalErrMsg = 'Unsuccessful call to `balanceOf` and/or `allowance` on supplied contract address';
+        } else if (!isAddressIncomplete && !_.isUndefined(this.props.tokenByAddress[this.state.address])) {
+            globalErrMsg = 'A token already exists with this address';
+        }
 
-		if (globalErrMsg !== '') {
-			this.setState({
-				globalErrMsg,
-				shouldShowAddressIncompleteErr: isAddressIncomplete,
-			});
-			return;
-		}
+        if (globalErrMsg !== '') {
+            this.setState({
+                globalErrMsg,
+                shouldShowAddressIncompleteErr: isAddressIncomplete,
+            });
+            return;
+        }
 
-		const newToken: Token = {
-			address: this.state.address,
-			decimals: _.parseInt(this.state.decimals),
-			iconUrl: undefined,
-			name: this.state.name,
-			symbol: this.state.symbol.toUpperCase(),
-			isTracked: true,
-			isRegistered: false,
-		};
-		const newTokenState: TokenState = {
-			balance,
-			allowance,
-		};
-		this.props.onNewTokenSubmitted(newToken, newTokenState);
-	}
-	private _onTokenNameChanged(e: any, name: string) {
-		let nameErrText = '';
-		const maxLength = 30;
-		const tokens = _.values(this.props.tokenByAddress);
-		const tokenWithNameIfExists = _.find(tokens, { name });
-		const tokenWithNameExists = !_.isUndefined(tokenWithNameIfExists);
-		if (name === '') {
-			nameErrText = 'Name is required';
-		} else if (!this._isValidName(name)) {
-			nameErrText = 'Name should only contain letters, digits and spaces';
-		} else if (name.length > maxLength) {
-			nameErrText = `Max length is ${maxLength}`;
-		} else if (tokenWithNameExists) {
-			nameErrText = 'Token with this name already exists';
-		}
+        const newToken: Token = {
+            address: this.state.address,
+            decimals: _.parseInt(this.state.decimals),
+            iconUrl: undefined,
+            name: this.state.name,
+            symbol: this.state.symbol.toUpperCase(),
+            isTracked: true,
+            isRegistered: false,
+        };
+        const newTokenState: TokenState = {
+            balance,
+            allowance,
+        };
+        this.props.onNewTokenSubmitted(newToken, newTokenState);
+    }
+    private _onTokenNameChanged(e: any, name: string) {
+        let nameErrText = '';
+        const maxLength = 30;
+        const tokens = _.values(this.props.tokenByAddress);
+        const tokenWithNameIfExists = _.find(tokens, { name });
+        const tokenWithNameExists = !_.isUndefined(tokenWithNameIfExists);
+        if (name === '') {
+            nameErrText = 'Name is required';
+        } else if (!this._isValidName(name)) {
+            nameErrText = 'Name should only contain letters, digits and spaces';
+        } else if (name.length > maxLength) {
+            nameErrText = `Max length is ${maxLength}`;
+        } else if (tokenWithNameExists) {
+            nameErrText = 'Token with this name already exists';
+        }
 
-		this.setState({
-			name,
-			nameErrText,
-		});
-	}
-	private _onTokenSymbolChanged(e: any, symbol: string) {
-		let symbolErrText = '';
-		const maxLength = 5;
-		const tokens = _.values(this.props.tokenByAddress);
-		const tokenWithSymbolExists = !_.isUndefined(_.find(tokens, { symbol }));
-		if (symbol === '') {
-			symbolErrText = 'Symbol is required';
-		} else if (!this._isAlphanumeric(symbol)) {
-			symbolErrText = 'Can only include alphanumeric characters';
-		} else if (symbol.length > maxLength) {
-			symbolErrText = `Max length is ${maxLength}`;
-		} else if (tokenWithSymbolExists) {
-			symbolErrText = 'Token with symbol already exists';
-		}
+        this.setState({
+            name,
+            nameErrText,
+        });
+    }
+    private _onTokenSymbolChanged(e: any, symbol: string) {
+        let symbolErrText = '';
+        const maxLength = 5;
+        const tokens = _.values(this.props.tokenByAddress);
+        const tokenWithSymbolExists = !_.isUndefined(_.find(tokens, { symbol }));
+        if (symbol === '') {
+            symbolErrText = 'Symbol is required';
+        } else if (!this._isAlphanumeric(symbol)) {
+            symbolErrText = 'Can only include alphanumeric characters';
+        } else if (symbol.length > maxLength) {
+            symbolErrText = `Max length is ${maxLength}`;
+        } else if (tokenWithSymbolExists) {
+            symbolErrText = 'Token with symbol already exists';
+        }
 
-		this.setState({
-			symbol,
-			symbolErrText,
-		});
-	}
-	private _onTokenDecimalsChanged(e: any, decimals: string) {
-		let decimalsErrText = '';
-		const maxLength = 2;
-		if (decimals === '') {
-			decimalsErrText = 'Decimals is required';
-		} else if (!this._isInteger(decimals)) {
-			decimalsErrText = 'Must be an integer';
-		} else if (decimals.length > maxLength) {
-			decimalsErrText = `Max length is ${maxLength}`;
-		}
+        this.setState({
+            symbol,
+            symbolErrText,
+        });
+    }
+    private _onTokenDecimalsChanged(e: any, decimals: string) {
+        let decimalsErrText = '';
+        const maxLength = 2;
+        if (decimals === '') {
+            decimalsErrText = 'Decimals is required';
+        } else if (!this._isInteger(decimals)) {
+            decimalsErrText = 'Must be an integer';
+        } else if (decimals.length > maxLength) {
+            decimalsErrText = `Max length is ${maxLength}`;
+        }
 
-		this.setState({
-			decimals,
-			decimalsErrText,
-		});
-	}
-	private _onTokenAddressChanged(address?: string) {
-		if (!_.isUndefined(address)) {
-			this.setState({
-				address,
-			});
-		}
-	}
-	private _isValidName(input: string) {
-		return /^[a-z0-9 ]+$/i.test(input);
-	}
-	private _isInteger(input: string) {
-		return /^[0-9]+$/i.test(input);
-	}
-	private _isAlphanumeric(input: string) {
-		return /^[a-zA-Z0-9]+$/i.test(input);
-	}
+        this.setState({
+            decimals,
+            decimalsErrText,
+        });
+    }
+    private _onTokenAddressChanged(address?: string) {
+        if (!_.isUndefined(address)) {
+            this.setState({
+                address,
+            });
+        }
+    }
+    private _isValidName(input: string) {
+        return /^[a-z0-9 ]+$/i.test(input);
+    }
+    private _isInteger(input: string) {
+        return /^[0-9]+$/i.test(input);
+    }
+    private _isAlphanumeric(input: string) {
+        return /^[a-zA-Z0-9]+$/i.test(input);
+    }
 }
diff --git a/packages/website/ts/components/inputs/address_input.tsx b/packages/website/ts/components/inputs/address_input.tsx
index 236bf9a00..dd4131140 100644
--- a/packages/website/ts/components/inputs/address_input.tsx
+++ b/packages/website/ts/components/inputs/address_input.tsx
@@ -6,66 +6,66 @@ import { RequiredLabel } from 'ts/components/ui/required_label';
 import { colors } from 'ts/utils/colors';
 
 interface AddressInputProps {
-	disabled?: boolean;
-	initialAddress: string;
-	isRequired?: boolean;
-	hintText?: string;
-	shouldHideLabel?: boolean;
-	label?: string;
-	shouldShowIncompleteErrs?: boolean;
-	updateAddress: (address?: string) => void;
+    disabled?: boolean;
+    initialAddress: string;
+    isRequired?: boolean;
+    hintText?: string;
+    shouldHideLabel?: boolean;
+    label?: string;
+    shouldShowIncompleteErrs?: boolean;
+    updateAddress: (address?: string) => void;
 }
 
 interface AddressInputState {
-	address: string;
-	errMsg: string;
+    address: string;
+    errMsg: string;
 }
 
 export class AddressInput extends React.Component<AddressInputProps, AddressInputState> {
-	constructor(props: AddressInputProps) {
-		super(props);
-		this.state = {
-			address: this.props.initialAddress,
-			errMsg: '',
-		};
-	}
-	public componentWillReceiveProps(nextProps: AddressInputProps) {
-		if (nextProps.shouldShowIncompleteErrs && this.props.isRequired && this.state.address === '') {
-			this.setState({
-				errMsg: 'Address is required',
-			});
-		}
-	}
-	public render() {
-		const label = this.props.isRequired ? <RequiredLabel label={this.props.label} /> : this.props.label;
-		const labelDisplay = this.props.shouldHideLabel ? 'hidden' : 'block';
-		const hintText = this.props.hintText ? this.props.hintText : '';
-		return (
-			<div className="overflow-hidden">
-				<TextField
-					id={`address-field-${this.props.label}`}
-					disabled={_.isUndefined(this.props.disabled) ? false : this.props.disabled}
-					fullWidth={true}
-					hintText={hintText}
-					floatingLabelFixed={true}
-					floatingLabelStyle={{ color: colors.grey, display: labelDisplay }}
-					floatingLabelText={label}
-					errorText={this.state.errMsg}
-					value={this.state.address}
-					onChange={this._onOrderTakerAddressUpdated.bind(this)}
-				/>
-			</div>
-		);
-	}
-	private _onOrderTakerAddressUpdated(e: any) {
-		const address = e.target.value.toLowerCase();
-		const isValidAddress = addressUtils.isAddress(address) || address === '';
-		const errMsg = isValidAddress ? '' : 'Invalid ethereum address';
-		this.setState({
-			address,
-			errMsg,
-		});
-		const addressIfValid = isValidAddress ? address : undefined;
-		this.props.updateAddress(addressIfValid);
-	}
+    constructor(props: AddressInputProps) {
+        super(props);
+        this.state = {
+            address: this.props.initialAddress,
+            errMsg: '',
+        };
+    }
+    public componentWillReceiveProps(nextProps: AddressInputProps) {
+        if (nextProps.shouldShowIncompleteErrs && this.props.isRequired && this.state.address === '') {
+            this.setState({
+                errMsg: 'Address is required',
+            });
+        }
+    }
+    public render() {
+        const label = this.props.isRequired ? <RequiredLabel label={this.props.label} /> : this.props.label;
+        const labelDisplay = this.props.shouldHideLabel ? 'hidden' : 'block';
+        const hintText = this.props.hintText ? this.props.hintText : '';
+        return (
+            <div className="overflow-hidden">
+                <TextField
+                    id={`address-field-${this.props.label}`}
+                    disabled={_.isUndefined(this.props.disabled) ? false : this.props.disabled}
+                    fullWidth={true}
+                    hintText={hintText}
+                    floatingLabelFixed={true}
+                    floatingLabelStyle={{ color: colors.grey, display: labelDisplay }}
+                    floatingLabelText={label}
+                    errorText={this.state.errMsg}
+                    value={this.state.address}
+                    onChange={this._onOrderTakerAddressUpdated.bind(this)}
+                />
+            </div>
+        );
+    }
+    private _onOrderTakerAddressUpdated(e: any) {
+        const address = e.target.value.toLowerCase();
+        const isValidAddress = addressUtils.isAddress(address) || address === '';
+        const errMsg = isValidAddress ? '' : 'Invalid ethereum address';
+        this.setState({
+            address,
+            errMsg,
+        });
+        const addressIfValid = isValidAddress ? address : undefined;
+        this.props.updateAddress(addressIfValid);
+    }
 }
diff --git a/packages/website/ts/components/inputs/allowance_toggle.tsx b/packages/website/ts/components/inputs/allowance_toggle.tsx
index 245784824..da46db4f4 100644
--- a/packages/website/ts/components/inputs/allowance_toggle.tsx
+++ b/packages/website/ts/components/inputs/allowance_toggle.tsx
@@ -11,83 +11,83 @@ import { utils } from 'ts/utils/utils';
 const DEFAULT_ALLOWANCE_AMOUNT_IN_BASE_UNITS = new BigNumber(2).pow(256).minus(1);
 
 interface AllowanceToggleProps {
-	blockchain: Blockchain;
-	dispatcher: Dispatcher;
-	onErrorOccurred: (errType: BalanceErrs) => void;
-	token: Token;
-	tokenState: TokenState;
-	userAddress: string;
+    blockchain: Blockchain;
+    dispatcher: Dispatcher;
+    onErrorOccurred: (errType: BalanceErrs) => void;
+    token: Token;
+    tokenState: TokenState;
+    userAddress: string;
 }
 
 interface AllowanceToggleState {
-	isSpinnerVisible: boolean;
-	prevAllowance: BigNumber;
+    isSpinnerVisible: boolean;
+    prevAllowance: BigNumber;
 }
 
 export class AllowanceToggle extends React.Component<AllowanceToggleProps, AllowanceToggleState> {
-	constructor(props: AllowanceToggleProps) {
-		super(props);
-		this.state = {
-			isSpinnerVisible: false,
-			prevAllowance: props.tokenState.allowance,
-		};
-	}
-	public componentWillReceiveProps(nextProps: AllowanceToggleProps) {
-		if (!nextProps.tokenState.allowance.eq(this.state.prevAllowance)) {
-			this.setState({
-				isSpinnerVisible: false,
-				prevAllowance: nextProps.tokenState.allowance,
-			});
-		}
-	}
-	public render() {
-		return (
-			<div className="flex">
-				<div>
-					<Toggle
-						disabled={this.state.isSpinnerVisible}
-						toggled={this._isAllowanceSet()}
-						onToggle={this._onToggleAllowanceAsync.bind(this)}
-					/>
-				</div>
-				{this.state.isSpinnerVisible && (
-					<div className="pl1" style={{ paddingTop: 3 }}>
-						<i className="zmdi zmdi-spinner zmdi-hc-spin" />
-					</div>
-				)}
-			</div>
-		);
-	}
-	private async _onToggleAllowanceAsync(): Promise<void> {
-		if (this.props.userAddress === '') {
-			this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
-		}
+    constructor(props: AllowanceToggleProps) {
+        super(props);
+        this.state = {
+            isSpinnerVisible: false,
+            prevAllowance: props.tokenState.allowance,
+        };
+    }
+    public componentWillReceiveProps(nextProps: AllowanceToggleProps) {
+        if (!nextProps.tokenState.allowance.eq(this.state.prevAllowance)) {
+            this.setState({
+                isSpinnerVisible: false,
+                prevAllowance: nextProps.tokenState.allowance,
+            });
+        }
+    }
+    public render() {
+        return (
+            <div className="flex">
+                <div>
+                    <Toggle
+                        disabled={this.state.isSpinnerVisible}
+                        toggled={this._isAllowanceSet()}
+                        onToggle={this._onToggleAllowanceAsync.bind(this)}
+                    />
+                </div>
+                {this.state.isSpinnerVisible && (
+                    <div className="pl1" style={{ paddingTop: 3 }}>
+                        <i className="zmdi zmdi-spinner zmdi-hc-spin" />
+                    </div>
+                )}
+            </div>
+        );
+    }
+    private async _onToggleAllowanceAsync(): Promise<void> {
+        if (this.props.userAddress === '') {
+            this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
+        }
 
-		this.setState({
-			isSpinnerVisible: true,
-		});
+        this.setState({
+            isSpinnerVisible: true,
+        });
 
-		let newAllowanceAmountInBaseUnits = new BigNumber(0);
-		if (!this._isAllowanceSet()) {
-			newAllowanceAmountInBaseUnits = DEFAULT_ALLOWANCE_AMOUNT_IN_BASE_UNITS;
-		}
-		try {
-			await this.props.blockchain.setProxyAllowanceAsync(this.props.token, newAllowanceAmountInBaseUnits);
-		} catch (err) {
-			this.setState({
-				isSpinnerVisible: false,
-			});
-			const errMsg = `${err}`;
-			if (_.includes(errMsg, 'User denied transaction')) {
-				return;
-			}
-			utils.consoleLog(`Unexpected error encountered: ${err}`);
-			utils.consoleLog(err.stack);
-			this.props.onErrorOccurred(BalanceErrs.allowanceSettingFailed);
-			await errorReporter.reportAsync(err);
-		}
-	}
-	private _isAllowanceSet() {
-		return !this.props.tokenState.allowance.eq(0);
-	}
+        let newAllowanceAmountInBaseUnits = new BigNumber(0);
+        if (!this._isAllowanceSet()) {
+            newAllowanceAmountInBaseUnits = DEFAULT_ALLOWANCE_AMOUNT_IN_BASE_UNITS;
+        }
+        try {
+            await this.props.blockchain.setProxyAllowanceAsync(this.props.token, newAllowanceAmountInBaseUnits);
+        } catch (err) {
+            this.setState({
+                isSpinnerVisible: false,
+            });
+            const errMsg = `${err}`;
+            if (_.includes(errMsg, 'User denied transaction')) {
+                return;
+            }
+            utils.consoleLog(`Unexpected error encountered: ${err}`);
+            utils.consoleLog(err.stack);
+            this.props.onErrorOccurred(BalanceErrs.allowanceSettingFailed);
+            await errorReporter.reportAsync(err);
+        }
+    }
+    private _isAllowanceSet() {
+        return !this.props.tokenState.allowance.eq(0);
+    }
 }
diff --git a/packages/website/ts/components/inputs/balance_bounded_input.tsx b/packages/website/ts/components/inputs/balance_bounded_input.tsx
index 5cc91994e..ddc434b51 100644
--- a/packages/website/ts/components/inputs/balance_bounded_input.tsx
+++ b/packages/website/ts/components/inputs/balance_bounded_input.tsx
@@ -9,143 +9,143 @@ import { colors } from 'ts/utils/colors';
 import { utils } from 'ts/utils/utils';
 
 interface BalanceBoundedInputProps {
-	label?: string;
-	balance: BigNumber;
-	amount?: BigNumber;
-	onChange: ValidatedBigNumberCallback;
-	shouldShowIncompleteErrs?: boolean;
-	shouldCheckBalance: boolean;
-	validate?: (amount: BigNumber) => InputErrMsg;
-	onVisitBalancesPageClick?: () => void;
-	shouldHideVisitBalancesLink?: boolean;
+    label?: string;
+    balance: BigNumber;
+    amount?: BigNumber;
+    onChange: ValidatedBigNumberCallback;
+    shouldShowIncompleteErrs?: boolean;
+    shouldCheckBalance: boolean;
+    validate?: (amount: BigNumber) => InputErrMsg;
+    onVisitBalancesPageClick?: () => void;
+    shouldHideVisitBalancesLink?: boolean;
 }
 
 interface BalanceBoundedInputState {
-	errMsg: InputErrMsg;
-	amountString: string;
+    errMsg: InputErrMsg;
+    amountString: string;
 }
 
 export class BalanceBoundedInput extends React.Component<BalanceBoundedInputProps, BalanceBoundedInputState> {
-	public static defaultProps: Partial<BalanceBoundedInputProps> = {
-		shouldShowIncompleteErrs: false,
-		shouldHideVisitBalancesLink: false,
-	};
-	constructor(props: BalanceBoundedInputProps) {
-		super(props);
-		const amountString = this.props.amount ? this.props.amount.toString() : '';
-		this.state = {
-			errMsg: this._validate(amountString, props.balance),
-			amountString,
-		};
-	}
-	public componentWillReceiveProps(nextProps: BalanceBoundedInputProps) {
-		if (nextProps === this.props) {
-			return;
-		}
-		const isCurrentAmountNumeric = utils.isNumeric(this.state.amountString);
-		if (!_.isUndefined(nextProps.amount)) {
-			let shouldResetState = false;
-			if (!isCurrentAmountNumeric) {
-				shouldResetState = true;
-			} else {
-				const currentAmount = new BigNumber(this.state.amountString);
-				if (!currentAmount.eq(nextProps.amount) || !nextProps.balance.eq(this.props.balance)) {
-					shouldResetState = true;
-				}
-			}
-			if (shouldResetState) {
-				const amountString = nextProps.amount.toString();
-				this.setState({
-					errMsg: this._validate(amountString, nextProps.balance),
-					amountString,
-				});
-			}
-		} else if (isCurrentAmountNumeric) {
-			const amountString = '';
-			this.setState({
-				errMsg: this._validate(amountString, nextProps.balance),
-				amountString,
-			});
-		}
-	}
-	public render() {
-		let errorText = this.state.errMsg;
-		if (this.props.shouldShowIncompleteErrs && this.state.amountString === '') {
-			errorText = 'This field is required';
-		}
-		let label: React.ReactNode | string = '';
-		if (!_.isUndefined(this.props.label)) {
-			label = <RequiredLabel label={this.props.label} />;
-		}
-		return (
-			<TextField
-				fullWidth={true}
-				floatingLabelText={label}
-				floatingLabelFixed={true}
-				floatingLabelStyle={{ color: colors.grey, width: 206 }}
-				errorText={errorText}
-				value={this.state.amountString}
-				hintText={<span style={{ textTransform: 'capitalize' }}>amount</span>}
-				onChange={this._onValueChange.bind(this)}
-				underlineStyle={{ width: 'calc(100% + 50px)' }}
-			/>
-		);
-	}
-	private _onValueChange(e: any, amountString: string) {
-		const errMsg = this._validate(amountString, this.props.balance);
-		this.setState(
-			{
-				amountString,
-				errMsg,
-			},
-			() => {
-				const isValid = _.isUndefined(errMsg);
-				if (utils.isNumeric(amountString)) {
-					this.props.onChange(isValid, new BigNumber(amountString));
-				} else {
-					this.props.onChange(isValid);
-				}
-			},
-		);
-	}
-	private _validate(amountString: string, balance: BigNumber): InputErrMsg {
-		if (!utils.isNumeric(amountString)) {
-			return amountString !== '' ? 'Must be a number' : '';
-		}
-		const amount = new BigNumber(amountString);
-		if (amount.eq(0)) {
-			return 'Cannot be zero';
-		}
-		if (this.props.shouldCheckBalance && amount.gt(balance)) {
-			return <span>Insufficient balance. {this._renderIncreaseBalanceLink()}</span>;
-		}
-		const errMsg = _.isUndefined(this.props.validate) ? undefined : this.props.validate(amount);
-		return errMsg;
-	}
-	private _renderIncreaseBalanceLink() {
-		if (this.props.shouldHideVisitBalancesLink) {
-			return null;
-		}
+    public static defaultProps: Partial<BalanceBoundedInputProps> = {
+        shouldShowIncompleteErrs: false,
+        shouldHideVisitBalancesLink: false,
+    };
+    constructor(props: BalanceBoundedInputProps) {
+        super(props);
+        const amountString = this.props.amount ? this.props.amount.toString() : '';
+        this.state = {
+            errMsg: this._validate(amountString, props.balance),
+            amountString,
+        };
+    }
+    public componentWillReceiveProps(nextProps: BalanceBoundedInputProps) {
+        if (nextProps === this.props) {
+            return;
+        }
+        const isCurrentAmountNumeric = utils.isNumeric(this.state.amountString);
+        if (!_.isUndefined(nextProps.amount)) {
+            let shouldResetState = false;
+            if (!isCurrentAmountNumeric) {
+                shouldResetState = true;
+            } else {
+                const currentAmount = new BigNumber(this.state.amountString);
+                if (!currentAmount.eq(nextProps.amount) || !nextProps.balance.eq(this.props.balance)) {
+                    shouldResetState = true;
+                }
+            }
+            if (shouldResetState) {
+                const amountString = nextProps.amount.toString();
+                this.setState({
+                    errMsg: this._validate(amountString, nextProps.balance),
+                    amountString,
+                });
+            }
+        } else if (isCurrentAmountNumeric) {
+            const amountString = '';
+            this.setState({
+                errMsg: this._validate(amountString, nextProps.balance),
+                amountString,
+            });
+        }
+    }
+    public render() {
+        let errorText = this.state.errMsg;
+        if (this.props.shouldShowIncompleteErrs && this.state.amountString === '') {
+            errorText = 'This field is required';
+        }
+        let label: React.ReactNode | string = '';
+        if (!_.isUndefined(this.props.label)) {
+            label = <RequiredLabel label={this.props.label} />;
+        }
+        return (
+            <TextField
+                fullWidth={true}
+                floatingLabelText={label}
+                floatingLabelFixed={true}
+                floatingLabelStyle={{ color: colors.grey, width: 206 }}
+                errorText={errorText}
+                value={this.state.amountString}
+                hintText={<span style={{ textTransform: 'capitalize' }}>amount</span>}
+                onChange={this._onValueChange.bind(this)}
+                underlineStyle={{ width: 'calc(100% + 50px)' }}
+            />
+        );
+    }
+    private _onValueChange(e: any, amountString: string) {
+        const errMsg = this._validate(amountString, this.props.balance);
+        this.setState(
+            {
+                amountString,
+                errMsg,
+            },
+            () => {
+                const isValid = _.isUndefined(errMsg);
+                if (utils.isNumeric(amountString)) {
+                    this.props.onChange(isValid, new BigNumber(amountString));
+                } else {
+                    this.props.onChange(isValid);
+                }
+            },
+        );
+    }
+    private _validate(amountString: string, balance: BigNumber): InputErrMsg {
+        if (!utils.isNumeric(amountString)) {
+            return amountString !== '' ? 'Must be a number' : '';
+        }
+        const amount = new BigNumber(amountString);
+        if (amount.eq(0)) {
+            return 'Cannot be zero';
+        }
+        if (this.props.shouldCheckBalance && amount.gt(balance)) {
+            return <span>Insufficient balance. {this._renderIncreaseBalanceLink()}</span>;
+        }
+        const errMsg = _.isUndefined(this.props.validate) ? undefined : this.props.validate(amount);
+        return errMsg;
+    }
+    private _renderIncreaseBalanceLink() {
+        if (this.props.shouldHideVisitBalancesLink) {
+            return null;
+        }
 
-		const increaseBalanceText = 'Increase balance';
-		const linkStyle = {
-			cursor: 'pointer',
-			color: colors.darkestGrey,
-			textDecoration: 'underline',
-			display: 'inline',
-		};
-		if (_.isUndefined(this.props.onVisitBalancesPageClick)) {
-			return (
-				<Link to={`${WebsitePaths.Portal}/balances`} style={linkStyle}>
-					{increaseBalanceText}
-				</Link>
-			);
-		} else {
-			return (
-				<div onClick={this.props.onVisitBalancesPageClick} style={linkStyle}>
-					{increaseBalanceText}
-				</div>
-			);
-		}
-	}
+        const increaseBalanceText = 'Increase balance';
+        const linkStyle = {
+            cursor: 'pointer',
+            color: colors.darkestGrey,
+            textDecoration: 'underline',
+            display: 'inline',
+        };
+        if (_.isUndefined(this.props.onVisitBalancesPageClick)) {
+            return (
+                <Link to={`${WebsitePaths.Portal}/balances`} style={linkStyle}>
+                    {increaseBalanceText}
+                </Link>
+            );
+        } else {
+            return (
+                <div onClick={this.props.onVisitBalancesPageClick} style={linkStyle}>
+                    {increaseBalanceText}
+                </div>
+            );
+        }
+    }
 }
diff --git a/packages/website/ts/components/inputs/eth_amount_input.tsx b/packages/website/ts/components/inputs/eth_amount_input.tsx
index 7f9747094..a66f92c8c 100644
--- a/packages/website/ts/components/inputs/eth_amount_input.tsx
+++ b/packages/website/ts/components/inputs/eth_amount_input.tsx
@@ -7,43 +7,43 @@ import { ValidatedBigNumberCallback } from 'ts/types';
 import { constants } from 'ts/utils/constants';
 
 interface EthAmountInputProps {
-	label?: string;
-	balance: BigNumber;
-	amount?: BigNumber;
-	onChange: ValidatedBigNumberCallback;
-	shouldShowIncompleteErrs: boolean;
-	onVisitBalancesPageClick?: () => void;
-	shouldCheckBalance: boolean;
-	shouldHideVisitBalancesLink?: boolean;
+    label?: string;
+    balance: BigNumber;
+    amount?: BigNumber;
+    onChange: ValidatedBigNumberCallback;
+    shouldShowIncompleteErrs: boolean;
+    onVisitBalancesPageClick?: () => void;
+    shouldCheckBalance: boolean;
+    shouldHideVisitBalancesLink?: boolean;
 }
 
 interface EthAmountInputState {}
 
 export class EthAmountInput extends React.Component<EthAmountInputProps, EthAmountInputState> {
-	public render() {
-		const amount = this.props.amount
-			? ZeroEx.toUnitAmount(this.props.amount, constants.DECIMAL_PLACES_ETH)
-			: undefined;
-		return (
-			<div className="flex overflow-hidden" style={{ height: 63 }}>
-				<BalanceBoundedInput
-					label={this.props.label}
-					balance={this.props.balance}
-					amount={amount}
-					onChange={this._onChange.bind(this)}
-					shouldCheckBalance={this.props.shouldCheckBalance}
-					shouldShowIncompleteErrs={this.props.shouldShowIncompleteErrs}
-					onVisitBalancesPageClick={this.props.onVisitBalancesPageClick}
-					shouldHideVisitBalancesLink={this.props.shouldHideVisitBalancesLink}
-				/>
-				<div style={{ paddingTop: _.isUndefined(this.props.label) ? 15 : 40 }}>ETH</div>
-			</div>
-		);
-	}
-	private _onChange(isValid: boolean, amount?: BigNumber) {
-		const baseUnitAmountIfExists = _.isUndefined(amount)
-			? undefined
-			: ZeroEx.toBaseUnitAmount(amount, constants.DECIMAL_PLACES_ETH);
-		this.props.onChange(isValid, baseUnitAmountIfExists);
-	}
+    public render() {
+        const amount = this.props.amount
+            ? ZeroEx.toUnitAmount(this.props.amount, constants.DECIMAL_PLACES_ETH)
+            : undefined;
+        return (
+            <div className="flex overflow-hidden" style={{ height: 63 }}>
+                <BalanceBoundedInput
+                    label={this.props.label}
+                    balance={this.props.balance}
+                    amount={amount}
+                    onChange={this._onChange.bind(this)}
+                    shouldCheckBalance={this.props.shouldCheckBalance}
+                    shouldShowIncompleteErrs={this.props.shouldShowIncompleteErrs}
+                    onVisitBalancesPageClick={this.props.onVisitBalancesPageClick}
+                    shouldHideVisitBalancesLink={this.props.shouldHideVisitBalancesLink}
+                />
+                <div style={{ paddingTop: _.isUndefined(this.props.label) ? 15 : 40 }}>ETH</div>
+            </div>
+        );
+    }
+    private _onChange(isValid: boolean, amount?: BigNumber) {
+        const baseUnitAmountIfExists = _.isUndefined(amount)
+            ? undefined
+            : ZeroEx.toBaseUnitAmount(amount, constants.DECIMAL_PLACES_ETH);
+        this.props.onChange(isValid, baseUnitAmountIfExists);
+    }
 }
diff --git a/packages/website/ts/components/inputs/expiration_input.tsx b/packages/website/ts/components/inputs/expiration_input.tsx
index cb4ed7bd0..e473648d2 100644
--- a/packages/website/ts/components/inputs/expiration_input.tsx
+++ b/packages/website/ts/components/inputs/expiration_input.tsx
@@ -7,94 +7,94 @@ import * as React from 'react';
 import { utils } from 'ts/utils/utils';
 
 interface ExpirationInputProps {
-	orderExpiryTimestamp: BigNumber;
-	updateOrderExpiry: (unixTimestampSec: BigNumber) => void;
+    orderExpiryTimestamp: BigNumber;
+    updateOrderExpiry: (unixTimestampSec: BigNumber) => void;
 }
 
 interface ExpirationInputState {
-	dateMoment: moment.Moment;
-	timeMoment: moment.Moment;
+    dateMoment: moment.Moment;
+    timeMoment: moment.Moment;
 }
 
 export class ExpirationInput extends React.Component<ExpirationInputProps, ExpirationInputState> {
-	private _earliestPickableMoment: moment.Moment;
-	constructor(props: ExpirationInputProps) {
-		super(props);
-		// Set the earliest pickable date to today at 00:00, so users can only pick the current or later dates
-		this._earliestPickableMoment = moment().startOf('day');
-		const expirationMoment = utils.convertToMomentFromUnixTimestamp(props.orderExpiryTimestamp);
-		const initialOrderExpiryTimestamp = utils.initialOrderExpiryUnixTimestampSec();
-		const didUserSetExpiry = !initialOrderExpiryTimestamp.eq(props.orderExpiryTimestamp);
-		this.state = {
-			dateMoment: didUserSetExpiry ? expirationMoment : undefined,
-			timeMoment: didUserSetExpiry ? expirationMoment : undefined,
-		};
-	}
-	public render() {
-		const date = this.state.dateMoment ? this.state.dateMoment.toDate() : undefined;
-		const time = this.state.timeMoment ? this.state.timeMoment.toDate() : undefined;
-		return (
-			<div className="clearfix">
-				<div className="col col-6 overflow-hidden pr3 flex relative">
-					<DatePicker
-						className="overflow-hidden"
-						hintText="Date"
-						mode="landscape"
-						autoOk={true}
-						value={date}
-						onChange={this._onDateChanged.bind(this)}
-						shouldDisableDate={this._shouldDisableDate.bind(this)}
-					/>
-					<div className="absolute" style={{ fontSize: 20, right: 40, top: 13, pointerEvents: 'none' }}>
-						<i className="zmdi zmdi-calendar" />
-					</div>
-				</div>
-				<div className="col col-5 overflow-hidden flex relative">
-					<TimePicker
-						className="overflow-hidden"
-						hintText="Time"
-						autoOk={true}
-						value={time}
-						onChange={this._onTimeChanged.bind(this)}
-					/>
-					<div className="absolute" style={{ fontSize: 20, right: 9, top: 13, pointerEvents: 'none' }}>
-						<i className="zmdi zmdi-time" />
-					</div>
-				</div>
-				<div onClick={this._clearDates.bind(this)} className="col col-1 pt2" style={{ textAlign: 'right' }}>
-					<i style={{ fontSize: 16, cursor: 'pointer' }} className="zmdi zmdi-close" />
-				</div>
-			</div>
-		);
-	}
-	private _shouldDisableDate(date: Date): boolean {
-		return moment(date)
-			.startOf('day')
-			.isBefore(this._earliestPickableMoment);
-	}
-	private _clearDates() {
-		this.setState({
-			dateMoment: undefined,
-			timeMoment: undefined,
-		});
-		const defaultDateTime = utils.initialOrderExpiryUnixTimestampSec();
-		this.props.updateOrderExpiry(defaultDateTime);
-	}
-	private _onDateChanged(e: any, date: Date) {
-		const dateMoment = moment(date);
-		this.setState({
-			dateMoment,
-		});
-		const timestamp = utils.convertToUnixTimestampSeconds(dateMoment, this.state.timeMoment);
-		this.props.updateOrderExpiry(timestamp);
-	}
-	private _onTimeChanged(e: any, time: Date) {
-		const timeMoment = moment(time);
-		this.setState({
-			timeMoment,
-		});
-		const dateMoment = _.isUndefined(this.state.dateMoment) ? moment() : this.state.dateMoment;
-		const timestamp = utils.convertToUnixTimestampSeconds(dateMoment, timeMoment);
-		this.props.updateOrderExpiry(timestamp);
-	}
+    private _earliestPickableMoment: moment.Moment;
+    constructor(props: ExpirationInputProps) {
+        super(props);
+        // Set the earliest pickable date to today at 00:00, so users can only pick the current or later dates
+        this._earliestPickableMoment = moment().startOf('day');
+        const expirationMoment = utils.convertToMomentFromUnixTimestamp(props.orderExpiryTimestamp);
+        const initialOrderExpiryTimestamp = utils.initialOrderExpiryUnixTimestampSec();
+        const didUserSetExpiry = !initialOrderExpiryTimestamp.eq(props.orderExpiryTimestamp);
+        this.state = {
+            dateMoment: didUserSetExpiry ? expirationMoment : undefined,
+            timeMoment: didUserSetExpiry ? expirationMoment : undefined,
+        };
+    }
+    public render() {
+        const date = this.state.dateMoment ? this.state.dateMoment.toDate() : undefined;
+        const time = this.state.timeMoment ? this.state.timeMoment.toDate() : undefined;
+        return (
+            <div className="clearfix">
+                <div className="col col-6 overflow-hidden pr3 flex relative">
+                    <DatePicker
+                        className="overflow-hidden"
+                        hintText="Date"
+                        mode="landscape"
+                        autoOk={true}
+                        value={date}
+                        onChange={this._onDateChanged.bind(this)}
+                        shouldDisableDate={this._shouldDisableDate.bind(this)}
+                    />
+                    <div className="absolute" style={{ fontSize: 20, right: 40, top: 13, pointerEvents: 'none' }}>
+                        <i className="zmdi zmdi-calendar" />
+                    </div>
+                </div>
+                <div className="col col-5 overflow-hidden flex relative">
+                    <TimePicker
+                        className="overflow-hidden"
+                        hintText="Time"
+                        autoOk={true}
+                        value={time}
+                        onChange={this._onTimeChanged.bind(this)}
+                    />
+                    <div className="absolute" style={{ fontSize: 20, right: 9, top: 13, pointerEvents: 'none' }}>
+                        <i className="zmdi zmdi-time" />
+                    </div>
+                </div>
+                <div onClick={this._clearDates.bind(this)} className="col col-1 pt2" style={{ textAlign: 'right' }}>
+                    <i style={{ fontSize: 16, cursor: 'pointer' }} className="zmdi zmdi-close" />
+                </div>
+            </div>
+        );
+    }
+    private _shouldDisableDate(date: Date): boolean {
+        return moment(date)
+            .startOf('day')
+            .isBefore(this._earliestPickableMoment);
+    }
+    private _clearDates() {
+        this.setState({
+            dateMoment: undefined,
+            timeMoment: undefined,
+        });
+        const defaultDateTime = utils.initialOrderExpiryUnixTimestampSec();
+        this.props.updateOrderExpiry(defaultDateTime);
+    }
+    private _onDateChanged(e: any, date: Date) {
+        const dateMoment = moment(date);
+        this.setState({
+            dateMoment,
+        });
+        const timestamp = utils.convertToUnixTimestampSeconds(dateMoment, this.state.timeMoment);
+        this.props.updateOrderExpiry(timestamp);
+    }
+    private _onTimeChanged(e: any, time: Date) {
+        const timeMoment = moment(time);
+        this.setState({
+            timeMoment,
+        });
+        const dateMoment = _.isUndefined(this.state.dateMoment) ? moment() : this.state.dateMoment;
+        const timestamp = utils.convertToUnixTimestampSeconds(dateMoment, timeMoment);
+        this.props.updateOrderExpiry(timestamp);
+    }
 }
diff --git a/packages/website/ts/components/inputs/hash_input.tsx b/packages/website/ts/components/inputs/hash_input.tsx
index 36d7e6140..5a3d34fe6 100644
--- a/packages/website/ts/components/inputs/hash_input.tsx
+++ b/packages/website/ts/components/inputs/hash_input.tsx
@@ -8,55 +8,55 @@ import { HashData, Styles } from 'ts/types';
 import { constants } from 'ts/utils/constants';
 
 const styles: Styles = {
-	textField: {
-		overflow: 'hidden',
-		paddingTop: 8,
-		textOverflow: 'ellipsis',
-		whiteSpace: 'nowrap',
-	},
+    textField: {
+        overflow: 'hidden',
+        paddingTop: 8,
+        textOverflow: 'ellipsis',
+        whiteSpace: 'nowrap',
+    },
 };
 
 interface HashInputProps {
-	blockchain: Blockchain;
-	blockchainIsLoaded: boolean;
-	hashData: HashData;
-	label: string;
+    blockchain: Blockchain;
+    blockchainIsLoaded: boolean;
+    hashData: HashData;
+    label: string;
 }
 
 interface HashInputState {}
 
 export class HashInput extends React.Component<HashInputProps, HashInputState> {
-	public render() {
-		const msgHashHex = this.props.blockchainIsLoaded ? this._generateMessageHashHex() : '';
-		return (
-			<div>
-				<FakeTextField label={this.props.label}>
-					<div style={styles.textField} data-tip={true} data-for="hashTooltip">
-						{msgHashHex}
-					</div>
-				</FakeTextField>
-				<ReactTooltip id="hashTooltip">{msgHashHex}</ReactTooltip>
-			</div>
-		);
-	}
-	private _generateMessageHashHex() {
-		const exchangeContractAddress = this.props.blockchain.getExchangeContractAddressIfExists();
-		const hashData = this.props.hashData;
-		const order: Order = {
-			exchangeContractAddress,
-			expirationUnixTimestampSec: hashData.orderExpiryTimestamp,
-			feeRecipient: hashData.feeRecipientAddress,
-			maker: _.isEmpty(hashData.orderMakerAddress) ? constants.NULL_ADDRESS : hashData.orderMakerAddress,
-			makerFee: hashData.makerFee,
-			makerTokenAddress: hashData.depositTokenContractAddr,
-			makerTokenAmount: hashData.depositAmount,
-			salt: hashData.orderSalt,
-			taker: hashData.orderTakerAddress,
-			takerFee: hashData.takerFee,
-			takerTokenAddress: hashData.receiveTokenContractAddr,
-			takerTokenAmount: hashData.receiveAmount,
-		};
-		const orderHash = ZeroEx.getOrderHashHex(order);
-		return orderHash;
-	}
+    public render() {
+        const msgHashHex = this.props.blockchainIsLoaded ? this._generateMessageHashHex() : '';
+        return (
+            <div>
+                <FakeTextField label={this.props.label}>
+                    <div style={styles.textField} data-tip={true} data-for="hashTooltip">
+                        {msgHashHex}
+                    </div>
+                </FakeTextField>
+                <ReactTooltip id="hashTooltip">{msgHashHex}</ReactTooltip>
+            </div>
+        );
+    }
+    private _generateMessageHashHex() {
+        const exchangeContractAddress = this.props.blockchain.getExchangeContractAddressIfExists();
+        const hashData = this.props.hashData;
+        const order: Order = {
+            exchangeContractAddress,
+            expirationUnixTimestampSec: hashData.orderExpiryTimestamp,
+            feeRecipient: hashData.feeRecipientAddress,
+            maker: _.isEmpty(hashData.orderMakerAddress) ? constants.NULL_ADDRESS : hashData.orderMakerAddress,
+            makerFee: hashData.makerFee,
+            makerTokenAddress: hashData.depositTokenContractAddr,
+            makerTokenAmount: hashData.depositAmount,
+            salt: hashData.orderSalt,
+            taker: hashData.orderTakerAddress,
+            takerFee: hashData.takerFee,
+            takerTokenAddress: hashData.receiveTokenContractAddr,
+            takerTokenAmount: hashData.receiveAmount,
+        };
+        const orderHash = ZeroEx.getOrderHashHex(order);
+        return orderHash;
+    }
 }
diff --git a/packages/website/ts/components/inputs/identicon_address_input.tsx b/packages/website/ts/components/inputs/identicon_address_input.tsx
index f14cb4e9c..4cf9af64d 100644
--- a/packages/website/ts/components/inputs/identicon_address_input.tsx
+++ b/packages/website/ts/components/inputs/identicon_address_input.tsx
@@ -6,48 +6,48 @@ import { InputLabel } from 'ts/components/ui/input_label';
 import { RequiredLabel } from 'ts/components/ui/required_label';
 
 interface IdenticonAddressInputProps {
-	initialAddress: string;
-	isRequired?: boolean;
-	label: string;
-	updateOrderAddress: (address?: string) => void;
+    initialAddress: string;
+    isRequired?: boolean;
+    label: string;
+    updateOrderAddress: (address?: string) => void;
 }
 
 interface IdenticonAddressInputState {
-	address: string;
+    address: string;
 }
 
 export class IdenticonAddressInput extends React.Component<IdenticonAddressInputProps, IdenticonAddressInputState> {
-	constructor(props: IdenticonAddressInputProps) {
-		super(props);
-		this.state = {
-			address: props.initialAddress,
-		};
-	}
-	public render() {
-		const label = this.props.isRequired ? <RequiredLabel label={this.props.label} /> : this.props.label;
-		return (
-			<div className="relative" style={{ width: '100%' }}>
-				<InputLabel text={label} />
-				<div className="flex">
-					<div className="col col-1 pb1 pr1" style={{ paddingTop: 13 }}>
-						<Identicon address={this.state.address} diameter={26} />
-					</div>
-					<div className="col col-11 pb1 pl1" style={{ height: 65 }}>
-						<AddressInput
-							hintText="e.g 0x75bE4F78AA3699B3A348c84bDB2a96c3Db..."
-							shouldHideLabel={true}
-							initialAddress={this.props.initialAddress}
-							updateAddress={this._updateAddress.bind(this)}
-						/>
-					</div>
-				</div>
-			</div>
-		);
-	}
-	private _updateAddress(address?: string): void {
-		this.setState({
-			address,
-		});
-		this.props.updateOrderAddress(address);
-	}
+    constructor(props: IdenticonAddressInputProps) {
+        super(props);
+        this.state = {
+            address: props.initialAddress,
+        };
+    }
+    public render() {
+        const label = this.props.isRequired ? <RequiredLabel label={this.props.label} /> : this.props.label;
+        return (
+            <div className="relative" style={{ width: '100%' }}>
+                <InputLabel text={label} />
+                <div className="flex">
+                    <div className="col col-1 pb1 pr1" style={{ paddingTop: 13 }}>
+                        <Identicon address={this.state.address} diameter={26} />
+                    </div>
+                    <div className="col col-11 pb1 pl1" style={{ height: 65 }}>
+                        <AddressInput
+                            hintText="e.g 0x75bE4F78AA3699B3A348c84bDB2a96c3Db..."
+                            shouldHideLabel={true}
+                            initialAddress={this.props.initialAddress}
+                            updateAddress={this._updateAddress.bind(this)}
+                        />
+                    </div>
+                </div>
+            </div>
+        );
+    }
+    private _updateAddress(address?: string): void {
+        this.setState({
+            address,
+        });
+        this.props.updateOrderAddress(address);
+    }
 }
diff --git a/packages/website/ts/components/inputs/token_amount_input.tsx b/packages/website/ts/components/inputs/token_amount_input.tsx
index 0a71b2c00..63966d759 100644
--- a/packages/website/ts/components/inputs/token_amount_input.tsx
+++ b/packages/website/ts/components/inputs/token_amount_input.tsx
@@ -8,63 +8,63 @@ import { InputErrMsg, Token, TokenState, ValidatedBigNumberCallback, WebsitePath
 import { colors } from 'ts/utils/colors';
 
 interface TokenAmountInputProps {
-	token: Token;
-	tokenState: TokenState;
-	label?: string;
-	amount?: BigNumber;
-	shouldShowIncompleteErrs: boolean;
-	shouldCheckBalance: boolean;
-	shouldCheckAllowance: boolean;
-	onChange: ValidatedBigNumberCallback;
-	onVisitBalancesPageClick?: () => void;
+    token: Token;
+    tokenState: TokenState;
+    label?: string;
+    amount?: BigNumber;
+    shouldShowIncompleteErrs: boolean;
+    shouldCheckBalance: boolean;
+    shouldCheckAllowance: boolean;
+    onChange: ValidatedBigNumberCallback;
+    onVisitBalancesPageClick?: () => void;
 }
 
 interface TokenAmountInputState {}
 
 export class TokenAmountInput extends React.Component<TokenAmountInputProps, TokenAmountInputState> {
-	public render() {
-		const amount = this.props.amount
-			? ZeroEx.toUnitAmount(this.props.amount, this.props.token.decimals)
-			: undefined;
-		const hasLabel = !_.isUndefined(this.props.label);
-		return (
-			<div className="flex overflow-hidden" style={{ height: hasLabel ? 84 : 62 }}>
-				<BalanceBoundedInput
-					label={this.props.label}
-					amount={amount}
-					balance={ZeroEx.toUnitAmount(this.props.tokenState.balance, this.props.token.decimals)}
-					onChange={this._onChange.bind(this)}
-					validate={this._validate.bind(this)}
-					shouldCheckBalance={this.props.shouldCheckBalance}
-					shouldShowIncompleteErrs={this.props.shouldShowIncompleteErrs}
-					onVisitBalancesPageClick={this.props.onVisitBalancesPageClick}
-				/>
-				<div style={{ paddingTop: hasLabel ? 39 : 14 }}>{this.props.token.symbol}</div>
-			</div>
-		);
-	}
-	private _onChange(isValid: boolean, amount?: BigNumber) {
-		let baseUnitAmount;
-		if (!_.isUndefined(amount)) {
-			baseUnitAmount = ZeroEx.toBaseUnitAmount(amount, this.props.token.decimals);
-		}
-		this.props.onChange(isValid, baseUnitAmount);
-	}
-	private _validate(amount: BigNumber): InputErrMsg {
-		if (this.props.shouldCheckAllowance && amount.gt(this.props.tokenState.allowance)) {
-			return (
-				<span>
-					Insufficient allowance.{' '}
-					<Link
-						to={`${WebsitePaths.Portal}/balances`}
-						style={{ cursor: 'pointer', color: colors.darkestGrey }}
-					>
-						Set allowance
-					</Link>
-				</span>
-			);
-		} else {
-			return undefined;
-		}
-	}
+    public render() {
+        const amount = this.props.amount
+            ? ZeroEx.toUnitAmount(this.props.amount, this.props.token.decimals)
+            : undefined;
+        const hasLabel = !_.isUndefined(this.props.label);
+        return (
+            <div className="flex overflow-hidden" style={{ height: hasLabel ? 84 : 62 }}>
+                <BalanceBoundedInput
+                    label={this.props.label}
+                    amount={amount}
+                    balance={ZeroEx.toUnitAmount(this.props.tokenState.balance, this.props.token.decimals)}
+                    onChange={this._onChange.bind(this)}
+                    validate={this._validate.bind(this)}
+                    shouldCheckBalance={this.props.shouldCheckBalance}
+                    shouldShowIncompleteErrs={this.props.shouldShowIncompleteErrs}
+                    onVisitBalancesPageClick={this.props.onVisitBalancesPageClick}
+                />
+                <div style={{ paddingTop: hasLabel ? 39 : 14 }}>{this.props.token.symbol}</div>
+            </div>
+        );
+    }
+    private _onChange(isValid: boolean, amount?: BigNumber) {
+        let baseUnitAmount;
+        if (!_.isUndefined(amount)) {
+            baseUnitAmount = ZeroEx.toBaseUnitAmount(amount, this.props.token.decimals);
+        }
+        this.props.onChange(isValid, baseUnitAmount);
+    }
+    private _validate(amount: BigNumber): InputErrMsg {
+        if (this.props.shouldCheckAllowance && amount.gt(this.props.tokenState.allowance)) {
+            return (
+                <span>
+                    Insufficient allowance.{' '}
+                    <Link
+                        to={`${WebsitePaths.Portal}/balances`}
+                        style={{ cursor: 'pointer', color: colors.darkestGrey }}
+                    >
+                        Set allowance
+                    </Link>
+                </span>
+            );
+        } else {
+            return undefined;
+        }
+    }
 }
diff --git a/packages/website/ts/components/inputs/token_input.tsx b/packages/website/ts/components/inputs/token_input.tsx
index 3aceacb22..5df19b28c 100644
--- a/packages/website/ts/components/inputs/token_input.tsx
+++ b/packages/website/ts/components/inputs/token_input.tsx
@@ -12,93 +12,93 @@ import { colors } from 'ts/utils/colors';
 const TOKEN_ICON_DIMENSION = 80;
 
 interface TokenInputProps {
-	blockchain: Blockchain;
-	blockchainErr: BlockchainErrs;
-	dispatcher: Dispatcher;
-	label: string;
-	side: Side;
-	networkId: number;
-	assetToken: AssetToken;
-	updateChosenAssetToken: (side: Side, token: AssetToken) => void;
-	tokenByAddress: TokenByAddress;
-	userAddress: string;
+    blockchain: Blockchain;
+    blockchainErr: BlockchainErrs;
+    dispatcher: Dispatcher;
+    label: string;
+    side: Side;
+    networkId: number;
+    assetToken: AssetToken;
+    updateChosenAssetToken: (side: Side, token: AssetToken) => void;
+    tokenByAddress: TokenByAddress;
+    userAddress: string;
 }
 
 interface TokenInputState {
-	isHoveringIcon: boolean;
-	isPickerOpen: boolean;
-	trackCandidateTokenIfExists?: Token;
+    isHoveringIcon: boolean;
+    isPickerOpen: boolean;
+    trackCandidateTokenIfExists?: Token;
 }
 
 export class TokenInput extends React.Component<TokenInputProps, TokenInputState> {
-	constructor(props: TokenInputProps) {
-		super(props);
-		this.state = {
-			isHoveringIcon: false,
-			isPickerOpen: false,
-		};
-	}
-	public render() {
-		const token = this.props.tokenByAddress[this.props.assetToken.address];
-		const iconStyles = {
-			cursor: 'pointer',
-			opacity: this.state.isHoveringIcon ? 0.5 : 1,
-		};
-		return (
-			<div className="relative">
-				<div className="pb1">
-					<InputLabel text={this.props.label} />
-				</div>
-				<Paper
-					zDepth={1}
-					style={{ cursor: 'pointer' }}
-					onMouseEnter={this._onToggleHover.bind(this, true)}
-					onMouseLeave={this._onToggleHover.bind(this, false)}
-					onClick={this._onAssetClicked.bind(this)}
-				>
-					<div className="mx-auto pt2" style={{ width: TOKEN_ICON_DIMENSION, ...iconStyles }}>
-						<TokenIcon token={token} diameter={TOKEN_ICON_DIMENSION} />
-					</div>
-					<div className="py1 center" style={{ color: colors.grey }}>
-						{token.name}
-					</div>
-				</Paper>
-				<AssetPicker
-					userAddress={this.props.userAddress}
-					networkId={this.props.networkId}
-					blockchain={this.props.blockchain}
-					dispatcher={this.props.dispatcher}
-					isOpen={this.state.isPickerOpen}
-					currentTokenAddress={this.props.assetToken.address}
-					onTokenChosen={this._onTokenChosen.bind(this)}
-					tokenByAddress={this.props.tokenByAddress}
-				/>
-			</div>
-		);
-	}
-	private _onTokenChosen(tokenAddress: string) {
-		const assetToken: AssetToken = {
-			address: tokenAddress,
-			amount: this.props.assetToken.amount,
-		};
-		this.props.updateChosenAssetToken(this.props.side, assetToken);
-		this.setState({
-			isPickerOpen: false,
-		});
-	}
-	private _onToggleHover(isHoveringIcon: boolean) {
-		this.setState({
-			isHoveringIcon,
-		});
-	}
-	private _onAssetClicked() {
-		if (this.props.blockchainErr !== BlockchainErrs.NoError) {
-			this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
-			return;
-		}
+    constructor(props: TokenInputProps) {
+        super(props);
+        this.state = {
+            isHoveringIcon: false,
+            isPickerOpen: false,
+        };
+    }
+    public render() {
+        const token = this.props.tokenByAddress[this.props.assetToken.address];
+        const iconStyles = {
+            cursor: 'pointer',
+            opacity: this.state.isHoveringIcon ? 0.5 : 1,
+        };
+        return (
+            <div className="relative">
+                <div className="pb1">
+                    <InputLabel text={this.props.label} />
+                </div>
+                <Paper
+                    zDepth={1}
+                    style={{ cursor: 'pointer' }}
+                    onMouseEnter={this._onToggleHover.bind(this, true)}
+                    onMouseLeave={this._onToggleHover.bind(this, false)}
+                    onClick={this._onAssetClicked.bind(this)}
+                >
+                    <div className="mx-auto pt2" style={{ width: TOKEN_ICON_DIMENSION, ...iconStyles }}>
+                        <TokenIcon token={token} diameter={TOKEN_ICON_DIMENSION} />
+                    </div>
+                    <div className="py1 center" style={{ color: colors.grey }}>
+                        {token.name}
+                    </div>
+                </Paper>
+                <AssetPicker
+                    userAddress={this.props.userAddress}
+                    networkId={this.props.networkId}
+                    blockchain={this.props.blockchain}
+                    dispatcher={this.props.dispatcher}
+                    isOpen={this.state.isPickerOpen}
+                    currentTokenAddress={this.props.assetToken.address}
+                    onTokenChosen={this._onTokenChosen.bind(this)}
+                    tokenByAddress={this.props.tokenByAddress}
+                />
+            </div>
+        );
+    }
+    private _onTokenChosen(tokenAddress: string) {
+        const assetToken: AssetToken = {
+            address: tokenAddress,
+            amount: this.props.assetToken.amount,
+        };
+        this.props.updateChosenAssetToken(this.props.side, assetToken);
+        this.setState({
+            isPickerOpen: false,
+        });
+    }
+    private _onToggleHover(isHoveringIcon: boolean) {
+        this.setState({
+            isHoveringIcon,
+        });
+    }
+    private _onAssetClicked() {
+        if (this.props.blockchainErr !== BlockchainErrs.NoError) {
+            this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
+            return;
+        }
 
-		this.setState({
-			isPickerOpen: true,
-		});
-	}
+        this.setState({
+            isPickerOpen: true,
+        });
+    }
 }
diff --git a/packages/website/ts/components/order_json.tsx b/packages/website/ts/components/order_json.tsx
index 1640a178e..1b6b32a04 100644
--- a/packages/website/ts/components/order_json.tsx
+++ b/packages/website/ts/components/order_json.tsx
@@ -11,172 +11,172 @@ import { errorReporter } from 'ts/utils/error_reporter';
 import { utils } from 'ts/utils/utils';
 
 interface OrderJSONProps {
-	exchangeContractIfExists: string;
-	orderExpiryTimestamp: BigNumber;
-	orderSignatureData: SignatureData;
-	orderTakerAddress: string;
-	orderMakerAddress: string;
-	orderSalt: BigNumber;
-	orderMakerFee: BigNumber;
-	orderTakerFee: BigNumber;
-	orderFeeRecipient: string;
-	networkId: number;
-	sideToAssetToken: SideToAssetToken;
-	tokenByAddress: TokenByAddress;
+    exchangeContractIfExists: string;
+    orderExpiryTimestamp: BigNumber;
+    orderSignatureData: SignatureData;
+    orderTakerAddress: string;
+    orderMakerAddress: string;
+    orderSalt: BigNumber;
+    orderMakerFee: BigNumber;
+    orderTakerFee: BigNumber;
+    orderFeeRecipient: string;
+    networkId: number;
+    sideToAssetToken: SideToAssetToken;
+    tokenByAddress: TokenByAddress;
 }
 
 interface OrderJSONState {
-	shareLink: string;
+    shareLink: string;
 }
 
 export class OrderJSON extends React.Component<OrderJSONProps, OrderJSONState> {
-	constructor(props: OrderJSONProps) {
-		super(props);
-		this.state = {
-			shareLink: '',
-		};
-		// tslint:disable-next-line:no-floating-promises
-		this._setShareLinkAsync();
-	}
-	public render() {
-		const order = utils.generateOrder(
-			this.props.networkId,
-			this.props.exchangeContractIfExists,
-			this.props.sideToAssetToken,
-			this.props.orderExpiryTimestamp,
-			this.props.orderTakerAddress,
-			this.props.orderMakerAddress,
-			this.props.orderMakerFee,
-			this.props.orderTakerFee,
-			this.props.orderFeeRecipient,
-			this.props.orderSignatureData,
-			this.props.tokenByAddress,
-			this.props.orderSalt,
-		);
-		const orderJSON = JSON.stringify(order);
-		return (
-			<div>
-				<div className="pb2">
-					You have successfully generated and cryptographically signed an order! The following JSON contains
-					the order parameters and cryptographic signature that your counterparty will need to execute a trade
-					with you.
-				</div>
-				<div className="pb2 flex">
-					<div className="inline-block pl1" style={{ top: 1 }}>
-						<CopyIcon data={orderJSON} callToAction="Copy" />
-					</div>
-				</div>
-				<Paper className="center overflow-hidden">
-					<TextField
-						id="orderJSON"
-						style={{ width: 710 }}
-						value={JSON.stringify(order, null, '\t')}
-						multiLine={true}
-						rows={2}
-						rowsMax={8}
-						underlineStyle={{ display: 'none' }}
-					/>
-				</Paper>
-				<div className="pt3 pb2 center">
-					<div>Share your signed order!</div>
-					<div>
-						<div className="mx-auto overflow-hidden" style={{ width: 152 }}>
-							<TextField id={`${this.state.shareLink}-bitly`} value={this.state.shareLink} />
-						</div>
-					</div>
-					<div className="mx-auto pt1 flex" style={{ width: 91 }}>
-						<div>
-							<i
-								style={{ cursor: 'pointer', fontSize: 29 }}
-								onClick={this._shareViaFacebook.bind(this)}
-								className="zmdi zmdi-facebook-box"
-							/>
-						</div>
-						<div className="pl1" style={{ position: 'relative', width: 28 }}>
-							<i
-								style={{
-									cursor: 'pointer',
-									fontSize: 32,
-									position: 'absolute',
-									top: -2,
-									left: 8,
-								}}
-								onClick={this._shareViaEmailAsync.bind(this)}
-								className="zmdi zmdi-email"
-							/>
-						</div>
-						<div className="pl1">
-							<i
-								style={{ cursor: 'pointer', fontSize: 29 }}
-								onClick={this._shareViaTwitterAsync.bind(this)}
-								className="zmdi zmdi-twitter-box"
-							/>
-						</div>
-					</div>
-				</div>
-			</div>
-		);
-	}
-	private async _shareViaTwitterAsync() {
-		const tweetText = encodeURIComponent(`Fill my order using the 0x protocol: ${this.state.shareLink}`);
-		window.open(`https://twitter.com/intent/tweet?text=${tweetText}`, 'Share your order', 'width=500,height=400');
-	}
-	private async _shareViaFacebook() {
-		(window as any).FB.ui(
-			{
-				display: 'popup',
-				href: this.state.shareLink,
-				method: 'share',
-			},
-			_.noop,
-		);
-	}
-	private async _shareViaEmailAsync() {
-		const encodedSubject = encodeURIComponent("Let's trade using the 0x protocol");
-		const encodedBody = encodeURIComponent(`I generated an order with the 0x protocol.
+    constructor(props: OrderJSONProps) {
+        super(props);
+        this.state = {
+            shareLink: '',
+        };
+        // tslint:disable-next-line:no-floating-promises
+        this._setShareLinkAsync();
+    }
+    public render() {
+        const order = utils.generateOrder(
+            this.props.networkId,
+            this.props.exchangeContractIfExists,
+            this.props.sideToAssetToken,
+            this.props.orderExpiryTimestamp,
+            this.props.orderTakerAddress,
+            this.props.orderMakerAddress,
+            this.props.orderMakerFee,
+            this.props.orderTakerFee,
+            this.props.orderFeeRecipient,
+            this.props.orderSignatureData,
+            this.props.tokenByAddress,
+            this.props.orderSalt,
+        );
+        const orderJSON = JSON.stringify(order);
+        return (
+            <div>
+                <div className="pb2">
+                    You have successfully generated and cryptographically signed an order! The following JSON contains
+                    the order parameters and cryptographic signature that your counterparty will need to execute a trade
+                    with you.
+                </div>
+                <div className="pb2 flex">
+                    <div className="inline-block pl1" style={{ top: 1 }}>
+                        <CopyIcon data={orderJSON} callToAction="Copy" />
+                    </div>
+                </div>
+                <Paper className="center overflow-hidden">
+                    <TextField
+                        id="orderJSON"
+                        style={{ width: 710 }}
+                        value={JSON.stringify(order, null, '\t')}
+                        multiLine={true}
+                        rows={2}
+                        rowsMax={8}
+                        underlineStyle={{ display: 'none' }}
+                    />
+                </Paper>
+                <div className="pt3 pb2 center">
+                    <div>Share your signed order!</div>
+                    <div>
+                        <div className="mx-auto overflow-hidden" style={{ width: 152 }}>
+                            <TextField id={`${this.state.shareLink}-bitly`} value={this.state.shareLink} />
+                        </div>
+                    </div>
+                    <div className="mx-auto pt1 flex" style={{ width: 91 }}>
+                        <div>
+                            <i
+                                style={{ cursor: 'pointer', fontSize: 29 }}
+                                onClick={this._shareViaFacebook.bind(this)}
+                                className="zmdi zmdi-facebook-box"
+                            />
+                        </div>
+                        <div className="pl1" style={{ position: 'relative', width: 28 }}>
+                            <i
+                                style={{
+                                    cursor: 'pointer',
+                                    fontSize: 32,
+                                    position: 'absolute',
+                                    top: -2,
+                                    left: 8,
+                                }}
+                                onClick={this._shareViaEmailAsync.bind(this)}
+                                className="zmdi zmdi-email"
+                            />
+                        </div>
+                        <div className="pl1">
+                            <i
+                                style={{ cursor: 'pointer', fontSize: 29 }}
+                                onClick={this._shareViaTwitterAsync.bind(this)}
+                                className="zmdi zmdi-twitter-box"
+                            />
+                        </div>
+                    </div>
+                </div>
+            </div>
+        );
+    }
+    private async _shareViaTwitterAsync() {
+        const tweetText = encodeURIComponent(`Fill my order using the 0x protocol: ${this.state.shareLink}`);
+        window.open(`https://twitter.com/intent/tweet?text=${tweetText}`, 'Share your order', 'width=500,height=400');
+    }
+    private async _shareViaFacebook() {
+        (window as any).FB.ui(
+            {
+                display: 'popup',
+                href: this.state.shareLink,
+                method: 'share',
+            },
+            _.noop,
+        );
+    }
+    private async _shareViaEmailAsync() {
+        const encodedSubject = encodeURIComponent("Let's trade using the 0x protocol");
+        const encodedBody = encodeURIComponent(`I generated an order with the 0x protocol.
 You can see and fill it here: ${this.state.shareLink}`);
-		const mailToLink = `mailto:mail@example.org?subject=${encodedSubject}&body=${encodedBody}`;
-		window.open(mailToLink, '_blank');
-	}
-	private async _setShareLinkAsync() {
-		const shareLink = await this._generateShareLinkAsync();
-		this.setState({
-			shareLink,
-		});
-	}
-	private async _generateShareLinkAsync(): Promise<string> {
-		const longUrl = encodeURIComponent(this._getOrderUrl());
-		const bitlyRequestUrl = `${constants.URL_BITLY_API}/v3/shorten?access_token=${
-			configs.BITLY_ACCESS_TOKEN
-		}&longUrl=${longUrl}`;
-		const response = await fetch(bitlyRequestUrl);
-		const responseBody = await response.text();
-		const bodyObj = JSON.parse(responseBody);
-		if (response.status !== 200 || bodyObj.status_code !== 200) {
-			// TODO: Show error message in UI
-			utils.consoleLog(`Unexpected status code: ${response.status} -> ${responseBody}`);
-			await errorReporter.reportAsync(new Error(`Bitly returned non-200: ${JSON.stringify(response)}`));
-			return '';
-		}
-		return bodyObj.data.url;
-	}
-	private _getOrderUrl() {
-		const order = utils.generateOrder(
-			this.props.networkId,
-			this.props.exchangeContractIfExists,
-			this.props.sideToAssetToken,
-			this.props.orderExpiryTimestamp,
-			this.props.orderTakerAddress,
-			this.props.orderMakerAddress,
-			this.props.orderMakerFee,
-			this.props.orderTakerFee,
-			this.props.orderFeeRecipient,
-			this.props.orderSignatureData,
-			this.props.tokenByAddress,
-			this.props.orderSalt,
-		);
-		const orderJSONString = JSON.stringify(order);
-		const orderUrl = `${configs.BASE_URL}${WebsitePaths.Portal}/fill?order=${orderJSONString}`;
-		return orderUrl;
-	}
+        const mailToLink = `mailto:mail@example.org?subject=${encodedSubject}&body=${encodedBody}`;
+        window.open(mailToLink, '_blank');
+    }
+    private async _setShareLinkAsync() {
+        const shareLink = await this._generateShareLinkAsync();
+        this.setState({
+            shareLink,
+        });
+    }
+    private async _generateShareLinkAsync(): Promise<string> {
+        const longUrl = encodeURIComponent(this._getOrderUrl());
+        const bitlyRequestUrl = `${constants.URL_BITLY_API}/v3/shorten?access_token=${
+            configs.BITLY_ACCESS_TOKEN
+        }&longUrl=${longUrl}`;
+        const response = await fetch(bitlyRequestUrl);
+        const responseBody = await response.text();
+        const bodyObj = JSON.parse(responseBody);
+        if (response.status !== 200 || bodyObj.status_code !== 200) {
+            // TODO: Show error message in UI
+            utils.consoleLog(`Unexpected status code: ${response.status} -> ${responseBody}`);
+            await errorReporter.reportAsync(new Error(`Bitly returned non-200: ${JSON.stringify(response)}`));
+            return '';
+        }
+        return bodyObj.data.url;
+    }
+    private _getOrderUrl() {
+        const order = utils.generateOrder(
+            this.props.networkId,
+            this.props.exchangeContractIfExists,
+            this.props.sideToAssetToken,
+            this.props.orderExpiryTimestamp,
+            this.props.orderTakerAddress,
+            this.props.orderMakerAddress,
+            this.props.orderMakerFee,
+            this.props.orderTakerFee,
+            this.props.orderFeeRecipient,
+            this.props.orderSignatureData,
+            this.props.tokenByAddress,
+            this.props.orderSalt,
+        );
+        const orderJSONString = JSON.stringify(order);
+        const orderUrl = `${configs.BASE_URL}${WebsitePaths.Portal}/fill?order=${orderJSONString}`;
+        return orderUrl;
+    }
 }
diff --git a/packages/website/ts/components/portal.tsx b/packages/website/ts/components/portal.tsx
index e163a1fa2..e2e28e8b6 100644
--- a/packages/website/ts/components/portal.tsx
+++ b/packages/website/ts/components/portal.tsx
@@ -23,14 +23,14 @@ import { Dispatcher } from 'ts/redux/dispatcher';
 import { orderSchema } from 'ts/schemas/order_schema';
 import { SchemaValidator } from 'ts/schemas/validator';
 import {
-	BlockchainErrs,
-	HashData,
-	Order,
-	ScreenWidths,
-	Token,
-	TokenByAddress,
-	TokenStateByAddress,
-	WebsitePaths,
+    BlockchainErrs,
+    HashData,
+    Order,
+    ScreenWidths,
+    Token,
+    TokenByAddress,
+    TokenStateByAddress,
+    WebsitePaths,
 } from 'ts/types';
 import { colors } from 'ts/utils/colors';
 import { configs } from 'ts/utils/configs';
@@ -42,320 +42,320 @@ const THROTTLE_TIMEOUT = 100;
 export interface PortalPassedProps {}
 
 export interface PortalAllProps {
-	blockchainErr: BlockchainErrs;
-	blockchainIsLoaded: boolean;
-	dispatcher: Dispatcher;
-	hashData: HashData;
-	networkId: number;
-	nodeVersion: string;
-	orderFillAmount: BigNumber;
-	screenWidth: ScreenWidths;
-	tokenByAddress: TokenByAddress;
-	tokenStateByAddress: TokenStateByAddress;
-	userEtherBalance: BigNumber;
-	userAddress: string;
-	shouldBlockchainErrDialogBeOpen: boolean;
-	userSuppliedOrderCache: Order;
-	location: Location;
-	flashMessage?: string | React.ReactNode;
+    blockchainErr: BlockchainErrs;
+    blockchainIsLoaded: boolean;
+    dispatcher: Dispatcher;
+    hashData: HashData;
+    networkId: number;
+    nodeVersion: string;
+    orderFillAmount: BigNumber;
+    screenWidth: ScreenWidths;
+    tokenByAddress: TokenByAddress;
+    tokenStateByAddress: TokenStateByAddress;
+    userEtherBalance: BigNumber;
+    userAddress: string;
+    shouldBlockchainErrDialogBeOpen: boolean;
+    userSuppliedOrderCache: Order;
+    location: Location;
+    flashMessage?: string | React.ReactNode;
 }
 
 interface PortalAllState {
-	prevNetworkId: number;
-	prevNodeVersion: string;
-	prevUserAddress: string;
-	prevPathname: string;
-	isDisclaimerDialogOpen: boolean;
-	isWethNoticeDialogOpen: boolean;
+    prevNetworkId: number;
+    prevNodeVersion: string;
+    prevUserAddress: string;
+    prevPathname: string;
+    isDisclaimerDialogOpen: boolean;
+    isWethNoticeDialogOpen: boolean;
 }
 
 export class Portal extends React.Component<PortalAllProps, PortalAllState> {
-	private _blockchain: Blockchain;
-	private _sharedOrderIfExists: Order;
-	private _throttledScreenWidthUpdate: () => void;
-	public static hasAlreadyDismissedWethNotice() {
-		const didDismissWethNotice = localStorage.getItemIfExists(constants.LOCAL_STORAGE_KEY_DISMISS_WETH_NOTICE);
-		const hasAlreadyDismissedWethNotice = !_.isUndefined(didDismissWethNotice) && !_.isEmpty(didDismissWethNotice);
-		return hasAlreadyDismissedWethNotice;
-	}
-	constructor(props: PortalAllProps) {
-		super(props);
-		this._sharedOrderIfExists = this._getSharedOrderIfExists();
-		this._throttledScreenWidthUpdate = _.throttle(this._updateScreenWidth.bind(this), THROTTLE_TIMEOUT);
+    private _blockchain: Blockchain;
+    private _sharedOrderIfExists: Order;
+    private _throttledScreenWidthUpdate: () => void;
+    public static hasAlreadyDismissedWethNotice() {
+        const didDismissWethNotice = localStorage.getItemIfExists(constants.LOCAL_STORAGE_KEY_DISMISS_WETH_NOTICE);
+        const hasAlreadyDismissedWethNotice = !_.isUndefined(didDismissWethNotice) && !_.isEmpty(didDismissWethNotice);
+        return hasAlreadyDismissedWethNotice;
+    }
+    constructor(props: PortalAllProps) {
+        super(props);
+        this._sharedOrderIfExists = this._getSharedOrderIfExists();
+        this._throttledScreenWidthUpdate = _.throttle(this._updateScreenWidth.bind(this), THROTTLE_TIMEOUT);
 
-		const isViewingBalances = _.includes(props.location.pathname, `${WebsitePaths.Portal}/balances`);
-		const hasAlreadyDismissedWethNotice = Portal.hasAlreadyDismissedWethNotice();
+        const isViewingBalances = _.includes(props.location.pathname, `${WebsitePaths.Portal}/balances`);
+        const hasAlreadyDismissedWethNotice = Portal.hasAlreadyDismissedWethNotice();
 
-		const didAcceptPortalDisclaimer = localStorage.getItemIfExists(constants.LOCAL_STORAGE_KEY_ACCEPT_DISCLAIMER);
-		const hasAcceptedDisclaimer =
-			!_.isUndefined(didAcceptPortalDisclaimer) && !_.isEmpty(didAcceptPortalDisclaimer);
-		this.state = {
-			prevNetworkId: this.props.networkId,
-			prevNodeVersion: this.props.nodeVersion,
-			prevUserAddress: this.props.userAddress,
-			prevPathname: this.props.location.pathname,
-			isDisclaimerDialogOpen: !hasAcceptedDisclaimer,
-			isWethNoticeDialogOpen: !hasAlreadyDismissedWethNotice && isViewingBalances,
-		};
-	}
-	public componentDidMount() {
-		window.addEventListener('resize', this._throttledScreenWidthUpdate);
-		window.scrollTo(0, 0);
-	}
-	public componentWillMount() {
-		this._blockchain = new Blockchain(this.props.dispatcher);
-	}
-	public componentWillUnmount() {
-		this._blockchain.destroy();
-		window.removeEventListener('resize', this._throttledScreenWidthUpdate);
-		// We re-set the entire redux state when the portal is unmounted so that when it is re-rendered
-		// the initialization process always occurs from the same base state. This helps avoid
-		// initialization inconsistencies (i.e While the portal was unrendered, the user might have
-		// become disconnected from their backing Ethereum node, changes user accounts, etc...)
-		this.props.dispatcher.resetState();
-	}
-	public componentWillReceiveProps(nextProps: PortalAllProps) {
-		if (nextProps.networkId !== this.state.prevNetworkId) {
-			// tslint:disable-next-line:no-floating-promises
-			this._blockchain.networkIdUpdatedFireAndForgetAsync(nextProps.networkId);
-			this.setState({
-				prevNetworkId: nextProps.networkId,
-			});
-		}
-		if (nextProps.userAddress !== this.state.prevUserAddress) {
-			// tslint:disable-next-line:no-floating-promises
-			this._blockchain.userAddressUpdatedFireAndForgetAsync(nextProps.userAddress);
-			if (!_.isEmpty(nextProps.userAddress) && nextProps.blockchainIsLoaded) {
-				const tokens = _.values(nextProps.tokenByAddress);
-				// tslint:disable-next-line:no-floating-promises
-				this._updateBalanceAndAllowanceWithLoadingScreenAsync(tokens);
-			}
-			this.setState({
-				prevUserAddress: nextProps.userAddress,
-			});
-		}
-		if (nextProps.nodeVersion !== this.state.prevNodeVersion) {
-			// tslint:disable-next-line:no-floating-promises
-			this._blockchain.nodeVersionUpdatedFireAndForgetAsync(nextProps.nodeVersion);
-		}
-		if (nextProps.location.pathname !== this.state.prevPathname) {
-			const isViewingBalances = _.includes(nextProps.location.pathname, `${WebsitePaths.Portal}/balances`);
-			const hasAlreadyDismissedWethNotice = Portal.hasAlreadyDismissedWethNotice();
-			this.setState({
-				prevPathname: nextProps.location.pathname,
-				isWethNoticeDialogOpen: !hasAlreadyDismissedWethNotice && isViewingBalances,
-			});
-		}
-	}
-	public render() {
-		const updateShouldBlockchainErrDialogBeOpen = this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen.bind(
-			this.props.dispatcher,
-		);
-		const portalStyle: React.CSSProperties = {
-			minHeight: '100vh',
-			display: 'flex',
-			flexDirection: 'column',
-			justifyContent: 'space-between',
-		};
-		const portalMenuContainerStyle: React.CSSProperties = {
-			overflow: 'hidden',
-			backgroundColor: colors.darkestGrey,
-			color: colors.white,
-		};
-		return (
-			<div style={portalStyle}>
-				<DocumentTitle title="0x Portal DApp" />
-				<TopBar
-					userAddress={this.props.userAddress}
-					blockchainIsLoaded={this.props.blockchainIsLoaded}
-					location={this.props.location}
-				/>
-				<div id="portal" className="mx-auto max-width-4" style={{ width: '100%' }}>
-					<Paper className="mb3 mt2">
-						{!configs.IS_MAINNET_ENABLED && this.props.networkId === constants.NETWORK_ID_MAINNET ? (
-							<div className="p3 center">
-								<div className="h2 py2">Mainnet unavailable</div>
-								<div className="mx-auto pb2 pt2">
-									<img src="/images/zrx_token.png" style={{ width: 150 }} />
-								</div>
-								<div>
-									0x portal is currently unavailable on the Ethereum mainnet.
-									<div>To try it out, switch to the Kovan test network (networkId: 42).</div>
-									<div className="py2">Check back soon!</div>
-								</div>
-							</div>
-						) : (
-							<div className="mx-auto flex">
-								<div className="col col-2 pr2 pt1 sm-hide xs-hide" style={portalMenuContainerStyle}>
-									<PortalMenu menuItemStyle={{ color: colors.white }} />
-								</div>
-								<div className="col col-12 lg-col-10 md-col-10 sm-col sm-col-12">
-									<div className="py2" style={{ backgroundColor: colors.grey50 }}>
-										{this.props.blockchainIsLoaded ? (
-											<Switch>
-												<Route
-													path={`${WebsitePaths.Portal}/weth`}
-													render={this._renderEthWrapper.bind(this)}
-												/>
-												<Route
-													path={`${WebsitePaths.Portal}/fill`}
-													render={this._renderFillOrder.bind(this)}
-												/>
-												<Route
-													path={`${WebsitePaths.Portal}/balances`}
-													render={this._renderTokenBalances.bind(this)}
-												/>
-												<Route
-													path={`${WebsitePaths.Portal}/trades`}
-													component={this._renderTradeHistory.bind(this)}
-												/>
-												<Route
-													path={`${WebsitePaths.Home}`}
-													render={this._renderGenerateOrderForm.bind(this)}
-												/>
-											</Switch>
-										) : (
-											<Loading />
-										)}
-									</div>
-								</div>
-							</div>
-						)}
-					</Paper>
-					<BlockchainErrDialog
-						blockchain={this._blockchain}
-						blockchainErr={this.props.blockchainErr}
-						isOpen={this.props.shouldBlockchainErrDialogBeOpen}
-						userAddress={this.props.userAddress}
-						toggleDialogFn={updateShouldBlockchainErrDialogBeOpen}
-						networkId={this.props.networkId}
-					/>
-					<WrappedEthSectionNoticeDialog
-						isOpen={this.state.isWethNoticeDialogOpen}
-						onToggleDialog={this._onWethNoticeAccepted.bind(this)}
-					/>
-					<PortalDisclaimerDialog
-						isOpen={this.state.isDisclaimerDialogOpen}
-						onToggleDialog={this._onPortalDisclaimerAccepted.bind(this)}
-					/>
-					<FlashMessage dispatcher={this.props.dispatcher} flashMessage={this.props.flashMessage} />
-				</div>
-				<Footer />
-			</div>
-		);
-	}
-	private _renderEthWrapper() {
-		return (
-			<EthWrappers
-				networkId={this.props.networkId}
-				blockchain={this._blockchain}
-				dispatcher={this.props.dispatcher}
-				tokenByAddress={this.props.tokenByAddress}
-				tokenStateByAddress={this.props.tokenStateByAddress}
-				userAddress={this.props.userAddress}
-				userEtherBalance={this.props.userEtherBalance}
-			/>
-		);
-	}
-	private _renderTradeHistory() {
-		return (
-			<TradeHistory
-				tokenByAddress={this.props.tokenByAddress}
-				userAddress={this.props.userAddress}
-				networkId={this.props.networkId}
-			/>
-		);
-	}
-	private _renderTokenBalances() {
-		return (
-			<TokenBalances
-				blockchain={this._blockchain}
-				blockchainErr={this.props.blockchainErr}
-				blockchainIsLoaded={this.props.blockchainIsLoaded}
-				dispatcher={this.props.dispatcher}
-				screenWidth={this.props.screenWidth}
-				tokenByAddress={this.props.tokenByAddress}
-				tokenStateByAddress={this.props.tokenStateByAddress}
-				userAddress={this.props.userAddress}
-				userEtherBalance={this.props.userEtherBalance}
-				networkId={this.props.networkId}
-			/>
-		);
-	}
-	private _renderFillOrder(match: any, location: Location, history: History) {
-		const initialFillOrder = !_.isUndefined(this.props.userSuppliedOrderCache)
-			? this.props.userSuppliedOrderCache
-			: this._sharedOrderIfExists;
-		return (
-			<FillOrder
-				blockchain={this._blockchain}
-				blockchainErr={this.props.blockchainErr}
-				initialOrder={initialFillOrder}
-				isOrderInUrl={!_.isUndefined(this._sharedOrderIfExists)}
-				orderFillAmount={this.props.orderFillAmount}
-				networkId={this.props.networkId}
-				userAddress={this.props.userAddress}
-				tokenByAddress={this.props.tokenByAddress}
-				tokenStateByAddress={this.props.tokenStateByAddress}
-				dispatcher={this.props.dispatcher}
-			/>
-		);
-	}
-	private _renderGenerateOrderForm(match: any, location: Location, history: History) {
-		return (
-			<GenerateOrderForm
-				blockchain={this._blockchain}
-				hashData={this.props.hashData}
-				dispatcher={this.props.dispatcher}
-			/>
-		);
-	}
-	private _onPortalDisclaimerAccepted() {
-		localStorage.setItem(constants.LOCAL_STORAGE_KEY_ACCEPT_DISCLAIMER, 'set');
-		this.setState({
-			isDisclaimerDialogOpen: false,
-		});
-	}
-	private _onWethNoticeAccepted() {
-		localStorage.setItem(constants.LOCAL_STORAGE_KEY_DISMISS_WETH_NOTICE, 'set');
-		this.setState({
-			isWethNoticeDialogOpen: false,
-		});
-	}
-	private _getSharedOrderIfExists(): Order | undefined {
-		const queryString = window.location.search;
-		if (queryString.length === 0) {
-			return undefined;
-		}
-		const queryParams = queryString.substring(1).split('&');
-		const orderQueryParam = _.find(queryParams, queryParam => {
-			const queryPair = queryParam.split('=');
-			return queryPair[0] === 'order';
-		});
-		if (_.isUndefined(orderQueryParam)) {
-			return undefined;
-		}
-		const orderPair = orderQueryParam.split('=');
-		if (orderPair.length !== 2) {
-			return undefined;
-		}
+        const didAcceptPortalDisclaimer = localStorage.getItemIfExists(constants.LOCAL_STORAGE_KEY_ACCEPT_DISCLAIMER);
+        const hasAcceptedDisclaimer =
+            !_.isUndefined(didAcceptPortalDisclaimer) && !_.isEmpty(didAcceptPortalDisclaimer);
+        this.state = {
+            prevNetworkId: this.props.networkId,
+            prevNodeVersion: this.props.nodeVersion,
+            prevUserAddress: this.props.userAddress,
+            prevPathname: this.props.location.pathname,
+            isDisclaimerDialogOpen: !hasAcceptedDisclaimer,
+            isWethNoticeDialogOpen: !hasAlreadyDismissedWethNotice && isViewingBalances,
+        };
+    }
+    public componentDidMount() {
+        window.addEventListener('resize', this._throttledScreenWidthUpdate);
+        window.scrollTo(0, 0);
+    }
+    public componentWillMount() {
+        this._blockchain = new Blockchain(this.props.dispatcher);
+    }
+    public componentWillUnmount() {
+        this._blockchain.destroy();
+        window.removeEventListener('resize', this._throttledScreenWidthUpdate);
+        // We re-set the entire redux state when the portal is unmounted so that when it is re-rendered
+        // the initialization process always occurs from the same base state. This helps avoid
+        // initialization inconsistencies (i.e While the portal was unrendered, the user might have
+        // become disconnected from their backing Ethereum node, changes user accounts, etc...)
+        this.props.dispatcher.resetState();
+    }
+    public componentWillReceiveProps(nextProps: PortalAllProps) {
+        if (nextProps.networkId !== this.state.prevNetworkId) {
+            // tslint:disable-next-line:no-floating-promises
+            this._blockchain.networkIdUpdatedFireAndForgetAsync(nextProps.networkId);
+            this.setState({
+                prevNetworkId: nextProps.networkId,
+            });
+        }
+        if (nextProps.userAddress !== this.state.prevUserAddress) {
+            // tslint:disable-next-line:no-floating-promises
+            this._blockchain.userAddressUpdatedFireAndForgetAsync(nextProps.userAddress);
+            if (!_.isEmpty(nextProps.userAddress) && nextProps.blockchainIsLoaded) {
+                const tokens = _.values(nextProps.tokenByAddress);
+                // tslint:disable-next-line:no-floating-promises
+                this._updateBalanceAndAllowanceWithLoadingScreenAsync(tokens);
+            }
+            this.setState({
+                prevUserAddress: nextProps.userAddress,
+            });
+        }
+        if (nextProps.nodeVersion !== this.state.prevNodeVersion) {
+            // tslint:disable-next-line:no-floating-promises
+            this._blockchain.nodeVersionUpdatedFireAndForgetAsync(nextProps.nodeVersion);
+        }
+        if (nextProps.location.pathname !== this.state.prevPathname) {
+            const isViewingBalances = _.includes(nextProps.location.pathname, `${WebsitePaths.Portal}/balances`);
+            const hasAlreadyDismissedWethNotice = Portal.hasAlreadyDismissedWethNotice();
+            this.setState({
+                prevPathname: nextProps.location.pathname,
+                isWethNoticeDialogOpen: !hasAlreadyDismissedWethNotice && isViewingBalances,
+            });
+        }
+    }
+    public render() {
+        const updateShouldBlockchainErrDialogBeOpen = this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen.bind(
+            this.props.dispatcher,
+        );
+        const portalStyle: React.CSSProperties = {
+            minHeight: '100vh',
+            display: 'flex',
+            flexDirection: 'column',
+            justifyContent: 'space-between',
+        };
+        const portalMenuContainerStyle: React.CSSProperties = {
+            overflow: 'hidden',
+            backgroundColor: colors.darkestGrey,
+            color: colors.white,
+        };
+        return (
+            <div style={portalStyle}>
+                <DocumentTitle title="0x Portal DApp" />
+                <TopBar
+                    userAddress={this.props.userAddress}
+                    blockchainIsLoaded={this.props.blockchainIsLoaded}
+                    location={this.props.location}
+                />
+                <div id="portal" className="mx-auto max-width-4" style={{ width: '100%' }}>
+                    <Paper className="mb3 mt2">
+                        {!configs.IS_MAINNET_ENABLED && this.props.networkId === constants.NETWORK_ID_MAINNET ? (
+                            <div className="p3 center">
+                                <div className="h2 py2">Mainnet unavailable</div>
+                                <div className="mx-auto pb2 pt2">
+                                    <img src="/images/zrx_token.png" style={{ width: 150 }} />
+                                </div>
+                                <div>
+                                    0x portal is currently unavailable on the Ethereum mainnet.
+                                    <div>To try it out, switch to the Kovan test network (networkId: 42).</div>
+                                    <div className="py2">Check back soon!</div>
+                                </div>
+                            </div>
+                        ) : (
+                            <div className="mx-auto flex">
+                                <div className="col col-2 pr2 pt1 sm-hide xs-hide" style={portalMenuContainerStyle}>
+                                    <PortalMenu menuItemStyle={{ color: colors.white }} />
+                                </div>
+                                <div className="col col-12 lg-col-10 md-col-10 sm-col sm-col-12">
+                                    <div className="py2" style={{ backgroundColor: colors.grey50 }}>
+                                        {this.props.blockchainIsLoaded ? (
+                                            <Switch>
+                                                <Route
+                                                    path={`${WebsitePaths.Portal}/weth`}
+                                                    render={this._renderEthWrapper.bind(this)}
+                                                />
+                                                <Route
+                                                    path={`${WebsitePaths.Portal}/fill`}
+                                                    render={this._renderFillOrder.bind(this)}
+                                                />
+                                                <Route
+                                                    path={`${WebsitePaths.Portal}/balances`}
+                                                    render={this._renderTokenBalances.bind(this)}
+                                                />
+                                                <Route
+                                                    path={`${WebsitePaths.Portal}/trades`}
+                                                    component={this._renderTradeHistory.bind(this)}
+                                                />
+                                                <Route
+                                                    path={`${WebsitePaths.Home}`}
+                                                    render={this._renderGenerateOrderForm.bind(this)}
+                                                />
+                                            </Switch>
+                                        ) : (
+                                            <Loading />
+                                        )}
+                                    </div>
+                                </div>
+                            </div>
+                        )}
+                    </Paper>
+                    <BlockchainErrDialog
+                        blockchain={this._blockchain}
+                        blockchainErr={this.props.blockchainErr}
+                        isOpen={this.props.shouldBlockchainErrDialogBeOpen}
+                        userAddress={this.props.userAddress}
+                        toggleDialogFn={updateShouldBlockchainErrDialogBeOpen}
+                        networkId={this.props.networkId}
+                    />
+                    <WrappedEthSectionNoticeDialog
+                        isOpen={this.state.isWethNoticeDialogOpen}
+                        onToggleDialog={this._onWethNoticeAccepted.bind(this)}
+                    />
+                    <PortalDisclaimerDialog
+                        isOpen={this.state.isDisclaimerDialogOpen}
+                        onToggleDialog={this._onPortalDisclaimerAccepted.bind(this)}
+                    />
+                    <FlashMessage dispatcher={this.props.dispatcher} flashMessage={this.props.flashMessage} />
+                </div>
+                <Footer />
+            </div>
+        );
+    }
+    private _renderEthWrapper() {
+        return (
+            <EthWrappers
+                networkId={this.props.networkId}
+                blockchain={this._blockchain}
+                dispatcher={this.props.dispatcher}
+                tokenByAddress={this.props.tokenByAddress}
+                tokenStateByAddress={this.props.tokenStateByAddress}
+                userAddress={this.props.userAddress}
+                userEtherBalance={this.props.userEtherBalance}
+            />
+        );
+    }
+    private _renderTradeHistory() {
+        return (
+            <TradeHistory
+                tokenByAddress={this.props.tokenByAddress}
+                userAddress={this.props.userAddress}
+                networkId={this.props.networkId}
+            />
+        );
+    }
+    private _renderTokenBalances() {
+        return (
+            <TokenBalances
+                blockchain={this._blockchain}
+                blockchainErr={this.props.blockchainErr}
+                blockchainIsLoaded={this.props.blockchainIsLoaded}
+                dispatcher={this.props.dispatcher}
+                screenWidth={this.props.screenWidth}
+                tokenByAddress={this.props.tokenByAddress}
+                tokenStateByAddress={this.props.tokenStateByAddress}
+                userAddress={this.props.userAddress}
+                userEtherBalance={this.props.userEtherBalance}
+                networkId={this.props.networkId}
+            />
+        );
+    }
+    private _renderFillOrder(match: any, location: Location, history: History) {
+        const initialFillOrder = !_.isUndefined(this.props.userSuppliedOrderCache)
+            ? this.props.userSuppliedOrderCache
+            : this._sharedOrderIfExists;
+        return (
+            <FillOrder
+                blockchain={this._blockchain}
+                blockchainErr={this.props.blockchainErr}
+                initialOrder={initialFillOrder}
+                isOrderInUrl={!_.isUndefined(this._sharedOrderIfExists)}
+                orderFillAmount={this.props.orderFillAmount}
+                networkId={this.props.networkId}
+                userAddress={this.props.userAddress}
+                tokenByAddress={this.props.tokenByAddress}
+                tokenStateByAddress={this.props.tokenStateByAddress}
+                dispatcher={this.props.dispatcher}
+            />
+        );
+    }
+    private _renderGenerateOrderForm(match: any, location: Location, history: History) {
+        return (
+            <GenerateOrderForm
+                blockchain={this._blockchain}
+                hashData={this.props.hashData}
+                dispatcher={this.props.dispatcher}
+            />
+        );
+    }
+    private _onPortalDisclaimerAccepted() {
+        localStorage.setItem(constants.LOCAL_STORAGE_KEY_ACCEPT_DISCLAIMER, 'set');
+        this.setState({
+            isDisclaimerDialogOpen: false,
+        });
+    }
+    private _onWethNoticeAccepted() {
+        localStorage.setItem(constants.LOCAL_STORAGE_KEY_DISMISS_WETH_NOTICE, 'set');
+        this.setState({
+            isWethNoticeDialogOpen: false,
+        });
+    }
+    private _getSharedOrderIfExists(): Order | undefined {
+        const queryString = window.location.search;
+        if (queryString.length === 0) {
+            return undefined;
+        }
+        const queryParams = queryString.substring(1).split('&');
+        const orderQueryParam = _.find(queryParams, queryParam => {
+            const queryPair = queryParam.split('=');
+            return queryPair[0] === 'order';
+        });
+        if (_.isUndefined(orderQueryParam)) {
+            return undefined;
+        }
+        const orderPair = orderQueryParam.split('=');
+        if (orderPair.length !== 2) {
+            return undefined;
+        }
 
-		const validator = new SchemaValidator();
-		const order = JSON.parse(decodeURIComponent(orderPair[1]));
-		const validationResult = validator.validate(order, orderSchema);
-		if (validationResult.errors.length > 0) {
-			utils.consoleLog(`Invalid shared order: ${validationResult.errors}`);
-			return undefined;
-		}
-		return order;
-	}
-	private _updateScreenWidth() {
-		const newScreenWidth = utils.getScreenWidth();
-		this.props.dispatcher.updateScreenWidth(newScreenWidth);
-	}
-	private async _updateBalanceAndAllowanceWithLoadingScreenAsync(tokens: Token[]) {
-		this.props.dispatcher.updateBlockchainIsLoaded(false);
-		await this._blockchain.updateTokenBalancesAndAllowancesAsync(tokens);
-		this.props.dispatcher.updateBlockchainIsLoaded(true);
-	}
+        const validator = new SchemaValidator();
+        const order = JSON.parse(decodeURIComponent(orderPair[1]));
+        const validationResult = validator.validate(order, orderSchema);
+        if (validationResult.errors.length > 0) {
+            utils.consoleLog(`Invalid shared order: ${validationResult.errors}`);
+            return undefined;
+        }
+        return order;
+    }
+    private _updateScreenWidth() {
+        const newScreenWidth = utils.getScreenWidth();
+        this.props.dispatcher.updateScreenWidth(newScreenWidth);
+    }
+    private async _updateBalanceAndAllowanceWithLoadingScreenAsync(tokens: Token[]) {
+        this.props.dispatcher.updateBlockchainIsLoaded(false);
+        await this._blockchain.updateTokenBalancesAndAllowancesAsync(tokens);
+        this.props.dispatcher.updateBlockchainIsLoaded(true);
+    }
 }
diff --git a/packages/website/ts/components/portal_menu.tsx b/packages/website/ts/components/portal_menu.tsx
index b025f527e..a2f9340c8 100644
--- a/packages/website/ts/components/portal_menu.tsx
+++ b/packages/website/ts/components/portal_menu.tsx
@@ -4,70 +4,70 @@ import { MenuItem } from 'ts/components/ui/menu_item';
 import { WebsitePaths } from 'ts/types';
 
 export interface PortalMenuProps {
-	menuItemStyle: React.CSSProperties;
-	onClick?: () => void;
+    menuItemStyle: React.CSSProperties;
+    onClick?: () => void;
 }
 
 interface PortalMenuState {}
 
 export class PortalMenu extends React.Component<PortalMenuProps, PortalMenuState> {
-	public static defaultProps: Partial<PortalMenuProps> = {
-		onClick: _.noop,
-	};
-	public render() {
-		return (
-			<div>
-				<MenuItem
-					style={this.props.menuItemStyle}
-					className="py2"
-					to={`${WebsitePaths.Portal}`}
-					onClick={this.props.onClick.bind(this)}
-				>
-					{this._renderMenuItemWithIcon('Generate order', 'zmdi-arrow-right-top')}
-				</MenuItem>
-				<MenuItem
-					style={this.props.menuItemStyle}
-					className="py2"
-					to={`${WebsitePaths.Portal}/fill`}
-					onClick={this.props.onClick.bind(this)}
-				>
-					{this._renderMenuItemWithIcon('Fill order', 'zmdi-arrow-left-bottom')}
-				</MenuItem>
-				<MenuItem
-					style={this.props.menuItemStyle}
-					className="py2"
-					to={`${WebsitePaths.Portal}/balances`}
-					onClick={this.props.onClick.bind(this)}
-				>
-					{this._renderMenuItemWithIcon('Balances', 'zmdi-balance-wallet')}
-				</MenuItem>
-				<MenuItem
-					style={this.props.menuItemStyle}
-					className="py2"
-					to={`${WebsitePaths.Portal}/trades`}
-					onClick={this.props.onClick.bind(this)}
-				>
-					{this._renderMenuItemWithIcon('Trade history', 'zmdi-format-list-bulleted')}
-				</MenuItem>
-				<MenuItem
-					style={this.props.menuItemStyle}
-					className="py2"
-					to={`${WebsitePaths.Portal}/weth`}
-					onClick={this.props.onClick.bind(this)}
-				>
-					{this._renderMenuItemWithIcon('Wrap ETH', 'zmdi-circle-o')}
-				</MenuItem>
-			</div>
-		);
-	}
-	private _renderMenuItemWithIcon(title: string, iconName: string) {
-		return (
-			<div className="flex" style={{ fontWeight: 100 }}>
-				<div className="pr1 pl2">
-					<i style={{ fontSize: 20 }} className={`zmdi ${iconName}`} />
-				</div>
-				<div className="pl1">{title}</div>
-			</div>
-		);
-	}
+    public static defaultProps: Partial<PortalMenuProps> = {
+        onClick: _.noop,
+    };
+    public render() {
+        return (
+            <div>
+                <MenuItem
+                    style={this.props.menuItemStyle}
+                    className="py2"
+                    to={`${WebsitePaths.Portal}`}
+                    onClick={this.props.onClick.bind(this)}
+                >
+                    {this._renderMenuItemWithIcon('Generate order', 'zmdi-arrow-right-top')}
+                </MenuItem>
+                <MenuItem
+                    style={this.props.menuItemStyle}
+                    className="py2"
+                    to={`${WebsitePaths.Portal}/fill`}
+                    onClick={this.props.onClick.bind(this)}
+                >
+                    {this._renderMenuItemWithIcon('Fill order', 'zmdi-arrow-left-bottom')}
+                </MenuItem>
+                <MenuItem
+                    style={this.props.menuItemStyle}
+                    className="py2"
+                    to={`${WebsitePaths.Portal}/balances`}
+                    onClick={this.props.onClick.bind(this)}
+                >
+                    {this._renderMenuItemWithIcon('Balances', 'zmdi-balance-wallet')}
+                </MenuItem>
+                <MenuItem
+                    style={this.props.menuItemStyle}
+                    className="py2"
+                    to={`${WebsitePaths.Portal}/trades`}
+                    onClick={this.props.onClick.bind(this)}
+                >
+                    {this._renderMenuItemWithIcon('Trade history', 'zmdi-format-list-bulleted')}
+                </MenuItem>
+                <MenuItem
+                    style={this.props.menuItemStyle}
+                    className="py2"
+                    to={`${WebsitePaths.Portal}/weth`}
+                    onClick={this.props.onClick.bind(this)}
+                >
+                    {this._renderMenuItemWithIcon('Wrap ETH', 'zmdi-circle-o')}
+                </MenuItem>
+            </div>
+        );
+    }
+    private _renderMenuItemWithIcon(title: string, iconName: string) {
+        return (
+            <div className="flex" style={{ fontWeight: 100 }}>
+                <div className="pr1 pl2">
+                    <i style={{ fontSize: 20 }} className={`zmdi ${iconName}`} />
+                </div>
+                <div className="pl1">{title}</div>
+            </div>
+        );
+    }
 }
diff --git a/packages/website/ts/components/send_button.tsx b/packages/website/ts/components/send_button.tsx
index f97d9250b..f94ec346a 100644
--- a/packages/website/ts/components/send_button.tsx
+++ b/packages/website/ts/components/send_button.tsx
@@ -10,78 +10,78 @@ import { errorReporter } from 'ts/utils/error_reporter';
 import { utils } from 'ts/utils/utils';
 
 interface SendButtonProps {
-	token: Token;
-	tokenState: TokenState;
-	dispatcher: Dispatcher;
-	blockchain: Blockchain;
-	onError: () => void;
+    token: Token;
+    tokenState: TokenState;
+    dispatcher: Dispatcher;
+    blockchain: Blockchain;
+    onError: () => void;
 }
 
 interface SendButtonState {
-	isSendDialogVisible: boolean;
-	isSending: boolean;
+    isSendDialogVisible: boolean;
+    isSending: boolean;
 }
 
 export class SendButton extends React.Component<SendButtonProps, SendButtonState> {
-	public constructor(props: SendButtonProps) {
-		super(props);
-		this.state = {
-			isSendDialogVisible: false,
-			isSending: false,
-		};
-	}
-	public render() {
-		const labelStyle = this.state.isSending ? { fontSize: 10 } : {};
-		return (
-			<div>
-				<RaisedButton
-					style={{ width: '100%' }}
-					labelStyle={labelStyle}
-					disabled={this.state.isSending}
-					label={this.state.isSending ? 'Sending...' : 'Send'}
-					onClick={this._toggleSendDialog.bind(this)}
-				/>
-				<SendDialog
-					isOpen={this.state.isSendDialogVisible}
-					onComplete={this._onSendAmountSelectedAsync.bind(this)}
-					onCancelled={this._toggleSendDialog.bind(this)}
-					token={this.props.token}
-					tokenState={this.props.tokenState}
-				/>
-			</div>
-		);
-	}
-	private _toggleSendDialog() {
-		this.setState({
-			isSendDialogVisible: !this.state.isSendDialogVisible,
-		});
-	}
-	private async _onSendAmountSelectedAsync(recipient: string, value: BigNumber) {
-		this.setState({
-			isSending: true,
-		});
-		this._toggleSendDialog();
-		const token = this.props.token;
-		const tokenState = this.props.tokenState;
-		let balance = tokenState.balance;
-		try {
-			await this.props.blockchain.transferAsync(token, recipient, value);
-			balance = balance.minus(value);
-			this.props.dispatcher.replaceTokenBalanceByAddress(token.address, balance);
-		} catch (err) {
-			const errMsg = `${err}`;
-			if (_.includes(errMsg, BlockchainCallErrs.UserHasNoAssociatedAddresses)) {
-				this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
-				return;
-			} else if (!_.includes(errMsg, 'User denied transaction')) {
-				utils.consoleLog(`Unexpected error encountered: ${err}`);
-				utils.consoleLog(err.stack);
-				this.props.onError();
-				await errorReporter.reportAsync(err);
-			}
-		}
-		this.setState({
-			isSending: false,
-		});
-	}
+    public constructor(props: SendButtonProps) {
+        super(props);
+        this.state = {
+            isSendDialogVisible: false,
+            isSending: false,
+        };
+    }
+    public render() {
+        const labelStyle = this.state.isSending ? { fontSize: 10 } : {};
+        return (
+            <div>
+                <RaisedButton
+                    style={{ width: '100%' }}
+                    labelStyle={labelStyle}
+                    disabled={this.state.isSending}
+                    label={this.state.isSending ? 'Sending...' : 'Send'}
+                    onClick={this._toggleSendDialog.bind(this)}
+                />
+                <SendDialog
+                    isOpen={this.state.isSendDialogVisible}
+                    onComplete={this._onSendAmountSelectedAsync.bind(this)}
+                    onCancelled={this._toggleSendDialog.bind(this)}
+                    token={this.props.token}
+                    tokenState={this.props.tokenState}
+                />
+            </div>
+        );
+    }
+    private _toggleSendDialog() {
+        this.setState({
+            isSendDialogVisible: !this.state.isSendDialogVisible,
+        });
+    }
+    private async _onSendAmountSelectedAsync(recipient: string, value: BigNumber) {
+        this.setState({
+            isSending: true,
+        });
+        this._toggleSendDialog();
+        const token = this.props.token;
+        const tokenState = this.props.tokenState;
+        let balance = tokenState.balance;
+        try {
+            await this.props.blockchain.transferAsync(token, recipient, value);
+            balance = balance.minus(value);
+            this.props.dispatcher.replaceTokenBalanceByAddress(token.address, balance);
+        } catch (err) {
+            const errMsg = `${err}`;
+            if (_.includes(errMsg, BlockchainCallErrs.UserHasNoAssociatedAddresses)) {
+                this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
+                return;
+            } else if (!_.includes(errMsg, 'User denied transaction')) {
+                utils.consoleLog(`Unexpected error encountered: ${err}`);
+                utils.consoleLog(err.stack);
+                this.props.onError();
+                await errorReporter.reportAsync(err);
+            }
+        }
+        this.setState({
+            isSending: false,
+        });
+    }
 }
diff --git a/packages/website/ts/components/token_balances.tsx b/packages/website/ts/components/token_balances.tsx
index 480652c34..2cef413c7 100644
--- a/packages/website/ts/components/token_balances.tsx
+++ b/packages/website/ts/components/token_balances.tsx
@@ -23,16 +23,16 @@ import { TokenIcon } from 'ts/components/ui/token_icon';
 import { trackedTokenStorage } from 'ts/local_storage/tracked_token_storage';
 import { Dispatcher } from 'ts/redux/dispatcher';
 import {
-	BalanceErrs,
-	BlockchainCallErrs,
-	BlockchainErrs,
-	EtherscanLinkSuffixes,
-	ScreenWidths,
-	Styles,
-	Token,
-	TokenByAddress,
-	TokenStateByAddress,
-	TokenVisibility,
+    BalanceErrs,
+    BlockchainCallErrs,
+    BlockchainErrs,
+    EtherscanLinkSuffixes,
+    ScreenWidths,
+    Styles,
+    Token,
+    TokenByAddress,
+    TokenStateByAddress,
+    TokenVisibility,
 } from 'ts/types';
 import { colors } from 'ts/utils/colors';
 import { configs } from 'ts/utils/configs';
@@ -53,554 +53,554 @@ const TOKEN_COL_SPAN_LG = 2;
 const TOKEN_COL_SPAN_SM = 1;
 
 const styles: Styles = {
-	bgColor: {
-		backgroundColor: colors.grey50,
-	},
+    bgColor: {
+        backgroundColor: colors.grey50,
+    },
 };
 
 interface TokenBalancesProps {
-	blockchain: Blockchain;
-	blockchainErr: BlockchainErrs;
-	blockchainIsLoaded: boolean;
-	dispatcher: Dispatcher;
-	screenWidth: ScreenWidths;
-	tokenByAddress: TokenByAddress;
-	tokenStateByAddress: TokenStateByAddress;
-	userAddress: string;
-	userEtherBalance: BigNumber;
-	networkId: number;
+    blockchain: Blockchain;
+    blockchainErr: BlockchainErrs;
+    blockchainIsLoaded: boolean;
+    dispatcher: Dispatcher;
+    screenWidth: ScreenWidths;
+    tokenByAddress: TokenByAddress;
+    tokenStateByAddress: TokenStateByAddress;
+    userAddress: string;
+    userEtherBalance: BigNumber;
+    networkId: number;
 }
 
 interface TokenBalancesState {
-	errorType: BalanceErrs;
-	isBalanceSpinnerVisible: boolean;
-	isDharmaDialogVisible: boolean;
-	isZRXSpinnerVisible: boolean;
-	currentZrxBalance?: BigNumber;
-	isTokenPickerOpen: boolean;
-	isAddingToken: boolean;
+    errorType: BalanceErrs;
+    isBalanceSpinnerVisible: boolean;
+    isDharmaDialogVisible: boolean;
+    isZRXSpinnerVisible: boolean;
+    currentZrxBalance?: BigNumber;
+    isTokenPickerOpen: boolean;
+    isAddingToken: boolean;
 }
 
 export class TokenBalances extends React.Component<TokenBalancesProps, TokenBalancesState> {
-	public constructor(props: TokenBalancesProps) {
-		super(props);
-		this.state = {
-			errorType: undefined,
-			isBalanceSpinnerVisible: false,
-			isZRXSpinnerVisible: false,
-			isDharmaDialogVisible: DharmaLoanFrame.isAuthTokenPresent(),
-			isTokenPickerOpen: false,
-			isAddingToken: false,
-		};
-	}
-	public componentWillReceiveProps(nextProps: TokenBalancesProps) {
-		if (nextProps.userEtherBalance !== this.props.userEtherBalance) {
-			if (this.state.isBalanceSpinnerVisible) {
-				const receivedAmount = nextProps.userEtherBalance.minus(this.props.userEtherBalance);
-				this.props.dispatcher.showFlashMessage(`Received ${receivedAmount.toString(10)} Kovan Ether`);
-			}
-			this.setState({
-				isBalanceSpinnerVisible: false,
-			});
-		}
-		const nextZrxToken = _.find(_.values(nextProps.tokenByAddress), t => t.symbol === ZRX_TOKEN_SYMBOL);
-		const nextZrxTokenBalance = nextProps.tokenStateByAddress[nextZrxToken.address].balance;
-		if (!_.isUndefined(this.state.currentZrxBalance) && !nextZrxTokenBalance.eq(this.state.currentZrxBalance)) {
-			if (this.state.isZRXSpinnerVisible) {
-				const receivedAmount = nextZrxTokenBalance.minus(this.state.currentZrxBalance);
-				const receiveAmountInUnits = ZeroEx.toUnitAmount(receivedAmount, constants.DECIMAL_PLACES_ZRX);
-				this.props.dispatcher.showFlashMessage(`Received ${receiveAmountInUnits.toString(10)} Kovan ZRX`);
-			}
-			this.setState({
-				isZRXSpinnerVisible: false,
-				currentZrxBalance: undefined,
-			});
-		}
-	}
-	public componentDidMount() {
-		window.scrollTo(0, 0);
-	}
-	public render() {
-		const errorDialogActions = [
-			<FlatButton
-				key="errorOkBtn"
-				label="Ok"
-				primary={true}
-				onTouchTap={this._onErrorDialogToggle.bind(this, false)}
-			/>,
-		];
-		const dharmaDialogActions = [
-			<FlatButton
-				key="dharmaCloseBtn"
-				label="Close"
-				primary={true}
-				onTouchTap={this._onDharmaDialogToggle.bind(this, false)}
-			/>,
-		];
-		const isTestNetwork = this.props.networkId === constants.NETWORK_ID_TESTNET;
-		const dharmaButtonColumnStyle = {
-			paddingLeft: 3,
-			display: isTestNetwork ? 'table-cell' : 'none',
-		};
-		const stubColumnStyle = {
-			display: isTestNetwork ? 'none' : 'table-cell',
-		};
-		const allTokenRowHeight = _.size(this.props.tokenByAddress) * TOKEN_TABLE_ROW_HEIGHT;
-		const tokenTableHeight =
-			allTokenRowHeight < MAX_TOKEN_TABLE_HEIGHT ? allTokenRowHeight : MAX_TOKEN_TABLE_HEIGHT;
-		const isSmallScreen = this.props.screenWidth === ScreenWidths.Sm;
-		const tokenColSpan = isSmallScreen ? TOKEN_COL_SPAN_SM : TOKEN_COL_SPAN_LG;
-		const dharmaLoanExplanation =
-			'If you need access to larger amounts of ether,<br> \
+    public constructor(props: TokenBalancesProps) {
+        super(props);
+        this.state = {
+            errorType: undefined,
+            isBalanceSpinnerVisible: false,
+            isZRXSpinnerVisible: false,
+            isDharmaDialogVisible: DharmaLoanFrame.isAuthTokenPresent(),
+            isTokenPickerOpen: false,
+            isAddingToken: false,
+        };
+    }
+    public componentWillReceiveProps(nextProps: TokenBalancesProps) {
+        if (nextProps.userEtherBalance !== this.props.userEtherBalance) {
+            if (this.state.isBalanceSpinnerVisible) {
+                const receivedAmount = nextProps.userEtherBalance.minus(this.props.userEtherBalance);
+                this.props.dispatcher.showFlashMessage(`Received ${receivedAmount.toString(10)} Kovan Ether`);
+            }
+            this.setState({
+                isBalanceSpinnerVisible: false,
+            });
+        }
+        const nextZrxToken = _.find(_.values(nextProps.tokenByAddress), t => t.symbol === ZRX_TOKEN_SYMBOL);
+        const nextZrxTokenBalance = nextProps.tokenStateByAddress[nextZrxToken.address].balance;
+        if (!_.isUndefined(this.state.currentZrxBalance) && !nextZrxTokenBalance.eq(this.state.currentZrxBalance)) {
+            if (this.state.isZRXSpinnerVisible) {
+                const receivedAmount = nextZrxTokenBalance.minus(this.state.currentZrxBalance);
+                const receiveAmountInUnits = ZeroEx.toUnitAmount(receivedAmount, constants.DECIMAL_PLACES_ZRX);
+                this.props.dispatcher.showFlashMessage(`Received ${receiveAmountInUnits.toString(10)} Kovan ZRX`);
+            }
+            this.setState({
+                isZRXSpinnerVisible: false,
+                currentZrxBalance: undefined,
+            });
+        }
+    }
+    public componentDidMount() {
+        window.scrollTo(0, 0);
+    }
+    public render() {
+        const errorDialogActions = [
+            <FlatButton
+                key="errorOkBtn"
+                label="Ok"
+                primary={true}
+                onTouchTap={this._onErrorDialogToggle.bind(this, false)}
+            />,
+        ];
+        const dharmaDialogActions = [
+            <FlatButton
+                key="dharmaCloseBtn"
+                label="Close"
+                primary={true}
+                onTouchTap={this._onDharmaDialogToggle.bind(this, false)}
+            />,
+        ];
+        const isTestNetwork = this.props.networkId === constants.NETWORK_ID_TESTNET;
+        const dharmaButtonColumnStyle = {
+            paddingLeft: 3,
+            display: isTestNetwork ? 'table-cell' : 'none',
+        };
+        const stubColumnStyle = {
+            display: isTestNetwork ? 'none' : 'table-cell',
+        };
+        const allTokenRowHeight = _.size(this.props.tokenByAddress) * TOKEN_TABLE_ROW_HEIGHT;
+        const tokenTableHeight =
+            allTokenRowHeight < MAX_TOKEN_TABLE_HEIGHT ? allTokenRowHeight : MAX_TOKEN_TABLE_HEIGHT;
+        const isSmallScreen = this.props.screenWidth === ScreenWidths.Sm;
+        const tokenColSpan = isSmallScreen ? TOKEN_COL_SPAN_SM : TOKEN_COL_SPAN_LG;
+        const dharmaLoanExplanation =
+            'If you need access to larger amounts of ether,<br> \
                                      you can request a loan from the Dharma Loan<br> \
                                      network.  Your loan should be funded in 5<br>  \
                                      minutes or less.';
-		const allowanceExplanation =
-			'0x smart contracts require access to your<br> \
+        const allowanceExplanation =
+            '0x smart contracts require access to your<br> \
                                   token balances in order to execute trades.<br> \
                                   Toggling sets an allowance for the<br> \
                                   smart contract so you can start trading that token.';
-		return (
-			<div className="lg-px4 md-px4 sm-px1 pb2">
-				<h3>{isTestNetwork ? 'Test ether' : 'Ether'}</h3>
-				<Divider />
-				<div className="pt2 pb2">
-					{isTestNetwork
-						? 'In order to try out the 0x Portal Dapp, request some test ether to pay for \
+        return (
+            <div className="lg-px4 md-px4 sm-px1 pb2">
+                <h3>{isTestNetwork ? 'Test ether' : 'Ether'}</h3>
+                <Divider />
+                <div className="pt2 pb2">
+                    {isTestNetwork
+                        ? 'In order to try out the 0x Portal Dapp, request some test ether to pay for \
                         gas costs. It might take a bit of time for the test ether to show up.'
-						: 'Ether must be converted to Ether Tokens in order to be tradable via 0x. \
+                        : 'Ether must be converted to Ether Tokens in order to be tradable via 0x. \
                          You can convert between Ether and Ether Tokens from the "Wrap ETH" tab.'}
-				</div>
-				<Table selectable={false} style={styles.bgColor}>
-					<TableHeader displaySelectAll={false} adjustForCheckbox={false}>
-						<TableRow>
-							<TableHeaderColumn>Currency</TableHeaderColumn>
-							<TableHeaderColumn>Balance</TableHeaderColumn>
-							<TableRowColumn className="sm-hide xs-hide" style={stubColumnStyle} />
-							{isTestNetwork && (
-								<TableHeaderColumn style={{ paddingLeft: 3 }}>
-									{isSmallScreen ? 'Faucet' : 'Request from faucet'}
-								</TableHeaderColumn>
-							)}
-							{isTestNetwork && (
-								<TableHeaderColumn style={dharmaButtonColumnStyle}>
-									{isSmallScreen ? 'Loan' : 'Request Dharma loan'}
-									<HelpTooltip style={{ paddingLeft: 4 }} explanation={dharmaLoanExplanation} />
-								</TableHeaderColumn>
-							)}
-						</TableRow>
-					</TableHeader>
-					<TableBody displayRowCheckbox={false}>
-						<TableRow key="ETH">
-							<TableRowColumn className="py1">
-								<img style={{ width: ICON_DIMENSION, height: ICON_DIMENSION }} src={ETHER_ICON_PATH} />
-							</TableRowColumn>
-							<TableRowColumn>
-								{this.props.userEtherBalance.toFixed(PRECISION)} ETH
-								{this.state.isBalanceSpinnerVisible && (
-									<span className="pl1">
-										<i className="zmdi zmdi-spinner zmdi-hc-spin" />
-									</span>
-								)}
-							</TableRowColumn>
-							<TableRowColumn className="sm-hide xs-hide" style={stubColumnStyle} />
-							{isTestNetwork && (
-								<TableRowColumn style={{ paddingLeft: 3 }}>
-									<LifeCycleRaisedButton
-										labelReady="Request"
-										labelLoading="Sending..."
-										labelComplete="Sent!"
-										onClickAsyncFn={this._faucetRequestAsync.bind(this, true)}
-									/>
-								</TableRowColumn>
-							)}
-							{isTestNetwork && (
-								<TableRowColumn style={dharmaButtonColumnStyle}>
-									<RaisedButton
-										label="Request"
-										style={{ width: '100%' }}
-										onTouchTap={this._onDharmaDialogToggle.bind(this)}
-									/>
-								</TableRowColumn>
-							)}
-						</TableRow>
-					</TableBody>
-				</Table>
-				<div className="clearfix" style={{ paddingBottom: 1 }}>
-					<div className="col col-10">
-						<h3 className="pt2">{isTestNetwork ? 'Test tokens' : 'Tokens'}</h3>
-					</div>
-					<div className="col col-1 pt3 align-right">
-						<FloatingActionButton mini={true} zDepth={0} onClick={this._onAddTokenClicked.bind(this)}>
-							<ContentAdd />
-						</FloatingActionButton>
-					</div>
-					<div className="col col-1 pt3 align-right">
-						<FloatingActionButton mini={true} zDepth={0} onClick={this._onRemoveTokenClicked.bind(this)}>
-							<ContentRemove />
-						</FloatingActionButton>
-					</div>
-				</div>
-				<Divider />
-				<div className="pt2 pb2">
-					{isTestNetwork
-						? "Mint some test tokens you'd like to use to generate or fill an order using 0x."
-						: "Set trading permissions for a token you'd like to start trading."}
-				</div>
-				<Table selectable={false} bodyStyle={{ height: tokenTableHeight }} style={styles.bgColor}>
-					<TableHeader displaySelectAll={false} adjustForCheckbox={false}>
-						<TableRow>
-							<TableHeaderColumn colSpan={tokenColSpan}>Token</TableHeaderColumn>
-							<TableHeaderColumn style={{ paddingLeft: 3 }}>Balance</TableHeaderColumn>
-							<TableHeaderColumn>
-								<div className="inline-block">Allowance</div>
-								<HelpTooltip style={{ paddingLeft: 4 }} explanation={allowanceExplanation} />
-							</TableHeaderColumn>
-							<TableHeaderColumn>Action</TableHeaderColumn>
-							{this.props.screenWidth !== ScreenWidths.Sm && <TableHeaderColumn>Send</TableHeaderColumn>}
-						</TableRow>
-					</TableHeader>
-					<TableBody displayRowCheckbox={false}>{this._renderTokenTableRows()}</TableBody>
-				</Table>
-				<Dialog
-					title="Oh oh"
-					titleStyle={{ fontWeight: 100 }}
-					actions={errorDialogActions}
-					open={!_.isUndefined(this.state.errorType)}
-					onRequestClose={this._onErrorDialogToggle.bind(this, false)}
-				>
-					{this._renderErrorDialogBody()}
-				</Dialog>
-				<Dialog
-					title="Request Dharma Loan"
-					titleStyle={{ fontWeight: 100, backgroundColor: colors.white }}
-					bodyStyle={{ backgroundColor: colors.dharmaDarkGrey }}
-					actionsContainerStyle={{ backgroundColor: colors.white }}
-					autoScrollBodyContent={true}
-					actions={dharmaDialogActions}
-					open={this.state.isDharmaDialogVisible}
-				>
-					{this._renderDharmaLoanFrame()}
-				</Dialog>
-				<AssetPicker
-					userAddress={this.props.userAddress}
-					networkId={this.props.networkId}
-					blockchain={this.props.blockchain}
-					dispatcher={this.props.dispatcher}
-					isOpen={this.state.isTokenPickerOpen}
-					currentTokenAddress={''}
-					onTokenChosen={this._onAssetTokenPicked.bind(this)}
-					tokenByAddress={this.props.tokenByAddress}
-					tokenVisibility={this.state.isAddingToken ? TokenVisibility.UNTRACKED : TokenVisibility.TRACKED}
-				/>
-			</div>
-		);
-	}
-	private _renderTokenTableRows() {
-		if (!this.props.blockchainIsLoaded || this.props.blockchainErr !== BlockchainErrs.NoError) {
-			return '';
-		}
-		const isSmallScreen = this.props.screenWidth === ScreenWidths.Sm;
-		const tokenColSpan = isSmallScreen ? TOKEN_COL_SPAN_SM : TOKEN_COL_SPAN_LG;
-		const actionPaddingX = isSmallScreen ? 2 : 24;
-		const allTokens = _.values(this.props.tokenByAddress);
-		const trackedTokens = _.filter(allTokens, t => t.isTracked);
-		const trackedTokensStartingWithEtherToken = trackedTokens.sort(
-			firstBy((t: Token) => t.symbol !== ETHER_TOKEN_SYMBOL)
-				.thenBy((t: Token) => t.symbol !== ZRX_TOKEN_SYMBOL)
-				.thenBy('address'),
-		);
-		const tableRows = _.map(
-			trackedTokensStartingWithEtherToken,
-			this._renderTokenRow.bind(this, tokenColSpan, actionPaddingX),
-		);
-		return tableRows;
-	}
-	private _renderTokenRow(tokenColSpan: number, actionPaddingX: number, token: Token) {
-		const tokenState = this.props.tokenStateByAddress[token.address];
-		const tokenLink = utils.getEtherScanLinkIfExists(
-			token.address,
-			this.props.networkId,
-			EtherscanLinkSuffixes.Address,
-		);
-		const isMintable =
-			_.includes(configs.SYMBOLS_OF_MINTABLE_TOKENS, token.symbol) &&
-			this.props.networkId !== constants.NETWORK_ID_MAINNET;
-		return (
-			<TableRow key={token.address} style={{ height: TOKEN_TABLE_ROW_HEIGHT }}>
-				<TableRowColumn colSpan={tokenColSpan}>
-					{_.isUndefined(tokenLink) ? (
-						this._renderTokenName(token)
-					) : (
-						<a href={tokenLink} target="_blank" style={{ textDecoration: 'none' }}>
-							{this._renderTokenName(token)}
-						</a>
-					)}
-				</TableRowColumn>
-				<TableRowColumn style={{ paddingRight: 3, paddingLeft: 3 }}>
-					{this._renderAmount(tokenState.balance, token.decimals)} {token.symbol}
-					{this.state.isZRXSpinnerVisible &&
-						token.symbol === ZRX_TOKEN_SYMBOL && (
-							<span className="pl1">
-								<i className="zmdi zmdi-spinner zmdi-hc-spin" />
-							</span>
-						)}
-				</TableRowColumn>
-				<TableRowColumn>
-					<AllowanceToggle
-						blockchain={this.props.blockchain}
-						dispatcher={this.props.dispatcher}
-						token={token}
-						tokenState={tokenState}
-						onErrorOccurred={this._onErrorOccurred.bind(this)}
-						userAddress={this.props.userAddress}
-					/>
-				</TableRowColumn>
-				<TableRowColumn style={{ paddingLeft: actionPaddingX, paddingRight: actionPaddingX }}>
-					{isMintable && (
-						<LifeCycleRaisedButton
-							labelReady="Mint"
-							labelLoading={<span style={{ fontSize: 12 }}>Minting...</span>}
-							labelComplete="Minted!"
-							onClickAsyncFn={this._onMintTestTokensAsync.bind(this, token)}
-						/>
-					)}
-					{token.symbol === ZRX_TOKEN_SYMBOL &&
-						this.props.networkId === constants.NETWORK_ID_TESTNET && (
-							<LifeCycleRaisedButton
-								labelReady="Request"
-								labelLoading="Sending..."
-								labelComplete="Sent!"
-								onClickAsyncFn={this._faucetRequestAsync.bind(this, false)}
-							/>
-						)}
-				</TableRowColumn>
-				{this.props.screenWidth !== ScreenWidths.Sm && (
-					<TableRowColumn
-						style={{
-							paddingLeft: actionPaddingX,
-							paddingRight: actionPaddingX,
-						}}
-					>
-						<SendButton
-							blockchain={this.props.blockchain}
-							dispatcher={this.props.dispatcher}
-							token={token}
-							tokenState={tokenState}
-							onError={this._onSendFailed.bind(this)}
-						/>
-					</TableRowColumn>
-				)}
-			</TableRow>
-		);
-	}
-	private _onAssetTokenPicked(tokenAddress: string) {
-		if (_.isEmpty(tokenAddress)) {
-			this.setState({
-				isTokenPickerOpen: false,
-			});
-			return;
-		}
-		const token = this.props.tokenByAddress[tokenAddress];
-		const isDefaultTrackedToken = _.includes(configs.DEFAULT_TRACKED_TOKEN_SYMBOLS, token.symbol);
-		if (!this.state.isAddingToken && !isDefaultTrackedToken) {
-			if (token.isRegistered) {
-				// Remove the token from tracked tokens
-				const newToken = {
-					...token,
-					isTracked: false,
-				};
-				this.props.dispatcher.updateTokenByAddress([newToken]);
-			} else {
-				this.props.dispatcher.removeTokenToTokenByAddress(token);
-			}
-			this.props.dispatcher.removeFromTokenStateByAddress(tokenAddress);
-			trackedTokenStorage.removeTrackedToken(this.props.userAddress, this.props.networkId, tokenAddress);
-		} else if (isDefaultTrackedToken) {
-			this.props.dispatcher.showFlashMessage(`Cannot remove ${token.name} because it's a default token`);
-		}
-		this.setState({
-			isTokenPickerOpen: false,
-		});
-	}
-	private _onSendFailed() {
-		this.setState({
-			errorType: BalanceErrs.sendFailed,
-		});
-	}
-	private _renderAmount(amount: BigNumber, decimals: number) {
-		const unitAmount = ZeroEx.toUnitAmount(amount, decimals);
-		return unitAmount.toNumber().toFixed(PRECISION);
-	}
-	private _renderTokenName(token: Token) {
-		const tooltipId = `tooltip-${token.address}`;
-		return (
-			<div className="flex">
-				<TokenIcon token={token} diameter={ICON_DIMENSION} />
-				<div data-tip={true} data-for={tooltipId} className="mt2 ml2 sm-hide xs-hide">
-					{token.name}
-				</div>
-				<ReactTooltip id={tooltipId}>{token.address}</ReactTooltip>
-			</div>
-		);
-	}
-	private _renderErrorDialogBody() {
-		switch (this.state.errorType) {
-			case BalanceErrs.incorrectNetworkForFaucet:
-				return (
-					<div>
-						Our faucet can only send test Ether to addresses on the {constants.TESTNET_NAME} testnet
-						(networkId {constants.NETWORK_ID_TESTNET}). Please make sure you are connected to the{' '}
-						{constants.TESTNET_NAME} testnet and try requesting ether again.
-					</div>
-				);
+                </div>
+                <Table selectable={false} style={styles.bgColor}>
+                    <TableHeader displaySelectAll={false} adjustForCheckbox={false}>
+                        <TableRow>
+                            <TableHeaderColumn>Currency</TableHeaderColumn>
+                            <TableHeaderColumn>Balance</TableHeaderColumn>
+                            <TableRowColumn className="sm-hide xs-hide" style={stubColumnStyle} />
+                            {isTestNetwork && (
+                                <TableHeaderColumn style={{ paddingLeft: 3 }}>
+                                    {isSmallScreen ? 'Faucet' : 'Request from faucet'}
+                                </TableHeaderColumn>
+                            )}
+                            {isTestNetwork && (
+                                <TableHeaderColumn style={dharmaButtonColumnStyle}>
+                                    {isSmallScreen ? 'Loan' : 'Request Dharma loan'}
+                                    <HelpTooltip style={{ paddingLeft: 4 }} explanation={dharmaLoanExplanation} />
+                                </TableHeaderColumn>
+                            )}
+                        </TableRow>
+                    </TableHeader>
+                    <TableBody displayRowCheckbox={false}>
+                        <TableRow key="ETH">
+                            <TableRowColumn className="py1">
+                                <img style={{ width: ICON_DIMENSION, height: ICON_DIMENSION }} src={ETHER_ICON_PATH} />
+                            </TableRowColumn>
+                            <TableRowColumn>
+                                {this.props.userEtherBalance.toFixed(PRECISION)} ETH
+                                {this.state.isBalanceSpinnerVisible && (
+                                    <span className="pl1">
+                                        <i className="zmdi zmdi-spinner zmdi-hc-spin" />
+                                    </span>
+                                )}
+                            </TableRowColumn>
+                            <TableRowColumn className="sm-hide xs-hide" style={stubColumnStyle} />
+                            {isTestNetwork && (
+                                <TableRowColumn style={{ paddingLeft: 3 }}>
+                                    <LifeCycleRaisedButton
+                                        labelReady="Request"
+                                        labelLoading="Sending..."
+                                        labelComplete="Sent!"
+                                        onClickAsyncFn={this._faucetRequestAsync.bind(this, true)}
+                                    />
+                                </TableRowColumn>
+                            )}
+                            {isTestNetwork && (
+                                <TableRowColumn style={dharmaButtonColumnStyle}>
+                                    <RaisedButton
+                                        label="Request"
+                                        style={{ width: '100%' }}
+                                        onTouchTap={this._onDharmaDialogToggle.bind(this)}
+                                    />
+                                </TableRowColumn>
+                            )}
+                        </TableRow>
+                    </TableBody>
+                </Table>
+                <div className="clearfix" style={{ paddingBottom: 1 }}>
+                    <div className="col col-10">
+                        <h3 className="pt2">{isTestNetwork ? 'Test tokens' : 'Tokens'}</h3>
+                    </div>
+                    <div className="col col-1 pt3 align-right">
+                        <FloatingActionButton mini={true} zDepth={0} onClick={this._onAddTokenClicked.bind(this)}>
+                            <ContentAdd />
+                        </FloatingActionButton>
+                    </div>
+                    <div className="col col-1 pt3 align-right">
+                        <FloatingActionButton mini={true} zDepth={0} onClick={this._onRemoveTokenClicked.bind(this)}>
+                            <ContentRemove />
+                        </FloatingActionButton>
+                    </div>
+                </div>
+                <Divider />
+                <div className="pt2 pb2">
+                    {isTestNetwork
+                        ? "Mint some test tokens you'd like to use to generate or fill an order using 0x."
+                        : "Set trading permissions for a token you'd like to start trading."}
+                </div>
+                <Table selectable={false} bodyStyle={{ height: tokenTableHeight }} style={styles.bgColor}>
+                    <TableHeader displaySelectAll={false} adjustForCheckbox={false}>
+                        <TableRow>
+                            <TableHeaderColumn colSpan={tokenColSpan}>Token</TableHeaderColumn>
+                            <TableHeaderColumn style={{ paddingLeft: 3 }}>Balance</TableHeaderColumn>
+                            <TableHeaderColumn>
+                                <div className="inline-block">Allowance</div>
+                                <HelpTooltip style={{ paddingLeft: 4 }} explanation={allowanceExplanation} />
+                            </TableHeaderColumn>
+                            <TableHeaderColumn>Action</TableHeaderColumn>
+                            {this.props.screenWidth !== ScreenWidths.Sm && <TableHeaderColumn>Send</TableHeaderColumn>}
+                        </TableRow>
+                    </TableHeader>
+                    <TableBody displayRowCheckbox={false}>{this._renderTokenTableRows()}</TableBody>
+                </Table>
+                <Dialog
+                    title="Oh oh"
+                    titleStyle={{ fontWeight: 100 }}
+                    actions={errorDialogActions}
+                    open={!_.isUndefined(this.state.errorType)}
+                    onRequestClose={this._onErrorDialogToggle.bind(this, false)}
+                >
+                    {this._renderErrorDialogBody()}
+                </Dialog>
+                <Dialog
+                    title="Request Dharma Loan"
+                    titleStyle={{ fontWeight: 100, backgroundColor: colors.white }}
+                    bodyStyle={{ backgroundColor: colors.dharmaDarkGrey }}
+                    actionsContainerStyle={{ backgroundColor: colors.white }}
+                    autoScrollBodyContent={true}
+                    actions={dharmaDialogActions}
+                    open={this.state.isDharmaDialogVisible}
+                >
+                    {this._renderDharmaLoanFrame()}
+                </Dialog>
+                <AssetPicker
+                    userAddress={this.props.userAddress}
+                    networkId={this.props.networkId}
+                    blockchain={this.props.blockchain}
+                    dispatcher={this.props.dispatcher}
+                    isOpen={this.state.isTokenPickerOpen}
+                    currentTokenAddress={''}
+                    onTokenChosen={this._onAssetTokenPicked.bind(this)}
+                    tokenByAddress={this.props.tokenByAddress}
+                    tokenVisibility={this.state.isAddingToken ? TokenVisibility.UNTRACKED : TokenVisibility.TRACKED}
+                />
+            </div>
+        );
+    }
+    private _renderTokenTableRows() {
+        if (!this.props.blockchainIsLoaded || this.props.blockchainErr !== BlockchainErrs.NoError) {
+            return '';
+        }
+        const isSmallScreen = this.props.screenWidth === ScreenWidths.Sm;
+        const tokenColSpan = isSmallScreen ? TOKEN_COL_SPAN_SM : TOKEN_COL_SPAN_LG;
+        const actionPaddingX = isSmallScreen ? 2 : 24;
+        const allTokens = _.values(this.props.tokenByAddress);
+        const trackedTokens = _.filter(allTokens, t => t.isTracked);
+        const trackedTokensStartingWithEtherToken = trackedTokens.sort(
+            firstBy((t: Token) => t.symbol !== ETHER_TOKEN_SYMBOL)
+                .thenBy((t: Token) => t.symbol !== ZRX_TOKEN_SYMBOL)
+                .thenBy('address'),
+        );
+        const tableRows = _.map(
+            trackedTokensStartingWithEtherToken,
+            this._renderTokenRow.bind(this, tokenColSpan, actionPaddingX),
+        );
+        return tableRows;
+    }
+    private _renderTokenRow(tokenColSpan: number, actionPaddingX: number, token: Token) {
+        const tokenState = this.props.tokenStateByAddress[token.address];
+        const tokenLink = utils.getEtherScanLinkIfExists(
+            token.address,
+            this.props.networkId,
+            EtherscanLinkSuffixes.Address,
+        );
+        const isMintable =
+            _.includes(configs.SYMBOLS_OF_MINTABLE_TOKENS, token.symbol) &&
+            this.props.networkId !== constants.NETWORK_ID_MAINNET;
+        return (
+            <TableRow key={token.address} style={{ height: TOKEN_TABLE_ROW_HEIGHT }}>
+                <TableRowColumn colSpan={tokenColSpan}>
+                    {_.isUndefined(tokenLink) ? (
+                        this._renderTokenName(token)
+                    ) : (
+                        <a href={tokenLink} target="_blank" style={{ textDecoration: 'none' }}>
+                            {this._renderTokenName(token)}
+                        </a>
+                    )}
+                </TableRowColumn>
+                <TableRowColumn style={{ paddingRight: 3, paddingLeft: 3 }}>
+                    {this._renderAmount(tokenState.balance, token.decimals)} {token.symbol}
+                    {this.state.isZRXSpinnerVisible &&
+                        token.symbol === ZRX_TOKEN_SYMBOL && (
+                            <span className="pl1">
+                                <i className="zmdi zmdi-spinner zmdi-hc-spin" />
+                            </span>
+                        )}
+                </TableRowColumn>
+                <TableRowColumn>
+                    <AllowanceToggle
+                        blockchain={this.props.blockchain}
+                        dispatcher={this.props.dispatcher}
+                        token={token}
+                        tokenState={tokenState}
+                        onErrorOccurred={this._onErrorOccurred.bind(this)}
+                        userAddress={this.props.userAddress}
+                    />
+                </TableRowColumn>
+                <TableRowColumn style={{ paddingLeft: actionPaddingX, paddingRight: actionPaddingX }}>
+                    {isMintable && (
+                        <LifeCycleRaisedButton
+                            labelReady="Mint"
+                            labelLoading={<span style={{ fontSize: 12 }}>Minting...</span>}
+                            labelComplete="Minted!"
+                            onClickAsyncFn={this._onMintTestTokensAsync.bind(this, token)}
+                        />
+                    )}
+                    {token.symbol === ZRX_TOKEN_SYMBOL &&
+                        this.props.networkId === constants.NETWORK_ID_TESTNET && (
+                            <LifeCycleRaisedButton
+                                labelReady="Request"
+                                labelLoading="Sending..."
+                                labelComplete="Sent!"
+                                onClickAsyncFn={this._faucetRequestAsync.bind(this, false)}
+                            />
+                        )}
+                </TableRowColumn>
+                {this.props.screenWidth !== ScreenWidths.Sm && (
+                    <TableRowColumn
+                        style={{
+                            paddingLeft: actionPaddingX,
+                            paddingRight: actionPaddingX,
+                        }}
+                    >
+                        <SendButton
+                            blockchain={this.props.blockchain}
+                            dispatcher={this.props.dispatcher}
+                            token={token}
+                            tokenState={tokenState}
+                            onError={this._onSendFailed.bind(this)}
+                        />
+                    </TableRowColumn>
+                )}
+            </TableRow>
+        );
+    }
+    private _onAssetTokenPicked(tokenAddress: string) {
+        if (_.isEmpty(tokenAddress)) {
+            this.setState({
+                isTokenPickerOpen: false,
+            });
+            return;
+        }
+        const token = this.props.tokenByAddress[tokenAddress];
+        const isDefaultTrackedToken = _.includes(configs.DEFAULT_TRACKED_TOKEN_SYMBOLS, token.symbol);
+        if (!this.state.isAddingToken && !isDefaultTrackedToken) {
+            if (token.isRegistered) {
+                // Remove the token from tracked tokens
+                const newToken = {
+                    ...token,
+                    isTracked: false,
+                };
+                this.props.dispatcher.updateTokenByAddress([newToken]);
+            } else {
+                this.props.dispatcher.removeTokenToTokenByAddress(token);
+            }
+            this.props.dispatcher.removeFromTokenStateByAddress(tokenAddress);
+            trackedTokenStorage.removeTrackedToken(this.props.userAddress, this.props.networkId, tokenAddress);
+        } else if (isDefaultTrackedToken) {
+            this.props.dispatcher.showFlashMessage(`Cannot remove ${token.name} because it's a default token`);
+        }
+        this.setState({
+            isTokenPickerOpen: false,
+        });
+    }
+    private _onSendFailed() {
+        this.setState({
+            errorType: BalanceErrs.sendFailed,
+        });
+    }
+    private _renderAmount(amount: BigNumber, decimals: number) {
+        const unitAmount = ZeroEx.toUnitAmount(amount, decimals);
+        return unitAmount.toNumber().toFixed(PRECISION);
+    }
+    private _renderTokenName(token: Token) {
+        const tooltipId = `tooltip-${token.address}`;
+        return (
+            <div className="flex">
+                <TokenIcon token={token} diameter={ICON_DIMENSION} />
+                <div data-tip={true} data-for={tooltipId} className="mt2 ml2 sm-hide xs-hide">
+                    {token.name}
+                </div>
+                <ReactTooltip id={tooltipId}>{token.address}</ReactTooltip>
+            </div>
+        );
+    }
+    private _renderErrorDialogBody() {
+        switch (this.state.errorType) {
+            case BalanceErrs.incorrectNetworkForFaucet:
+                return (
+                    <div>
+                        Our faucet can only send test Ether to addresses on the {constants.TESTNET_NAME} testnet
+                        (networkId {constants.NETWORK_ID_TESTNET}). Please make sure you are connected to the{' '}
+                        {constants.TESTNET_NAME} testnet and try requesting ether again.
+                    </div>
+                );
 
-			case BalanceErrs.faucetRequestFailed:
-				return (
-					<div>
-						An unexpected error occurred while trying to request test Ether from our faucet. Please refresh
-						the page and try again.
-					</div>
-				);
+            case BalanceErrs.faucetRequestFailed:
+                return (
+                    <div>
+                        An unexpected error occurred while trying to request test Ether from our faucet. Please refresh
+                        the page and try again.
+                    </div>
+                );
 
-			case BalanceErrs.faucetQueueIsFull:
-				return <div>Our test Ether faucet queue is full. Please try requesting test Ether again later.</div>;
+            case BalanceErrs.faucetQueueIsFull:
+                return <div>Our test Ether faucet queue is full. Please try requesting test Ether again later.</div>;
 
-			case BalanceErrs.mintingFailed:
-				return <div>Minting your test tokens failed unexpectedly. Please refresh the page and try again.</div>;
+            case BalanceErrs.mintingFailed:
+                return <div>Minting your test tokens failed unexpectedly. Please refresh the page and try again.</div>;
 
-			case BalanceErrs.allowanceSettingFailed:
-				return (
-					<div>
-						An unexpected error occurred while trying to set your test token allowance. Please refresh the
-						page and try again.
-					</div>
-				);
+            case BalanceErrs.allowanceSettingFailed:
+                return (
+                    <div>
+                        An unexpected error occurred while trying to set your test token allowance. Please refresh the
+                        page and try again.
+                    </div>
+                );
 
-			case undefined:
-				return null; // No error to show
+            case undefined:
+                return null; // No error to show
 
-			default:
-				throw utils.spawnSwitchErr('errorType', this.state.errorType);
-		}
-	}
-	private _renderDharmaLoanFrame() {
-		if (utils.isUserOnMobile()) {
-			return (
-				<h4 style={{ textAlign: 'center' }}>
-					We apologize -- Dharma loan requests are not available on mobile yet. Please try again through your
-					desktop browser.
-				</h4>
-			);
-		} else {
-			return (
-				<DharmaLoanFrame
-					partner="0x"
-					env={utils.getCurrentEnvironment()}
-					screenWidth={this.props.screenWidth}
-				/>
-			);
-		}
-	}
-	private _onErrorOccurred(errorType: BalanceErrs) {
-		this.setState({
-			errorType,
-		});
-	}
-	private async _onMintTestTokensAsync(token: Token): Promise<boolean> {
-		try {
-			await this.props.blockchain.mintTestTokensAsync(token);
-			const amount = ZeroEx.toUnitAmount(constants.MINT_AMOUNT, token.decimals);
-			this.props.dispatcher.showFlashMessage(`Successfully minted ${amount.toString(10)} ${token.symbol}`);
-			return true;
-		} catch (err) {
-			const errMsg = `${err}`;
-			if (_.includes(errMsg, BlockchainCallErrs.UserHasNoAssociatedAddresses)) {
-				this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
-				return false;
-			}
-			if (_.includes(errMsg, 'User denied transaction')) {
-				return false;
-			}
-			utils.consoleLog(`Unexpected error encountered: ${err}`);
-			utils.consoleLog(err.stack);
-			this.setState({
-				errorType: BalanceErrs.mintingFailed,
-			});
-			await errorReporter.reportAsync(err);
-			return false;
-		}
-	}
-	private async _faucetRequestAsync(isEtherRequest: boolean): Promise<boolean> {
-		if (this.props.userAddress === '') {
-			this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
-			return false;
-		}
+            default:
+                throw utils.spawnSwitchErr('errorType', this.state.errorType);
+        }
+    }
+    private _renderDharmaLoanFrame() {
+        if (utils.isUserOnMobile()) {
+            return (
+                <h4 style={{ textAlign: 'center' }}>
+                    We apologize -- Dharma loan requests are not available on mobile yet. Please try again through your
+                    desktop browser.
+                </h4>
+            );
+        } else {
+            return (
+                <DharmaLoanFrame
+                    partner="0x"
+                    env={utils.getCurrentEnvironment()}
+                    screenWidth={this.props.screenWidth}
+                />
+            );
+        }
+    }
+    private _onErrorOccurred(errorType: BalanceErrs) {
+        this.setState({
+            errorType,
+        });
+    }
+    private async _onMintTestTokensAsync(token: Token): Promise<boolean> {
+        try {
+            await this.props.blockchain.mintTestTokensAsync(token);
+            const amount = ZeroEx.toUnitAmount(constants.MINT_AMOUNT, token.decimals);
+            this.props.dispatcher.showFlashMessage(`Successfully minted ${amount.toString(10)} ${token.symbol}`);
+            return true;
+        } catch (err) {
+            const errMsg = `${err}`;
+            if (_.includes(errMsg, BlockchainCallErrs.UserHasNoAssociatedAddresses)) {
+                this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
+                return false;
+            }
+            if (_.includes(errMsg, 'User denied transaction')) {
+                return false;
+            }
+            utils.consoleLog(`Unexpected error encountered: ${err}`);
+            utils.consoleLog(err.stack);
+            this.setState({
+                errorType: BalanceErrs.mintingFailed,
+            });
+            await errorReporter.reportAsync(err);
+            return false;
+        }
+    }
+    private async _faucetRequestAsync(isEtherRequest: boolean): Promise<boolean> {
+        if (this.props.userAddress === '') {
+            this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
+            return false;
+        }
 
-		// If on another network other then the testnet our faucet serves test ether
-		// from, we must show user an error message
-		if (this.props.blockchain.networkId !== constants.NETWORK_ID_TESTNET) {
-			this.setState({
-				errorType: BalanceErrs.incorrectNetworkForFaucet,
-			});
-			return false;
-		}
+        // If on another network other then the testnet our faucet serves test ether
+        // from, we must show user an error message
+        if (this.props.blockchain.networkId !== constants.NETWORK_ID_TESTNET) {
+            this.setState({
+                errorType: BalanceErrs.incorrectNetworkForFaucet,
+            });
+            return false;
+        }
 
-		await utils.sleepAsync(ARTIFICIAL_FAUCET_REQUEST_DELAY);
+        await utils.sleepAsync(ARTIFICIAL_FAUCET_REQUEST_DELAY);
 
-		const segment = isEtherRequest ? 'ether' : 'zrx';
-		const response = await fetch(`${constants.URL_ETHER_FAUCET}/${segment}/${this.props.userAddress}`);
-		const responseBody = await response.text();
-		if (response.status !== constants.SUCCESS_STATUS) {
-			utils.consoleLog(`Unexpected status code: ${response.status} -> ${responseBody}`);
-			const errorType =
-				response.status === constants.UNAVAILABLE_STATUS
-					? BalanceErrs.faucetQueueIsFull
-					: BalanceErrs.faucetRequestFailed;
-			this.setState({
-				errorType,
-			});
-			await errorReporter.reportAsync(new Error(`Faucet returned non-200: ${JSON.stringify(response)}`));
-			return false;
-		}
+        const segment = isEtherRequest ? 'ether' : 'zrx';
+        const response = await fetch(`${constants.URL_ETHER_FAUCET}/${segment}/${this.props.userAddress}`);
+        const responseBody = await response.text();
+        if (response.status !== constants.SUCCESS_STATUS) {
+            utils.consoleLog(`Unexpected status code: ${response.status} -> ${responseBody}`);
+            const errorType =
+                response.status === constants.UNAVAILABLE_STATUS
+                    ? BalanceErrs.faucetQueueIsFull
+                    : BalanceErrs.faucetRequestFailed;
+            this.setState({
+                errorType,
+            });
+            await errorReporter.reportAsync(new Error(`Faucet returned non-200: ${JSON.stringify(response)}`));
+            return false;
+        }
 
-		if (isEtherRequest) {
-			this.setState({
-				isBalanceSpinnerVisible: true,
-			});
-		} else {
-			const tokens = _.values(this.props.tokenByAddress);
-			const zrxToken = _.find(tokens, t => t.symbol === ZRX_TOKEN_SYMBOL);
-			const zrxTokenState = this.props.tokenStateByAddress[zrxToken.address];
-			this.setState({
-				isZRXSpinnerVisible: true,
-				currentZrxBalance: zrxTokenState.balance,
-			});
-			// tslint:disable-next-line:no-floating-promises
-			this.props.blockchain.pollTokenBalanceAsync(zrxToken);
-		}
-		return true;
-	}
-	private _onErrorDialogToggle(isOpen: boolean) {
-		this.setState({
-			errorType: undefined,
-		});
-	}
-	private _onDharmaDialogToggle() {
-		this.setState({
-			isDharmaDialogVisible: !this.state.isDharmaDialogVisible,
-		});
-	}
-	private _onAddTokenClicked() {
-		this.setState({
-			isTokenPickerOpen: true,
-			isAddingToken: true,
-		});
-	}
-	private _onRemoveTokenClicked() {
-		this.setState({
-			isTokenPickerOpen: true,
-			isAddingToken: false,
-		});
-	}
+        if (isEtherRequest) {
+            this.setState({
+                isBalanceSpinnerVisible: true,
+            });
+        } else {
+            const tokens = _.values(this.props.tokenByAddress);
+            const zrxToken = _.find(tokens, t => t.symbol === ZRX_TOKEN_SYMBOL);
+            const zrxTokenState = this.props.tokenStateByAddress[zrxToken.address];
+            this.setState({
+                isZRXSpinnerVisible: true,
+                currentZrxBalance: zrxTokenState.balance,
+            });
+            // tslint:disable-next-line:no-floating-promises
+            this.props.blockchain.pollTokenBalanceAsync(zrxToken);
+        }
+        return true;
+    }
+    private _onErrorDialogToggle(isOpen: boolean) {
+        this.setState({
+            errorType: undefined,
+        });
+    }
+    private _onDharmaDialogToggle() {
+        this.setState({
+            isDharmaDialogVisible: !this.state.isDharmaDialogVisible,
+        });
+    }
+    private _onAddTokenClicked() {
+        this.setState({
+            isTokenPickerOpen: true,
+            isAddingToken: true,
+        });
+    }
+    private _onRemoveTokenClicked() {
+        this.setState({
+            isTokenPickerOpen: true,
+            isAddingToken: false,
+        });
+    }
 } // tslint:disable:max-file-line-count
diff --git a/packages/website/ts/components/top_bar.tsx b/packages/website/ts/components/top_bar.tsx
index 1f111cb07..11d3e7cc2 100644
--- a/packages/website/ts/components/top_bar.tsx
+++ b/packages/website/ts/components/top_bar.tsx
@@ -15,333 +15,333 @@ import { colors } from 'ts/utils/colors';
 import { constants } from 'ts/utils/constants';
 
 interface TopBarProps {
-	userAddress?: string;
-	blockchainIsLoaded: boolean;
-	location: Location;
-	docsVersion?: string;
-	availableDocVersions?: string[];
-	menu?: DocsMenu;
-	menuSubsectionsBySection?: MenuSubsectionsBySection;
-	shouldFullWidth?: boolean;
-	docsInfo?: DocsInfo;
-	style?: React.CSSProperties;
-	isNightVersion?: boolean;
+    userAddress?: string;
+    blockchainIsLoaded: boolean;
+    location: Location;
+    docsVersion?: string;
+    availableDocVersions?: string[];
+    menu?: DocsMenu;
+    menuSubsectionsBySection?: MenuSubsectionsBySection;
+    shouldFullWidth?: boolean;
+    docsInfo?: DocsInfo;
+    style?: React.CSSProperties;
+    isNightVersion?: boolean;
 }
 
 interface TopBarState {
-	isDrawerOpen: boolean;
+    isDrawerOpen: boolean;
 }
 
 const styles: Styles = {
-	address: {
-		marginRight: 12,
-		overflow: 'hidden',
-		paddingTop: 4,
-		textOverflow: 'ellipsis',
-		whiteSpace: 'nowrap',
-		width: 70,
-	},
-	topBar: {
-		backgroundcolor: colors.white,
-		height: 59,
-		width: '100%',
-		position: 'relative',
-		top: 0,
-		zIndex: 1100,
-		paddingBottom: 1,
-	},
-	bottomBar: {
-		boxShadow: 'rgba(0, 0, 0, 0.187647) 0px 1px 3px',
-	},
-	menuItem: {
-		fontSize: 14,
-		color: colors.darkestGrey,
-		paddingTop: 6,
-		paddingBottom: 6,
-		marginTop: 17,
-		cursor: 'pointer',
-		fontWeight: 400,
-	},
+    address: {
+        marginRight: 12,
+        overflow: 'hidden',
+        paddingTop: 4,
+        textOverflow: 'ellipsis',
+        whiteSpace: 'nowrap',
+        width: 70,
+    },
+    topBar: {
+        backgroundcolor: colors.white,
+        height: 59,
+        width: '100%',
+        position: 'relative',
+        top: 0,
+        zIndex: 1100,
+        paddingBottom: 1,
+    },
+    bottomBar: {
+        boxShadow: 'rgba(0, 0, 0, 0.187647) 0px 1px 3px',
+    },
+    menuItem: {
+        fontSize: 14,
+        color: colors.darkestGrey,
+        paddingTop: 6,
+        paddingBottom: 6,
+        marginTop: 17,
+        cursor: 'pointer',
+        fontWeight: 400,
+    },
 };
 
 export class TopBar extends React.Component<TopBarProps, TopBarState> {
-	public static defaultProps: Partial<TopBarProps> = {
-		shouldFullWidth: false,
-		style: {},
-		isNightVersion: false,
-	};
-	constructor(props: TopBarProps) {
-		super(props);
-		this.state = {
-			isDrawerOpen: false,
-		};
-	}
-	public render() {
-		const isNightVersion = this.props.isNightVersion;
-		const isFullWidthPage = this.props.shouldFullWidth;
-		const parentClassNames = `flex mx-auto ${isFullWidthPage ? 'pl2' : 'max-width-4'}`;
-		const developerSectionMenuItems = [
-			<Link key="subMenuItem-zeroEx" to={WebsitePaths.ZeroExJs} className="text-decoration-none">
-				<MenuItem style={{ fontSize: styles.menuItem.fontSize }} primaryText="0x.js" />
-			</Link>,
-			<Link key="subMenuItem-smartContracts" to={WebsitePaths.SmartContracts} className="text-decoration-none">
-				<MenuItem style={{ fontSize: styles.menuItem.fontSize }} primaryText="Smart Contracts" />
-			</Link>,
-			<Link key="subMenuItem-0xconnect" to={WebsitePaths.Connect} className="text-decoration-none">
-				<MenuItem style={{ fontSize: styles.menuItem.fontSize }} primaryText="0x Connect" />
-			</Link>,
-			<a
-				key="subMenuItem-standard-relayer-api"
-				target="_blank"
-				className="text-decoration-none"
-				href={constants.URL_STANDARD_RELAYER_API_GITHUB}
-			>
-				<MenuItem style={{ fontSize: styles.menuItem.fontSize }} primaryText="Standard Relayer API" />
-			</a>,
-			<a
-				key="subMenuItem-github"
-				target="_blank"
-				className="text-decoration-none"
-				href={constants.URL_GITHUB_ORG}
-			>
-				<MenuItem style={{ fontSize: styles.menuItem.fontSize }} primaryText="GitHub" />
-			</a>,
-			<a
-				key="subMenuItem-whitePaper"
-				target="_blank"
-				className="text-decoration-none"
-				href={`${WebsitePaths.Whitepaper}`}
-			>
-				<MenuItem style={{ fontSize: styles.menuItem.fontSize }} primaryText="Whitepaper" />
-			</a>,
-		];
-		const bottomBorderStyle = this._shouldDisplayBottomBar() ? styles.bottomBar : {};
-		const fullWidthClasses = isFullWidthPage ? 'pr4' : '';
-		const logoUrl = isNightVersion ? '/images/protocol_logo_white.png' : '/images/protocol_logo_black.png';
-		const menuClasses = `col col-${isFullWidthPage ? '4' : '5'} ${fullWidthClasses} lg-pr0 md-pr2 sm-hide xs-hide`;
-		const menuIconStyle = {
-			fontSize: 25,
-			color: isNightVersion ? 'white' : 'black',
-			cursor: 'pointer',
-			paddingTop: 16,
-		};
-		return (
-			<div style={{ ...styles.topBar, ...bottomBorderStyle, ...this.props.style }} className="pb1">
-				<div className={parentClassNames}>
-					<div className="col col-2 sm-pl2 md-pl2 lg-pl0" style={{ paddingTop: 15 }}>
-						<Link to={`${WebsitePaths.Home}`} className="text-decoration-none">
-							<img src={logoUrl} height="30" />
-						</Link>
-					</div>
-					<div className={`col col-${isFullWidthPage ? '8' : '9'} lg-hide md-hide`} />
-					<div className={`col col-${isFullWidthPage ? '6' : '5'} sm-hide xs-hide`} />
-					{!this._isViewingPortal() && (
-						<div className={menuClasses}>
-							<div className="flex justify-between">
-								<DropDownMenuItem
-									title="Developers"
-									subMenuItems={developerSectionMenuItems}
-									style={styles.menuItem}
-									isNightVersion={isNightVersion}
-								/>
-								<TopBarMenuItem
-									title="Wiki"
-									path={`${WebsitePaths.Wiki}`}
-									style={styles.menuItem}
-									isNightVersion={isNightVersion}
-								/>
-								<TopBarMenuItem
-									title="About"
-									path={`${WebsitePaths.About}`}
-									style={styles.menuItem}
-									isNightVersion={isNightVersion}
-								/>
-								<TopBarMenuItem
-									title="Portal DApp"
-									path={`${WebsitePaths.Portal}`}
-									isPrimary={true}
-									style={styles.menuItem}
-									className={`${isFullWidthPage && 'md-hide'}`}
-									isNightVersion={isNightVersion}
-								/>
-							</div>
-						</div>
-					)}
-					{this.props.blockchainIsLoaded &&
-						!_.isEmpty(this.props.userAddress) && (
-							<div className="col col-5 sm-hide xs-hide">{this._renderUser()}</div>
-						)}
-					<div className={`col ${isFullWidthPage ? 'col-2 pl2' : 'col-1'} md-hide lg-hide`}>
-						<div style={menuIconStyle}>
-							<i className="zmdi zmdi-menu" onClick={this._onMenuButtonClick.bind(this)} />
-						</div>
-					</div>
-				</div>
-				{this._renderDrawer()}
-			</div>
-		);
-	}
-	private _renderDrawer() {
-		return (
-			<Drawer
-				open={this.state.isDrawerOpen}
-				docked={false}
-				openSecondary={true}
-				onRequestChange={this._onMenuButtonClick.bind(this)}
-			>
-				{this._renderPortalMenu()}
-				{this._renderDocsMenu()}
-				{this._renderWiki()}
-				<div className="pl1 py1 mt3" style={{ backgroundColor: colors.lightGrey }}>
-					Website
-				</div>
-				<Link to={WebsitePaths.Home} className="text-decoration-none">
-					<MenuItem className="py2">Home</MenuItem>
-				</Link>
-				<Link to={`${WebsitePaths.Wiki}`} className="text-decoration-none">
-					<MenuItem className="py2">Wiki</MenuItem>
-				</Link>
-				{!this._isViewing0xjsDocs() && (
-					<Link to={WebsitePaths.ZeroExJs} className="text-decoration-none">
-						<MenuItem className="py2">0x.js Docs</MenuItem>
-					</Link>
-				)}
-				{!this._isViewingConnectDocs() && (
-					<Link to={WebsitePaths.Connect} className="text-decoration-none">
-						<MenuItem className="py2">0x Connect Docs</MenuItem>
-					</Link>
-				)}
-				{!this._isViewingSmartContractsDocs() && (
-					<Link to={WebsitePaths.SmartContracts} className="text-decoration-none">
-						<MenuItem className="py2">Smart Contract Docs</MenuItem>
-					</Link>
-				)}
-				{!this._isViewingPortal() && (
-					<Link to={`${WebsitePaths.Portal}`} className="text-decoration-none">
-						<MenuItem className="py2">Portal DApp</MenuItem>
-					</Link>
-				)}
-				<a className="text-decoration-none" target="_blank" href={`${WebsitePaths.Whitepaper}`}>
-					<MenuItem className="py2">Whitepaper</MenuItem>
-				</a>
-				<Link to={`${WebsitePaths.About}`} className="text-decoration-none">
-					<MenuItem className="py2">About</MenuItem>
-				</Link>
-				<a className="text-decoration-none" target="_blank" href={constants.URL_BLOG}>
-					<MenuItem className="py2">Blog</MenuItem>
-				</a>
-				<Link to={`${WebsitePaths.FAQ}`} className="text-decoration-none">
-					<MenuItem className="py2" onTouchTap={this._onMenuButtonClick.bind(this)}>
-						FAQ
-					</MenuItem>
-				</Link>
-			</Drawer>
-		);
-	}
-	private _renderDocsMenu(): React.ReactNode {
-		if (
-			(!this._isViewing0xjsDocs() && !this._isViewingSmartContractsDocs() && !this._isViewingConnectDocs()) ||
-			_.isUndefined(this.props.menu)
-		) {
-			return undefined;
-		}
+    public static defaultProps: Partial<TopBarProps> = {
+        shouldFullWidth: false,
+        style: {},
+        isNightVersion: false,
+    };
+    constructor(props: TopBarProps) {
+        super(props);
+        this.state = {
+            isDrawerOpen: false,
+        };
+    }
+    public render() {
+        const isNightVersion = this.props.isNightVersion;
+        const isFullWidthPage = this.props.shouldFullWidth;
+        const parentClassNames = `flex mx-auto ${isFullWidthPage ? 'pl2' : 'max-width-4'}`;
+        const developerSectionMenuItems = [
+            <Link key="subMenuItem-zeroEx" to={WebsitePaths.ZeroExJs} className="text-decoration-none">
+                <MenuItem style={{ fontSize: styles.menuItem.fontSize }} primaryText="0x.js" />
+            </Link>,
+            <Link key="subMenuItem-smartContracts" to={WebsitePaths.SmartContracts} className="text-decoration-none">
+                <MenuItem style={{ fontSize: styles.menuItem.fontSize }} primaryText="Smart Contracts" />
+            </Link>,
+            <Link key="subMenuItem-0xconnect" to={WebsitePaths.Connect} className="text-decoration-none">
+                <MenuItem style={{ fontSize: styles.menuItem.fontSize }} primaryText="0x Connect" />
+            </Link>,
+            <a
+                key="subMenuItem-standard-relayer-api"
+                target="_blank"
+                className="text-decoration-none"
+                href={constants.URL_STANDARD_RELAYER_API_GITHUB}
+            >
+                <MenuItem style={{ fontSize: styles.menuItem.fontSize }} primaryText="Standard Relayer API" />
+            </a>,
+            <a
+                key="subMenuItem-github"
+                target="_blank"
+                className="text-decoration-none"
+                href={constants.URL_GITHUB_ORG}
+            >
+                <MenuItem style={{ fontSize: styles.menuItem.fontSize }} primaryText="GitHub" />
+            </a>,
+            <a
+                key="subMenuItem-whitePaper"
+                target="_blank"
+                className="text-decoration-none"
+                href={`${WebsitePaths.Whitepaper}`}
+            >
+                <MenuItem style={{ fontSize: styles.menuItem.fontSize }} primaryText="Whitepaper" />
+            </a>,
+        ];
+        const bottomBorderStyle = this._shouldDisplayBottomBar() ? styles.bottomBar : {};
+        const fullWidthClasses = isFullWidthPage ? 'pr4' : '';
+        const logoUrl = isNightVersion ? '/images/protocol_logo_white.png' : '/images/protocol_logo_black.png';
+        const menuClasses = `col col-${isFullWidthPage ? '4' : '5'} ${fullWidthClasses} lg-pr0 md-pr2 sm-hide xs-hide`;
+        const menuIconStyle = {
+            fontSize: 25,
+            color: isNightVersion ? 'white' : 'black',
+            cursor: 'pointer',
+            paddingTop: 16,
+        };
+        return (
+            <div style={{ ...styles.topBar, ...bottomBorderStyle, ...this.props.style }} className="pb1">
+                <div className={parentClassNames}>
+                    <div className="col col-2 sm-pl2 md-pl2 lg-pl0" style={{ paddingTop: 15 }}>
+                        <Link to={`${WebsitePaths.Home}`} className="text-decoration-none">
+                            <img src={logoUrl} height="30" />
+                        </Link>
+                    </div>
+                    <div className={`col col-${isFullWidthPage ? '8' : '9'} lg-hide md-hide`} />
+                    <div className={`col col-${isFullWidthPage ? '6' : '5'} sm-hide xs-hide`} />
+                    {!this._isViewingPortal() && (
+                        <div className={menuClasses}>
+                            <div className="flex justify-between">
+                                <DropDownMenuItem
+                                    title="Developers"
+                                    subMenuItems={developerSectionMenuItems}
+                                    style={styles.menuItem}
+                                    isNightVersion={isNightVersion}
+                                />
+                                <TopBarMenuItem
+                                    title="Wiki"
+                                    path={`${WebsitePaths.Wiki}`}
+                                    style={styles.menuItem}
+                                    isNightVersion={isNightVersion}
+                                />
+                                <TopBarMenuItem
+                                    title="About"
+                                    path={`${WebsitePaths.About}`}
+                                    style={styles.menuItem}
+                                    isNightVersion={isNightVersion}
+                                />
+                                <TopBarMenuItem
+                                    title="Portal DApp"
+                                    path={`${WebsitePaths.Portal}`}
+                                    isPrimary={true}
+                                    style={styles.menuItem}
+                                    className={`${isFullWidthPage && 'md-hide'}`}
+                                    isNightVersion={isNightVersion}
+                                />
+                            </div>
+                        </div>
+                    )}
+                    {this.props.blockchainIsLoaded &&
+                        !_.isEmpty(this.props.userAddress) && (
+                            <div className="col col-5 sm-hide xs-hide">{this._renderUser()}</div>
+                        )}
+                    <div className={`col ${isFullWidthPage ? 'col-2 pl2' : 'col-1'} md-hide lg-hide`}>
+                        <div style={menuIconStyle}>
+                            <i className="zmdi zmdi-menu" onClick={this._onMenuButtonClick.bind(this)} />
+                        </div>
+                    </div>
+                </div>
+                {this._renderDrawer()}
+            </div>
+        );
+    }
+    private _renderDrawer() {
+        return (
+            <Drawer
+                open={this.state.isDrawerOpen}
+                docked={false}
+                openSecondary={true}
+                onRequestChange={this._onMenuButtonClick.bind(this)}
+            >
+                {this._renderPortalMenu()}
+                {this._renderDocsMenu()}
+                {this._renderWiki()}
+                <div className="pl1 py1 mt3" style={{ backgroundColor: colors.lightGrey }}>
+                    Website
+                </div>
+                <Link to={WebsitePaths.Home} className="text-decoration-none">
+                    <MenuItem className="py2">Home</MenuItem>
+                </Link>
+                <Link to={`${WebsitePaths.Wiki}`} className="text-decoration-none">
+                    <MenuItem className="py2">Wiki</MenuItem>
+                </Link>
+                {!this._isViewing0xjsDocs() && (
+                    <Link to={WebsitePaths.ZeroExJs} className="text-decoration-none">
+                        <MenuItem className="py2">0x.js Docs</MenuItem>
+                    </Link>
+                )}
+                {!this._isViewingConnectDocs() && (
+                    <Link to={WebsitePaths.Connect} className="text-decoration-none">
+                        <MenuItem className="py2">0x Connect Docs</MenuItem>
+                    </Link>
+                )}
+                {!this._isViewingSmartContractsDocs() && (
+                    <Link to={WebsitePaths.SmartContracts} className="text-decoration-none">
+                        <MenuItem className="py2">Smart Contract Docs</MenuItem>
+                    </Link>
+                )}
+                {!this._isViewingPortal() && (
+                    <Link to={`${WebsitePaths.Portal}`} className="text-decoration-none">
+                        <MenuItem className="py2">Portal DApp</MenuItem>
+                    </Link>
+                )}
+                <a className="text-decoration-none" target="_blank" href={`${WebsitePaths.Whitepaper}`}>
+                    <MenuItem className="py2">Whitepaper</MenuItem>
+                </a>
+                <Link to={`${WebsitePaths.About}`} className="text-decoration-none">
+                    <MenuItem className="py2">About</MenuItem>
+                </Link>
+                <a className="text-decoration-none" target="_blank" href={constants.URL_BLOG}>
+                    <MenuItem className="py2">Blog</MenuItem>
+                </a>
+                <Link to={`${WebsitePaths.FAQ}`} className="text-decoration-none">
+                    <MenuItem className="py2" onTouchTap={this._onMenuButtonClick.bind(this)}>
+                        FAQ
+                    </MenuItem>
+                </Link>
+            </Drawer>
+        );
+    }
+    private _renderDocsMenu(): React.ReactNode {
+        if (
+            (!this._isViewing0xjsDocs() && !this._isViewingSmartContractsDocs() && !this._isViewingConnectDocs()) ||
+            _.isUndefined(this.props.menu)
+        ) {
+            return undefined;
+        }
 
-		const sectionTitle = `${this.props.docsInfo.displayName} Docs`;
-		return (
-			<div className="lg-hide md-hide">
-				<div className="pl1 py1" style={{ backgroundColor: colors.lightGrey }}>
-					{sectionTitle}
-				</div>
-				<NestedSidebarMenu
-					topLevelMenu={this.props.menu}
-					menuSubsectionsBySection={this.props.menuSubsectionsBySection}
-					shouldDisplaySectionHeaders={false}
-					onMenuItemClick={this._onMenuButtonClick.bind(this)}
-					selectedVersion={this.props.docsVersion}
-					docPath={this.props.docsInfo.websitePath}
-					versions={this.props.availableDocVersions}
-				/>
-			</div>
-		);
-	}
-	private _renderWiki(): React.ReactNode {
-		if (!this._isViewingWiki()) {
-			return undefined;
-		}
+        const sectionTitle = `${this.props.docsInfo.displayName} Docs`;
+        return (
+            <div className="lg-hide md-hide">
+                <div className="pl1 py1" style={{ backgroundColor: colors.lightGrey }}>
+                    {sectionTitle}
+                </div>
+                <NestedSidebarMenu
+                    topLevelMenu={this.props.menu}
+                    menuSubsectionsBySection={this.props.menuSubsectionsBySection}
+                    shouldDisplaySectionHeaders={false}
+                    onMenuItemClick={this._onMenuButtonClick.bind(this)}
+                    selectedVersion={this.props.docsVersion}
+                    docPath={this.props.docsInfo.websitePath}
+                    versions={this.props.availableDocVersions}
+                />
+            </div>
+        );
+    }
+    private _renderWiki(): React.ReactNode {
+        if (!this._isViewingWiki()) {
+            return undefined;
+        }
 
-		return (
-			<div className="lg-hide md-hide">
-				<div className="pl1 py1" style={{ backgroundColor: colors.lightGrey }}>
-					0x Protocol Wiki
-				</div>
-				<NestedSidebarMenu
-					topLevelMenu={this.props.menuSubsectionsBySection}
-					menuSubsectionsBySection={this.props.menuSubsectionsBySection}
-					shouldDisplaySectionHeaders={false}
-					onMenuItemClick={this._onMenuButtonClick.bind(this)}
-				/>
-			</div>
-		);
-	}
-	private _renderPortalMenu(): React.ReactNode {
-		if (!this._isViewingPortal()) {
-			return undefined;
-		}
+        return (
+            <div className="lg-hide md-hide">
+                <div className="pl1 py1" style={{ backgroundColor: colors.lightGrey }}>
+                    0x Protocol Wiki
+                </div>
+                <NestedSidebarMenu
+                    topLevelMenu={this.props.menuSubsectionsBySection}
+                    menuSubsectionsBySection={this.props.menuSubsectionsBySection}
+                    shouldDisplaySectionHeaders={false}
+                    onMenuItemClick={this._onMenuButtonClick.bind(this)}
+                />
+            </div>
+        );
+    }
+    private _renderPortalMenu(): React.ReactNode {
+        if (!this._isViewingPortal()) {
+            return undefined;
+        }
 
-		return (
-			<div className="lg-hide md-hide">
-				<div className="pl1 py1" style={{ backgroundColor: colors.lightGrey }}>
-					Portal DApp
-				</div>
-				<PortalMenu menuItemStyle={{ color: 'black' }} onClick={this._onMenuButtonClick.bind(this)} />
-			</div>
-		);
-	}
-	private _renderUser() {
-		const userAddress = this.props.userAddress;
-		const identiconDiameter = 26;
-		return (
-			<div className="flex right lg-pr0 md-pr2 sm-pr2" style={{ paddingTop: 16 }}>
-				<div style={styles.address} data-tip={true} data-for="userAddressTooltip">
-					{!_.isEmpty(userAddress) ? userAddress : ''}
-				</div>
-				<ReactTooltip id="userAddressTooltip">{userAddress}</ReactTooltip>
-				<div>
-					<Identicon address={userAddress} diameter={identiconDiameter} />
-				</div>
-			</div>
-		);
-	}
-	private _onMenuButtonClick() {
-		this.setState({
-			isDrawerOpen: !this.state.isDrawerOpen,
-		});
-	}
-	private _isViewingPortal() {
-		return _.includes(this.props.location.pathname, WebsitePaths.Portal);
-	}
-	private _isViewingFAQ() {
-		return _.includes(this.props.location.pathname, WebsitePaths.FAQ);
-	}
-	private _isViewing0xjsDocs() {
-		return _.includes(this.props.location.pathname, WebsitePaths.ZeroExJs);
-	}
-	private _isViewingConnectDocs() {
-		return _.includes(this.props.location.pathname, WebsitePaths.Connect);
-	}
-	private _isViewingSmartContractsDocs() {
-		return _.includes(this.props.location.pathname, WebsitePaths.SmartContracts);
-	}
-	private _isViewingWiki() {
-		return _.includes(this.props.location.pathname, WebsitePaths.Wiki);
-	}
-	private _shouldDisplayBottomBar() {
-		return (
-			this._isViewingWiki() ||
-			this._isViewing0xjsDocs() ||
-			this._isViewingFAQ() ||
-			this._isViewingSmartContractsDocs() ||
-			this._isViewingConnectDocs()
-		);
-	}
+        return (
+            <div className="lg-hide md-hide">
+                <div className="pl1 py1" style={{ backgroundColor: colors.lightGrey }}>
+                    Portal DApp
+                </div>
+                <PortalMenu menuItemStyle={{ color: 'black' }} onClick={this._onMenuButtonClick.bind(this)} />
+            </div>
+        );
+    }
+    private _renderUser() {
+        const userAddress = this.props.userAddress;
+        const identiconDiameter = 26;
+        return (
+            <div className="flex right lg-pr0 md-pr2 sm-pr2" style={{ paddingTop: 16 }}>
+                <div style={styles.address} data-tip={true} data-for="userAddressTooltip">
+                    {!_.isEmpty(userAddress) ? userAddress : ''}
+                </div>
+                <ReactTooltip id="userAddressTooltip">{userAddress}</ReactTooltip>
+                <div>
+                    <Identicon address={userAddress} diameter={identiconDiameter} />
+                </div>
+            </div>
+        );
+    }
+    private _onMenuButtonClick() {
+        this.setState({
+            isDrawerOpen: !this.state.isDrawerOpen,
+        });
+    }
+    private _isViewingPortal() {
+        return _.includes(this.props.location.pathname, WebsitePaths.Portal);
+    }
+    private _isViewingFAQ() {
+        return _.includes(this.props.location.pathname, WebsitePaths.FAQ);
+    }
+    private _isViewing0xjsDocs() {
+        return _.includes(this.props.location.pathname, WebsitePaths.ZeroExJs);
+    }
+    private _isViewingConnectDocs() {
+        return _.includes(this.props.location.pathname, WebsitePaths.Connect);
+    }
+    private _isViewingSmartContractsDocs() {
+        return _.includes(this.props.location.pathname, WebsitePaths.SmartContracts);
+    }
+    private _isViewingWiki() {
+        return _.includes(this.props.location.pathname, WebsitePaths.Wiki);
+    }
+    private _shouldDisplayBottomBar() {
+        return (
+            this._isViewingWiki() ||
+            this._isViewing0xjsDocs() ||
+            this._isViewingFAQ() ||
+            this._isViewingSmartContractsDocs() ||
+            this._isViewingConnectDocs()
+        );
+    }
 }
diff --git a/packages/website/ts/components/top_bar_menu_item.tsx b/packages/website/ts/components/top_bar_menu_item.tsx
index 0138740ba..96ee86142 100644
--- a/packages/website/ts/components/top_bar_menu_item.tsx
+++ b/packages/website/ts/components/top_bar_menu_item.tsx
@@ -4,49 +4,49 @@ import { Link } from 'react-router-dom';
 import { colors } from 'ts/utils/colors';
 
 const DEFAULT_STYLE = {
-	color: colors.darkestGrey,
+    color: colors.darkestGrey,
 };
 
 interface TopBarMenuItemProps {
-	title: string;
-	path?: string;
-	isPrimary?: boolean;
-	style?: React.CSSProperties;
-	className?: string;
-	isNightVersion?: boolean;
+    title: string;
+    path?: string;
+    isPrimary?: boolean;
+    style?: React.CSSProperties;
+    className?: string;
+    isNightVersion?: boolean;
 }
 
 interface TopBarMenuItemState {}
 
 export class TopBarMenuItem extends React.Component<TopBarMenuItemProps, TopBarMenuItemState> {
-	public static defaultProps: Partial<TopBarMenuItemProps> = {
-		isPrimary: false,
-		style: DEFAULT_STYLE,
-		className: '',
-		isNightVersion: false,
-	};
-	public render() {
-		const primaryStyles = this.props.isPrimary
-			? {
-					borderRadius: 4,
-					border: `1px solid ${this.props.isNightVersion ? colors.grey : colors.greyishPink}`,
-					marginTop: 15,
-					paddingLeft: 9,
-					paddingRight: 9,
-					width: 77,
-				}
-			: {};
-		const menuItemColor = this.props.isNightVersion ? 'white' : this.props.style.color;
-		const linkColor = _.isUndefined(menuItemColor) ? colors.darkestGrey : menuItemColor;
-		return (
-			<div
-				className={`center ${this.props.className}`}
-				style={{ ...this.props.style, ...primaryStyles, color: menuItemColor }}
-			>
-				<Link to={this.props.path} className="text-decoration-none" style={{ color: linkColor }}>
-					{this.props.title}
-				</Link>
-			</div>
-		);
-	}
+    public static defaultProps: Partial<TopBarMenuItemProps> = {
+        isPrimary: false,
+        style: DEFAULT_STYLE,
+        className: '',
+        isNightVersion: false,
+    };
+    public render() {
+        const primaryStyles = this.props.isPrimary
+            ? {
+                  borderRadius: 4,
+                  border: `1px solid ${this.props.isNightVersion ? colors.grey : colors.greyishPink}`,
+                  marginTop: 15,
+                  paddingLeft: 9,
+                  paddingRight: 9,
+                  width: 77,
+              }
+            : {};
+        const menuItemColor = this.props.isNightVersion ? 'white' : this.props.style.color;
+        const linkColor = _.isUndefined(menuItemColor) ? colors.darkestGrey : menuItemColor;
+        return (
+            <div
+                className={`center ${this.props.className}`}
+                style={{ ...this.props.style, ...primaryStyles, color: menuItemColor }}
+            >
+                <Link to={this.props.path} className="text-decoration-none" style={{ color: linkColor }}>
+                    {this.props.title}
+                </Link>
+            </div>
+        );
+    }
 }
diff --git a/packages/website/ts/components/track_token_confirmation.tsx b/packages/website/ts/components/track_token_confirmation.tsx
index 1887bd11c..76971aefa 100644
--- a/packages/website/ts/components/track_token_confirmation.tsx
+++ b/packages/website/ts/components/track_token_confirmation.tsx
@@ -6,56 +6,56 @@ import { colors } from 'ts/utils/colors';
 import { utils } from 'ts/utils/utils';
 
 interface TrackTokenConfirmationProps {
-	tokens: Token[];
-	tokenByAddress: TokenByAddress;
-	networkId: number;
-	isAddingTokenToTracked: boolean;
+    tokens: Token[];
+    tokenByAddress: TokenByAddress;
+    networkId: number;
+    isAddingTokenToTracked: boolean;
 }
 
 interface TrackTokenConfirmationState {}
 
 export class TrackTokenConfirmation extends React.Component<TrackTokenConfirmationProps, TrackTokenConfirmationState> {
-	public render() {
-		const isMultipleTokens = this.props.tokens.length > 1;
-		const allTokens = _.values(this.props.tokenByAddress);
-		return (
-			<div style={{ color: colors.grey700 }}>
-				{this.props.isAddingTokenToTracked ? (
-					<div className="py4 my4 center">
-						<span className="pr1">
-							<i className="zmdi zmdi-spinner zmdi-hc-spin" />
-						</span>
-						<span>Adding token{isMultipleTokens && 's'}...</span>
-					</div>
-				) : (
-					<div>
-						<div>You do not currently track the following token{isMultipleTokens && 's'}:</div>
-						<div className="py2 clearfix mx-auto center" style={{ width: 355 }}>
-							{_.map(this.props.tokens, (token: Token) => (
-								<div
-									key={`token-profile-${token.name}`}
-									className={`col col-${isMultipleTokens ? '6' : '12'} px2`}
-								>
-									<Party
-										label={token.name}
-										address={token.address}
-										networkId={this.props.networkId}
-										alternativeImage={token.iconUrl}
-										isInTokenRegistry={token.isRegistered}
-										hasUniqueNameAndSymbol={utils.hasUniqueNameAndSymbol(allTokens, token)}
-									/>
-								</div>
-							))}
-						</div>
-						<div>
-							Tracking a token adds it to the balances section of 0x Portal and allows you to
-							generate/fill orders involving the token
-							{isMultipleTokens && 's'}. Would you like to start tracking{' '}
-							{isMultipleTokens ? 'these' : 'this'} token?
-						</div>
-					</div>
-				)}
-			</div>
-		);
-	}
+    public render() {
+        const isMultipleTokens = this.props.tokens.length > 1;
+        const allTokens = _.values(this.props.tokenByAddress);
+        return (
+            <div style={{ color: colors.grey700 }}>
+                {this.props.isAddingTokenToTracked ? (
+                    <div className="py4 my4 center">
+                        <span className="pr1">
+                            <i className="zmdi zmdi-spinner zmdi-hc-spin" />
+                        </span>
+                        <span>Adding token{isMultipleTokens && 's'}...</span>
+                    </div>
+                ) : (
+                    <div>
+                        <div>You do not currently track the following token{isMultipleTokens && 's'}:</div>
+                        <div className="py2 clearfix mx-auto center" style={{ width: 355 }}>
+                            {_.map(this.props.tokens, (token: Token) => (
+                                <div
+                                    key={`token-profile-${token.name}`}
+                                    className={`col col-${isMultipleTokens ? '6' : '12'} px2`}
+                                >
+                                    <Party
+                                        label={token.name}
+                                        address={token.address}
+                                        networkId={this.props.networkId}
+                                        alternativeImage={token.iconUrl}
+                                        isInTokenRegistry={token.isRegistered}
+                                        hasUniqueNameAndSymbol={utils.hasUniqueNameAndSymbol(allTokens, token)}
+                                    />
+                                </div>
+                            ))}
+                        </div>
+                        <div>
+                            Tracking a token adds it to the balances section of 0x Portal and allows you to
+                            generate/fill orders involving the token
+                            {isMultipleTokens && 's'}. Would you like to start tracking{' '}
+                            {isMultipleTokens ? 'these' : 'this'} token?
+                        </div>
+                    </div>
+                )}
+            </div>
+        );
+    }
 }
diff --git a/packages/website/ts/components/trade_history/trade_history.tsx b/packages/website/ts/components/trade_history/trade_history.tsx
index 3963135f7..635358627 100644
--- a/packages/website/ts/components/trade_history/trade_history.tsx
+++ b/packages/website/ts/components/trade_history/trade_history.tsx
@@ -10,106 +10,106 @@ import { utils } from 'ts/utils/utils';
 const FILL_POLLING_INTERVAL = 1000;
 
 interface TradeHistoryProps {
-	tokenByAddress: TokenByAddress;
-	userAddress: string;
-	networkId: number;
+    tokenByAddress: TokenByAddress;
+    userAddress: string;
+    networkId: number;
 }
 
 interface TradeHistoryState {
-	sortedFills: Fill[];
+    sortedFills: Fill[];
 }
 
 export class TradeHistory extends React.Component<TradeHistoryProps, TradeHistoryState> {
-	private _fillPollingIntervalId: number;
-	public constructor(props: TradeHistoryProps) {
-		super(props);
-		const sortedFills = this._getSortedFills();
-		this.state = {
-			sortedFills,
-		};
-	}
-	public componentWillMount() {
-		this._startPollingForFills();
-	}
-	public componentWillUnmount() {
-		this._stopPollingForFills();
-	}
-	public componentDidMount() {
-		window.scrollTo(0, 0);
-	}
-	public render() {
-		return (
-			<div className="lg-px4 md-px4 sm-px2">
-				<h3>Trade history</h3>
-				<Divider />
-				<div className="pt2" style={{ height: 608, overflow: 'scroll' }}>
-					{this._renderTrades()}
-				</div>
-			</div>
-		);
-	}
-	private _renderTrades() {
-		const numNonCustomFills = this._numFillsWithoutCustomERC20Tokens();
-		if (numNonCustomFills === 0) {
-			return this._renderEmptyNotice();
-		}
+    private _fillPollingIntervalId: number;
+    public constructor(props: TradeHistoryProps) {
+        super(props);
+        const sortedFills = this._getSortedFills();
+        this.state = {
+            sortedFills,
+        };
+    }
+    public componentWillMount() {
+        this._startPollingForFills();
+    }
+    public componentWillUnmount() {
+        this._stopPollingForFills();
+    }
+    public componentDidMount() {
+        window.scrollTo(0, 0);
+    }
+    public render() {
+        return (
+            <div className="lg-px4 md-px4 sm-px2">
+                <h3>Trade history</h3>
+                <Divider />
+                <div className="pt2" style={{ height: 608, overflow: 'scroll' }}>
+                    {this._renderTrades()}
+                </div>
+            </div>
+        );
+    }
+    private _renderTrades() {
+        const numNonCustomFills = this._numFillsWithoutCustomERC20Tokens();
+        if (numNonCustomFills === 0) {
+            return this._renderEmptyNotice();
+        }
 
-		return _.map(this.state.sortedFills, (fill, index) => {
-			return (
-				<TradeHistoryItem
-					key={`${fill.orderHash}-${fill.filledTakerTokenAmount}-${index}`}
-					fill={fill}
-					tokenByAddress={this.props.tokenByAddress}
-					userAddress={this.props.userAddress}
-					networkId={this.props.networkId}
-				/>
-			);
-		});
-	}
-	private _renderEmptyNotice() {
-		return (
-			<Paper className="mt1 p2 mx-auto center" style={{ width: '80%' }}>
-				No filled orders yet.
-			</Paper>
-		);
-	}
-	private _numFillsWithoutCustomERC20Tokens() {
-		let numNonCustomFills = 0;
-		const tokens = _.values(this.props.tokenByAddress);
-		_.each(this.state.sortedFills, fill => {
-			const takerToken = _.find(tokens, token => {
-				return token.address === fill.takerToken;
-			});
-			const makerToken = _.find(tokens, token => {
-				return token.address === fill.makerToken;
-			});
-			// For now we don't show history items for orders using custom ERC20
-			// tokens the client does not know how to display.
-			// TODO: Try to retrieve the name/symbol of an unknown token in order to display it
-			// Be sure to remove similar logic in trade_history_item.tsx
-			if (!_.isUndefined(takerToken) && !_.isUndefined(makerToken)) {
-				numNonCustomFills += 1;
-			}
-		});
-		return numNonCustomFills;
-	}
-	private _startPollingForFills() {
-		this._fillPollingIntervalId = window.setInterval(() => {
-			const sortedFills = this._getSortedFills();
-			if (!utils.deepEqual(sortedFills, this.state.sortedFills)) {
-				this.setState({
-					sortedFills,
-				});
-			}
-		}, FILL_POLLING_INTERVAL);
-	}
-	private _stopPollingForFills() {
-		clearInterval(this._fillPollingIntervalId);
-	}
-	private _getSortedFills() {
-		const fillsByHash = tradeHistoryStorage.getUserFillsByHash(this.props.userAddress, this.props.networkId);
-		const fills = _.values(fillsByHash);
-		const sortedFills = _.sortBy(fills, [(fill: Fill) => fill.blockTimestamp * -1]);
-		return sortedFills;
-	}
+        return _.map(this.state.sortedFills, (fill, index) => {
+            return (
+                <TradeHistoryItem
+                    key={`${fill.orderHash}-${fill.filledTakerTokenAmount}-${index}`}
+                    fill={fill}
+                    tokenByAddress={this.props.tokenByAddress}
+                    userAddress={this.props.userAddress}
+                    networkId={this.props.networkId}
+                />
+            );
+        });
+    }
+    private _renderEmptyNotice() {
+        return (
+            <Paper className="mt1 p2 mx-auto center" style={{ width: '80%' }}>
+                No filled orders yet.
+            </Paper>
+        );
+    }
+    private _numFillsWithoutCustomERC20Tokens() {
+        let numNonCustomFills = 0;
+        const tokens = _.values(this.props.tokenByAddress);
+        _.each(this.state.sortedFills, fill => {
+            const takerToken = _.find(tokens, token => {
+                return token.address === fill.takerToken;
+            });
+            const makerToken = _.find(tokens, token => {
+                return token.address === fill.makerToken;
+            });
+            // For now we don't show history items for orders using custom ERC20
+            // tokens the client does not know how to display.
+            // TODO: Try to retrieve the name/symbol of an unknown token in order to display it
+            // Be sure to remove similar logic in trade_history_item.tsx
+            if (!_.isUndefined(takerToken) && !_.isUndefined(makerToken)) {
+                numNonCustomFills += 1;
+            }
+        });
+        return numNonCustomFills;
+    }
+    private _startPollingForFills() {
+        this._fillPollingIntervalId = window.setInterval(() => {
+            const sortedFills = this._getSortedFills();
+            if (!utils.deepEqual(sortedFills, this.state.sortedFills)) {
+                this.setState({
+                    sortedFills,
+                });
+            }
+        }, FILL_POLLING_INTERVAL);
+    }
+    private _stopPollingForFills() {
+        clearInterval(this._fillPollingIntervalId);
+    }
+    private _getSortedFills() {
+        const fillsByHash = tradeHistoryStorage.getUserFillsByHash(this.props.userAddress, this.props.networkId);
+        const fills = _.values(fillsByHash);
+        const sortedFills = _.sortBy(fills, [(fill: Fill) => fill.blockTimestamp * -1]);
+        return sortedFills;
+    }
 }
diff --git a/packages/website/ts/components/trade_history/trade_history_item.tsx b/packages/website/ts/components/trade_history/trade_history_item.tsx
index 118bde3b9..7e42e64e6 100644
--- a/packages/website/ts/components/trade_history/trade_history_item.tsx
+++ b/packages/website/ts/components/trade_history/trade_history_item.tsx
@@ -14,157 +14,157 @@ const PRECISION = 5;
 const IDENTICON_DIAMETER = 40;
 
 interface TradeHistoryItemProps {
-	fill: Fill;
-	tokenByAddress: TokenByAddress;
-	userAddress: string;
-	networkId: number;
+    fill: Fill;
+    tokenByAddress: TokenByAddress;
+    userAddress: string;
+    networkId: number;
 }
 
 interface TradeHistoryItemState {}
 
 export class TradeHistoryItem extends React.Component<TradeHistoryItemProps, TradeHistoryItemState> {
-	public render() {
-		const fill = this.props.fill;
-		const tokens = _.values(this.props.tokenByAddress);
-		const takerToken = _.find(tokens, token => {
-			return token.address === fill.takerToken;
-		});
-		const makerToken = _.find(tokens, token => {
-			return token.address === fill.makerToken;
-		});
-		// For now we don't show history items for orders using custom ERC20
-		// tokens the client does not know how to display.
-		// TODO: Try to retrieve the name/symbol of an unknown token in order to display it
-		// Be sure to remove similar logic in trade_history.tsx
-		if (_.isUndefined(takerToken) || _.isUndefined(makerToken)) {
-			return null;
-		}
+    public render() {
+        const fill = this.props.fill;
+        const tokens = _.values(this.props.tokenByAddress);
+        const takerToken = _.find(tokens, token => {
+            return token.address === fill.takerToken;
+        });
+        const makerToken = _.find(tokens, token => {
+            return token.address === fill.makerToken;
+        });
+        // For now we don't show history items for orders using custom ERC20
+        // tokens the client does not know how to display.
+        // TODO: Try to retrieve the name/symbol of an unknown token in order to display it
+        // Be sure to remove similar logic in trade_history.tsx
+        if (_.isUndefined(takerToken) || _.isUndefined(makerToken)) {
+            return null;
+        }
 
-		const amountColStyle: React.CSSProperties = {
-			fontWeight: 100,
-			display: 'inline-block',
-		};
-		const amountColClassNames =
-			'col col-12 lg-col-4 md-col-4 lg-py2 md-py2 sm-py1 lg-pr2 md-pr2 \
+        const amountColStyle: React.CSSProperties = {
+            fontWeight: 100,
+            display: 'inline-block',
+        };
+        const amountColClassNames =
+            'col col-12 lg-col-4 md-col-4 lg-py2 md-py2 sm-py1 lg-pr2 md-pr2 \
                                      lg-right-align md-right-align sm-center';
 
-		return (
-			<Paper className="py1" style={{ margin: '3px 3px 15px 3px' }}>
-				<div className="clearfix">
-					<div className="col col-12 lg-col-1 md-col-1 pt2 lg-pl3 md-pl3">{this._renderDate()}</div>
-					<div
-						className="col col-12 lg-col-6 md-col-6 lg-pl3 md-pl3"
-						style={{ fontSize: 12, fontWeight: 100 }}
-					>
-						<div className="flex sm-mx-auto xs-mx-auto" style={{ paddingTop: 4, width: 224 }}>
-							<Party
-								label="Maker"
-								address={fill.maker}
-								identiconDiameter={IDENTICON_DIAMETER}
-								networkId={this.props.networkId}
-							/>
-							<i style={{ fontSize: 30 }} className="zmdi zmdi-swap py3" />
-							<Party
-								label="Taker"
-								address={fill.taker}
-								identiconDiameter={IDENTICON_DIAMETER}
-								networkId={this.props.networkId}
-							/>
-						</div>
-					</div>
-					<div className={amountColClassNames} style={amountColStyle}>
-						{this._renderAmounts(makerToken, takerToken)}
-					</div>
-					<div className="col col-12 lg-col-1 md-col-1 lg-pr3 md-pr3 lg-py3 md-py3 sm-pb1 sm-center">
-						<div className="pt1 lg-right md-right sm-mx-auto" style={{ width: 13 }}>
-							<EtherScanIcon
-								addressOrTxHash={fill.transactionHash}
-								networkId={this.props.networkId}
-								etherscanLinkSuffixes={EtherscanLinkSuffixes.Tx}
-							/>
-						</div>
-					</div>
-				</div>
-			</Paper>
-		);
-	}
-	private _renderAmounts(makerToken: Token, takerToken: Token) {
-		const fill = this.props.fill;
-		const filledTakerTokenAmountInUnits = ZeroEx.toUnitAmount(fill.filledTakerTokenAmount, takerToken.decimals);
-		const filledMakerTokenAmountInUnits = ZeroEx.toUnitAmount(fill.filledMakerTokenAmount, takerToken.decimals);
-		let exchangeRate = filledTakerTokenAmountInUnits.div(filledMakerTokenAmountInUnits);
-		const fillMakerTokenAmount = ZeroEx.toBaseUnitAmount(filledMakerTokenAmountInUnits, makerToken.decimals);
+        return (
+            <Paper className="py1" style={{ margin: '3px 3px 15px 3px' }}>
+                <div className="clearfix">
+                    <div className="col col-12 lg-col-1 md-col-1 pt2 lg-pl3 md-pl3">{this._renderDate()}</div>
+                    <div
+                        className="col col-12 lg-col-6 md-col-6 lg-pl3 md-pl3"
+                        style={{ fontSize: 12, fontWeight: 100 }}
+                    >
+                        <div className="flex sm-mx-auto xs-mx-auto" style={{ paddingTop: 4, width: 224 }}>
+                            <Party
+                                label="Maker"
+                                address={fill.maker}
+                                identiconDiameter={IDENTICON_DIAMETER}
+                                networkId={this.props.networkId}
+                            />
+                            <i style={{ fontSize: 30 }} className="zmdi zmdi-swap py3" />
+                            <Party
+                                label="Taker"
+                                address={fill.taker}
+                                identiconDiameter={IDENTICON_DIAMETER}
+                                networkId={this.props.networkId}
+                            />
+                        </div>
+                    </div>
+                    <div className={amountColClassNames} style={amountColStyle}>
+                        {this._renderAmounts(makerToken, takerToken)}
+                    </div>
+                    <div className="col col-12 lg-col-1 md-col-1 lg-pr3 md-pr3 lg-py3 md-py3 sm-pb1 sm-center">
+                        <div className="pt1 lg-right md-right sm-mx-auto" style={{ width: 13 }}>
+                            <EtherScanIcon
+                                addressOrTxHash={fill.transactionHash}
+                                networkId={this.props.networkId}
+                                etherscanLinkSuffixes={EtherscanLinkSuffixes.Tx}
+                            />
+                        </div>
+                    </div>
+                </div>
+            </Paper>
+        );
+    }
+    private _renderAmounts(makerToken: Token, takerToken: Token) {
+        const fill = this.props.fill;
+        const filledTakerTokenAmountInUnits = ZeroEx.toUnitAmount(fill.filledTakerTokenAmount, takerToken.decimals);
+        const filledMakerTokenAmountInUnits = ZeroEx.toUnitAmount(fill.filledMakerTokenAmount, takerToken.decimals);
+        let exchangeRate = filledTakerTokenAmountInUnits.div(filledMakerTokenAmountInUnits);
+        const fillMakerTokenAmount = ZeroEx.toBaseUnitAmount(filledMakerTokenAmountInUnits, makerToken.decimals);
 
-		let receiveAmount;
-		let receiveToken;
-		let givenAmount;
-		let givenToken;
-		if (this.props.userAddress === fill.maker && this.props.userAddress === fill.taker) {
-			receiveAmount = new BigNumber(0);
-			givenAmount = new BigNumber(0);
-			receiveToken = makerToken;
-			givenToken = takerToken;
-		} else if (this.props.userAddress === fill.maker) {
-			receiveAmount = fill.filledTakerTokenAmount;
-			givenAmount = fillMakerTokenAmount;
-			receiveToken = takerToken;
-			givenToken = makerToken;
-			exchangeRate = new BigNumber(1).div(exchangeRate);
-		} else if (this.props.userAddress === fill.taker) {
-			receiveAmount = fillMakerTokenAmount;
-			givenAmount = fill.filledTakerTokenAmount;
-			receiveToken = makerToken;
-			givenToken = takerToken;
-		} else {
-			// This condition should never be hit
-			throw new Error("Found Fill that wasn't performed by this user");
-		}
+        let receiveAmount;
+        let receiveToken;
+        let givenAmount;
+        let givenToken;
+        if (this.props.userAddress === fill.maker && this.props.userAddress === fill.taker) {
+            receiveAmount = new BigNumber(0);
+            givenAmount = new BigNumber(0);
+            receiveToken = makerToken;
+            givenToken = takerToken;
+        } else if (this.props.userAddress === fill.maker) {
+            receiveAmount = fill.filledTakerTokenAmount;
+            givenAmount = fillMakerTokenAmount;
+            receiveToken = takerToken;
+            givenToken = makerToken;
+            exchangeRate = new BigNumber(1).div(exchangeRate);
+        } else if (this.props.userAddress === fill.taker) {
+            receiveAmount = fillMakerTokenAmount;
+            givenAmount = fill.filledTakerTokenAmount;
+            receiveToken = makerToken;
+            givenToken = takerToken;
+        } else {
+            // This condition should never be hit
+            throw new Error("Found Fill that wasn't performed by this user");
+        }
 
-		return (
-			<div>
-				<div style={{ color: colors.green400, fontSize: 16 }}>
-					<span>+ </span>
-					{this._renderAmount(receiveAmount, receiveToken.symbol, receiveToken.decimals)}
-				</div>
-				<div className="pb1 inline-block" style={{ color: colors.red200, fontSize: 16 }}>
-					<span>- </span>
-					{this._renderAmount(givenAmount, givenToken.symbol, givenToken.decimals)}
-				</div>
-				<div style={{ color: colors.grey400, fontSize: 14 }}>
-					{exchangeRate.toFixed(PRECISION)} {givenToken.symbol}/{receiveToken.symbol}
-				</div>
-			</div>
-		);
-	}
-	private _renderDate() {
-		const blockMoment = moment.unix(this.props.fill.blockTimestamp);
-		if (!blockMoment.isValid()) {
-			return null;
-		}
+        return (
+            <div>
+                <div style={{ color: colors.green400, fontSize: 16 }}>
+                    <span>+ </span>
+                    {this._renderAmount(receiveAmount, receiveToken.symbol, receiveToken.decimals)}
+                </div>
+                <div className="pb1 inline-block" style={{ color: colors.red200, fontSize: 16 }}>
+                    <span>- </span>
+                    {this._renderAmount(givenAmount, givenToken.symbol, givenToken.decimals)}
+                </div>
+                <div style={{ color: colors.grey400, fontSize: 14 }}>
+                    {exchangeRate.toFixed(PRECISION)} {givenToken.symbol}/{receiveToken.symbol}
+                </div>
+            </div>
+        );
+    }
+    private _renderDate() {
+        const blockMoment = moment.unix(this.props.fill.blockTimestamp);
+        if (!blockMoment.isValid()) {
+            return null;
+        }
 
-		const dayOfMonth = blockMoment.format('D');
-		const monthAbreviation = blockMoment.format('MMM');
-		const formattedBlockDate = blockMoment.format('H:mmA - MMMM D, YYYY');
-		const dateTooltipId = `${this.props.fill.transactionHash}-date`;
+        const dayOfMonth = blockMoment.format('D');
+        const monthAbreviation = blockMoment.format('MMM');
+        const formattedBlockDate = blockMoment.format('H:mmA - MMMM D, YYYY');
+        const dateTooltipId = `${this.props.fill.transactionHash}-date`;
 
-		return (
-			<div data-tip={true} data-for={dateTooltipId}>
-				<div className="center pt1" style={{ fontSize: 13 }}>
-					{monthAbreviation}
-				</div>
-				<div className="center" style={{ fontSize: 24, fontWeight: 100 }}>
-					{dayOfMonth}
-				</div>
-				<ReactTooltip id={dateTooltipId}>{formattedBlockDate}</ReactTooltip>
-			</div>
-		);
-	}
-	private _renderAmount(amount: BigNumber, symbol: string, decimals: number) {
-		const unitAmount = ZeroEx.toUnitAmount(amount, decimals);
-		return (
-			<span>
-				{unitAmount.toFixed(PRECISION)} {symbol}
-			</span>
-		);
-	}
+        return (
+            <div data-tip={true} data-for={dateTooltipId}>
+                <div className="center pt1" style={{ fontSize: 13 }}>
+                    {monthAbreviation}
+                </div>
+                <div className="center" style={{ fontSize: 24, fontWeight: 100 }}>
+                    {dayOfMonth}
+                </div>
+                <ReactTooltip id={dateTooltipId}>{formattedBlockDate}</ReactTooltip>
+            </div>
+        );
+    }
+    private _renderAmount(amount: BigNumber, symbol: string, decimals: number) {
+        const unitAmount = ZeroEx.toUnitAmount(amount, decimals);
+        return (
+            <span>
+                {unitAmount.toFixed(PRECISION)} {symbol}
+            </span>
+        );
+    }
 }
diff --git a/packages/website/ts/components/ui/alert.tsx b/packages/website/ts/components/ui/alert.tsx
index 91ef8f76e..54881b499 100644
--- a/packages/website/ts/components/ui/alert.tsx
+++ b/packages/website/ts/components/ui/alert.tsx
@@ -3,23 +3,23 @@ import { AlertTypes } from 'ts/types';
 import { colors } from 'ts/utils/colors';
 
 interface AlertProps {
-	type: AlertTypes;
-	message: string | React.ReactNode;
+    type: AlertTypes;
+    message: string | React.ReactNode;
 }
 
 export function Alert(props: AlertProps) {
-	const isAlert = props.type === AlertTypes.ERROR;
-	const errMsgStyles = {
-		background: isAlert ? colors.red200 : colors.lightestGreen,
-		color: colors.white,
-		marginTop: 10,
-		padding: 4,
-		paddingLeft: 8,
-	};
+    const isAlert = props.type === AlertTypes.ERROR;
+    const errMsgStyles = {
+        background: isAlert ? colors.red200 : colors.lightestGreen,
+        color: colors.white,
+        marginTop: 10,
+        padding: 4,
+        paddingLeft: 8,
+    };
 
-	return (
-		<div className="rounded center" style={errMsgStyles}>
-			{props.message}
-		</div>
-	);
+    return (
+        <div className="rounded center" style={errMsgStyles}>
+            {props.message}
+        </div>
+    );
 }
diff --git a/packages/website/ts/components/ui/badge.tsx b/packages/website/ts/components/ui/badge.tsx
index 1d2d81af6..7f7ea006e 100644
--- a/packages/website/ts/components/ui/badge.tsx
+++ b/packages/website/ts/components/ui/badge.tsx
@@ -3,55 +3,55 @@ import * as React from 'react';
 import { Styles } from 'ts/types';
 
 const styles: Styles = {
-	badge: {
-		width: 50,
-		fontSize: 11,
-		height: 10,
-		borderRadius: 5,
-		marginTop: 25,
-		lineHeight: 0.9,
-		fontFamily: 'Roboto Mono',
-		marginLeft: 3,
-		marginRight: 3,
-	},
+    badge: {
+        width: 50,
+        fontSize: 11,
+        height: 10,
+        borderRadius: 5,
+        marginTop: 25,
+        lineHeight: 0.9,
+        fontFamily: 'Roboto Mono',
+        marginLeft: 3,
+        marginRight: 3,
+    },
 };
 
 interface BadgeProps {
-	title: string;
-	backgroundColor: string;
+    title: string;
+    backgroundColor: string;
 }
 
 interface BadgeState {
-	isHovering: boolean;
+    isHovering: boolean;
 }
 
 export class Badge extends React.Component<BadgeProps, BadgeState> {
-	constructor(props: BadgeProps) {
-		super(props);
-		this.state = {
-			isHovering: false,
-		};
-	}
-	public render() {
-		const badgeStyle = {
-			...styles.badge,
-			backgroundColor: this.props.backgroundColor,
-			opacity: this.state.isHovering ? 0.7 : 1,
-		};
-		return (
-			<div
-				className="p1 center"
-				style={badgeStyle}
-				onMouseOver={this._setHoverState.bind(this, true)}
-				onMouseOut={this._setHoverState.bind(this, false)}
-			>
-				{this.props.title}
-			</div>
-		);
-	}
-	private _setHoverState(isHovering: boolean) {
-		this.setState({
-			isHovering,
-		});
-	}
+    constructor(props: BadgeProps) {
+        super(props);
+        this.state = {
+            isHovering: false,
+        };
+    }
+    public render() {
+        const badgeStyle = {
+            ...styles.badge,
+            backgroundColor: this.props.backgroundColor,
+            opacity: this.state.isHovering ? 0.7 : 1,
+        };
+        return (
+            <div
+                className="p1 center"
+                style={badgeStyle}
+                onMouseOver={this._setHoverState.bind(this, true)}
+                onMouseOut={this._setHoverState.bind(this, false)}
+            >
+                {this.props.title}
+            </div>
+        );
+    }
+    private _setHoverState(isHovering: boolean) {
+        this.setState({
+            isHovering,
+        });
+    }
 }
diff --git a/packages/website/ts/components/ui/copy_icon.tsx b/packages/website/ts/components/ui/copy_icon.tsx
index 72ab77e1f..df55e0922 100644
--- a/packages/website/ts/components/ui/copy_icon.tsx
+++ b/packages/website/ts/components/ui/copy_icon.tsx
@@ -6,74 +6,74 @@ import ReactTooltip = require('react-tooltip');
 import { colors } from 'ts/utils/colors';
 
 interface CopyIconProps {
-	data: string;
-	callToAction?: string;
+    data: string;
+    callToAction?: string;
 }
 
 interface CopyIconState {
-	isHovering: boolean;
+    isHovering: boolean;
 }
 
 export class CopyIcon extends React.Component<CopyIconProps, CopyIconState> {
-	private _copyTooltipTimeoutId: number;
-	private _copyable: HTMLInputElement;
-	constructor(props: CopyIconProps) {
-		super(props);
-		this.state = {
-			isHovering: false,
-		};
-	}
-	public componentDidUpdate() {
-		// Remove tooltip if hover away
-		if (!this.state.isHovering && this._copyTooltipTimeoutId) {
-			clearInterval(this._copyTooltipTimeoutId);
-			this._hideTooltip();
-		}
-	}
-	public render() {
-		return (
-			<div className="inline-block">
-				<CopyToClipboard text={this.props.data} onCopy={this._onCopy.bind(this)}>
-					<div
-						className="inline flex"
-						style={{ cursor: 'pointer', color: colors.amber600 }}
-						ref={this._setRefToProperty.bind(this)}
-						data-tip={true}
-						data-for="copy"
-						data-event="click"
-						data-iscapture={true} // This let's the click event continue to propogate
-						onMouseOver={this._setHoverState.bind(this, true)}
-						onMouseOut={this._setHoverState.bind(this, false)}
-					>
-						<div>
-							<i style={{ fontSize: 15 }} className="zmdi zmdi-copy" />
-						</div>
-						{this.props.callToAction && <div className="pl1">{this.props.callToAction}</div>}
-					</div>
-				</CopyToClipboard>
-				<ReactTooltip id="copy">Copied!</ReactTooltip>
-			</div>
-		);
-	}
-	private _setRefToProperty(el: HTMLInputElement) {
-		this._copyable = el;
-	}
-	private _setHoverState(isHovering: boolean) {
-		this.setState({
-			isHovering,
-		});
-	}
-	private _onCopy() {
-		if (this._copyTooltipTimeoutId) {
-			clearInterval(this._copyTooltipTimeoutId);
-		}
+    private _copyTooltipTimeoutId: number;
+    private _copyable: HTMLInputElement;
+    constructor(props: CopyIconProps) {
+        super(props);
+        this.state = {
+            isHovering: false,
+        };
+    }
+    public componentDidUpdate() {
+        // Remove tooltip if hover away
+        if (!this.state.isHovering && this._copyTooltipTimeoutId) {
+            clearInterval(this._copyTooltipTimeoutId);
+            this._hideTooltip();
+        }
+    }
+    public render() {
+        return (
+            <div className="inline-block">
+                <CopyToClipboard text={this.props.data} onCopy={this._onCopy.bind(this)}>
+                    <div
+                        className="inline flex"
+                        style={{ cursor: 'pointer', color: colors.amber600 }}
+                        ref={this._setRefToProperty.bind(this)}
+                        data-tip={true}
+                        data-for="copy"
+                        data-event="click"
+                        data-iscapture={true} // This let's the click event continue to propogate
+                        onMouseOver={this._setHoverState.bind(this, true)}
+                        onMouseOut={this._setHoverState.bind(this, false)}
+                    >
+                        <div>
+                            <i style={{ fontSize: 15 }} className="zmdi zmdi-copy" />
+                        </div>
+                        {this.props.callToAction && <div className="pl1">{this.props.callToAction}</div>}
+                    </div>
+                </CopyToClipboard>
+                <ReactTooltip id="copy">Copied!</ReactTooltip>
+            </div>
+        );
+    }
+    private _setRefToProperty(el: HTMLInputElement) {
+        this._copyable = el;
+    }
+    private _setHoverState(isHovering: boolean) {
+        this.setState({
+            isHovering,
+        });
+    }
+    private _onCopy() {
+        if (this._copyTooltipTimeoutId) {
+            clearInterval(this._copyTooltipTimeoutId);
+        }
 
-		const tooltipLifespanMs = 1000;
-		this._copyTooltipTimeoutId = window.setTimeout(() => {
-			this._hideTooltip();
-		}, tooltipLifespanMs);
-	}
-	private _hideTooltip() {
-		ReactTooltip.hide(ReactDOM.findDOMNode(this._copyable));
-	}
+        const tooltipLifespanMs = 1000;
+        this._copyTooltipTimeoutId = window.setTimeout(() => {
+            this._hideTooltip();
+        }, tooltipLifespanMs);
+    }
+    private _hideTooltip() {
+        ReactTooltip.hide(ReactDOM.findDOMNode(this._copyable));
+    }
 }
diff --git a/packages/website/ts/components/ui/drop_down_menu_item.tsx b/packages/website/ts/components/ui/drop_down_menu_item.tsx
index 64f88f318..a578fb4f9 100644
--- a/packages/website/ts/components/ui/drop_down_menu_item.tsx
+++ b/packages/website/ts/components/ui/drop_down_menu_item.tsx
@@ -6,99 +6,99 @@ import { colors } from 'ts/utils/colors';
 
 const CHECK_CLOSE_POPOVER_INTERVAL_MS = 300;
 const DEFAULT_STYLE = {
-	fontSize: 14,
+    fontSize: 14,
 };
 
 interface DropDownMenuItemProps {
-	title: string;
-	subMenuItems: React.ReactNode[];
-	style?: React.CSSProperties;
-	menuItemStyle?: React.CSSProperties;
-	isNightVersion?: boolean;
+    title: string;
+    subMenuItems: React.ReactNode[];
+    style?: React.CSSProperties;
+    menuItemStyle?: React.CSSProperties;
+    isNightVersion?: boolean;
 }
 
 interface DropDownMenuItemState {
-	isDropDownOpen: boolean;
-	anchorEl?: HTMLInputElement;
+    isDropDownOpen: boolean;
+    anchorEl?: HTMLInputElement;
 }
 
 export class DropDownMenuItem extends React.Component<DropDownMenuItemProps, DropDownMenuItemState> {
-	public static defaultProps: Partial<DropDownMenuItemProps> = {
-		style: DEFAULT_STYLE,
-		menuItemStyle: DEFAULT_STYLE,
-		isNightVersion: false,
-	};
-	private _isHovering: boolean;
-	private _popoverCloseCheckIntervalId: number;
-	constructor(props: DropDownMenuItemProps) {
-		super(props);
-		this.state = {
-			isDropDownOpen: false,
-		};
-	}
-	public componentDidMount() {
-		this._popoverCloseCheckIntervalId = window.setInterval(() => {
-			this._checkIfShouldClosePopover();
-		}, CHECK_CLOSE_POPOVER_INTERVAL_MS);
-	}
-	public componentWillUnmount() {
-		window.clearInterval(this._popoverCloseCheckIntervalId);
-	}
-	public render() {
-		const colorStyle = this.props.isNightVersion ? 'white' : this.props.style.color;
-		return (
-			<div
-				style={{ ...this.props.style, color: colorStyle }}
-				onMouseEnter={this._onHover.bind(this)}
-				onMouseLeave={this._onHoverOff.bind(this)}
-			>
-				<div className="flex relative">
-					<div style={{ paddingRight: 10 }}>{this.props.title}</div>
-					<div className="absolute" style={{ paddingLeft: 3, right: 3, top: -2 }}>
-						<i className="zmdi zmdi-caret-right" style={{ fontSize: 22 }} />
-					</div>
-				</div>
-				<Popover
-					open={this.state.isDropDownOpen}
-					anchorEl={this.state.anchorEl}
-					anchorOrigin={{ horizontal: 'middle', vertical: 'bottom' }}
-					targetOrigin={{ horizontal: 'middle', vertical: 'top' }}
-					onRequestClose={this._closePopover.bind(this)}
-					useLayerForClickAway={false}
-				>
-					<div onMouseEnter={this._onHover.bind(this)} onMouseLeave={this._onHoverOff.bind(this)}>
-						<Menu style={{ color: colors.grey }}>{this.props.subMenuItems}</Menu>
-					</div>
-				</Popover>
-			</div>
-		);
-	}
-	private _onHover(event: React.FormEvent<HTMLInputElement>) {
-		this._isHovering = true;
-		this._checkIfShouldOpenPopover(event);
-	}
-	private _checkIfShouldOpenPopover(event: React.FormEvent<HTMLInputElement>) {
-		if (this.state.isDropDownOpen) {
-			return; // noop
-		}
+    public static defaultProps: Partial<DropDownMenuItemProps> = {
+        style: DEFAULT_STYLE,
+        menuItemStyle: DEFAULT_STYLE,
+        isNightVersion: false,
+    };
+    private _isHovering: boolean;
+    private _popoverCloseCheckIntervalId: number;
+    constructor(props: DropDownMenuItemProps) {
+        super(props);
+        this.state = {
+            isDropDownOpen: false,
+        };
+    }
+    public componentDidMount() {
+        this._popoverCloseCheckIntervalId = window.setInterval(() => {
+            this._checkIfShouldClosePopover();
+        }, CHECK_CLOSE_POPOVER_INTERVAL_MS);
+    }
+    public componentWillUnmount() {
+        window.clearInterval(this._popoverCloseCheckIntervalId);
+    }
+    public render() {
+        const colorStyle = this.props.isNightVersion ? 'white' : this.props.style.color;
+        return (
+            <div
+                style={{ ...this.props.style, color: colorStyle }}
+                onMouseEnter={this._onHover.bind(this)}
+                onMouseLeave={this._onHoverOff.bind(this)}
+            >
+                <div className="flex relative">
+                    <div style={{ paddingRight: 10 }}>{this.props.title}</div>
+                    <div className="absolute" style={{ paddingLeft: 3, right: 3, top: -2 }}>
+                        <i className="zmdi zmdi-caret-right" style={{ fontSize: 22 }} />
+                    </div>
+                </div>
+                <Popover
+                    open={this.state.isDropDownOpen}
+                    anchorEl={this.state.anchorEl}
+                    anchorOrigin={{ horizontal: 'middle', vertical: 'bottom' }}
+                    targetOrigin={{ horizontal: 'middle', vertical: 'top' }}
+                    onRequestClose={this._closePopover.bind(this)}
+                    useLayerForClickAway={false}
+                >
+                    <div onMouseEnter={this._onHover.bind(this)} onMouseLeave={this._onHoverOff.bind(this)}>
+                        <Menu style={{ color: colors.grey }}>{this.props.subMenuItems}</Menu>
+                    </div>
+                </Popover>
+            </div>
+        );
+    }
+    private _onHover(event: React.FormEvent<HTMLInputElement>) {
+        this._isHovering = true;
+        this._checkIfShouldOpenPopover(event);
+    }
+    private _checkIfShouldOpenPopover(event: React.FormEvent<HTMLInputElement>) {
+        if (this.state.isDropDownOpen) {
+            return; // noop
+        }
 
-		this.setState({
-			isDropDownOpen: true,
-			anchorEl: event.currentTarget,
-		});
-	}
-	private _onHoverOff(event: React.FormEvent<HTMLInputElement>) {
-		this._isHovering = false;
-	}
-	private _checkIfShouldClosePopover() {
-		if (!this.state.isDropDownOpen || this._isHovering) {
-			return; // noop
-		}
-		this._closePopover();
-	}
-	private _closePopover() {
-		this.setState({
-			isDropDownOpen: false,
-		});
-	}
+        this.setState({
+            isDropDownOpen: true,
+            anchorEl: event.currentTarget,
+        });
+    }
+    private _onHoverOff(event: React.FormEvent<HTMLInputElement>) {
+        this._isHovering = false;
+    }
+    private _checkIfShouldClosePopover() {
+        if (!this.state.isDropDownOpen || this._isHovering) {
+            return; // noop
+        }
+        this._closePopover();
+    }
+    private _closePopover() {
+        this.setState({
+            isDropDownOpen: false,
+        });
+    }
 }
diff --git a/packages/website/ts/components/ui/ethereum_address.tsx b/packages/website/ts/components/ui/ethereum_address.tsx
index ba51135be..b75d97e39 100644
--- a/packages/website/ts/components/ui/ethereum_address.tsx
+++ b/packages/website/ts/components/ui/ethereum_address.tsx
@@ -5,26 +5,26 @@ import { EtherscanLinkSuffixes } from 'ts/types';
 import { utils } from 'ts/utils/utils';
 
 interface EthereumAddressProps {
-	address: string;
-	networkId: number;
+    address: string;
+    networkId: number;
 }
 
 export const EthereumAddress = (props: EthereumAddressProps) => {
-	const tooltipId = `${props.address}-ethereum-address`;
-	const truncatedAddress = utils.getAddressBeginAndEnd(props.address);
-	return (
-		<div>
-			<div className="inline" style={{ fontSize: 13 }} data-tip={true} data-for={tooltipId}>
-				{truncatedAddress}
-			</div>
-			<div className="pl1 inline">
-				<EtherScanIcon
-					addressOrTxHash={props.address}
-					networkId={props.networkId}
-					etherscanLinkSuffixes={EtherscanLinkSuffixes.Address}
-				/>
-			</div>
-			<ReactTooltip id={tooltipId}>{props.address}</ReactTooltip>
-		</div>
-	);
+    const tooltipId = `${props.address}-ethereum-address`;
+    const truncatedAddress = utils.getAddressBeginAndEnd(props.address);
+    return (
+        <div>
+            <div className="inline" style={{ fontSize: 13 }} data-tip={true} data-for={tooltipId}>
+                {truncatedAddress}
+            </div>
+            <div className="pl1 inline">
+                <EtherScanIcon
+                    addressOrTxHash={props.address}
+                    networkId={props.networkId}
+                    etherscanLinkSuffixes={EtherscanLinkSuffixes.Address}
+                />
+            </div>
+            <ReactTooltip id={tooltipId}>{props.address}</ReactTooltip>
+        </div>
+    );
 };
diff --git a/packages/website/ts/components/ui/etherscan_icon.tsx b/packages/website/ts/components/ui/etherscan_icon.tsx
index 5b224c3e1..3b17bd0fa 100644
--- a/packages/website/ts/components/ui/etherscan_icon.tsx
+++ b/packages/website/ts/components/ui/etherscan_icon.tsx
@@ -6,36 +6,36 @@ import { colors } from 'ts/utils/colors';
 import { utils } from 'ts/utils/utils';
 
 interface EtherScanIconProps {
-	addressOrTxHash: string;
-	etherscanLinkSuffixes: EtherscanLinkSuffixes;
-	networkId: number;
+    addressOrTxHash: string;
+    etherscanLinkSuffixes: EtherscanLinkSuffixes;
+    networkId: number;
 }
 
 export const EtherScanIcon = (props: EtherScanIconProps) => {
-	const etherscanLinkIfExists = utils.getEtherScanLinkIfExists(
-		props.addressOrTxHash,
-		props.networkId,
-		EtherscanLinkSuffixes.Address,
-	);
-	const transactionTooltipId = `${props.addressOrTxHash}-etherscan-icon-tooltip`;
-	return (
-		<div className="inline">
-			{!_.isUndefined(etherscanLinkIfExists) ? (
-				<a href={etherscanLinkIfExists} target="_blank">
-					{renderIcon()}
-				</a>
-			) : (
-				<div className="inline" data-tip={true} data-for={transactionTooltipId}>
-					{renderIcon()}
-					<ReactTooltip id={transactionTooltipId}>
-						Your network (id: {props.networkId}) is not supported by Etherscan
-					</ReactTooltip>
-				</div>
-			)}
-		</div>
-	);
+    const etherscanLinkIfExists = utils.getEtherScanLinkIfExists(
+        props.addressOrTxHash,
+        props.networkId,
+        EtherscanLinkSuffixes.Address,
+    );
+    const transactionTooltipId = `${props.addressOrTxHash}-etherscan-icon-tooltip`;
+    return (
+        <div className="inline">
+            {!_.isUndefined(etherscanLinkIfExists) ? (
+                <a href={etherscanLinkIfExists} target="_blank">
+                    {renderIcon()}
+                </a>
+            ) : (
+                <div className="inline" data-tip={true} data-for={transactionTooltipId}>
+                    {renderIcon()}
+                    <ReactTooltip id={transactionTooltipId}>
+                        Your network (id: {props.networkId}) is not supported by Etherscan
+                    </ReactTooltip>
+                </div>
+            )}
+        </div>
+    );
 };
 
 function renderIcon() {
-	return <i style={{ color: colors.amber600 }} className="zmdi zmdi-open-in-new" />;
+    return <i style={{ color: colors.amber600 }} className="zmdi zmdi-open-in-new" />;
 }
diff --git a/packages/website/ts/components/ui/fake_text_field.tsx b/packages/website/ts/components/ui/fake_text_field.tsx
index 6d321bb46..f3d9410f6 100644
--- a/packages/website/ts/components/ui/fake_text_field.tsx
+++ b/packages/website/ts/components/ui/fake_text_field.tsx
@@ -3,32 +3,32 @@ import { InputLabel } from 'ts/components/ui/input_label';
 import { Styles } from 'ts/types';
 
 const styles: Styles = {
-	hr: {
-		borderBottom: '1px solid rgb(224, 224, 224)',
-		borderLeft: 'none rgb(224, 224, 224)',
-		borderRight: 'none rgb(224, 224, 224)',
-		borderTop: 'none rgb(224, 224, 224)',
-		bottom: 6,
-		boxSizing: 'content-box',
-		margin: 0,
-		position: 'absolute',
-		width: '100%',
-	},
+    hr: {
+        borderBottom: '1px solid rgb(224, 224, 224)',
+        borderLeft: 'none rgb(224, 224, 224)',
+        borderRight: 'none rgb(224, 224, 224)',
+        borderTop: 'none rgb(224, 224, 224)',
+        bottom: 6,
+        boxSizing: 'content-box',
+        margin: 0,
+        position: 'absolute',
+        width: '100%',
+    },
 };
 
 interface FakeTextFieldProps {
-	label?: React.ReactNode | string;
-	children?: any;
+    label?: React.ReactNode | string;
+    children?: any;
 }
 
 export function FakeTextField(props: FakeTextFieldProps) {
-	return (
-		<div className="relative">
-			{props.label !== '' && <InputLabel text={props.label} />}
-			<div className="pb2" style={{ height: 23 }}>
-				{props.children}
-			</div>
-			<hr style={styles.hr} />
-		</div>
-	);
+    return (
+        <div className="relative">
+            {props.label !== '' && <InputLabel text={props.label} />}
+            <div className="pb2" style={{ height: 23 }}>
+                {props.children}
+            </div>
+            <hr style={styles.hr} />
+        </div>
+    );
 }
diff --git a/packages/website/ts/components/ui/flash_message.tsx b/packages/website/ts/components/ui/flash_message.tsx
index 57a66d21f..2cb1fc764 100644
--- a/packages/website/ts/components/ui/flash_message.tsx
+++ b/packages/website/ts/components/ui/flash_message.tsx
@@ -6,35 +6,35 @@ import { Dispatcher } from 'ts/redux/dispatcher';
 const SHOW_DURATION_MS = 4000;
 
 interface FlashMessageProps {
-	dispatcher: Dispatcher;
-	flashMessage?: string | React.ReactNode;
-	showDurationMs?: number;
-	bodyStyle?: React.CSSProperties;
+    dispatcher: Dispatcher;
+    flashMessage?: string | React.ReactNode;
+    showDurationMs?: number;
+    bodyStyle?: React.CSSProperties;
 }
 
 interface FlashMessageState {}
 
 export class FlashMessage extends React.Component<FlashMessageProps, FlashMessageState> {
-	public static defaultProps: Partial<FlashMessageProps> = {
-		showDurationMs: SHOW_DURATION_MS,
-		bodyStyle: {},
-	};
-	public render() {
-		if (!_.isUndefined(this.props.flashMessage)) {
-			return (
-				<Snackbar
-					open={true}
-					message={this.props.flashMessage}
-					autoHideDuration={this.props.showDurationMs}
-					onRequestClose={this._onClose.bind(this)}
-					bodyStyle={this.props.bodyStyle}
-				/>
-			);
-		} else {
-			return null;
-		}
-	}
-	private _onClose() {
-		this.props.dispatcher.hideFlashMessage();
-	}
+    public static defaultProps: Partial<FlashMessageProps> = {
+        showDurationMs: SHOW_DURATION_MS,
+        bodyStyle: {},
+    };
+    public render() {
+        if (!_.isUndefined(this.props.flashMessage)) {
+            return (
+                <Snackbar
+                    open={true}
+                    message={this.props.flashMessage}
+                    autoHideDuration={this.props.showDurationMs}
+                    onRequestClose={this._onClose.bind(this)}
+                    bodyStyle={this.props.bodyStyle}
+                />
+            );
+        } else {
+            return null;
+        }
+    }
+    private _onClose() {
+        this.props.dispatcher.hideFlashMessage();
+    }
 }
diff --git a/packages/website/ts/components/ui/help_tooltip.tsx b/packages/website/ts/components/ui/help_tooltip.tsx
index c946a70cb..d827eebb9 100644
--- a/packages/website/ts/components/ui/help_tooltip.tsx
+++ b/packages/website/ts/components/ui/help_tooltip.tsx
@@ -2,21 +2,21 @@ import * as React from 'react';
 import ReactTooltip = require('react-tooltip');
 
 interface HelpTooltipProps {
-	style?: React.CSSProperties;
-	explanation: React.ReactNode;
+    style?: React.CSSProperties;
+    explanation: React.ReactNode;
 }
 
 export const HelpTooltip = (props: HelpTooltipProps) => {
-	return (
-		<div
-			style={{ ...props.style }}
-			className="inline-block"
-			data-tip={props.explanation}
-			data-for="helpTooltip"
-			data-multiline={true}
-		>
-			<i style={{ fontSize: 16 }} className="zmdi zmdi-help" />
-			<ReactTooltip id="helpTooltip" />
-		</div>
-	);
+    return (
+        <div
+            style={{ ...props.style }}
+            className="inline-block"
+            data-tip={props.explanation}
+            data-for="helpTooltip"
+            data-multiline={true}
+        >
+            <i style={{ fontSize: 16 }} className="zmdi zmdi-help" />
+            <ReactTooltip id="helpTooltip" />
+        </div>
+    );
 };
diff --git a/packages/website/ts/components/ui/identicon.tsx b/packages/website/ts/components/ui/identicon.tsx
index bad7a657d..bad6c2a78 100644
--- a/packages/website/ts/components/ui/identicon.tsx
+++ b/packages/website/ts/components/ui/identicon.tsx
@@ -4,45 +4,45 @@ import * as React from 'react';
 import { constants } from 'ts/utils/constants';
 
 interface IdenticonProps {
-	address: string;
-	diameter: number;
-	style?: React.CSSProperties;
+    address: string;
+    diameter: number;
+    style?: React.CSSProperties;
 }
 
 interface IdenticonState {}
 
 export class Identicon extends React.Component<IdenticonProps, IdenticonState> {
-	public static defaultProps: Partial<IdenticonProps> = {
-		style: {},
-	};
-	public render() {
-		let address = this.props.address;
-		if (_.isEmpty(address)) {
-			address = constants.NULL_ADDRESS;
-		}
-		const diameter = this.props.diameter;
-		const icon = blockies({
-			seed: address.toLowerCase(),
-		});
-		return (
-			<div
-				className="circle mx-auto relative transitionFix"
-				style={{
-					width: diameter,
-					height: diameter,
-					overflow: 'hidden',
-					...this.props.style,
-				}}
-			>
-				<img
-					src={icon.toDataURL()}
-					style={{
-						width: diameter,
-						height: diameter,
-						imageRendering: 'pixelated',
-					}}
-				/>
-			</div>
-		);
-	}
+    public static defaultProps: Partial<IdenticonProps> = {
+        style: {},
+    };
+    public render() {
+        let address = this.props.address;
+        if (_.isEmpty(address)) {
+            address = constants.NULL_ADDRESS;
+        }
+        const diameter = this.props.diameter;
+        const icon = blockies({
+            seed: address.toLowerCase(),
+        });
+        return (
+            <div
+                className="circle mx-auto relative transitionFix"
+                style={{
+                    width: diameter,
+                    height: diameter,
+                    overflow: 'hidden',
+                    ...this.props.style,
+                }}
+            >
+                <img
+                    src={icon.toDataURL()}
+                    style={{
+                        width: diameter,
+                        height: diameter,
+                        imageRendering: 'pixelated',
+                    }}
+                />
+            </div>
+        );
+    }
 }
diff --git a/packages/website/ts/components/ui/input_label.tsx b/packages/website/ts/components/ui/input_label.tsx
index 1cbda6692..e2009ad20 100644
--- a/packages/website/ts/components/ui/input_label.tsx
+++ b/packages/website/ts/components/ui/input_label.tsx
@@ -2,24 +2,24 @@ import * as React from 'react';
 import { colors } from 'ts/utils/colors';
 
 export interface InputLabelProps {
-	text: string | Element | React.ReactNode;
+    text: string | Element | React.ReactNode;
 }
 
 const styles = {
-	label: {
-		color: colors.grey,
-		fontSize: 12,
-		pointerEvents: 'none',
-		textAlign: 'left',
-		transform: 'scale(0.75) translate(0px, -28px)',
-		transformOrigin: 'left top 0px',
-		transition: 'all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms',
-		userSelect: 'none',
-		width: 240,
-		zIndex: 1,
-	},
+    label: {
+        color: colors.grey,
+        fontSize: 12,
+        pointerEvents: 'none',
+        textAlign: 'left',
+        transform: 'scale(0.75) translate(0px, -28px)',
+        transformOrigin: 'left top 0px',
+        transition: 'all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms',
+        userSelect: 'none',
+        width: 240,
+        zIndex: 1,
+    },
 };
 
 export const InputLabel = (props: InputLabelProps) => {
-	return <label style={styles.label}>{props.text}</label>;
+    return <label style={styles.label}>{props.text}</label>;
 };
diff --git a/packages/website/ts/components/ui/lifecycle_raised_button.tsx b/packages/website/ts/components/ui/lifecycle_raised_button.tsx
index fd23912f1..8ff856a75 100644
--- a/packages/website/ts/components/ui/lifecycle_raised_button.tsx
+++ b/packages/website/ts/components/ui/lifecycle_raised_button.tsx
@@ -7,97 +7,97 @@ import { utils } from 'ts/utils/utils';
 const COMPLETE_STATE_SHOW_LENGTH_MS = 2000;
 
 enum ButtonState {
-	READY,
-	LOADING,
-	COMPLETE,
+    READY,
+    LOADING,
+    COMPLETE,
 }
 
 interface LifeCycleRaisedButtonProps {
-	isHidden?: boolean;
-	isDisabled?: boolean;
-	isPrimary?: boolean;
-	labelReady: React.ReactNode | string;
-	labelLoading: React.ReactNode | string;
-	labelComplete: React.ReactNode | string;
-	onClickAsyncFn: () => Promise<boolean>;
-	backgroundColor?: string;
-	labelColor?: string;
+    isHidden?: boolean;
+    isDisabled?: boolean;
+    isPrimary?: boolean;
+    labelReady: React.ReactNode | string;
+    labelLoading: React.ReactNode | string;
+    labelComplete: React.ReactNode | string;
+    onClickAsyncFn: () => Promise<boolean>;
+    backgroundColor?: string;
+    labelColor?: string;
 }
 
 interface LifeCycleRaisedButtonState {
-	buttonState: ButtonState;
+    buttonState: ButtonState;
 }
 
 export class LifeCycleRaisedButton extends React.Component<LifeCycleRaisedButtonProps, LifeCycleRaisedButtonState> {
-	public static defaultProps: Partial<LifeCycleRaisedButtonProps> = {
-		isDisabled: false,
-		backgroundColor: colors.white,
-		labelColor: colors.darkGrey,
-	};
-	private _buttonTimeoutId: number;
-	private _didUnmount: boolean;
-	constructor(props: LifeCycleRaisedButtonProps) {
-		super(props);
-		this.state = {
-			buttonState: ButtonState.READY,
-		};
-	}
-	public componentWillUnmount() {
-		clearTimeout(this._buttonTimeoutId);
-		this._didUnmount = true;
-	}
-	public render() {
-		if (this.props.isHidden) {
-			return <span />;
-		}
+    public static defaultProps: Partial<LifeCycleRaisedButtonProps> = {
+        isDisabled: false,
+        backgroundColor: colors.white,
+        labelColor: colors.darkGrey,
+    };
+    private _buttonTimeoutId: number;
+    private _didUnmount: boolean;
+    constructor(props: LifeCycleRaisedButtonProps) {
+        super(props);
+        this.state = {
+            buttonState: ButtonState.READY,
+        };
+    }
+    public componentWillUnmount() {
+        clearTimeout(this._buttonTimeoutId);
+        this._didUnmount = true;
+    }
+    public render() {
+        if (this.props.isHidden) {
+            return <span />;
+        }
 
-		let label;
-		switch (this.state.buttonState) {
-			case ButtonState.READY:
-				label = this.props.labelReady;
-				break;
-			case ButtonState.LOADING:
-				label = this.props.labelLoading;
-				break;
-			case ButtonState.COMPLETE:
-				label = this.props.labelComplete;
-				break;
-			default:
-				throw utils.spawnSwitchErr('ButtonState', this.state.buttonState);
-		}
-		return (
-			<RaisedButton
-				primary={this.props.isPrimary}
-				label={label}
-				style={{ width: '100%' }}
-				backgroundColor={this.props.backgroundColor}
-				labelColor={this.props.labelColor}
-				onTouchTap={this.onClickAsync.bind(this)}
-				disabled={this.props.isDisabled || this.state.buttonState !== ButtonState.READY}
-			/>
-		);
-	}
-	public async onClickAsync() {
-		this.setState({
-			buttonState: ButtonState.LOADING,
-		});
-		const didSucceed = await this.props.onClickAsyncFn();
-		if (this._didUnmount) {
-			return; // noop since unmount called before async callback returned.
-		}
-		if (didSucceed) {
-			this.setState({
-				buttonState: ButtonState.COMPLETE,
-			});
-			this._buttonTimeoutId = window.setTimeout(() => {
-				this.setState({
-					buttonState: ButtonState.READY,
-				});
-			}, COMPLETE_STATE_SHOW_LENGTH_MS);
-		} else {
-			this.setState({
-				buttonState: ButtonState.READY,
-			});
-		}
-	}
+        let label;
+        switch (this.state.buttonState) {
+            case ButtonState.READY:
+                label = this.props.labelReady;
+                break;
+            case ButtonState.LOADING:
+                label = this.props.labelLoading;
+                break;
+            case ButtonState.COMPLETE:
+                label = this.props.labelComplete;
+                break;
+            default:
+                throw utils.spawnSwitchErr('ButtonState', this.state.buttonState);
+        }
+        return (
+            <RaisedButton
+                primary={this.props.isPrimary}
+                label={label}
+                style={{ width: '100%' }}
+                backgroundColor={this.props.backgroundColor}
+                labelColor={this.props.labelColor}
+                onTouchTap={this.onClickAsync.bind(this)}
+                disabled={this.props.isDisabled || this.state.buttonState !== ButtonState.READY}
+            />
+        );
+    }
+    public async onClickAsync() {
+        this.setState({
+            buttonState: ButtonState.LOADING,
+        });
+        const didSucceed = await this.props.onClickAsyncFn();
+        if (this._didUnmount) {
+            return; // noop since unmount called before async callback returned.
+        }
+        if (didSucceed) {
+            this.setState({
+                buttonState: ButtonState.COMPLETE,
+            });
+            this._buttonTimeoutId = window.setTimeout(() => {
+                this.setState({
+                    buttonState: ButtonState.READY,
+                });
+            }, COMPLETE_STATE_SHOW_LENGTH_MS);
+        } else {
+            this.setState({
+                buttonState: ButtonState.READY,
+            });
+        }
+    }
 }
diff --git a/packages/website/ts/components/ui/loading.tsx b/packages/website/ts/components/ui/loading.tsx
index e9bfe3316..aa319e9e9 100644
--- a/packages/website/ts/components/ui/loading.tsx
+++ b/packages/website/ts/components/ui/loading.tsx
@@ -10,30 +10,30 @@ interface LoadingProps {}
 interface LoadingState {}
 
 export class Loading extends React.Component<LoadingProps, LoadingState> {
-	public render() {
-		return (
-			<div className="pt4 sm-px2 sm-pt2 sm-m1" style={{ height: 500 }}>
-				<Paper className="mx-auto" style={{ maxWidth: 400 }}>
-					{utils.isUserOnMobile() ? (
-						<img className="p1" src="/gifs/0xAnimation.gif" width="96%" />
-					) : (
-						<div style={{ pointerEvents: 'none' }}>
-							<Video
-								autoPlay={true}
-								loop={true}
-								muted={true}
-								controls={[]}
-								poster="/images/loading_poster.png"
-							>
-								<source src="/videos/0xAnimation.mp4" type="video/mp4" />
-							</Video>
-						</div>
-					)}
-					<div className="center pt2" style={{ paddingBottom: 11 }}>
-						Connecting to the blockchain...
-					</div>
-				</Paper>
-			</div>
-		);
-	}
+    public render() {
+        return (
+            <div className="pt4 sm-px2 sm-pt2 sm-m1" style={{ height: 500 }}>
+                <Paper className="mx-auto" style={{ maxWidth: 400 }}>
+                    {utils.isUserOnMobile() ? (
+                        <img className="p1" src="/gifs/0xAnimation.gif" width="96%" />
+                    ) : (
+                        <div style={{ pointerEvents: 'none' }}>
+                            <Video
+                                autoPlay={true}
+                                loop={true}
+                                muted={true}
+                                controls={[]}
+                                poster="/images/loading_poster.png"
+                            >
+                                <source src="/videos/0xAnimation.mp4" type="video/mp4" />
+                            </Video>
+                        </div>
+                    )}
+                    <div className="center pt2" style={{ paddingBottom: 11 }}>
+                        Connecting to the blockchain...
+                    </div>
+                </Paper>
+            </div>
+        );
+    }
 }
diff --git a/packages/website/ts/components/ui/menu_item.tsx b/packages/website/ts/components/ui/menu_item.tsx
index 956b5eae8..3482f436c 100644
--- a/packages/website/ts/components/ui/menu_item.tsx
+++ b/packages/website/ts/components/ui/menu_item.tsx
@@ -3,49 +3,49 @@ import * as React from 'react';
 import { Link } from 'react-router-dom';
 
 interface MenuItemProps {
-	to: string;
-	style?: React.CSSProperties;
-	onClick?: () => void;
-	className?: string;
+    to: string;
+    style?: React.CSSProperties;
+    onClick?: () => void;
+    className?: string;
 }
 
 interface MenuItemState {
-	isHovering: boolean;
+    isHovering: boolean;
 }
 
 export class MenuItem extends React.Component<MenuItemProps, MenuItemState> {
-	public static defaultProps: Partial<MenuItemProps> = {
-		onClick: _.noop,
-		className: '',
-	};
-	public constructor(props: MenuItemProps) {
-		super(props);
-		this.state = {
-			isHovering: false,
-		};
-	}
-	public render() {
-		const menuItemStyles = {
-			cursor: 'pointer',
-			opacity: this.state.isHovering ? 0.5 : 1,
-		};
-		return (
-			<Link to={this.props.to} style={{ textDecoration: 'none', ...this.props.style }}>
-				<div
-					onClick={this.props.onClick.bind(this)}
-					className={`mx-auto ${this.props.className}`}
-					style={menuItemStyles}
-					onMouseEnter={this._onToggleHover.bind(this, true)}
-					onMouseLeave={this._onToggleHover.bind(this, false)}
-				>
-					{this.props.children}
-				</div>
-			</Link>
-		);
-	}
-	private _onToggleHover(isHovering: boolean) {
-		this.setState({
-			isHovering,
-		});
-	}
+    public static defaultProps: Partial<MenuItemProps> = {
+        onClick: _.noop,
+        className: '',
+    };
+    public constructor(props: MenuItemProps) {
+        super(props);
+        this.state = {
+            isHovering: false,
+        };
+    }
+    public render() {
+        const menuItemStyles = {
+            cursor: 'pointer',
+            opacity: this.state.isHovering ? 0.5 : 1,
+        };
+        return (
+            <Link to={this.props.to} style={{ textDecoration: 'none', ...this.props.style }}>
+                <div
+                    onClick={this.props.onClick.bind(this)}
+                    className={`mx-auto ${this.props.className}`}
+                    style={menuItemStyles}
+                    onMouseEnter={this._onToggleHover.bind(this, true)}
+                    onMouseLeave={this._onToggleHover.bind(this, false)}
+                >
+                    {this.props.children}
+                </div>
+            </Link>
+        );
+    }
+    private _onToggleHover(isHovering: boolean) {
+        this.setState({
+            isHovering,
+        });
+    }
 }
diff --git a/packages/website/ts/components/ui/party.tsx b/packages/website/ts/components/ui/party.tsx
index ef3c7b425..ca2577b61 100644
--- a/packages/website/ts/components/ui/party.tsx
+++ b/packages/website/ts/components/ui/party.tsx
@@ -11,129 +11,129 @@ const IMAGE_DIMENSION = 100;
 const IDENTICON_DIAMETER = 95;
 
 interface PartyProps {
-	label: string;
-	address: string;
-	networkId: number;
-	alternativeImage?: string;
-	identiconDiameter?: number;
-	identiconStyle?: React.CSSProperties;
-	isInTokenRegistry?: boolean;
-	hasUniqueNameAndSymbol?: boolean;
+    label: string;
+    address: string;
+    networkId: number;
+    alternativeImage?: string;
+    identiconDiameter?: number;
+    identiconStyle?: React.CSSProperties;
+    isInTokenRegistry?: boolean;
+    hasUniqueNameAndSymbol?: boolean;
 }
 
 interface PartyState {}
 
 export class Party extends React.Component<PartyProps, PartyState> {
-	public static defaultProps: Partial<PartyProps> = {
-		identiconStyle: {},
-		identiconDiameter: IDENTICON_DIAMETER,
-	};
-	public render() {
-		const label = this.props.label;
-		const address = this.props.address;
-		const identiconDiameter = this.props.identiconDiameter;
-		const emptyIdenticonStyles = {
-			width: identiconDiameter,
-			height: identiconDiameter,
-			backgroundColor: 'lightgray',
-			marginTop: 13,
-			marginBottom: 10,
-		};
-		const tokenImageStyle = {
-			width: IMAGE_DIMENSION,
-			height: IMAGE_DIMENSION,
-		};
-		const etherscanLinkIfExists = utils.getEtherScanLinkIfExists(
-			this.props.address,
-			this.props.networkId,
-			EtherscanLinkSuffixes.Address,
-		);
-		const isRegistered = this.props.isInTokenRegistry;
-		const registeredTooltipId = `${this.props.address}-${isRegistered}-registeredTooltip`;
-		const uniqueNameAndSymbolTooltipId = `${this.props.address}-${isRegistered}-uniqueTooltip`;
-		return (
-			<div style={{ overflow: 'hidden' }}>
-				<div className="pb1 center">{label}</div>
-				{_.isEmpty(address) ? (
-					<div className="circle mx-auto" style={emptyIdenticonStyles} />
-				) : (
-					<a href={etherscanLinkIfExists} target="_blank">
-						{isRegistered && !_.isUndefined(this.props.alternativeImage) ? (
-							<img style={tokenImageStyle} src={this.props.alternativeImage} />
-						) : (
-							<div className="mx-auto" style={{ height: identiconDiameter, width: identiconDiameter }}>
-								<Identicon
-									address={this.props.address}
-									diameter={identiconDiameter}
-									style={this.props.identiconStyle}
-								/>
-							</div>
-						)}
-					</a>
-				)}
-				<div className="mx-auto center pt1">
-					<div style={{ height: 25 }}>
-						<EthereumAddress address={address} networkId={this.props.networkId} />
-					</div>
-					{!_.isUndefined(this.props.isInTokenRegistry) && (
-						<div>
-							<div
-								data-tip={true}
-								data-for={registeredTooltipId}
-								className="mx-auto"
-								style={{ fontSize: 13, width: 127 }}
-							>
-								<span
-									style={{
-										color: isRegistered ? colors.brightGreen : colors.red500,
-									}}
-								>
-									<i
-										className={`zmdi ${isRegistered ? 'zmdi-check-circle' : 'zmdi-alert-triangle'}`}
-									/>
-								</span>{' '}
-								<span>{isRegistered ? 'Registered' : 'Unregistered'} token</span>
-								<ReactTooltip id={registeredTooltipId}>
-									{isRegistered ? (
-										<div>
-											This token address was found in the token registry<br />
-											smart contract and is therefore believed to be a<br />
-											legitimate token.
-										</div>
-									) : (
-										<div>
-											This token is not included in the token registry<br />
-											smart contract. We cannot guarantee the legitimacy<br />
-											of this token. Make sure to verify its address on Etherscan.
-										</div>
-									)}
-								</ReactTooltip>
-							</div>
-						</div>
-					)}
-					{!_.isUndefined(this.props.hasUniqueNameAndSymbol) &&
-						!this.props.hasUniqueNameAndSymbol && (
-							<div>
-								<div
-									data-tip={true}
-									data-for={uniqueNameAndSymbolTooltipId}
-									className="mx-auto"
-									style={{ fontSize: 13, width: 127 }}
-								>
-									<span style={{ color: colors.red500 }}>
-										<i className="zmdi zmdi-alert-octagon" />
-									</span>{' '}
-									<span>Suspicious token</span>
-									<ReactTooltip id={uniqueNameAndSymbolTooltipId}>
-										This token shares it's name, symbol or both with<br />
-										a token in the 0x Token Registry but it has a different<br />
-										smart contract address. This is most likely a scam token!
-									</ReactTooltip>
-								</div>
-							</div>
-						)}
-				</div>
-			</div>
-		);
-	}
+    public static defaultProps: Partial<PartyProps> = {
+        identiconStyle: {},
+        identiconDiameter: IDENTICON_DIAMETER,
+    };
+    public render() {
+        const label = this.props.label;
+        const address = this.props.address;
+        const identiconDiameter = this.props.identiconDiameter;
+        const emptyIdenticonStyles = {
+            width: identiconDiameter,
+            height: identiconDiameter,
+            backgroundColor: 'lightgray',
+            marginTop: 13,
+            marginBottom: 10,
+        };
+        const tokenImageStyle = {
+            width: IMAGE_DIMENSION,
+            height: IMAGE_DIMENSION,
+        };
+        const etherscanLinkIfExists = utils.getEtherScanLinkIfExists(
+            this.props.address,
+            this.props.networkId,
+            EtherscanLinkSuffixes.Address,
+        );
+        const isRegistered = this.props.isInTokenRegistry;
+        const registeredTooltipId = `${this.props.address}-${isRegistered}-registeredTooltip`;
+        const uniqueNameAndSymbolTooltipId = `${this.props.address}-${isRegistered}-uniqueTooltip`;
+        return (
+            <div style={{ overflow: 'hidden' }}>
+                <div className="pb1 center">{label}</div>
+                {_.isEmpty(address) ? (
+                    <div className="circle mx-auto" style={emptyIdenticonStyles} />
+                ) : (
+                    <a href={etherscanLinkIfExists} target="_blank">
+                        {isRegistered && !_.isUndefined(this.props.alternativeImage) ? (
+                            <img style={tokenImageStyle} src={this.props.alternativeImage} />
+                        ) : (
+                            <div className="mx-auto" style={{ height: identiconDiameter, width: identiconDiameter }}>
+                                <Identicon
+                                    address={this.props.address}
+                                    diameter={identiconDiameter}
+                                    style={this.props.identiconStyle}
+                                />
+                            </div>
+                        )}
+                    </a>
+                )}
+                <div className="mx-auto center pt1">
+                    <div style={{ height: 25 }}>
+                        <EthereumAddress address={address} networkId={this.props.networkId} />
+                    </div>
+                    {!_.isUndefined(this.props.isInTokenRegistry) && (
+                        <div>
+                            <div
+                                data-tip={true}
+                                data-for={registeredTooltipId}
+                                className="mx-auto"
+                                style={{ fontSize: 13, width: 127 }}
+                            >
+                                <span
+                                    style={{
+                                        color: isRegistered ? colors.brightGreen : colors.red500,
+                                    }}
+                                >
+                                    <i
+                                        className={`zmdi ${isRegistered ? 'zmdi-check-circle' : 'zmdi-alert-triangle'}`}
+                                    />
+                                </span>{' '}
+                                <span>{isRegistered ? 'Registered' : 'Unregistered'} token</span>
+                                <ReactTooltip id={registeredTooltipId}>
+                                    {isRegistered ? (
+                                        <div>
+                                            This token address was found in the token registry<br />
+                                            smart contract and is therefore believed to be a<br />
+                                            legitimate token.
+                                        </div>
+                                    ) : (
+                                        <div>
+                                            This token is not included in the token registry<br />
+                                            smart contract. We cannot guarantee the legitimacy<br />
+                                            of this token. Make sure to verify its address on Etherscan.
+                                        </div>
+                                    )}
+                                </ReactTooltip>
+                            </div>
+                        </div>
+                    )}
+                    {!_.isUndefined(this.props.hasUniqueNameAndSymbol) &&
+                        !this.props.hasUniqueNameAndSymbol && (
+                            <div>
+                                <div
+                                    data-tip={true}
+                                    data-for={uniqueNameAndSymbolTooltipId}
+                                    className="mx-auto"
+                                    style={{ fontSize: 13, width: 127 }}
+                                >
+                                    <span style={{ color: colors.red500 }}>
+                                        <i className="zmdi zmdi-alert-octagon" />
+                                    </span>{' '}
+                                    <span>Suspicious token</span>
+                                    <ReactTooltip id={uniqueNameAndSymbolTooltipId}>
+                                        This token shares it's name, symbol or both with<br />
+                                        a token in the 0x Token Registry but it has a different<br />
+                                        smart contract address. This is most likely a scam token!
+                                    </ReactTooltip>
+                                </div>
+                            </div>
+                        )}
+                </div>
+            </div>
+        );
+    }
 }
diff --git a/packages/website/ts/components/ui/required_label.tsx b/packages/website/ts/components/ui/required_label.tsx
index 638683427..a5e7a22ce 100644
--- a/packages/website/ts/components/ui/required_label.tsx
+++ b/packages/website/ts/components/ui/required_label.tsx
@@ -2,14 +2,14 @@ import * as React from 'react';
 import { colors } from 'ts/utils/colors';
 
 export interface RequiredLabelProps {
-	label: string | React.ReactNode;
+    label: string | React.ReactNode;
 }
 
 export const RequiredLabel = (props: RequiredLabelProps) => {
-	return (
-		<span>
-			{props.label}
-			<span style={{ color: colors.red600 }}>*</span>
-		</span>
-	);
+    return (
+        <span>
+            {props.label}
+            <span style={{ color: colors.red600 }}>*</span>
+        </span>
+    );
 };
diff --git a/packages/website/ts/components/ui/simple_loading.tsx b/packages/website/ts/components/ui/simple_loading.tsx
index 9f1fd5a13..81744196d 100644
--- a/packages/website/ts/components/ui/simple_loading.tsx
+++ b/packages/website/ts/components/ui/simple_loading.tsx
@@ -2,16 +2,16 @@ import CircularProgress from 'material-ui/CircularProgress';
 import * as React from 'react';
 
 export interface SimpleLoadingProps {
-	message: string;
+    message: string;
 }
 
 export const SimpleLoading = (props: SimpleLoadingProps) => {
-	return (
-		<div className="mx-auto pt3" style={{ maxWidth: 400, height: 409 }}>
-			<div className="relative" style={{ top: '50%', transform: 'translateY(-50%)', height: 95 }}>
-				<CircularProgress />
-				<div className="pt3 pb3">{props.message}</div>
-			</div>
-		</div>
-	);
+    return (
+        <div className="mx-auto pt3" style={{ maxWidth: 400, height: 409 }}>
+            <div className="relative" style={{ top: '50%', transform: 'translateY(-50%)', height: 95 }}>
+                <CircularProgress />
+                <div className="pt3 pb3">{props.message}</div>
+            </div>
+        </div>
+    );
 };
diff --git a/packages/website/ts/components/ui/swap_icon.tsx b/packages/website/ts/components/ui/swap_icon.tsx
index 99e3450de..c41592287 100644
--- a/packages/website/ts/components/ui/swap_icon.tsx
+++ b/packages/website/ts/components/ui/swap_icon.tsx
@@ -3,40 +3,40 @@ import * as React from 'react';
 import { colors } from 'ts/utils/colors';
 
 interface SwapIconProps {
-	swapTokensFn: () => void;
+    swapTokensFn: () => void;
 }
 
 interface SwapIconState {
-	isHovering: boolean;
+    isHovering: boolean;
 }
 
 export class SwapIcon extends React.Component<SwapIconProps, SwapIconState> {
-	public constructor(props: SwapIconProps) {
-		super(props);
-		this.state = {
-			isHovering: false,
-		};
-	}
-	public render() {
-		const swapStyles = {
-			color: this.state.isHovering ? colors.amber600 : colors.amber800,
-			fontSize: 50,
-		};
-		return (
-			<div
-				className="mx-auto pt4"
-				style={{ cursor: 'pointer', height: 50, width: 37.5 }}
-				onClick={this.props.swapTokensFn}
-				onMouseEnter={this._onToggleHover.bind(this, true)}
-				onMouseLeave={this._onToggleHover.bind(this, false)}
-			>
-				<i style={swapStyles} className="zmdi zmdi-swap" />
-			</div>
-		);
-	}
-	private _onToggleHover(isHovering: boolean) {
-		this.setState({
-			isHovering,
-		});
-	}
+    public constructor(props: SwapIconProps) {
+        super(props);
+        this.state = {
+            isHovering: false,
+        };
+    }
+    public render() {
+        const swapStyles = {
+            color: this.state.isHovering ? colors.amber600 : colors.amber800,
+            fontSize: 50,
+        };
+        return (
+            <div
+                className="mx-auto pt4"
+                style={{ cursor: 'pointer', height: 50, width: 37.5 }}
+                onClick={this.props.swapTokensFn}
+                onMouseEnter={this._onToggleHover.bind(this, true)}
+                onMouseLeave={this._onToggleHover.bind(this, false)}
+            >
+                <i style={swapStyles} className="zmdi zmdi-swap" />
+            </div>
+        );
+    }
+    private _onToggleHover(isHovering: boolean) {
+        this.setState({
+            isHovering,
+        });
+    }
 }
diff --git a/packages/website/ts/components/ui/token_icon.tsx b/packages/website/ts/components/ui/token_icon.tsx
index a729821ce..ff57a96de 100644
--- a/packages/website/ts/components/ui/token_icon.tsx
+++ b/packages/website/ts/components/ui/token_icon.tsx
@@ -4,24 +4,24 @@ import { Identicon } from 'ts/components/ui/identicon';
 import { Token } from 'ts/types';
 
 interface TokenIconProps {
-	token: Token;
-	diameter: number;
+    token: Token;
+    diameter: number;
 }
 
 interface TokenIconState {}
 
 export class TokenIcon extends React.Component<TokenIconProps, TokenIconState> {
-	public render() {
-		const token = this.props.token;
-		const diameter = this.props.diameter;
-		return (
-			<div>
-				{token.isRegistered && !_.isUndefined(token.iconUrl) ? (
-					<img style={{ width: diameter, height: diameter }} src={token.iconUrl} />
-				) : (
-					<Identicon address={token.address} diameter={diameter} />
-				)}
-			</div>
-		);
-	}
+    public render() {
+        const token = this.props.token;
+        const diameter = this.props.diameter;
+        return (
+            <div>
+                {token.isRegistered && !_.isUndefined(token.iconUrl) ? (
+                    <img style={{ width: diameter, height: diameter }} src={token.iconUrl} />
+                ) : (
+                    <Identicon address={token.address} diameter={diameter} />
+                )}
+            </div>
+        );
+    }
 }
diff --git a/packages/website/ts/components/visual_order.tsx b/packages/website/ts/components/visual_order.tsx
index a9779ac62..092954086 100644
--- a/packages/website/ts/components/visual_order.tsx
+++ b/packages/website/ts/components/visual_order.tsx
@@ -8,69 +8,69 @@ import { utils } from 'ts/utils/utils';
 const PRECISION = 5;
 
 interface VisualOrderProps {
-	orderTakerAddress: string;
-	orderMakerAddress: string;
-	makerAssetToken: AssetToken;
-	takerAssetToken: AssetToken;
-	makerToken: Token;
-	takerToken: Token;
-	networkId: number;
-	tokenByAddress: TokenByAddress;
-	isMakerTokenAddressInRegistry: boolean;
-	isTakerTokenAddressInRegistry: boolean;
+    orderTakerAddress: string;
+    orderMakerAddress: string;
+    makerAssetToken: AssetToken;
+    takerAssetToken: AssetToken;
+    makerToken: Token;
+    takerToken: Token;
+    networkId: number;
+    tokenByAddress: TokenByAddress;
+    isMakerTokenAddressInRegistry: boolean;
+    isTakerTokenAddressInRegistry: boolean;
 }
 
 interface VisualOrderState {}
 
 export class VisualOrder extends React.Component<VisualOrderProps, VisualOrderState> {
-	public render() {
-		const allTokens = _.values(this.props.tokenByAddress);
-		const makerImage = this.props.makerToken.iconUrl;
-		const takerImage = this.props.takerToken.iconUrl;
-		return (
-			<div>
-				<div className="clearfix">
-					<div className="col col-5 center">
-						<Party
-							label="Send"
-							address={this.props.takerToken.address}
-							alternativeImage={takerImage}
-							networkId={this.props.networkId}
-							isInTokenRegistry={this.props.isTakerTokenAddressInRegistry}
-							hasUniqueNameAndSymbol={utils.hasUniqueNameAndSymbol(allTokens, this.props.takerToken)}
-						/>
-					</div>
-					<div className="col col-2 center pt1">
-						<div className="pb1">
-							{this._renderAmount(this.props.takerAssetToken, this.props.takerToken)}
-						</div>
-						<div className="lg-p2 md-p2 sm-p1">
-							<img src="/images/trade_arrows.png" style={{ width: 47 }} />
-						</div>
-						<div className="pt1">
-							{this._renderAmount(this.props.makerAssetToken, this.props.makerToken)}
-						</div>
-					</div>
-					<div className="col col-5 center">
-						<Party
-							label="Receive"
-							address={this.props.makerToken.address}
-							alternativeImage={makerImage}
-							networkId={this.props.networkId}
-							isInTokenRegistry={this.props.isMakerTokenAddressInRegistry}
-							hasUniqueNameAndSymbol={utils.hasUniqueNameAndSymbol(allTokens, this.props.makerToken)}
-						/>
-					</div>
-				</div>
-			</div>
-		);
-	}
-	private _renderAmount(assetToken: AssetToken, token: Token) {
-		const unitAmount = ZeroEx.toUnitAmount(assetToken.amount, token.decimals);
-		return (
-			<div style={{ fontSize: 13 }}>
-				{unitAmount.toNumber().toFixed(PRECISION)} {token.symbol}
-			</div>
-		);
-	}
+    public render() {
+        const allTokens = _.values(this.props.tokenByAddress);
+        const makerImage = this.props.makerToken.iconUrl;
+        const takerImage = this.props.takerToken.iconUrl;
+        return (
+            <div>
+                <div className="clearfix">
+                    <div className="col col-5 center">
+                        <Party
+                            label="Send"
+                            address={this.props.takerToken.address}
+                            alternativeImage={takerImage}
+                            networkId={this.props.networkId}
+                            isInTokenRegistry={this.props.isTakerTokenAddressInRegistry}
+                            hasUniqueNameAndSymbol={utils.hasUniqueNameAndSymbol(allTokens, this.props.takerToken)}
+                        />
+                    </div>
+                    <div className="col col-2 center pt1">
+                        <div className="pb1">
+                            {this._renderAmount(this.props.takerAssetToken, this.props.takerToken)}
+                        </div>
+                        <div className="lg-p2 md-p2 sm-p1">
+                            <img src="/images/trade_arrows.png" style={{ width: 47 }} />
+                        </div>
+                        <div className="pt1">
+                            {this._renderAmount(this.props.makerAssetToken, this.props.makerToken)}
+                        </div>
+                    </div>
+                    <div className="col col-5 center">
+                        <Party
+                            label="Receive"
+                            address={this.props.makerToken.address}
+                            alternativeImage={makerImage}
+                            networkId={this.props.networkId}
+                            isInTokenRegistry={this.props.isMakerTokenAddressInRegistry}
+                            hasUniqueNameAndSymbol={utils.hasUniqueNameAndSymbol(allTokens, this.props.makerToken)}
+                        />
+                    </div>
+                </div>
+            </div>
+        );
+    }
+    private _renderAmount(assetToken: AssetToken, token: Token) {
+        const unitAmount = ZeroEx.toUnitAmount(assetToken.amount, token.decimals);
+        return (
+            <div style={{ fontSize: 13 }}>
+                {unitAmount.toNumber().toFixed(PRECISION)} {token.symbol}
+            </div>
+        );
+    }
 }
diff --git a/packages/website/ts/containers/connect_documentation.tsx b/packages/website/ts/containers/connect_documentation.tsx
index 2f5326d57..3e02a7d05 100644
--- a/packages/website/ts/containers/connect_documentation.tsx
+++ b/packages/website/ts/containers/connect_documentation.tsx
@@ -16,81 +16,81 @@ const InstallationMarkdown = require('md/docs/connect/installation');
 /* tslint:enable:no-var-requires */
 
 const connectDocSections = {
-	introduction: 'introduction',
-	installation: 'installation',
-	httpClient: 'httpClient',
-	webSocketOrderbookChannel: 'webSocketOrderbookChannel',
-	types: constants.TYPES_SECTION_NAME,
+    introduction: 'introduction',
+    installation: 'installation',
+    httpClient: 'httpClient',
+    webSocketOrderbookChannel: 'webSocketOrderbookChannel',
+    types: constants.TYPES_SECTION_NAME,
 };
 
 const docsInfoConfig: DocsInfoConfig = {
-	displayName: '0x Connect',
-	subPackageName: 'connect',
-	packageUrl: 'https://github.com/0xProject/0x.js',
-	websitePath: WebsitePaths.Connect,
-	docsJsonRoot: 'https://s3.amazonaws.com/connect-docs-jsons',
-	menu: {
-		introduction: [connectDocSections.introduction],
-		install: [connectDocSections.installation],
-		httpClient: [connectDocSections.httpClient],
-		webSocketOrderbookChannel: [connectDocSections.webSocketOrderbookChannel],
-		types: [connectDocSections.types],
-	},
-	sectionNameToMarkdown: {
-		[connectDocSections.introduction]: IntroMarkdown,
-		[connectDocSections.installation]: InstallationMarkdown,
-	},
-	// Note: This needs to be kept in sync with the types exported in index.ts. Unfortunately there is
-	// currently no way to extract the re-exported types from index.ts via TypeDoc :(
-	publicTypes: [
-		'Client',
-		'FeesRequest',
-		'FeesResponse',
-		'OrderbookChannel',
-		'OrderbookChannelHandler',
-		'OrderbookChannelSubscriptionOpts',
-		'OrderbookRequest',
-		'OrderbookResponse',
-		'OrdersRequest',
-		'TokenPairsItem',
-		'TokenPairsRequest',
-		'TokenTradeInfo',
-		'Order',
-		'SignedOrder',
-		'ECSignature',
-	],
-	sectionNameToModulePath: {
-		[connectDocSections.httpClient]: ['"src/http_client"'],
-		[connectDocSections.webSocketOrderbookChannel]: ['"src/ws_orderbook_channel"'],
-		[connectDocSections.types]: ['"src/types"'],
-	},
-	menuSubsectionToVersionWhenIntroduced: {},
-	sections: connectDocSections,
-	visibleConstructors: [connectDocSections.httpClient, connectDocSections.webSocketOrderbookChannel],
-	convertToDocAgnosticFormatFn: typeDocUtils.convertToDocAgnosticFormat.bind(typeDocUtils),
+    displayName: '0x Connect',
+    subPackageName: 'connect',
+    packageUrl: 'https://github.com/0xProject/0x.js',
+    websitePath: WebsitePaths.Connect,
+    docsJsonRoot: 'https://s3.amazonaws.com/connect-docs-jsons',
+    menu: {
+        introduction: [connectDocSections.introduction],
+        install: [connectDocSections.installation],
+        httpClient: [connectDocSections.httpClient],
+        webSocketOrderbookChannel: [connectDocSections.webSocketOrderbookChannel],
+        types: [connectDocSections.types],
+    },
+    sectionNameToMarkdown: {
+        [connectDocSections.introduction]: IntroMarkdown,
+        [connectDocSections.installation]: InstallationMarkdown,
+    },
+    // Note: This needs to be kept in sync with the types exported in index.ts. Unfortunately there is
+    // currently no way to extract the re-exported types from index.ts via TypeDoc :(
+    publicTypes: [
+        'Client',
+        'FeesRequest',
+        'FeesResponse',
+        'OrderbookChannel',
+        'OrderbookChannelHandler',
+        'OrderbookChannelSubscriptionOpts',
+        'OrderbookRequest',
+        'OrderbookResponse',
+        'OrdersRequest',
+        'TokenPairsItem',
+        'TokenPairsRequest',
+        'TokenTradeInfo',
+        'Order',
+        'SignedOrder',
+        'ECSignature',
+    ],
+    sectionNameToModulePath: {
+        [connectDocSections.httpClient]: ['"src/http_client"'],
+        [connectDocSections.webSocketOrderbookChannel]: ['"src/ws_orderbook_channel"'],
+        [connectDocSections.types]: ['"src/types"'],
+    },
+    menuSubsectionToVersionWhenIntroduced: {},
+    sections: connectDocSections,
+    visibleConstructors: [connectDocSections.httpClient, connectDocSections.webSocketOrderbookChannel],
+    convertToDocAgnosticFormatFn: typeDocUtils.convertToDocAgnosticFormat.bind(typeDocUtils),
 };
 const docsInfo = new DocsInfo(docsInfoConfig);
 
 interface ConnectedState {
-	docsVersion: string;
-	availableDocVersions: string[];
-	docsInfo: DocsInfo;
+    docsVersion: string;
+    availableDocVersions: string[];
+    docsInfo: DocsInfo;
 }
 
 interface ConnectedDispatch {
-	dispatcher: Dispatcher;
+    dispatcher: Dispatcher;
 }
 
 const mapStateToProps = (state: State, ownProps: DocumentationAllProps): ConnectedState => ({
-	docsVersion: state.docsVersion,
-	availableDocVersions: state.availableDocVersions,
-	docsInfo,
+    docsVersion: state.docsVersion,
+    availableDocVersions: state.availableDocVersions,
+    docsInfo,
 });
 
 const mapDispatchToProps = (dispatch: Dispatch<State>): ConnectedDispatch => ({
-	dispatcher: new Dispatcher(dispatch),
+    dispatcher: new Dispatcher(dispatch),
 });
 
 export const Documentation: React.ComponentClass<DocumentationAllProps> = connect(mapStateToProps, mapDispatchToProps)(
-	DocumentationComponent,
+    DocumentationComponent,
 );
diff --git a/packages/website/ts/containers/generate_order_form.tsx b/packages/website/ts/containers/generate_order_form.tsx
index c2b781557..3fd31087f 100644
--- a/packages/website/ts/containers/generate_order_form.tsx
+++ b/packages/website/ts/containers/generate_order_form.tsx
@@ -7,48 +7,48 @@ import { GenerateOrderForm as GenerateOrderFormComponent } from 'ts/components/g
 import { Dispatcher } from 'ts/redux/dispatcher';
 import { State } from 'ts/redux/reducer';
 import {
-	BlockchainErrs,
-	HashData,
-	SideToAssetToken,
-	SignatureData,
-	TokenByAddress,
-	TokenStateByAddress,
+    BlockchainErrs,
+    HashData,
+    SideToAssetToken,
+    SignatureData,
+    TokenByAddress,
+    TokenStateByAddress,
 } from 'ts/types';
 
 interface GenerateOrderFormProps {
-	blockchain: Blockchain;
-	hashData: HashData;
-	dispatcher: Dispatcher;
+    blockchain: Blockchain;
+    hashData: HashData;
+    dispatcher: Dispatcher;
 }
 
 interface ConnectedState {
-	blockchainErr: BlockchainErrs;
-	blockchainIsLoaded: boolean;
-	orderExpiryTimestamp: BigNumber;
-	orderSignatureData: SignatureData;
-	userAddress: string;
-	orderTakerAddress: string;
-	orderSalt: BigNumber;
-	networkId: number;
-	sideToAssetToken: SideToAssetToken;
-	tokenByAddress: TokenByAddress;
-	tokenStateByAddress: TokenStateByAddress;
+    blockchainErr: BlockchainErrs;
+    blockchainIsLoaded: boolean;
+    orderExpiryTimestamp: BigNumber;
+    orderSignatureData: SignatureData;
+    userAddress: string;
+    orderTakerAddress: string;
+    orderSalt: BigNumber;
+    networkId: number;
+    sideToAssetToken: SideToAssetToken;
+    tokenByAddress: TokenByAddress;
+    tokenStateByAddress: TokenStateByAddress;
 }
 
 const mapStateToProps = (state: State, ownProps: GenerateOrderFormProps): ConnectedState => ({
-	blockchainErr: state.blockchainErr,
-	blockchainIsLoaded: state.blockchainIsLoaded,
-	orderExpiryTimestamp: state.orderExpiryTimestamp,
-	orderSignatureData: state.orderSignatureData,
-	orderTakerAddress: state.orderTakerAddress,
-	orderSalt: state.orderSalt,
-	networkId: state.networkId,
-	sideToAssetToken: state.sideToAssetToken,
-	tokenByAddress: state.tokenByAddress,
-	tokenStateByAddress: state.tokenStateByAddress,
-	userAddress: state.userAddress,
+    blockchainErr: state.blockchainErr,
+    blockchainIsLoaded: state.blockchainIsLoaded,
+    orderExpiryTimestamp: state.orderExpiryTimestamp,
+    orderSignatureData: state.orderSignatureData,
+    orderTakerAddress: state.orderTakerAddress,
+    orderSalt: state.orderSalt,
+    networkId: state.networkId,
+    sideToAssetToken: state.sideToAssetToken,
+    tokenByAddress: state.tokenByAddress,
+    tokenStateByAddress: state.tokenStateByAddress,
+    userAddress: state.userAddress,
 });
 
 export const GenerateOrderForm: React.ComponentClass<GenerateOrderFormProps> = connect(mapStateToProps)(
-	GenerateOrderFormComponent,
+    GenerateOrderFormComponent,
 );
diff --git a/packages/website/ts/containers/portal.tsx b/packages/website/ts/containers/portal.tsx
index bc7aa213c..f0247935b 100644
--- a/packages/website/ts/containers/portal.tsx
+++ b/packages/website/ts/containers/portal.tsx
@@ -10,72 +10,72 @@ import { BlockchainErrs, HashData, Order, ScreenWidths, Side, TokenByAddress, To
 import { constants } from 'ts/utils/constants';
 
 interface ConnectedState {
-	blockchainErr: BlockchainErrs;
-	blockchainIsLoaded: boolean;
-	hashData: HashData;
-	networkId: number;
-	nodeVersion: string;
-	orderFillAmount: BigNumber;
-	tokenByAddress: TokenByAddress;
-	tokenStateByAddress: TokenStateByAddress;
-	userEtherBalance: BigNumber;
-	screenWidth: ScreenWidths;
-	shouldBlockchainErrDialogBeOpen: boolean;
-	userAddress: string;
-	userSuppliedOrderCache: Order;
-	flashMessage?: string | React.ReactNode;
+    blockchainErr: BlockchainErrs;
+    blockchainIsLoaded: boolean;
+    hashData: HashData;
+    networkId: number;
+    nodeVersion: string;
+    orderFillAmount: BigNumber;
+    tokenByAddress: TokenByAddress;
+    tokenStateByAddress: TokenStateByAddress;
+    userEtherBalance: BigNumber;
+    screenWidth: ScreenWidths;
+    shouldBlockchainErrDialogBeOpen: boolean;
+    userAddress: string;
+    userSuppliedOrderCache: Order;
+    flashMessage?: string | React.ReactNode;
 }
 
 interface ConnectedDispatch {
-	dispatcher: Dispatcher;
+    dispatcher: Dispatcher;
 }
 
 const mapStateToProps = (state: State, ownProps: PortalComponentAllProps): ConnectedState => {
-	const receiveAssetToken = state.sideToAssetToken[Side.Receive];
-	const depositAssetToken = state.sideToAssetToken[Side.Deposit];
-	const receiveAddress = !_.isUndefined(receiveAssetToken.address)
-		? receiveAssetToken.address
-		: constants.NULL_ADDRESS;
-	const depositAddress = !_.isUndefined(depositAssetToken.address)
-		? depositAssetToken.address
-		: constants.NULL_ADDRESS;
-	const receiveAmount = !_.isUndefined(receiveAssetToken.amount) ? receiveAssetToken.amount : new BigNumber(0);
-	const depositAmount = !_.isUndefined(depositAssetToken.amount) ? depositAssetToken.amount : new BigNumber(0);
-	const hashData = {
-		depositAmount,
-		depositTokenContractAddr: depositAddress,
-		feeRecipientAddress: constants.NULL_ADDRESS,
-		makerFee: constants.MAKER_FEE,
-		orderExpiryTimestamp: state.orderExpiryTimestamp,
-		orderMakerAddress: state.userAddress,
-		orderTakerAddress: state.orderTakerAddress !== '' ? state.orderTakerAddress : constants.NULL_ADDRESS,
-		receiveAmount,
-		receiveTokenContractAddr: receiveAddress,
-		takerFee: constants.TAKER_FEE,
-		orderSalt: state.orderSalt,
-	};
-	return {
-		blockchainErr: state.blockchainErr,
-		blockchainIsLoaded: state.blockchainIsLoaded,
-		networkId: state.networkId,
-		nodeVersion: state.nodeVersion,
-		orderFillAmount: state.orderFillAmount,
-		hashData,
-		screenWidth: state.screenWidth,
-		shouldBlockchainErrDialogBeOpen: state.shouldBlockchainErrDialogBeOpen,
-		tokenByAddress: state.tokenByAddress,
-		tokenStateByAddress: state.tokenStateByAddress,
-		userAddress: state.userAddress,
-		userEtherBalance: state.userEtherBalance,
-		userSuppliedOrderCache: state.userSuppliedOrderCache,
-		flashMessage: state.flashMessage,
-	};
+    const receiveAssetToken = state.sideToAssetToken[Side.Receive];
+    const depositAssetToken = state.sideToAssetToken[Side.Deposit];
+    const receiveAddress = !_.isUndefined(receiveAssetToken.address)
+        ? receiveAssetToken.address
+        : constants.NULL_ADDRESS;
+    const depositAddress = !_.isUndefined(depositAssetToken.address)
+        ? depositAssetToken.address
+        : constants.NULL_ADDRESS;
+    const receiveAmount = !_.isUndefined(receiveAssetToken.amount) ? receiveAssetToken.amount : new BigNumber(0);
+    const depositAmount = !_.isUndefined(depositAssetToken.amount) ? depositAssetToken.amount : new BigNumber(0);
+    const hashData = {
+        depositAmount,
+        depositTokenContractAddr: depositAddress,
+        feeRecipientAddress: constants.NULL_ADDRESS,
+        makerFee: constants.MAKER_FEE,
+        orderExpiryTimestamp: state.orderExpiryTimestamp,
+        orderMakerAddress: state.userAddress,
+        orderTakerAddress: state.orderTakerAddress !== '' ? state.orderTakerAddress : constants.NULL_ADDRESS,
+        receiveAmount,
+        receiveTokenContractAddr: receiveAddress,
+        takerFee: constants.TAKER_FEE,
+        orderSalt: state.orderSalt,
+    };
+    return {
+        blockchainErr: state.blockchainErr,
+        blockchainIsLoaded: state.blockchainIsLoaded,
+        networkId: state.networkId,
+        nodeVersion: state.nodeVersion,
+        orderFillAmount: state.orderFillAmount,
+        hashData,
+        screenWidth: state.screenWidth,
+        shouldBlockchainErrDialogBeOpen: state.shouldBlockchainErrDialogBeOpen,
+        tokenByAddress: state.tokenByAddress,
+        tokenStateByAddress: state.tokenStateByAddress,
+        userAddress: state.userAddress,
+        userEtherBalance: state.userEtherBalance,
+        userSuppliedOrderCache: state.userSuppliedOrderCache,
+        flashMessage: state.flashMessage,
+    };
 };
 
 const mapDispatchToProps = (dispatch: Dispatch<State>): ConnectedDispatch => ({
-	dispatcher: new Dispatcher(dispatch),
+    dispatcher: new Dispatcher(dispatch),
 });
 
 export const Portal: React.ComponentClass<PortalComponentAllProps> = connect(mapStateToProps, mapDispatchToProps)(
-	PortalComponent,
+    PortalComponent,
 );
diff --git a/packages/website/ts/containers/smart_contracts_documentation.tsx b/packages/website/ts/containers/smart_contracts_documentation.tsx
index addfd1af9..8be33b546 100644
--- a/packages/website/ts/containers/smart_contracts_documentation.tsx
+++ b/packages/website/ts/containers/smart_contracts_documentation.tsx
@@ -14,49 +14,49 @@ const IntroMarkdown = require('md/docs/smart_contracts/introduction');
 /* tslint:enable:no-var-requires */
 
 const docsInfoConfig: DocsInfoConfig = {
-	displayName: '0x Smart Contracts',
-	packageUrl: 'https://github.com/0xProject/contracts',
-	websitePath: WebsitePaths.SmartContracts,
-	docsJsonRoot: 'https://s3.amazonaws.com/smart-contracts-docs-json',
-	menu: {
-		introduction: [Sections.Introduction],
-		contracts: [Sections.Exchange, Sections.TokenRegistry, Sections.ZRXToken, Sections.TokenTransferProxy],
-	},
-	sectionNameToMarkdown: {
-		[Sections.Introduction]: IntroMarkdown,
-	},
-	sections: {
-		Introduction: Sections.Introduction,
-		Exchange: Sections.Exchange,
-		TokenTransferProxy: Sections.TokenTransferProxy,
-		TokenRegistry: Sections.TokenRegistry,
-		ZRXToken: Sections.ZRXToken,
-	},
-	visibleConstructors: [Sections.Exchange, Sections.TokenRegistry, Sections.ZRXToken, Sections.TokenTransferProxy],
-	convertToDocAgnosticFormatFn: doxityUtils.convertToDocAgnosticFormat.bind(doxityUtils),
+    displayName: '0x Smart Contracts',
+    packageUrl: 'https://github.com/0xProject/contracts',
+    websitePath: WebsitePaths.SmartContracts,
+    docsJsonRoot: 'https://s3.amazonaws.com/smart-contracts-docs-json',
+    menu: {
+        introduction: [Sections.Introduction],
+        contracts: [Sections.Exchange, Sections.TokenRegistry, Sections.ZRXToken, Sections.TokenTransferProxy],
+    },
+    sectionNameToMarkdown: {
+        [Sections.Introduction]: IntroMarkdown,
+    },
+    sections: {
+        Introduction: Sections.Introduction,
+        Exchange: Sections.Exchange,
+        TokenTransferProxy: Sections.TokenTransferProxy,
+        TokenRegistry: Sections.TokenRegistry,
+        ZRXToken: Sections.ZRXToken,
+    },
+    visibleConstructors: [Sections.Exchange, Sections.TokenRegistry, Sections.ZRXToken, Sections.TokenTransferProxy],
+    convertToDocAgnosticFormatFn: doxityUtils.convertToDocAgnosticFormat.bind(doxityUtils),
 };
 const docsInfo = new DocsInfo(docsInfoConfig);
 
 interface ConnectedState {
-	docsVersion: string;
-	availableDocVersions: string[];
+    docsVersion: string;
+    availableDocVersions: string[];
 }
 
 interface ConnectedDispatch {
-	dispatcher: Dispatcher;
-	docsInfo: DocsInfo;
+    dispatcher: Dispatcher;
+    docsInfo: DocsInfo;
 }
 
 const mapStateToProps = (state: State, ownProps: DocumentationAllProps): ConnectedState => ({
-	docsVersion: state.docsVersion,
-	availableDocVersions: state.availableDocVersions,
+    docsVersion: state.docsVersion,
+    availableDocVersions: state.availableDocVersions,
 });
 
 const mapDispatchToProps = (dispatch: Dispatch<State>): ConnectedDispatch => ({
-	dispatcher: new Dispatcher(dispatch),
-	docsInfo,
+    dispatcher: new Dispatcher(dispatch),
+    docsInfo,
 });
 
 export const Documentation: React.ComponentClass<DocumentationAllProps> = connect(mapStateToProps, mapDispatchToProps)(
-	DocumentationComponent,
+    DocumentationComponent,
 );
diff --git a/packages/website/ts/containers/zero_ex_js_documentation.tsx b/packages/website/ts/containers/zero_ex_js_documentation.tsx
index d416cbc12..8ae6a7b73 100644
--- a/packages/website/ts/containers/zero_ex_js_documentation.tsx
+++ b/packages/website/ts/containers/zero_ex_js_documentation.tsx
@@ -19,152 +19,152 @@ const versioningMarkdown = require('md/docs/0xjs/versioning');
 /* tslint:enable:no-var-requires */
 
 const zeroExJsDocSections = {
-	introduction: 'introduction',
-	installation: 'installation',
-	testrpc: 'testrpc',
-	async: 'async',
-	errors: 'errors',
-	versioning: 'versioning',
-	zeroEx: 'zeroEx',
-	exchange: 'exchange',
-	token: 'token',
-	tokenRegistry: 'tokenRegistry',
-	etherToken: 'etherToken',
-	proxy: 'proxy',
-	orderWatcher: 'orderWatcher',
-	types: constants.TYPES_SECTION_NAME,
+    introduction: 'introduction',
+    installation: 'installation',
+    testrpc: 'testrpc',
+    async: 'async',
+    errors: 'errors',
+    versioning: 'versioning',
+    zeroEx: 'zeroEx',
+    exchange: 'exchange',
+    token: 'token',
+    tokenRegistry: 'tokenRegistry',
+    etherToken: 'etherToken',
+    proxy: 'proxy',
+    orderWatcher: 'orderWatcher',
+    types: constants.TYPES_SECTION_NAME,
 };
 
 const docsInfoConfig: DocsInfoConfig = {
-	displayName: '0x.js',
-	packageUrl: 'https://github.com/0xProject/0x.js',
-	subPackageName: '0x.js',
-	websitePath: WebsitePaths.ZeroExJs,
-	docsJsonRoot: 'https://s3.amazonaws.com/0xjs-docs-jsons',
-	menu: {
-		introduction: [zeroExJsDocSections.introduction],
-		install: [zeroExJsDocSections.installation],
-		topics: [zeroExJsDocSections.async, zeroExJsDocSections.errors, zeroExJsDocSections.versioning],
-		zeroEx: [zeroExJsDocSections.zeroEx],
-		contracts: [
-			zeroExJsDocSections.exchange,
-			zeroExJsDocSections.token,
-			zeroExJsDocSections.tokenRegistry,
-			zeroExJsDocSections.etherToken,
-			zeroExJsDocSections.proxy,
-		],
-		orderWatcher: [zeroExJsDocSections.orderWatcher],
-		types: [zeroExJsDocSections.types],
-	},
-	sectionNameToMarkdown: {
-		[zeroExJsDocSections.introduction]: IntroMarkdown,
-		[zeroExJsDocSections.installation]: InstallationMarkdown,
-		[zeroExJsDocSections.async]: AsyncMarkdown,
-		[zeroExJsDocSections.errors]: ErrorsMarkdown,
-		[zeroExJsDocSections.versioning]: versioningMarkdown,
-	},
-	// Note: This needs to be kept in sync with the types exported in index.ts. Unfortunately there is
-	// currently no way to extract the re-exported types from index.ts via TypeDoc :(
-	publicTypes: [
-		'Order',
-		'SignedOrder',
-		'ECSignature',
-		'ZeroExError',
-		'EventCallback',
-		'EventCallbackAsync',
-		'EventCallbackSync',
-		'ExchangeContractErrs',
-		'ContractEvent',
-		'Token',
-		'ExchangeEvents',
-		'IndexedFilterValues',
-		'SubscriptionOpts',
-		'BlockRange',
-		'BlockParam',
-		'OrderFillOrKillRequest',
-		'OrderCancellationRequest',
-		'OrderFillRequest',
-		'ContractEventEmitter',
-		'Web3Provider',
-		'ContractEventArgs',
-		'LogCancelArgs',
-		'LogFillArgs',
-		'LogErrorContractEventArgs',
-		'LogFillContractEventArgs',
-		'LogCancelContractEventArgs',
-		'EtherTokenContractEventArgs',
-		'WithdrawalContractEventArgs',
-		'DepositContractEventArgs',
-		'TokenEvents',
-		'ExchangeContractEventArgs',
-		'TransferContractEventArgs',
-		'ApprovalContractEventArgs',
-		'TokenContractEventArgs',
-		'ZeroExConfig',
-		'TransactionReceiptWithDecodedLogs',
-		'LogWithDecodedArgs',
-		'EtherTokenEvents',
-		'BlockParamLiteral',
-		'DecodedLogArgs',
-		'MethodOpts',
-		'ValidateOrderFillableOpts',
-		'OrderTransactionOpts',
-		'TransactionOpts',
-		'ContractEventArg',
-		'LogEvent',
-		'LogEntry',
-		'DecodedLogEvent',
-		'EventWatcherCallback',
-		'OnOrderStateChangeCallback',
-		'OrderStateValid',
-		'OrderStateInvalid',
-		'OrderState',
-		'FilterObject',
-	],
-	sectionNameToModulePath: {
-		[zeroExJsDocSections.zeroEx]: ['"src/0x"'],
-		[zeroExJsDocSections.exchange]: ['"src/contract_wrappers/exchange_wrapper"'],
-		[zeroExJsDocSections.tokenRegistry]: ['"src/contract_wrappers/token_registry_wrapper"'],
-		[zeroExJsDocSections.token]: ['"src/contract_wrappers/token_wrapper"'],
-		[zeroExJsDocSections.etherToken]: ['"src/contract_wrappers/ether_token_wrapper"'],
-		[zeroExJsDocSections.proxy]: [
-			'"src/contract_wrappers/proxy_wrapper"',
-			'"src/contract_wrappers/token_transfer_proxy_wrapper"',
-		],
-		[zeroExJsDocSections.orderWatcher]: ['"src/order_watcher/order_state_watcher"'],
-		[zeroExJsDocSections.types]: ['"src/types"'],
-	},
-	menuSubsectionToVersionWhenIntroduced: {
-		[zeroExJsDocSections.etherToken]: '0.7.1',
-		[zeroExJsDocSections.proxy]: '0.8.0',
-		[zeroExJsDocSections.orderWatcher]: '0.27.1',
-	},
-	sections: zeroExJsDocSections,
-	visibleConstructors: [zeroExJsDocSections.zeroEx],
-	convertToDocAgnosticFormatFn: typeDocUtils.convertToDocAgnosticFormat.bind(typeDocUtils),
+    displayName: '0x.js',
+    packageUrl: 'https://github.com/0xProject/0x.js',
+    subPackageName: '0x.js',
+    websitePath: WebsitePaths.ZeroExJs,
+    docsJsonRoot: 'https://s3.amazonaws.com/0xjs-docs-jsons',
+    menu: {
+        introduction: [zeroExJsDocSections.introduction],
+        install: [zeroExJsDocSections.installation],
+        topics: [zeroExJsDocSections.async, zeroExJsDocSections.errors, zeroExJsDocSections.versioning],
+        zeroEx: [zeroExJsDocSections.zeroEx],
+        contracts: [
+            zeroExJsDocSections.exchange,
+            zeroExJsDocSections.token,
+            zeroExJsDocSections.tokenRegistry,
+            zeroExJsDocSections.etherToken,
+            zeroExJsDocSections.proxy,
+        ],
+        orderWatcher: [zeroExJsDocSections.orderWatcher],
+        types: [zeroExJsDocSections.types],
+    },
+    sectionNameToMarkdown: {
+        [zeroExJsDocSections.introduction]: IntroMarkdown,
+        [zeroExJsDocSections.installation]: InstallationMarkdown,
+        [zeroExJsDocSections.async]: AsyncMarkdown,
+        [zeroExJsDocSections.errors]: ErrorsMarkdown,
+        [zeroExJsDocSections.versioning]: versioningMarkdown,
+    },
+    // Note: This needs to be kept in sync with the types exported in index.ts. Unfortunately there is
+    // currently no way to extract the re-exported types from index.ts via TypeDoc :(
+    publicTypes: [
+        'Order',
+        'SignedOrder',
+        'ECSignature',
+        'ZeroExError',
+        'EventCallback',
+        'EventCallbackAsync',
+        'EventCallbackSync',
+        'ExchangeContractErrs',
+        'ContractEvent',
+        'Token',
+        'ExchangeEvents',
+        'IndexedFilterValues',
+        'SubscriptionOpts',
+        'BlockRange',
+        'BlockParam',
+        'OrderFillOrKillRequest',
+        'OrderCancellationRequest',
+        'OrderFillRequest',
+        'ContractEventEmitter',
+        'Web3Provider',
+        'ContractEventArgs',
+        'LogCancelArgs',
+        'LogFillArgs',
+        'LogErrorContractEventArgs',
+        'LogFillContractEventArgs',
+        'LogCancelContractEventArgs',
+        'EtherTokenContractEventArgs',
+        'WithdrawalContractEventArgs',
+        'DepositContractEventArgs',
+        'TokenEvents',
+        'ExchangeContractEventArgs',
+        'TransferContractEventArgs',
+        'ApprovalContractEventArgs',
+        'TokenContractEventArgs',
+        'ZeroExConfig',
+        'TransactionReceiptWithDecodedLogs',
+        'LogWithDecodedArgs',
+        'EtherTokenEvents',
+        'BlockParamLiteral',
+        'DecodedLogArgs',
+        'MethodOpts',
+        'ValidateOrderFillableOpts',
+        'OrderTransactionOpts',
+        'TransactionOpts',
+        'ContractEventArg',
+        'LogEvent',
+        'LogEntry',
+        'DecodedLogEvent',
+        'EventWatcherCallback',
+        'OnOrderStateChangeCallback',
+        'OrderStateValid',
+        'OrderStateInvalid',
+        'OrderState',
+        'FilterObject',
+    ],
+    sectionNameToModulePath: {
+        [zeroExJsDocSections.zeroEx]: ['"src/0x"'],
+        [zeroExJsDocSections.exchange]: ['"src/contract_wrappers/exchange_wrapper"'],
+        [zeroExJsDocSections.tokenRegistry]: ['"src/contract_wrappers/token_registry_wrapper"'],
+        [zeroExJsDocSections.token]: ['"src/contract_wrappers/token_wrapper"'],
+        [zeroExJsDocSections.etherToken]: ['"src/contract_wrappers/ether_token_wrapper"'],
+        [zeroExJsDocSections.proxy]: [
+            '"src/contract_wrappers/proxy_wrapper"',
+            '"src/contract_wrappers/token_transfer_proxy_wrapper"',
+        ],
+        [zeroExJsDocSections.orderWatcher]: ['"src/order_watcher/order_state_watcher"'],
+        [zeroExJsDocSections.types]: ['"src/types"'],
+    },
+    menuSubsectionToVersionWhenIntroduced: {
+        [zeroExJsDocSections.etherToken]: '0.7.1',
+        [zeroExJsDocSections.proxy]: '0.8.0',
+        [zeroExJsDocSections.orderWatcher]: '0.27.1',
+    },
+    sections: zeroExJsDocSections,
+    visibleConstructors: [zeroExJsDocSections.zeroEx],
+    convertToDocAgnosticFormatFn: typeDocUtils.convertToDocAgnosticFormat.bind(typeDocUtils),
 };
 const docsInfo = new DocsInfo(docsInfoConfig);
 
 interface ConnectedState {
-	docsVersion: string;
-	availableDocVersions: string[];
-	docsInfo: DocsInfo;
+    docsVersion: string;
+    availableDocVersions: string[];
+    docsInfo: DocsInfo;
 }
 
 interface ConnectedDispatch {
-	dispatcher: Dispatcher;
+    dispatcher: Dispatcher;
 }
 
 const mapStateToProps = (state: State, ownProps: DocumentationAllProps): ConnectedState => ({
-	docsVersion: state.docsVersion,
-	availableDocVersions: state.availableDocVersions,
-	docsInfo,
+    docsVersion: state.docsVersion,
+    availableDocVersions: state.availableDocVersions,
+    docsInfo,
 });
 
 const mapDispatchToProps = (dispatch: Dispatch<State>): ConnectedDispatch => ({
-	dispatcher: new Dispatcher(dispatch),
+    dispatcher: new Dispatcher(dispatch),
 });
 
 export const Documentation: React.ComponentClass<DocumentationAllProps> = connect(mapStateToProps, mapDispatchToProps)(
-	DocumentationComponent,
+    DocumentationComponent,
 );
diff --git a/packages/website/ts/globals.d.ts b/packages/website/ts/globals.d.ts
index 736b23d9d..383e5cbe0 100644
--- a/packages/website/ts/globals.d.ts
+++ b/packages/website/ts/globals.d.ts
@@ -14,10 +14,10 @@ declare module 'ledgerco';
 declare module 'ethereumjs-tx';
 
 declare module '*.json' {
-	const json: any;
-	/* tslint:disable */
-	export default json;
-	/* tslint:enable */
+    const json: any;
+    /* tslint:disable */
+    export default json;
+    /* tslint:enable */
 }
 
 // tslint:disable:max-classes-per-file
@@ -25,137 +25,137 @@ declare module '*.json' {
 // find-version declarations
 declare function findVersions(version: string): string[];
 declare module 'find-versions' {
-	export = findVersions;
+    export = findVersions;
 }
 
 // compare-version declarations
 declare function compareVersions(firstVersion: string, secondVersion: string): number;
 declare module 'compare-versions' {
-	export = compareVersions;
+    export = compareVersions;
 }
 
 // semver-sort declarations
 declare module 'semver-sort' {
-	const desc: (versions: string[]) => string[];
+    const desc: (versions: string[]) => string[];
 }
 
 // xml-js declarations
 declare interface XML2JSONOpts {
-	compact?: boolean;
-	spaces?: number;
+    compact?: boolean;
+    spaces?: number;
 }
 declare module 'xml-js' {
-	const xml2json: (xml: string, opts: XML2JSONOpts) => string;
+    const xml2json: (xml: string, opts: XML2JSONOpts) => string;
 }
 
 // This will be defined by default in TS 2.4
 // Source: https://github.com/Microsoft/TypeScript/issues/12364
 interface System {
-	import<T>(module: string): Promise<T>;
+    import<T>(module: string): Promise<T>;
 }
 declare var System: System;
 
 // jsonschema declarations
 // Source: https://github.com/tdegrunt/jsonschema/blob/master/lib/index.d.ts
 declare interface Schema {
-	id?: string;
-	$schema?: string;
-	title?: string;
-	description?: string;
-	multipleOf?: number;
-	maximum?: number;
-	exclusiveMaximum?: boolean;
-	minimum?: number;
-	exclusiveMinimum?: boolean;
-	maxLength?: number;
-	minLength?: number;
-	pattern?: string;
-	additionalItems?: boolean | Schema;
-	items?: Schema | Schema[];
-	maxItems?: number;
-	minItems?: number;
-	uniqueItems?: boolean;
-	maxProperties?: number;
-	minProperties?: number;
-	required?: string[];
-	additionalProperties?: boolean | Schema;
-	definitions?: {
-		[name: string]: Schema;
-	};
-	properties?: {
-		[name: string]: Schema;
-	};
-	patternProperties?: {
-		[name: string]: Schema;
-	};
-	dependencies?: {
-		[name: string]: Schema | string[];
-	};
-	enum?: any[];
-	type?: string | string[];
-	allOf?: Schema[];
-	anyOf?: Schema[];
-	oneOf?: Schema[];
-	not?: Schema;
-	// This is the only property that's not defined in https://github.com/tdegrunt/jsonschema/blob/master/lib/index.d.ts
-	// There is an open issue for that: https://github.com/tdegrunt/jsonschema/issues/194
-	// There is also an opened PR: https://github.com/tdegrunt/jsonschema/pull/218/files
-	// As soon as it gets merged we should be good to use types from 'jsonschema' package
-	$ref?: string;
+    id?: string;
+    $schema?: string;
+    title?: string;
+    description?: string;
+    multipleOf?: number;
+    maximum?: number;
+    exclusiveMaximum?: boolean;
+    minimum?: number;
+    exclusiveMinimum?: boolean;
+    maxLength?: number;
+    minLength?: number;
+    pattern?: string;
+    additionalItems?: boolean | Schema;
+    items?: Schema | Schema[];
+    maxItems?: number;
+    minItems?: number;
+    uniqueItems?: boolean;
+    maxProperties?: number;
+    minProperties?: number;
+    required?: string[];
+    additionalProperties?: boolean | Schema;
+    definitions?: {
+        [name: string]: Schema;
+    };
+    properties?: {
+        [name: string]: Schema;
+    };
+    patternProperties?: {
+        [name: string]: Schema;
+    };
+    dependencies?: {
+        [name: string]: Schema | string[];
+    };
+    enum?: any[];
+    type?: string | string[];
+    allOf?: Schema[];
+    anyOf?: Schema[];
+    oneOf?: Schema[];
+    not?: Schema;
+    // This is the only property that's not defined in https://github.com/tdegrunt/jsonschema/blob/master/lib/index.d.ts
+    // There is an open issue for that: https://github.com/tdegrunt/jsonschema/issues/194
+    // There is also an opened PR: https://github.com/tdegrunt/jsonschema/pull/218/files
+    // As soon as it gets merged we should be good to use types from 'jsonschema' package
+    $ref?: string;
 }
 
 // blockies declarations
 declare interface BlockiesIcon {
-	toDataURL(): string;
+    toDataURL(): string;
 }
 declare interface BlockiesConfig {
-	seed: string;
+    seed: string;
 }
 declare function blockies(config: BlockiesConfig): BlockiesIcon;
 declare module 'blockies' {
-	export = blockies;
+    export = blockies;
 }
 
 // is-mobile declarations
 declare function isMobile(): boolean;
 declare module 'is-mobile' {
-	export = isMobile;
+    export = isMobile;
 }
 
 // web3-provider-engine declarations
 declare class Subprovider {}
 declare module 'web3-provider-engine/subproviders/subprovider' {
-	export = Subprovider;
+    export = Subprovider;
 }
 declare module 'web3-provider-engine/subproviders/rpc' {
-	import * as Web3 from 'web3';
-	class RpcSubprovider {
-		constructor(options: { rpcUrl: string });
-		public handleRequest(
-			payload: Web3.JSONRPCRequestPayload,
-			next: () => void,
-			end: (err: Error | null, data?: any) => void,
-		): void;
-	}
-	export = RpcSubprovider;
+    import * as Web3 from 'web3';
+    class RpcSubprovider {
+        constructor(options: { rpcUrl: string });
+        public handleRequest(
+            payload: Web3.JSONRPCRequestPayload,
+            next: () => void,
+            end: (err: Error | null, data?: any) => void,
+        ): void;
+    }
+    export = RpcSubprovider;
 }
 declare module 'web3-provider-engine' {
-	class Web3ProviderEngine {
-		public on(event: string, handler: () => void): void;
-		public send(payload: any): void;
-		public sendAsync(payload: any, callback: (error: any, response: any) => void): void;
-		public addProvider(provider: any): void;
-		public start(): void;
-		public stop(): void;
-	}
-	export = Web3ProviderEngine;
+    class Web3ProviderEngine {
+        public on(event: string, handler: () => void): void;
+        public send(payload: any): void;
+        public sendAsync(payload: any, callback: (error: any, response: any) => void): void;
+        public addProvider(provider: any): void;
+        public start(): void;
+        public stop(): void;
+    }
+    export = Web3ProviderEngine;
 }
 
 declare interface Artifact {
-	abi: any;
-	networks: {
-		[networkId: number]: {
-			address: string;
-		};
-	};
+    abi: any;
+    networks: {
+        [networkId: number]: {
+            address: string;
+        };
+    };
 }
diff --git a/packages/website/ts/index.tsx b/packages/website/ts/index.tsx
index df45c80bd..ffb551561 100644
--- a/packages/website/ts/index.tsx
+++ b/packages/website/ts/index.tsx
@@ -32,44 +32,44 @@ import 'less/all.less';
 // At the same time webpack statically parses for System.import() to determine bundle chunk split points
 // so each lazy import needs it's own `System.import()` declaration.
 const LazyPortal = createLazyComponent('Portal', async () =>
-	System.import<any>(/* webpackChunkName: "portal" */ 'ts/containers/portal'),
+    System.import<any>(/* webpackChunkName: "portal" */ 'ts/containers/portal'),
 );
 const LazyZeroExJSDocumentation = createLazyComponent('Documentation', async () =>
-	System.import<any>(/* webpackChunkName: "zeroExDocs" */ 'ts/containers/zero_ex_js_documentation'),
+    System.import<any>(/* webpackChunkName: "zeroExDocs" */ 'ts/containers/zero_ex_js_documentation'),
 );
 const LazySmartContractsDocumentation = createLazyComponent('Documentation', async () =>
-	System.import<any>(/* webpackChunkName: "smartContractDocs" */ 'ts/containers/smart_contracts_documentation'),
+    System.import<any>(/* webpackChunkName: "smartContractDocs" */ 'ts/containers/smart_contracts_documentation'),
 );
 const LazyConnectDocumentation = createLazyComponent('Documentation', async () =>
-	System.import<any>(/* webpackChunkName: "connectDocs" */ 'ts/containers/connect_documentation'),
+    System.import<any>(/* webpackChunkName: "connectDocs" */ 'ts/containers/connect_documentation'),
 );
 
 const store: ReduxStore<State> = createStore(reducer);
 render(
-	<Router>
-		<div>
-			<MuiThemeProvider muiTheme={muiTheme}>
-				<Provider store={store}>
-					<div>
-						<Switch>
-							<Route exact={true} path="/" component={Landing as any} />
-							<Redirect from="/otc" to={`${WebsitePaths.Portal}`} />
-							<Route path={`${WebsitePaths.Portal}`} component={LazyPortal} />
-							<Route path={`${WebsitePaths.FAQ}`} component={FAQ as any} />
-							<Route path={`${WebsitePaths.About}`} component={About as any} />
-							<Route path={`${WebsitePaths.Wiki}`} component={Wiki as any} />
-							<Route path={`${WebsitePaths.ZeroExJs}/:version?`} component={LazyZeroExJSDocumentation} />
-							<Route path={`${WebsitePaths.Connect}/:version?`} component={LazyConnectDocumentation} />
-							<Route
-								path={`${WebsitePaths.SmartContracts}/:version?`}
-								component={LazySmartContractsDocumentation}
-							/>
-							<Route component={NotFound as any} />
-						</Switch>
-					</div>
-				</Provider>
-			</MuiThemeProvider>
-		</div>
-	</Router>,
-	document.getElementById('app'),
+    <Router>
+        <div>
+            <MuiThemeProvider muiTheme={muiTheme}>
+                <Provider store={store}>
+                    <div>
+                        <Switch>
+                            <Route exact={true} path="/" component={Landing as any} />
+                            <Redirect from="/otc" to={`${WebsitePaths.Portal}`} />
+                            <Route path={`${WebsitePaths.Portal}`} component={LazyPortal} />
+                            <Route path={`${WebsitePaths.FAQ}`} component={FAQ as any} />
+                            <Route path={`${WebsitePaths.About}`} component={About as any} />
+                            <Route path={`${WebsitePaths.Wiki}`} component={Wiki as any} />
+                            <Route path={`${WebsitePaths.ZeroExJs}/:version?`} component={LazyZeroExJSDocumentation} />
+                            <Route path={`${WebsitePaths.Connect}/:version?`} component={LazyConnectDocumentation} />
+                            <Route
+                                path={`${WebsitePaths.SmartContracts}/:version?`}
+                                component={LazySmartContractsDocumentation}
+                            />
+                            <Route component={NotFound as any} />
+                        </Switch>
+                    </div>
+                </Provider>
+            </MuiThemeProvider>
+        </div>
+    </Router>,
+    document.getElementById('app'),
 );
diff --git a/packages/website/ts/lazy_component.tsx b/packages/website/ts/lazy_component.tsx
index 5efebb667..48800c2dd 100644
--- a/packages/website/ts/lazy_component.tsx
+++ b/packages/website/ts/lazy_component.tsx
@@ -2,12 +2,12 @@ import * as _ from 'lodash';
 import * as React from 'react';
 
 interface LazyComponentProps {
-	reactComponentPromise: Promise<React.ComponentClass<any>>;
-	reactComponentProps: any;
+    reactComponentPromise: Promise<React.ComponentClass<any>>;
+    reactComponentProps: any;
 }
 
 interface LazyComponentState {
-	component?: React.ComponentClass<any>;
+    component?: React.ComponentClass<any>;
 }
 
 /**
@@ -15,33 +15,33 @@ interface LazyComponentState {
  * Source: https://reacttraining.com/react-router/web/guides/code-splitting
  */
 export class LazyComponent extends React.Component<LazyComponentProps, LazyComponentState> {
-	constructor(props: LazyComponentProps) {
-		super(props);
-		this.state = {
-			component: undefined,
-		};
-	}
-	public componentWillMount() {
-		// tslint:disable-next-line:no-floating-promises
-		this._loadComponentFireAndForgetAsync(this.props);
-	}
-	public componentWillReceiveProps(nextProps: LazyComponentProps) {
-		if (nextProps.reactComponentPromise !== this.props.reactComponentPromise) {
-			// tslint:disable-next-line:no-floating-promises
-			this._loadComponentFireAndForgetAsync(nextProps);
-		}
-	}
-	public render() {
-		return _.isUndefined(this.state.component)
-			? null
-			: React.createElement(this.state.component, this.props.reactComponentProps);
-	}
-	private async _loadComponentFireAndForgetAsync(props: LazyComponentProps) {
-		const component = await props.reactComponentPromise;
-		this.setState({
-			component,
-		});
-	}
+    constructor(props: LazyComponentProps) {
+        super(props);
+        this.state = {
+            component: undefined,
+        };
+    }
+    public componentWillMount() {
+        // tslint:disable-next-line:no-floating-promises
+        this._loadComponentFireAndForgetAsync(this.props);
+    }
+    public componentWillReceiveProps(nextProps: LazyComponentProps) {
+        if (nextProps.reactComponentPromise !== this.props.reactComponentPromise) {
+            // tslint:disable-next-line:no-floating-promises
+            this._loadComponentFireAndForgetAsync(nextProps);
+        }
+    }
+    public render() {
+        return _.isUndefined(this.state.component)
+            ? null
+            : React.createElement(this.state.component, this.props.reactComponentProps);
+    }
+    private async _loadComponentFireAndForgetAsync(props: LazyComponentProps) {
+        const component = await props.reactComponentPromise;
+        this.setState({
+            component,
+        });
+    }
 }
 
 /**
@@ -52,15 +52,15 @@ export class LazyComponent extends React.Component<LazyComponentProps, LazyCompo
  * @example `const LazyPortal = createLazyComponent('Portal', () => System.import<any>('ts/containers/portal'));``
  */
 export const createLazyComponent = (componentName: string, lazyImport: () => Promise<any>) => {
-	return (props: any) => {
-		const reactComponentPromise = (async (): Promise<React.ComponentClass<any>> => {
-			const mod = await lazyImport();
-			const component = mod[componentName];
-			if (_.isUndefined(component)) {
-				throw new Error(`Did not find exported component: ${componentName}`);
-			}
-			return component;
-		})();
-		return <LazyComponent reactComponentPromise={reactComponentPromise} reactComponentProps={props} />;
-	};
+    return (props: any) => {
+        const reactComponentPromise = (async (): Promise<React.ComponentClass<any>> => {
+            const mod = await lazyImport();
+            const component = mod[componentName];
+            if (_.isUndefined(component)) {
+                throw new Error(`Did not find exported component: ${componentName}`);
+            }
+            return component;
+        })();
+        return <LazyComponent reactComponentPromise={reactComponentPromise} reactComponentProps={props} />;
+    };
 };
diff --git a/packages/website/ts/local_storage/local_storage.ts b/packages/website/ts/local_storage/local_storage.ts
index 4e5b77a0a..d94e6877b 100644
--- a/packages/website/ts/local_storage/local_storage.ts
+++ b/packages/website/ts/local_storage/local_storage.ts
@@ -1,35 +1,35 @@
 import * as _ from 'lodash';
 
 export const localStorage = {
-	doesExist() {
-		return !!window.localStorage;
-	},
-	getItemIfExists(key: string): string {
-		if (!this.doesExist) {
-			return undefined;
-		}
-		const item = window.localStorage.getItem(key);
-		if (_.isNull(item) || item === 'undefined') {
-			return '';
-		}
-		return item;
-	},
-	setItem(key: string, value: string) {
-		if (!this.doesExist || _.isUndefined(value)) {
-			return;
-		}
-		window.localStorage.setItem(key, value);
-	},
-	removeItem(key: string) {
-		if (!this.doesExist) {
-			return;
-		}
-		window.localStorage.removeItem(key);
-	},
-	getAllKeys(): string[] {
-		if (!this.doesExist) {
-			return [];
-		}
-		return _.keys(window.localStorage);
-	},
+    doesExist() {
+        return !!window.localStorage;
+    },
+    getItemIfExists(key: string): string {
+        if (!this.doesExist) {
+            return undefined;
+        }
+        const item = window.localStorage.getItem(key);
+        if (_.isNull(item) || item === 'undefined') {
+            return '';
+        }
+        return item;
+    },
+    setItem(key: string, value: string) {
+        if (!this.doesExist || _.isUndefined(value)) {
+            return;
+        }
+        window.localStorage.setItem(key, value);
+    },
+    removeItem(key: string) {
+        if (!this.doesExist) {
+            return;
+        }
+        window.localStorage.removeItem(key);
+    },
+    getAllKeys(): string[] {
+        if (!this.doesExist) {
+            return [];
+        }
+        return _.keys(window.localStorage);
+    },
 };
diff --git a/packages/website/ts/local_storage/tracked_token_storage.ts b/packages/website/ts/local_storage/tracked_token_storage.ts
index 2c62084e0..7733e8436 100644
--- a/packages/website/ts/local_storage/tracked_token_storage.ts
+++ b/packages/website/ts/local_storage/tracked_token_storage.ts
@@ -7,61 +7,61 @@ const TRACKED_TOKENS_KEY = 'trackedTokens';
 const TRACKED_TOKENS_CLEAR_KEY = 'lastClearTrackedTokensDate';
 
 export const trackedTokenStorage = {
-	// Clear trackedTokens localStorage if we've updated the config variable in an update
-	// that introduced a backward incompatible change requiring the tracked tokens to be re-set
-	clearIfRequired(): void {
-		const lastClearFillDate = localStorage.getItemIfExists(TRACKED_TOKENS_CLEAR_KEY);
-		if (lastClearFillDate !== configs.LAST_LOCAL_STORAGE_TRACKED_TOKEN_CLEARANCE_DATE) {
-			localStorage.removeItem(TRACKED_TOKENS_KEY);
-		}
-		localStorage.setItem(TRACKED_TOKENS_CLEAR_KEY, configs.LAST_LOCAL_STORAGE_TRACKED_TOKEN_CLEARANCE_DATE);
-	},
-	addTrackedTokenToUser(userAddress: string, networkId: number, token: Token): void {
-		const trackedTokensByUserAddress = this.getTrackedTokensByUserAddress();
-		let trackedTokensByNetworkId = trackedTokensByUserAddress[userAddress];
-		if (_.isUndefined(trackedTokensByNetworkId)) {
-			trackedTokensByNetworkId = {};
-		}
-		const trackedTokens = !_.isUndefined(trackedTokensByNetworkId[networkId])
-			? trackedTokensByNetworkId[networkId]
-			: [];
-		trackedTokens.push(token);
-		trackedTokensByNetworkId[networkId] = trackedTokens;
-		trackedTokensByUserAddress[userAddress] = trackedTokensByNetworkId;
-		const trackedTokensByUserAddressJSONString = JSON.stringify(trackedTokensByUserAddress);
-		localStorage.setItem(TRACKED_TOKENS_KEY, trackedTokensByUserAddressJSONString);
-	},
-	getTrackedTokensByUserAddress(): TrackedTokensByUserAddress {
-		const trackedTokensJSONString = localStorage.getItemIfExists(TRACKED_TOKENS_KEY);
-		if (_.isEmpty(trackedTokensJSONString)) {
-			return {};
-		}
-		const trackedTokensByUserAddress = JSON.parse(trackedTokensJSONString);
-		return trackedTokensByUserAddress;
-	},
-	getTrackedTokensIfExists(userAddress: string, networkId: number): Token[] {
-		const trackedTokensJSONString = localStorage.getItemIfExists(TRACKED_TOKENS_KEY);
-		if (_.isEmpty(trackedTokensJSONString)) {
-			return undefined;
-		}
-		const trackedTokensByUserAddress = JSON.parse(trackedTokensJSONString);
-		const trackedTokensByNetworkId = trackedTokensByUserAddress[userAddress];
-		if (_.isUndefined(trackedTokensByNetworkId)) {
-			return undefined;
-		}
-		const trackedTokens = trackedTokensByNetworkId[networkId];
-		return trackedTokens;
-	},
-	removeTrackedToken(userAddress: string, networkId: number, tokenAddress: string): void {
-		const trackedTokensByUserAddress = this.getTrackedTokensByUserAddress();
-		const trackedTokensByNetworkId = trackedTokensByUserAddress[userAddress];
-		const trackedTokens = trackedTokensByNetworkId[networkId];
-		const remainingTrackedTokens = _.filter(trackedTokens, (token: Token) => {
-			return token.address !== tokenAddress;
-		});
-		trackedTokensByNetworkId[networkId] = remainingTrackedTokens;
-		trackedTokensByUserAddress[userAddress] = trackedTokensByNetworkId;
-		const trackedTokensByUserAddressJSONString = JSON.stringify(trackedTokensByUserAddress);
-		localStorage.setItem(TRACKED_TOKENS_KEY, trackedTokensByUserAddressJSONString);
-	},
+    // Clear trackedTokens localStorage if we've updated the config variable in an update
+    // that introduced a backward incompatible change requiring the tracked tokens to be re-set
+    clearIfRequired(): void {
+        const lastClearFillDate = localStorage.getItemIfExists(TRACKED_TOKENS_CLEAR_KEY);
+        if (lastClearFillDate !== configs.LAST_LOCAL_STORAGE_TRACKED_TOKEN_CLEARANCE_DATE) {
+            localStorage.removeItem(TRACKED_TOKENS_KEY);
+        }
+        localStorage.setItem(TRACKED_TOKENS_CLEAR_KEY, configs.LAST_LOCAL_STORAGE_TRACKED_TOKEN_CLEARANCE_DATE);
+    },
+    addTrackedTokenToUser(userAddress: string, networkId: number, token: Token): void {
+        const trackedTokensByUserAddress = this.getTrackedTokensByUserAddress();
+        let trackedTokensByNetworkId = trackedTokensByUserAddress[userAddress];
+        if (_.isUndefined(trackedTokensByNetworkId)) {
+            trackedTokensByNetworkId = {};
+        }
+        const trackedTokens = !_.isUndefined(trackedTokensByNetworkId[networkId])
+            ? trackedTokensByNetworkId[networkId]
+            : [];
+        trackedTokens.push(token);
+        trackedTokensByNetworkId[networkId] = trackedTokens;
+        trackedTokensByUserAddress[userAddress] = trackedTokensByNetworkId;
+        const trackedTokensByUserAddressJSONString = JSON.stringify(trackedTokensByUserAddress);
+        localStorage.setItem(TRACKED_TOKENS_KEY, trackedTokensByUserAddressJSONString);
+    },
+    getTrackedTokensByUserAddress(): TrackedTokensByUserAddress {
+        const trackedTokensJSONString = localStorage.getItemIfExists(TRACKED_TOKENS_KEY);
+        if (_.isEmpty(trackedTokensJSONString)) {
+            return {};
+        }
+        const trackedTokensByUserAddress = JSON.parse(trackedTokensJSONString);
+        return trackedTokensByUserAddress;
+    },
+    getTrackedTokensIfExists(userAddress: string, networkId: number): Token[] {
+        const trackedTokensJSONString = localStorage.getItemIfExists(TRACKED_TOKENS_KEY);
+        if (_.isEmpty(trackedTokensJSONString)) {
+            return undefined;
+        }
+        const trackedTokensByUserAddress = JSON.parse(trackedTokensJSONString);
+        const trackedTokensByNetworkId = trackedTokensByUserAddress[userAddress];
+        if (_.isUndefined(trackedTokensByNetworkId)) {
+            return undefined;
+        }
+        const trackedTokens = trackedTokensByNetworkId[networkId];
+        return trackedTokens;
+    },
+    removeTrackedToken(userAddress: string, networkId: number, tokenAddress: string): void {
+        const trackedTokensByUserAddress = this.getTrackedTokensByUserAddress();
+        const trackedTokensByNetworkId = trackedTokensByUserAddress[userAddress];
+        const trackedTokens = trackedTokensByNetworkId[networkId];
+        const remainingTrackedTokens = _.filter(trackedTokens, (token: Token) => {
+            return token.address !== tokenAddress;
+        });
+        trackedTokensByNetworkId[networkId] = remainingTrackedTokens;
+        trackedTokensByUserAddress[userAddress] = trackedTokensByNetworkId;
+        const trackedTokensByUserAddressJSONString = JSON.stringify(trackedTokensByUserAddress);
+        localStorage.setItem(TRACKED_TOKENS_KEY, trackedTokensByUserAddressJSONString);
+    },
 };
diff --git a/packages/website/ts/local_storage/trade_history_storage.tsx b/packages/website/ts/local_storage/trade_history_storage.tsx
index b20244b29..df731236e 100644
--- a/packages/website/ts/local_storage/trade_history_storage.tsx
+++ b/packages/website/ts/local_storage/trade_history_storage.tsx
@@ -11,84 +11,84 @@ const FILLS_LATEST_BLOCK = 'fillsLatestBlock';
 const FILL_CLEAR_KEY = 'lastClearFillDate';
 
 export const tradeHistoryStorage = {
-	// Clear all fill related localStorage if we've updated the config variable in an update
-	// that introduced a backward incompatible change requiring the user to re-fetch the fills from
-	// the blockchain
-	clearIfRequired() {
-		const lastClearFillDate = localStorage.getItemIfExists(FILL_CLEAR_KEY);
-		if (lastClearFillDate !== configs.LAST_LOCAL_STORAGE_FILL_CLEARANCE_DATE) {
-			const localStorageKeys = localStorage.getAllKeys();
-			_.each(localStorageKeys, key => {
-				if (_.startsWith(key, `${FILLS_KEY}-`) || _.startsWith(key, `${FILLS_LATEST_BLOCK}-`)) {
-					localStorage.removeItem(key);
-				}
-			});
-		}
-		localStorage.setItem(FILL_CLEAR_KEY, configs.LAST_LOCAL_STORAGE_FILL_CLEARANCE_DATE);
-	},
-	addFillToUser(userAddress: string, networkId: number, fill: Fill) {
-		const fillsByHash = this.getUserFillsByHash(userAddress, networkId);
-		const fillHash = this._getFillHash(fill);
-		const doesFillExist = !_.isUndefined(fillsByHash[fillHash]);
-		if (doesFillExist) {
-			return; // noop
-		}
-		fillsByHash[fillHash] = fill;
-		const userFillsJSONString = JSON.stringify(fillsByHash);
-		const userFillsKey = this._getUserFillsKey(userAddress, networkId);
-		localStorage.setItem(userFillsKey, userFillsJSONString);
-	},
-	removeFillFromUser(userAddress: string, networkId: number, fill: Fill) {
-		const fillsByHash = this.getUserFillsByHash(userAddress, networkId);
-		const fillHash = this._getFillHash(fill);
-		const doesFillExist = !_.isUndefined(fillsByHash[fillHash]);
-		if (!doesFillExist) {
-			return; // noop
-		}
-		delete fillsByHash[fillHash];
-		const userFillsJSONString = JSON.stringify(fillsByHash);
-		const userFillsKey = this._getUserFillsKey(userAddress, networkId);
-		localStorage.setItem(userFillsKey, userFillsJSONString);
-	},
-	getUserFillsByHash(userAddress: string, networkId: number): { [fillHash: string]: Fill } {
-		const userFillsKey = this._getUserFillsKey(userAddress, networkId);
-		const userFillsJSONString = localStorage.getItemIfExists(userFillsKey);
-		if (_.isEmpty(userFillsJSONString)) {
-			return {};
-		}
-		const userFillsByHash = JSON.parse(userFillsJSONString);
-		_.each(userFillsByHash, (fill, hash) => {
-			fill.paidMakerFee = new BigNumber(fill.paidMakerFee);
-			fill.paidTakerFee = new BigNumber(fill.paidTakerFee);
-			fill.filledTakerTokenAmount = new BigNumber(fill.filledTakerTokenAmount);
-			fill.filledMakerTokenAmount = new BigNumber(fill.filledMakerTokenAmount);
-		});
-		return userFillsByHash;
-	},
-	getFillsLatestBlock(userAddress: string, networkId: number): number {
-		const userFillsLatestBlockKey = this._getFillsLatestBlockKey(userAddress, networkId);
-		const blockNumberStr = localStorage.getItemIfExists(userFillsLatestBlockKey);
-		if (_.isEmpty(blockNumberStr)) {
-			return constants.GENESIS_ORDER_BLOCK_BY_NETWORK_ID[networkId];
-		}
-		const blockNumber = _.parseInt(blockNumberStr);
-		return blockNumber;
-	},
-	setFillsLatestBlock(userAddress: string, networkId: number, blockNumber: number) {
-		const userFillsLatestBlockKey = this._getFillsLatestBlockKey(userAddress, networkId);
-		localStorage.setItem(userFillsLatestBlockKey, `${blockNumber}`);
-	},
-	_getUserFillsKey(userAddress: string, networkId: number) {
-		const userFillsKey = `${FILLS_KEY}-${userAddress}-${networkId}`;
-		return userFillsKey;
-	},
-	_getFillsLatestBlockKey(userAddress: string, networkId: number) {
-		const userFillsLatestBlockKey = `${FILLS_LATEST_BLOCK}-${userAddress}-${networkId}`;
-		return userFillsLatestBlockKey;
-	},
-	_getFillHash(fill: Fill): string {
-		const fillJSON = JSON.stringify(fill);
-		const fillHash = ethUtil.sha256(fillJSON);
-		return fillHash.toString('hex');
-	},
+    // Clear all fill related localStorage if we've updated the config variable in an update
+    // that introduced a backward incompatible change requiring the user to re-fetch the fills from
+    // the blockchain
+    clearIfRequired() {
+        const lastClearFillDate = localStorage.getItemIfExists(FILL_CLEAR_KEY);
+        if (lastClearFillDate !== configs.LAST_LOCAL_STORAGE_FILL_CLEARANCE_DATE) {
+            const localStorageKeys = localStorage.getAllKeys();
+            _.each(localStorageKeys, key => {
+                if (_.startsWith(key, `${FILLS_KEY}-`) || _.startsWith(key, `${FILLS_LATEST_BLOCK}-`)) {
+                    localStorage.removeItem(key);
+                }
+            });
+        }
+        localStorage.setItem(FILL_CLEAR_KEY, configs.LAST_LOCAL_STORAGE_FILL_CLEARANCE_DATE);
+    },
+    addFillToUser(userAddress: string, networkId: number, fill: Fill) {
+        const fillsByHash = this.getUserFillsByHash(userAddress, networkId);
+        const fillHash = this._getFillHash(fill);
+        const doesFillExist = !_.isUndefined(fillsByHash[fillHash]);
+        if (doesFillExist) {
+            return; // noop
+        }
+        fillsByHash[fillHash] = fill;
+        const userFillsJSONString = JSON.stringify(fillsByHash);
+        const userFillsKey = this._getUserFillsKey(userAddress, networkId);
+        localStorage.setItem(userFillsKey, userFillsJSONString);
+    },
+    removeFillFromUser(userAddress: string, networkId: number, fill: Fill) {
+        const fillsByHash = this.getUserFillsByHash(userAddress, networkId);
+        const fillHash = this._getFillHash(fill);
+        const doesFillExist = !_.isUndefined(fillsByHash[fillHash]);
+        if (!doesFillExist) {
+            return; // noop
+        }
+        delete fillsByHash[fillHash];
+        const userFillsJSONString = JSON.stringify(fillsByHash);
+        const userFillsKey = this._getUserFillsKey(userAddress, networkId);
+        localStorage.setItem(userFillsKey, userFillsJSONString);
+    },
+    getUserFillsByHash(userAddress: string, networkId: number): { [fillHash: string]: Fill } {
+        const userFillsKey = this._getUserFillsKey(userAddress, networkId);
+        const userFillsJSONString = localStorage.getItemIfExists(userFillsKey);
+        if (_.isEmpty(userFillsJSONString)) {
+            return {};
+        }
+        const userFillsByHash = JSON.parse(userFillsJSONString);
+        _.each(userFillsByHash, (fill, hash) => {
+            fill.paidMakerFee = new BigNumber(fill.paidMakerFee);
+            fill.paidTakerFee = new BigNumber(fill.paidTakerFee);
+            fill.filledTakerTokenAmount = new BigNumber(fill.filledTakerTokenAmount);
+            fill.filledMakerTokenAmount = new BigNumber(fill.filledMakerTokenAmount);
+        });
+        return userFillsByHash;
+    },
+    getFillsLatestBlock(userAddress: string, networkId: number): number {
+        const userFillsLatestBlockKey = this._getFillsLatestBlockKey(userAddress, networkId);
+        const blockNumberStr = localStorage.getItemIfExists(userFillsLatestBlockKey);
+        if (_.isEmpty(blockNumberStr)) {
+            return constants.GENESIS_ORDER_BLOCK_BY_NETWORK_ID[networkId];
+        }
+        const blockNumber = _.parseInt(blockNumberStr);
+        return blockNumber;
+    },
+    setFillsLatestBlock(userAddress: string, networkId: number, blockNumber: number) {
+        const userFillsLatestBlockKey = this._getFillsLatestBlockKey(userAddress, networkId);
+        localStorage.setItem(userFillsLatestBlockKey, `${blockNumber}`);
+    },
+    _getUserFillsKey(userAddress: string, networkId: number) {
+        const userFillsKey = `${FILLS_KEY}-${userAddress}-${networkId}`;
+        return userFillsKey;
+    },
+    _getFillsLatestBlockKey(userAddress: string, networkId: number) {
+        const userFillsLatestBlockKey = `${FILLS_LATEST_BLOCK}-${userAddress}-${networkId}`;
+        return userFillsLatestBlockKey;
+    },
+    _getFillHash(fill: Fill): string {
+        const fillJSON = JSON.stringify(fill);
+        const fillHash = ethUtil.sha256(fillJSON);
+        return fillHash.toString('hex');
+    },
 };
diff --git a/packages/website/ts/pages/about/about.tsx b/packages/website/ts/pages/about/about.tsx
index 411456427..c929673f5 100644
--- a/packages/website/ts/pages/about/about.tsx
+++ b/packages/website/ts/pages/about/about.tsx
@@ -10,239 +10,239 @@ import { constants } from 'ts/utils/constants';
 import { utils } from 'ts/utils/utils';
 
 const teamRow1: ProfileInfo[] = [
-	{
-		name: 'Will Warren',
-		title: 'Co-founder & CEO',
-		description: `Smart contract R&D. Previously applied physics at Los Alamos \
+    {
+        name: 'Will Warren',
+        title: 'Co-founder & CEO',
+        description: `Smart contract R&D. Previously applied physics at Los Alamos \
                       Nat Lab. Mechanical engineering at UC San Diego. PhD dropout.`,
-		image: '/images/team/will.jpg',
-		linkedIn: 'https://www.linkedin.com/in/will-warren-92aab62b/',
-		github: 'https://github.com/willwarren89',
-		medium: 'https://medium.com/@willwarren89',
-	},
-	{
-		name: 'Amir Bandeali',
-		title: 'Co-founder & CTO',
-		description: `Smart contract R&D. Previously fixed income trader at DRW. \
+        image: '/images/team/will.jpg',
+        linkedIn: 'https://www.linkedin.com/in/will-warren-92aab62b/',
+        github: 'https://github.com/willwarren89',
+        medium: 'https://medium.com/@willwarren89',
+    },
+    {
+        name: 'Amir Bandeali',
+        title: 'Co-founder & CTO',
+        description: `Smart contract R&D. Previously fixed income trader at DRW. \
                       Finance at University of Illinois, Urbana-Champaign.`,
-		image: '/images/team/amir.jpeg',
-		linkedIn: 'https://www.linkedin.com/in/abandeali1/',
-		github: 'https://github.com/abandeali1',
-		medium: 'https://medium.com/@abandeali1',
-	},
-	{
-		name: 'Fabio Berger',
-		title: 'Senior Engineer',
-		description: `Full-stack blockchain engineer. Previously software engineer \
+        image: '/images/team/amir.jpeg',
+        linkedIn: 'https://www.linkedin.com/in/abandeali1/',
+        github: 'https://github.com/abandeali1',
+        medium: 'https://medium.com/@abandeali1',
+    },
+    {
+        name: 'Fabio Berger',
+        title: 'Senior Engineer',
+        description: `Full-stack blockchain engineer. Previously software engineer \
                       at Airtable and founder of WealthLift. Computer science at Duke.`,
-		image: '/images/team/fabio.jpg',
-		linkedIn: 'https://www.linkedin.com/in/fabio-berger-03ab261a/',
-		github: 'https://github.com/fabioberger',
-		medium: 'https://medium.com/@fabioberger',
-	},
+        image: '/images/team/fabio.jpg',
+        linkedIn: 'https://www.linkedin.com/in/fabio-berger-03ab261a/',
+        github: 'https://github.com/fabioberger',
+        medium: 'https://medium.com/@fabioberger',
+    },
 ];
 
 const teamRow2: ProfileInfo[] = [
-	{
-		name: 'Alex Xu',
-		title: 'Director of Operations',
-		description: `Strategy and operations. Previously digital marketing at Google \
+    {
+        name: 'Alex Xu',
+        title: 'Director of Operations',
+        description: `Strategy and operations. Previously digital marketing at Google \
                       and vendor management at Amazon. Economics at UC San Diego.`,
-		image: '/images/team/alex.jpg',
-		linkedIn: 'https://www.linkedin.com/in/alex-xu/',
-		github: '',
-		medium: 'https://medium.com/@aqxu',
-	},
-	{
-		name: 'Leonid Logvinov',
-		title: 'Engineer',
-		description: `Full-stack blockchain engineer. Previously blockchain engineer \
+        image: '/images/team/alex.jpg',
+        linkedIn: 'https://www.linkedin.com/in/alex-xu/',
+        github: '',
+        medium: 'https://medium.com/@aqxu',
+    },
+    {
+        name: 'Leonid Logvinov',
+        title: 'Engineer',
+        description: `Full-stack blockchain engineer. Previously blockchain engineer \
                       at Neufund. Computer science at University of Warsaw.`,
-		image: '/images/team/leonid.png',
-		linkedIn: 'https://www.linkedin.com/in/leonidlogvinov/',
-		github: 'https://github.com/LogvinovLeon',
-		medium: 'https://medium.com/@Logvinov',
-	},
-	{
-		name: 'Ben Burns',
-		title: 'Designer',
-		description: `Product, motion, and graphic designer. Previously designer \
+        image: '/images/team/leonid.png',
+        linkedIn: 'https://www.linkedin.com/in/leonidlogvinov/',
+        github: 'https://github.com/LogvinovLeon',
+        medium: 'https://medium.com/@Logvinov',
+    },
+    {
+        name: 'Ben Burns',
+        title: 'Designer',
+        description: `Product, motion, and graphic designer. Previously designer \
                       at Airtable and Apple. Digital Design at University of Cincinnati.`,
-		image: '/images/team/ben.jpg',
-		linkedIn: 'https://www.linkedin.com/in/ben-burns-30170478/',
-		github: '',
-		medium: '',
-	},
+        image: '/images/team/ben.jpg',
+        linkedIn: 'https://www.linkedin.com/in/ben-burns-30170478/',
+        github: '',
+        medium: '',
+    },
 ];
 
 const teamRow3: ProfileInfo[] = [
-	{
-		name: 'Brandon Millman',
-		title: 'Senior Engineer',
-		description: `Full-stack engineer. Previously senior software engineer at \
+    {
+        name: 'Brandon Millman',
+        title: 'Senior Engineer',
+        description: `Full-stack engineer. Previously senior software engineer at \
                       Twitter. Electrical and Computer Engineering at Duke.`,
-		image: '/images/team/brandon.png',
-		linkedIn: 'https://www.linkedin.com/in/brandon-millman-b093a022/',
-		github: 'https://github.com/BMillman19',
-		medium: 'https://medium.com/@bchillman',
-	},
-	{
-		name: 'Tom Schmidt',
-		title: 'Product Manager',
-		description: `Previously engineering at Apple, product management at Facebook and Instagram. Computer Science at Stanford.`,
-		image: '/images/team/tom.jpg',
-		linkedIn: 'https://www.linkedin.com/in/tomhschmidt/',
-		github: 'https://github.com/tomhschmidt',
-		medium: '',
-	},
-	{
-		name: 'Jacob Evans',
-		title: 'Blockchain Engineer',
-		description: `Previously software engineer at Qantas and RSA Security.`,
-		image: '/images/team/jacob.jpg',
-		linkedIn: 'https://www.linkedin.com/in/dekzter/',
-		github: 'https://github.com/dekz',
-		medium: '',
-	},
+        image: '/images/team/brandon.png',
+        linkedIn: 'https://www.linkedin.com/in/brandon-millman-b093a022/',
+        github: 'https://github.com/BMillman19',
+        medium: 'https://medium.com/@bchillman',
+    },
+    {
+        name: 'Tom Schmidt',
+        title: 'Product Manager',
+        description: `Previously engineering at Apple, product management at Facebook and Instagram. Computer Science at Stanford.`,
+        image: '/images/team/tom.jpg',
+        linkedIn: 'https://www.linkedin.com/in/tomhschmidt/',
+        github: 'https://github.com/tomhschmidt',
+        medium: '',
+    },
+    {
+        name: 'Jacob Evans',
+        title: 'Blockchain Engineer',
+        description: `Previously software engineer at Qantas and RSA Security.`,
+        image: '/images/team/jacob.jpg',
+        linkedIn: 'https://www.linkedin.com/in/dekzter/',
+        github: 'https://github.com/dekz',
+        medium: '',
+    },
 ];
 
 const advisors: ProfileInfo[] = [
-	{
-		name: 'Fred Ehrsam',
-		description: 'Co-founder of Coinbase. Previously FX trader at Goldman Sachs.',
-		image: '/images/advisors/fred.jpg',
-		linkedIn: 'https://www.linkedin.com/in/fredehrsam/',
-		medium: 'https://medium.com/@FEhrsam',
-		twitter: 'https://twitter.com/FEhrsam',
-	},
-	{
-		name: 'Olaf Carlson-Wee',
-		image: '/images/advisors/olaf.png',
-		description: 'Founder of Polychain Capital. First hire at Coinbase. Angel investor.',
-		linkedIn: 'https://www.linkedin.com/in/olafcw/',
-		angellist: 'https://angel.co/olafcw',
-	},
-	{
-		name: 'Joey Krug',
-		description: `Co-CIO at Pantera Capital. Founder of Augur. Thiel 20 Under 20 Fellow.`,
-		image: '/images/advisors/joey.jpg',
-		linkedIn: 'https://www.linkedin.com/in/joeykrug/',
-		github: 'https://github.com/joeykrug',
-		angellist: 'https://angel.co/joeykrug',
-	},
-	{
-		name: 'Linda Xie',
-		description: 'Co-founder of Scalar Capital. Previously PM at Coinbase.',
-		image: '/images/advisors/linda.jpg',
-		linkedIn: 'https://www.linkedin.com/in/lindaxie/',
-		medium: 'https://medium.com/@linda.xie',
-		twitter: 'https://twitter.com/ljxie',
-	},
+    {
+        name: 'Fred Ehrsam',
+        description: 'Co-founder of Coinbase. Previously FX trader at Goldman Sachs.',
+        image: '/images/advisors/fred.jpg',
+        linkedIn: 'https://www.linkedin.com/in/fredehrsam/',
+        medium: 'https://medium.com/@FEhrsam',
+        twitter: 'https://twitter.com/FEhrsam',
+    },
+    {
+        name: 'Olaf Carlson-Wee',
+        image: '/images/advisors/olaf.png',
+        description: 'Founder of Polychain Capital. First hire at Coinbase. Angel investor.',
+        linkedIn: 'https://www.linkedin.com/in/olafcw/',
+        angellist: 'https://angel.co/olafcw',
+    },
+    {
+        name: 'Joey Krug',
+        description: `Co-CIO at Pantera Capital. Founder of Augur. Thiel 20 Under 20 Fellow.`,
+        image: '/images/advisors/joey.jpg',
+        linkedIn: 'https://www.linkedin.com/in/joeykrug/',
+        github: 'https://github.com/joeykrug',
+        angellist: 'https://angel.co/joeykrug',
+    },
+    {
+        name: 'Linda Xie',
+        description: 'Co-founder of Scalar Capital. Previously PM at Coinbase.',
+        image: '/images/advisors/linda.jpg',
+        linkedIn: 'https://www.linkedin.com/in/lindaxie/',
+        medium: 'https://medium.com/@linda.xie',
+        twitter: 'https://twitter.com/ljxie',
+    },
 ];
 
 export interface AboutProps {
-	source: string;
-	location: Location;
+    source: string;
+    location: Location;
 }
 
 interface AboutState {}
 
 const styles: Styles = {
-	header: {
-		fontFamily: 'Roboto Mono',
-		fontSize: 36,
-		color: 'black',
-		paddingTop: 110,
-	},
-	weAreHiring: {
-		fontSize: 30,
-		color: colors.darkestGrey,
-		fontFamily: 'Roboto Mono',
-		letterSpacing: 7.5,
-	},
+    header: {
+        fontFamily: 'Roboto Mono',
+        fontSize: 36,
+        color: 'black',
+        paddingTop: 110,
+    },
+    weAreHiring: {
+        fontSize: 30,
+        color: colors.darkestGrey,
+        fontFamily: 'Roboto Mono',
+        letterSpacing: 7.5,
+    },
 };
 
 export class About extends React.Component<AboutProps, AboutState> {
-	public componentDidMount() {
-		window.scrollTo(0, 0);
-	}
-	public render() {
-		return (
-			<div style={{ backgroundColor: colors.lightestGrey }}>
-				<DocumentTitle title="0x About Us" />
-				<TopBar
-					blockchainIsLoaded={false}
-					location={this.props.location}
-					style={{ backgroundColor: colors.lightestGrey }}
-				/>
-				<div id="about" className="mx-auto max-width-4 py4" style={{ color: colors.grey800 }}>
-					<div className="mx-auto pb4 sm-px3" style={{ maxWidth: 435 }}>
-						<div style={styles.header}>About us:</div>
-						<div
-							className="pt3"
-							style={{
-								fontSize: 17,
-								color: colors.darkestGrey,
-								lineHeight: 1.5,
-							}}
-						>
-							Our team is a diverse and globally distributed group with backgrounds in engineering,
-							research, business and design. We are passionate about decentralized technology and its
-							potential to act as an equalizing force in the world.
-						</div>
-					</div>
-					<div className="pt3 md-px4 lg-px0">
-						<div className="clearfix pb3">{this._renderProfiles(teamRow1)}</div>
-						<div className="clearfix">{this._renderProfiles(teamRow2)}</div>
-						<div className="clearfix">{this._renderProfiles(teamRow3)}</div>
-					</div>
-					<div className="pt3 pb2">
-						<div
-							className="pt2 pb3 sm-center md-pl4 lg-pl0 md-ml3"
-							style={{
-								color: colors.grey,
-								fontSize: 24,
-								fontFamily: 'Roboto Mono',
-							}}
-						>
-							Advisors:
-						</div>
-						<div className="clearfix">{this._renderProfiles(advisors)}</div>
-					</div>
-					<div className="mx-auto py4 sm-px3" style={{ maxWidth: 308 }}>
-						<div className="pb2" style={styles.weAreHiring}>
-							WE'RE HIRING
-						</div>
-						<div
-							className="pb4 mb4"
-							style={{
-								fontSize: 16,
-								color: colors.darkestGrey,
-								lineHeight: 1.5,
-								letterSpacing: '0.5px',
-							}}
-						>
-							We are seeking outstanding candidates to{' '}
-							<a href={constants.URL_ANGELLIST} target="_blank" style={{ color: 'black' }}>
-								join our team
-							</a>
-							. We value passion, diversity and unique perspectives.
-						</div>
-					</div>
-				</div>
-				<Footer />
-			</div>
-		);
-	}
-	private _renderProfiles(profiles: ProfileInfo[]) {
-		const numIndiv = profiles.length;
-		const colSize = utils.getColSize(numIndiv);
-		return _.map(profiles, profile => {
-			return (
-				<div key={`profile-${profile.name}`}>
-					<Profile colSize={colSize} profileInfo={profile} />
-				</div>
-			);
-		});
-	}
+    public componentDidMount() {
+        window.scrollTo(0, 0);
+    }
+    public render() {
+        return (
+            <div style={{ backgroundColor: colors.lightestGrey }}>
+                <DocumentTitle title="0x About Us" />
+                <TopBar
+                    blockchainIsLoaded={false}
+                    location={this.props.location}
+                    style={{ backgroundColor: colors.lightestGrey }}
+                />
+                <div id="about" className="mx-auto max-width-4 py4" style={{ color: colors.grey800 }}>
+                    <div className="mx-auto pb4 sm-px3" style={{ maxWidth: 435 }}>
+                        <div style={styles.header}>About us:</div>
+                        <div
+                            className="pt3"
+                            style={{
+                                fontSize: 17,
+                                color: colors.darkestGrey,
+                                lineHeight: 1.5,
+                            }}
+                        >
+                            Our team is a diverse and globally distributed group with backgrounds in engineering,
+                            research, business and design. We are passionate about decentralized technology and its
+                            potential to act as an equalizing force in the world.
+                        </div>
+                    </div>
+                    <div className="pt3 md-px4 lg-px0">
+                        <div className="clearfix pb3">{this._renderProfiles(teamRow1)}</div>
+                        <div className="clearfix">{this._renderProfiles(teamRow2)}</div>
+                        <div className="clearfix">{this._renderProfiles(teamRow3)}</div>
+                    </div>
+                    <div className="pt3 pb2">
+                        <div
+                            className="pt2 pb3 sm-center md-pl4 lg-pl0 md-ml3"
+                            style={{
+                                color: colors.grey,
+                                fontSize: 24,
+                                fontFamily: 'Roboto Mono',
+                            }}
+                        >
+                            Advisors:
+                        </div>
+                        <div className="clearfix">{this._renderProfiles(advisors)}</div>
+                    </div>
+                    <div className="mx-auto py4 sm-px3" style={{ maxWidth: 308 }}>
+                        <div className="pb2" style={styles.weAreHiring}>
+                            WE'RE HIRING
+                        </div>
+                        <div
+                            className="pb4 mb4"
+                            style={{
+                                fontSize: 16,
+                                color: colors.darkestGrey,
+                                lineHeight: 1.5,
+                                letterSpacing: '0.5px',
+                            }}
+                        >
+                            We are seeking outstanding candidates to{' '}
+                            <a href={constants.URL_ANGELLIST} target="_blank" style={{ color: 'black' }}>
+                                join our team
+                            </a>
+                            . We value passion, diversity and unique perspectives.
+                        </div>
+                    </div>
+                </div>
+                <Footer />
+            </div>
+        );
+    }
+    private _renderProfiles(profiles: ProfileInfo[]) {
+        const numIndiv = profiles.length;
+        const colSize = utils.getColSize(numIndiv);
+        return _.map(profiles, profile => {
+            return (
+                <div key={`profile-${profile.name}`}>
+                    <Profile colSize={colSize} profileInfo={profile} />
+                </div>
+            );
+        });
+    }
 }
diff --git a/packages/website/ts/pages/about/profile.tsx b/packages/website/ts/pages/about/profile.tsx
index f1830851f..18b4e0d5a 100644
--- a/packages/website/ts/pages/about/profile.tsx
+++ b/packages/website/ts/pages/about/profile.tsx
@@ -5,75 +5,75 @@ import { colors } from 'ts/utils/colors';
 
 const IMAGE_DIMENSION = 149;
 const styles: Styles = {
-	subheader: {
-		textTransform: 'uppercase',
-		fontSize: 32,
-		margin: 0,
-	},
-	imageContainer: {
-		width: IMAGE_DIMENSION,
-		height: IMAGE_DIMENSION,
-		boxShadow: 'rgba(0, 0, 0, 0.19) 2px 5px 10px',
-	},
+    subheader: {
+        textTransform: 'uppercase',
+        fontSize: 32,
+        margin: 0,
+    },
+    imageContainer: {
+        width: IMAGE_DIMENSION,
+        height: IMAGE_DIMENSION,
+        boxShadow: 'rgba(0, 0, 0, 0.19) 2px 5px 10px',
+    },
 };
 
 interface ProfileProps {
-	colSize: number;
-	profileInfo: ProfileInfo;
+    colSize: number;
+    profileInfo: ProfileInfo;
 }
 
 export function Profile(props: ProfileProps) {
-	return (
-		<div className={`lg-col md-col lg-col-${props.colSize} md-col-6`}>
-			<div style={{ maxWidth: 300 }} className="mx-auto lg-px3 md-px3 sm-px4 sm-pb3">
-				<div className="circle overflow-hidden mx-auto" style={styles.imageContainer}>
-					<img width={IMAGE_DIMENSION} src={props.profileInfo.image} />
-				</div>
-				<div className="center" style={{ fontSize: 18, fontWeight: 'bold', paddingTop: 20 }}>
-					{props.profileInfo.name}
-				</div>
-				{!_.isUndefined(props.profileInfo.title) && (
-					<div
-						className="pt1 center"
-						style={{
-							fontSize: 14,
-							fontFamily: 'Roboto Mono',
-							color: colors.darkGrey,
-						}}
-					>
-						{props.profileInfo.title.toUpperCase()}
-					</div>
-				)}
-				<div style={{ minHeight: 60, lineHeight: 1.4 }} className="pt1 pb2 mx-auto lg-h6 md-h6 sm-h5 sm-center">
-					{props.profileInfo.description}
-				</div>
-				<div className="flex pb3 mx-auto sm-hide xs-hide" style={{ width: 280, opacity: 0.5 }}>
-					{renderSocialMediaIcons(props.profileInfo)}
-				</div>
-			</div>
-		</div>
-	);
+    return (
+        <div className={`lg-col md-col lg-col-${props.colSize} md-col-6`}>
+            <div style={{ maxWidth: 300 }} className="mx-auto lg-px3 md-px3 sm-px4 sm-pb3">
+                <div className="circle overflow-hidden mx-auto" style={styles.imageContainer}>
+                    <img width={IMAGE_DIMENSION} src={props.profileInfo.image} />
+                </div>
+                <div className="center" style={{ fontSize: 18, fontWeight: 'bold', paddingTop: 20 }}>
+                    {props.profileInfo.name}
+                </div>
+                {!_.isUndefined(props.profileInfo.title) && (
+                    <div
+                        className="pt1 center"
+                        style={{
+                            fontSize: 14,
+                            fontFamily: 'Roboto Mono',
+                            color: colors.darkGrey,
+                        }}
+                    >
+                        {props.profileInfo.title.toUpperCase()}
+                    </div>
+                )}
+                <div style={{ minHeight: 60, lineHeight: 1.4 }} className="pt1 pb2 mx-auto lg-h6 md-h6 sm-h5 sm-center">
+                    {props.profileInfo.description}
+                </div>
+                <div className="flex pb3 mx-auto sm-hide xs-hide" style={{ width: 280, opacity: 0.5 }}>
+                    {renderSocialMediaIcons(props.profileInfo)}
+                </div>
+            </div>
+        </div>
+    );
 }
 
 function renderSocialMediaIcons(profileInfo: ProfileInfo) {
-	const icons = [
-		renderSocialMediaIcon('zmdi-github-box', profileInfo.github),
-		renderSocialMediaIcon('zmdi-linkedin-box', profileInfo.linkedIn),
-		renderSocialMediaIcon('zmdi-twitter-box', profileInfo.twitter),
-	];
-	return icons;
+    const icons = [
+        renderSocialMediaIcon('zmdi-github-box', profileInfo.github),
+        renderSocialMediaIcon('zmdi-linkedin-box', profileInfo.linkedIn),
+        renderSocialMediaIcon('zmdi-twitter-box', profileInfo.twitter),
+    ];
+    return icons;
 }
 
 function renderSocialMediaIcon(iconName: string, url: string) {
-	if (_.isEmpty(url)) {
-		return null;
-	}
+    if (_.isEmpty(url)) {
+        return null;
+    }
 
-	return (
-		<div key={url} className="pr1">
-			<a href={url} style={{ color: 'inherit' }} target="_blank" className="text-decoration-none">
-				<i className={`zmdi ${iconName}`} style={{ ...styles.socalIcon }} />
-			</a>
-		</div>
-	);
+    return (
+        <div key={url} className="pr1">
+            <a href={url} style={{ color: 'inherit' }} target="_blank" className="text-decoration-none">
+                <i className={`zmdi ${iconName}`} style={{ ...styles.socalIcon }} />
+            </a>
+        </div>
+    );
 }
diff --git a/packages/website/ts/pages/documentation/comment.tsx b/packages/website/ts/pages/documentation/comment.tsx
index 6be39f586..23cfd96bd 100644
--- a/packages/website/ts/pages/documentation/comment.tsx
+++ b/packages/website/ts/pages/documentation/comment.tsx
@@ -4,20 +4,20 @@ import * as ReactMarkdown from 'react-markdown';
 import { MarkdownCodeBlock } from 'ts/pages/shared/markdown_code_block';
 
 interface CommentProps {
-	comment: string;
-	className?: string;
+    comment: string;
+    className?: string;
 }
 
 const defaultProps = {
-	className: '',
+    className: '',
 };
 
 export const Comment: React.SFC<CommentProps> = (props: CommentProps) => {
-	return (
-		<div className={`${props.className} comment`}>
-			<ReactMarkdown source={props.comment} renderers={{ CodeBlock: MarkdownCodeBlock }} />
-		</div>
-	);
+    return (
+        <div className={`${props.className} comment`}>
+            <ReactMarkdown source={props.comment} renderers={{ CodeBlock: MarkdownCodeBlock }} />
+        </div>
+    );
 };
 
 Comment.defaultProps = defaultProps;
diff --git a/packages/website/ts/pages/documentation/custom_enum.tsx b/packages/website/ts/pages/documentation/custom_enum.tsx
index 0006b8d7e..8d50a2f52 100644
--- a/packages/website/ts/pages/documentation/custom_enum.tsx
+++ b/packages/website/ts/pages/documentation/custom_enum.tsx
@@ -6,27 +6,27 @@ import { utils } from 'ts/utils/utils';
 const STRING_ENUM_CODE_PREFIX = ' strEnum(';
 
 interface CustomEnumProps {
-	type: CustomType;
+    type: CustomType;
 }
 
 // This component renders custom string enums that was a work-around for versions of
 // TypeScript <2.4.0 that did not support them natively. We keep it around to support
 // older versions of 0x.js <0.9.0
 export function CustomEnum(props: CustomEnumProps) {
-	const type = props.type;
-	if (!_.startsWith(type.defaultValue, STRING_ENUM_CODE_PREFIX)) {
-		utils.consoleLog('We do not yet support `Variable` types that are not strEnums');
-		return null;
-	}
-	// Remove the prefix and postfix, leaving only the strEnum values without quotes.
-	const enumValues = type.defaultValue.slice(10, -3).replace(/'/g, '');
-	return (
-		<span>
-			{`{`}
-			{'\t'}
-			{enumValues}
-			<br />
-			{`}`}
-		</span>
-	);
+    const type = props.type;
+    if (!_.startsWith(type.defaultValue, STRING_ENUM_CODE_PREFIX)) {
+        utils.consoleLog('We do not yet support `Variable` types that are not strEnums');
+        return null;
+    }
+    // Remove the prefix and postfix, leaving only the strEnum values without quotes.
+    const enumValues = type.defaultValue.slice(10, -3).replace(/'/g, '');
+    return (
+        <span>
+            {`{`}
+            {'\t'}
+            {enumValues}
+            <br />
+            {`}`}
+        </span>
+    );
 }
diff --git a/packages/website/ts/pages/documentation/docs_info.ts b/packages/website/ts/pages/documentation/docs_info.ts
index e1080f3a0..4b1ec122a 100644
--- a/packages/website/ts/pages/documentation/docs_info.ts
+++ b/packages/website/ts/pages/documentation/docs_info.ts
@@ -1,111 +1,111 @@
 import compareVersions = require('compare-versions');
 import * as _ from 'lodash';
 import {
-	DocAgnosticFormat,
-	DocsInfoConfig,
-	DocsMenu,
-	DoxityDocObj,
-	MenuSubsectionsBySection,
-	SectionsMap,
-	TypeDocNode,
+    DocAgnosticFormat,
+    DocsInfoConfig,
+    DocsMenu,
+    DoxityDocObj,
+    MenuSubsectionsBySection,
+    SectionsMap,
+    TypeDocNode,
 } from 'ts/types';
 
 export class DocsInfo {
-	public displayName: string;
-	public packageUrl: string;
-	public subPackageName?: string;
-	public websitePath: string;
-	public docsJsonRoot: string;
-	public menu: DocsMenu;
-	public sections: SectionsMap;
-	public sectionNameToMarkdown: { [sectionName: string]: string };
-	private _docsInfo: DocsInfoConfig;
-	constructor(config: DocsInfoConfig) {
-		this.displayName = config.displayName;
-		this.packageUrl = config.packageUrl;
-		this.subPackageName = config.subPackageName;
-		this.websitePath = config.websitePath;
-		this.docsJsonRoot = config.docsJsonRoot;
-		this.sections = config.sections;
-		this.sectionNameToMarkdown = config.sectionNameToMarkdown;
-		this._docsInfo = config;
-	}
-	public isPublicType(typeName: string): boolean {
-		if (_.isUndefined(this._docsInfo.publicTypes)) {
-			return false;
-		}
-		const isPublic = _.includes(this._docsInfo.publicTypes, typeName);
-		return isPublic;
-	}
-	public getModulePathsIfExists(sectionName: string): string[] {
-		const modulePathsIfExists = this._docsInfo.sectionNameToModulePath[sectionName];
-		return modulePathsIfExists;
-	}
-	public getMenu(selectedVersion?: string): { [section: string]: string[] } {
-		if (_.isUndefined(selectedVersion) || _.isUndefined(this._docsInfo.menuSubsectionToVersionWhenIntroduced)) {
-			return this._docsInfo.menu;
-		}
+    public displayName: string;
+    public packageUrl: string;
+    public subPackageName?: string;
+    public websitePath: string;
+    public docsJsonRoot: string;
+    public menu: DocsMenu;
+    public sections: SectionsMap;
+    public sectionNameToMarkdown: { [sectionName: string]: string };
+    private _docsInfo: DocsInfoConfig;
+    constructor(config: DocsInfoConfig) {
+        this.displayName = config.displayName;
+        this.packageUrl = config.packageUrl;
+        this.subPackageName = config.subPackageName;
+        this.websitePath = config.websitePath;
+        this.docsJsonRoot = config.docsJsonRoot;
+        this.sections = config.sections;
+        this.sectionNameToMarkdown = config.sectionNameToMarkdown;
+        this._docsInfo = config;
+    }
+    public isPublicType(typeName: string): boolean {
+        if (_.isUndefined(this._docsInfo.publicTypes)) {
+            return false;
+        }
+        const isPublic = _.includes(this._docsInfo.publicTypes, typeName);
+        return isPublic;
+    }
+    public getModulePathsIfExists(sectionName: string): string[] {
+        const modulePathsIfExists = this._docsInfo.sectionNameToModulePath[sectionName];
+        return modulePathsIfExists;
+    }
+    public getMenu(selectedVersion?: string): { [section: string]: string[] } {
+        if (_.isUndefined(selectedVersion) || _.isUndefined(this._docsInfo.menuSubsectionToVersionWhenIntroduced)) {
+            return this._docsInfo.menu;
+        }
 
-		const finalMenu = _.cloneDeep(this._docsInfo.menu);
-		if (_.isUndefined(finalMenu.contracts)) {
-			return finalMenu;
-		}
+        const finalMenu = _.cloneDeep(this._docsInfo.menu);
+        if (_.isUndefined(finalMenu.contracts)) {
+            return finalMenu;
+        }
 
-		// TODO: refactor to include more sections then simply the `contracts` section
-		finalMenu.contracts = _.filter(finalMenu.contracts, (contractName: string) => {
-			const versionIntroducedIfExists = this._docsInfo.menuSubsectionToVersionWhenIntroduced[contractName];
-			if (!_.isUndefined(versionIntroducedIfExists)) {
-				const existsInSelectedVersion = compareVersions(selectedVersion, versionIntroducedIfExists) >= 0;
-				return existsInSelectedVersion;
-			} else {
-				return true;
-			}
-		});
-		return finalMenu;
-	}
-	public getMenuSubsectionsBySection(docAgnosticFormat?: DocAgnosticFormat): MenuSubsectionsBySection {
-		const menuSubsectionsBySection = {} as MenuSubsectionsBySection;
-		if (_.isUndefined(docAgnosticFormat)) {
-			return menuSubsectionsBySection;
-		}
+        // TODO: refactor to include more sections then simply the `contracts` section
+        finalMenu.contracts = _.filter(finalMenu.contracts, (contractName: string) => {
+            const versionIntroducedIfExists = this._docsInfo.menuSubsectionToVersionWhenIntroduced[contractName];
+            if (!_.isUndefined(versionIntroducedIfExists)) {
+                const existsInSelectedVersion = compareVersions(selectedVersion, versionIntroducedIfExists) >= 0;
+                return existsInSelectedVersion;
+            } else {
+                return true;
+            }
+        });
+        return finalMenu;
+    }
+    public getMenuSubsectionsBySection(docAgnosticFormat?: DocAgnosticFormat): MenuSubsectionsBySection {
+        const menuSubsectionsBySection = {} as MenuSubsectionsBySection;
+        if (_.isUndefined(docAgnosticFormat)) {
+            return menuSubsectionsBySection;
+        }
 
-		const docSections = _.keys(this.sections);
-		_.each(docSections, sectionName => {
-			const docSection = docAgnosticFormat[sectionName];
-			if (_.isUndefined(docSection)) {
-				return; // no-op
-			}
+        const docSections = _.keys(this.sections);
+        _.each(docSections, sectionName => {
+            const docSection = docAgnosticFormat[sectionName];
+            if (_.isUndefined(docSection)) {
+                return; // no-op
+            }
 
-			if (!_.isUndefined(this.sections.types) && sectionName === this.sections.types) {
-				const sortedTypesNames = _.sortBy(docSection.types, 'name');
-				const typeNames = _.map(sortedTypesNames, t => t.name);
-				menuSubsectionsBySection[sectionName] = typeNames;
-			} else {
-				let eventNames: string[] = [];
-				if (!_.isUndefined(docSection.events)) {
-					const sortedEventNames = _.sortBy(docSection.events, 'name');
-					eventNames = _.map(sortedEventNames, m => m.name);
-				}
-				const sortedMethodNames = _.sortBy(docSection.methods, 'name');
-				const methodNames = _.map(sortedMethodNames, m => m.name);
-				menuSubsectionsBySection[sectionName] = [...methodNames, ...eventNames];
-			}
-		});
-		return menuSubsectionsBySection;
-	}
-	public getTypeDefinitionsByName(docAgnosticFormat: DocAgnosticFormat) {
-		if (_.isUndefined(this.sections.types)) {
-			return {};
-		}
+            if (!_.isUndefined(this.sections.types) && sectionName === this.sections.types) {
+                const sortedTypesNames = _.sortBy(docSection.types, 'name');
+                const typeNames = _.map(sortedTypesNames, t => t.name);
+                menuSubsectionsBySection[sectionName] = typeNames;
+            } else {
+                let eventNames: string[] = [];
+                if (!_.isUndefined(docSection.events)) {
+                    const sortedEventNames = _.sortBy(docSection.events, 'name');
+                    eventNames = _.map(sortedEventNames, m => m.name);
+                }
+                const sortedMethodNames = _.sortBy(docSection.methods, 'name');
+                const methodNames = _.map(sortedMethodNames, m => m.name);
+                menuSubsectionsBySection[sectionName] = [...methodNames, ...eventNames];
+            }
+        });
+        return menuSubsectionsBySection;
+    }
+    public getTypeDefinitionsByName(docAgnosticFormat: DocAgnosticFormat) {
+        if (_.isUndefined(this.sections.types)) {
+            return {};
+        }
 
-		const typeDocSection = docAgnosticFormat[this.sections.types];
-		const typeDefinitionByName = _.keyBy(typeDocSection.types, 'name');
-		return typeDefinitionByName;
-	}
-	public isVisibleConstructor(sectionName: string): boolean {
-		return _.includes(this._docsInfo.visibleConstructors, sectionName);
-	}
-	public convertToDocAgnosticFormat(docObj: DoxityDocObj | TypeDocNode): DocAgnosticFormat {
-		return this._docsInfo.convertToDocAgnosticFormatFn(docObj, this);
-	}
+        const typeDocSection = docAgnosticFormat[this.sections.types];
+        const typeDefinitionByName = _.keyBy(typeDocSection.types, 'name');
+        return typeDefinitionByName;
+    }
+    public isVisibleConstructor(sectionName: string): boolean {
+        return _.includes(this._docsInfo.visibleConstructors, sectionName);
+    }
+    public convertToDocAgnosticFormat(docObj: DoxityDocObj | TypeDocNode): DocAgnosticFormat {
+        return this._docsInfo.convertToDocAgnosticFormatFn(docObj, this);
+    }
 }
diff --git a/packages/website/ts/pages/documentation/documentation.tsx b/packages/website/ts/pages/documentation/documentation.tsx
index 0fc41d775..2315847ad 100644
--- a/packages/website/ts/pages/documentation/documentation.tsx
+++ b/packages/website/ts/pages/documentation/documentation.tsx
@@ -19,17 +19,17 @@ import { NestedSidebarMenu } from 'ts/pages/shared/nested_sidebar_menu';
 import { SectionHeader } from 'ts/pages/shared/section_header';
 import { Dispatcher } from 'ts/redux/dispatcher';
 import {
-	AddressByContractName,
-	DocAgnosticFormat,
-	DoxityDocObj,
-	EtherscanLinkSuffixes,
-	Event,
-	Networks,
-	Property,
-	SolidityMethod,
-	Styles,
-	TypeDefinitionByName,
-	TypescriptMethod,
+    AddressByContractName,
+    DocAgnosticFormat,
+    DoxityDocObj,
+    EtherscanLinkSuffixes,
+    Event,
+    Networks,
+    Property,
+    SolidityMethod,
+    Styles,
+    TypeDefinitionByName,
+    TypescriptMethod,
 } from 'ts/types';
 import { colors } from 'ts/utils/colors';
 import { configs } from 'ts/utils/configs';
@@ -40,340 +40,340 @@ import { utils } from 'ts/utils/utils';
 const SCROLL_TOP_ID = 'docsScrollTop';
 
 const networkNameToColor: { [network: string]: string } = {
-	[Networks.kovan]: colors.purple,
-	[Networks.ropsten]: colors.red,
-	[Networks.mainnet]: colors.turquois,
+    [Networks.kovan]: colors.purple,
+    [Networks.ropsten]: colors.red,
+    [Networks.mainnet]: colors.turquois,
 };
 
 export interface DocumentationAllProps {
-	source: string;
-	location: Location;
-	dispatcher: Dispatcher;
-	docsVersion: string;
-	availableDocVersions: string[];
-	docsInfo: DocsInfo;
+    source: string;
+    location: Location;
+    dispatcher: Dispatcher;
+    docsVersion: string;
+    availableDocVersions: string[];
+    docsInfo: DocsInfo;
 }
 
 interface DocumentationState {
-	docAgnosticFormat?: DocAgnosticFormat;
+    docAgnosticFormat?: DocAgnosticFormat;
 }
 
 const styles: Styles = {
-	mainContainers: {
-		position: 'absolute',
-		top: 1,
-		left: 0,
-		bottom: 0,
-		right: 0,
-		overflowZ: 'hidden',
-		overflowY: 'scroll',
-		minHeight: 'calc(100vh - 1px)',
-		WebkitOverflowScrolling: 'touch',
-	},
-	menuContainer: {
-		borderColor: colors.grey300,
-		maxWidth: 330,
-		marginLeft: 20,
-	},
+    mainContainers: {
+        position: 'absolute',
+        top: 1,
+        left: 0,
+        bottom: 0,
+        right: 0,
+        overflowZ: 'hidden',
+        overflowY: 'scroll',
+        minHeight: 'calc(100vh - 1px)',
+        WebkitOverflowScrolling: 'touch',
+    },
+    menuContainer: {
+        borderColor: colors.grey300,
+        maxWidth: 330,
+        marginLeft: 20,
+    },
 };
 
 export class Documentation extends React.Component<DocumentationAllProps, DocumentationState> {
-	constructor(props: DocumentationAllProps) {
-		super(props);
-		this.state = {
-			docAgnosticFormat: undefined,
-		};
-	}
-	public componentWillMount() {
-		const pathName = this.props.location.pathname;
-		const lastSegment = pathName.substr(pathName.lastIndexOf('/') + 1);
-		const versions = findVersions(lastSegment);
-		const preferredVersionIfExists = versions.length > 0 ? versions[0] : undefined;
-		// tslint:disable-next-line:no-floating-promises
-		this._fetchJSONDocsFireAndForgetAsync(preferredVersionIfExists);
-	}
-	public render() {
-		const menuSubsectionsBySection = _.isUndefined(this.state.docAgnosticFormat)
-			? {}
-			: this.props.docsInfo.getMenuSubsectionsBySection(this.state.docAgnosticFormat);
-		return (
-			<div>
-				<DocumentTitle title={`${this.props.docsInfo.displayName} Documentation`} />
-				<TopBar
-					blockchainIsLoaded={false}
-					location={this.props.location}
-					docsVersion={this.props.docsVersion}
-					availableDocVersions={this.props.availableDocVersions}
-					menu={this.props.docsInfo.getMenu(this.props.docsVersion)}
-					menuSubsectionsBySection={menuSubsectionsBySection}
-					shouldFullWidth={true}
-					docsInfo={this.props.docsInfo}
-				/>
-				{_.isUndefined(this.state.docAgnosticFormat) ? (
-					<div className="col col-12" style={styles.mainContainers}>
-						<div
-							className="relative sm-px2 sm-pt2 sm-m1"
-							style={{ height: 122, top: '50%', transform: 'translateY(-50%)' }}
-						>
-							<div className="center pb2">
-								<CircularProgress size={40} thickness={5} />
-							</div>
-							<div className="center pt2" style={{ paddingBottom: 11 }}>
-								Loading documentation...
-							</div>
-						</div>
-					</div>
-				) : (
-					<div className="mx-auto flex" style={{ color: colors.grey800, height: 43 }}>
-						<div className="relative col md-col-3 lg-col-3 lg-pl0 md-pl1 sm-hide xs-hide">
-							<div
-								className="border-right absolute"
-								style={{ ...styles.menuContainer, ...styles.mainContainers }}
-							>
-								<NestedSidebarMenu
-									selectedVersion={this.props.docsVersion}
-									versions={this.props.availableDocVersions}
-									topLevelMenu={this.props.docsInfo.getMenu(this.props.docsVersion)}
-									menuSubsectionsBySection={menuSubsectionsBySection}
-									docPath={this.props.docsInfo.websitePath}
-								/>
-							</div>
-						</div>
-						<div className="relative col lg-col-9 md-col-9 sm-col-12 col-12">
-							<div id="documentation" style={styles.mainContainers} className="absolute">
-								<div id={SCROLL_TOP_ID} />
-								<h1 className="md-pl2 sm-pl3">
-									<a href={this.props.docsInfo.packageUrl} target="_blank">
-										{this.props.docsInfo.displayName}
-									</a>
-								</h1>
-								{this._renderDocumentation()}
-							</div>
-						</div>
-					</div>
-				)}
-			</div>
-		);
-	}
-	private _renderDocumentation(): React.ReactNode {
-		const subMenus = _.values(this.props.docsInfo.getMenu());
-		const orderedSectionNames = _.flatten(subMenus);
+    constructor(props: DocumentationAllProps) {
+        super(props);
+        this.state = {
+            docAgnosticFormat: undefined,
+        };
+    }
+    public componentWillMount() {
+        const pathName = this.props.location.pathname;
+        const lastSegment = pathName.substr(pathName.lastIndexOf('/') + 1);
+        const versions = findVersions(lastSegment);
+        const preferredVersionIfExists = versions.length > 0 ? versions[0] : undefined;
+        // tslint:disable-next-line:no-floating-promises
+        this._fetchJSONDocsFireAndForgetAsync(preferredVersionIfExists);
+    }
+    public render() {
+        const menuSubsectionsBySection = _.isUndefined(this.state.docAgnosticFormat)
+            ? {}
+            : this.props.docsInfo.getMenuSubsectionsBySection(this.state.docAgnosticFormat);
+        return (
+            <div>
+                <DocumentTitle title={`${this.props.docsInfo.displayName} Documentation`} />
+                <TopBar
+                    blockchainIsLoaded={false}
+                    location={this.props.location}
+                    docsVersion={this.props.docsVersion}
+                    availableDocVersions={this.props.availableDocVersions}
+                    menu={this.props.docsInfo.getMenu(this.props.docsVersion)}
+                    menuSubsectionsBySection={menuSubsectionsBySection}
+                    shouldFullWidth={true}
+                    docsInfo={this.props.docsInfo}
+                />
+                {_.isUndefined(this.state.docAgnosticFormat) ? (
+                    <div className="col col-12" style={styles.mainContainers}>
+                        <div
+                            className="relative sm-px2 sm-pt2 sm-m1"
+                            style={{ height: 122, top: '50%', transform: 'translateY(-50%)' }}
+                        >
+                            <div className="center pb2">
+                                <CircularProgress size={40} thickness={5} />
+                            </div>
+                            <div className="center pt2" style={{ paddingBottom: 11 }}>
+                                Loading documentation...
+                            </div>
+                        </div>
+                    </div>
+                ) : (
+                    <div className="mx-auto flex" style={{ color: colors.grey800, height: 43 }}>
+                        <div className="relative col md-col-3 lg-col-3 lg-pl0 md-pl1 sm-hide xs-hide">
+                            <div
+                                className="border-right absolute"
+                                style={{ ...styles.menuContainer, ...styles.mainContainers }}
+                            >
+                                <NestedSidebarMenu
+                                    selectedVersion={this.props.docsVersion}
+                                    versions={this.props.availableDocVersions}
+                                    topLevelMenu={this.props.docsInfo.getMenu(this.props.docsVersion)}
+                                    menuSubsectionsBySection={menuSubsectionsBySection}
+                                    docPath={this.props.docsInfo.websitePath}
+                                />
+                            </div>
+                        </div>
+                        <div className="relative col lg-col-9 md-col-9 sm-col-12 col-12">
+                            <div id="documentation" style={styles.mainContainers} className="absolute">
+                                <div id={SCROLL_TOP_ID} />
+                                <h1 className="md-pl2 sm-pl3">
+                                    <a href={this.props.docsInfo.packageUrl} target="_blank">
+                                        {this.props.docsInfo.displayName}
+                                    </a>
+                                </h1>
+                                {this._renderDocumentation()}
+                            </div>
+                        </div>
+                    </div>
+                )}
+            </div>
+        );
+    }
+    private _renderDocumentation(): React.ReactNode {
+        const subMenus = _.values(this.props.docsInfo.getMenu());
+        const orderedSectionNames = _.flatten(subMenus);
 
-		const typeDefinitionByName = this.props.docsInfo.getTypeDefinitionsByName(this.state.docAgnosticFormat);
-		const renderedSections = _.map(orderedSectionNames, this._renderSection.bind(this, typeDefinitionByName));
+        const typeDefinitionByName = this.props.docsInfo.getTypeDefinitionsByName(this.state.docAgnosticFormat);
+        const renderedSections = _.map(orderedSectionNames, this._renderSection.bind(this, typeDefinitionByName));
 
-		return renderedSections;
-	}
-	private _renderSection(typeDefinitionByName: TypeDefinitionByName, sectionName: string): React.ReactNode {
-		const markdownFileIfExists = this.props.docsInfo.sectionNameToMarkdown[sectionName];
-		if (!_.isUndefined(markdownFileIfExists)) {
-			return (
-				<MarkdownSection
-					key={`markdown-section-${sectionName}`}
-					sectionName={sectionName}
-					markdownContent={markdownFileIfExists}
-				/>
-			);
-		}
+        return renderedSections;
+    }
+    private _renderSection(typeDefinitionByName: TypeDefinitionByName, sectionName: string): React.ReactNode {
+        const markdownFileIfExists = this.props.docsInfo.sectionNameToMarkdown[sectionName];
+        if (!_.isUndefined(markdownFileIfExists)) {
+            return (
+                <MarkdownSection
+                    key={`markdown-section-${sectionName}`}
+                    sectionName={sectionName}
+                    markdownContent={markdownFileIfExists}
+                />
+            );
+        }
 
-		const docSection = this.state.docAgnosticFormat[sectionName];
-		if (_.isUndefined(docSection)) {
-			return null;
-		}
+        const docSection = this.state.docAgnosticFormat[sectionName];
+        if (_.isUndefined(docSection)) {
+            return null;
+        }
 
-		const sortedTypes = _.sortBy(docSection.types, 'name');
-		const typeDefs = _.map(sortedTypes, customType => {
-			return (
-				<TypeDefinition
-					sectionName={sectionName}
-					key={`type-${customType.name}`}
-					customType={customType}
-					docsInfo={this.props.docsInfo}
-				/>
-			);
-		});
+        const sortedTypes = _.sortBy(docSection.types, 'name');
+        const typeDefs = _.map(sortedTypes, customType => {
+            return (
+                <TypeDefinition
+                    sectionName={sectionName}
+                    key={`type-${customType.name}`}
+                    customType={customType}
+                    docsInfo={this.props.docsInfo}
+                />
+            );
+        });
 
-		const sortedProperties = _.sortBy(docSection.properties, 'name');
-		const propertyDefs = _.map(sortedProperties, this._renderProperty.bind(this, sectionName));
+        const sortedProperties = _.sortBy(docSection.properties, 'name');
+        const propertyDefs = _.map(sortedProperties, this._renderProperty.bind(this, sectionName));
 
-		const sortedMethods = _.sortBy(docSection.methods, 'name');
-		const methodDefs = _.map(sortedMethods, method => {
-			const isConstructor = false;
-			return this._renderMethodBlocks(method, sectionName, isConstructor, typeDefinitionByName);
-		});
+        const sortedMethods = _.sortBy(docSection.methods, 'name');
+        const methodDefs = _.map(sortedMethods, method => {
+            const isConstructor = false;
+            return this._renderMethodBlocks(method, sectionName, isConstructor, typeDefinitionByName);
+        });
 
-		const sortedEvents = _.sortBy(docSection.events, 'name');
-		const eventDefs = _.map(sortedEvents, (event: Event, i: number) => {
-			return (
-				<EventDefinition
-					key={`event-${event.name}-${i}`}
-					event={event}
-					sectionName={sectionName}
-					docsInfo={this.props.docsInfo}
-				/>
-			);
-		});
-		return (
-			<div key={`section-${sectionName}`} className="py2 pr3 md-pl2 sm-pl3">
-				<div className="flex">
-					<div style={{ marginRight: 7 }}>
-						<SectionHeader sectionName={sectionName} />
-					</div>
-					{this._renderNetworkBadgesIfExists(sectionName)}
-				</div>
-				{docSection.comment && <Comment comment={docSection.comment} />}
-				{docSection.constructors.length > 0 &&
-					this.props.docsInfo.isVisibleConstructor(sectionName) && (
-						<div>
-							<h2 className="thin">Constructor</h2>
-							{this._renderConstructors(docSection.constructors, sectionName, typeDefinitionByName)}
-						</div>
-					)}
-				{docSection.properties.length > 0 && (
-					<div>
-						<h2 className="thin">Properties</h2>
-						<div>{propertyDefs}</div>
-					</div>
-				)}
-				{docSection.methods.length > 0 && (
-					<div>
-						<h2 className="thin">Methods</h2>
-						<div>{methodDefs}</div>
-					</div>
-				)}
-				{!_.isUndefined(docSection.events) &&
-					docSection.events.length > 0 && (
-						<div>
-							<h2 className="thin">Events</h2>
-							<div>{eventDefs}</div>
-						</div>
-					)}
-				{!_.isUndefined(typeDefs) &&
-					typeDefs.length > 0 && (
-						<div>
-							<div>{typeDefs}</div>
-						</div>
-					)}
-			</div>
-		);
-	}
-	private _renderNetworkBadgesIfExists(sectionName: string) {
-		const networkToAddressByContractName = configs.CONTRACT_ADDRESS[this.props.docsVersion];
-		const badges = _.map(
-			networkToAddressByContractName,
-			(addressByContractName: AddressByContractName, networkName: string) => {
-				const contractAddress = addressByContractName[sectionName];
-				if (_.isUndefined(contractAddress)) {
-					return null;
-				}
-				const linkIfExists = utils.getEtherScanLinkIfExists(
-					contractAddress,
-					constants.NETWORK_ID_BY_NAME[networkName],
-					EtherscanLinkSuffixes.Address,
-				);
-				return (
-					<a
-						key={`badge-${networkName}-${sectionName}`}
-						href={linkIfExists}
-						target="_blank"
-						style={{ color: colors.white, textDecoration: 'none' }}
-					>
-						<Badge title={networkName} backgroundColor={networkNameToColor[networkName]} />
-					</a>
-				);
-			},
-		);
-		return badges;
-	}
-	private _renderConstructors(
-		constructors: SolidityMethod[] | TypescriptMethod[],
-		sectionName: string,
-		typeDefinitionByName: TypeDefinitionByName,
-	): React.ReactNode {
-		const constructorDefs = _.map(constructors, constructor => {
-			return this._renderMethodBlocks(constructor, sectionName, constructor.isConstructor, typeDefinitionByName);
-		});
-		return <div>{constructorDefs}</div>;
-	}
-	private _renderProperty(sectionName: string, property: Property): React.ReactNode {
-		return (
-			<div key={`property-${property.name}-${property.type.name}`} className="pb3">
-				<code className="hljs">
-					{property.name}:
-					<Type type={property.type} sectionName={sectionName} docsInfo={this.props.docsInfo} />
-				</code>
-				{property.source && (
-					<SourceLink
-						version={this.props.docsVersion}
-						source={property.source}
-						baseUrl={this.props.docsInfo.packageUrl}
-						subPackageName={this.props.docsInfo.subPackageName}
-					/>
-				)}
-				{property.comment && <Comment comment={property.comment} className="py2" />}
-			</div>
-		);
-	}
-	private _renderMethodBlocks(
-		method: SolidityMethod | TypescriptMethod,
-		sectionName: string,
-		isConstructor: boolean,
-		typeDefinitionByName: TypeDefinitionByName,
-	): React.ReactNode {
-		return (
-			<MethodBlock
-				key={`method-${method.name}-${sectionName}`}
-				sectionName={sectionName}
-				method={method}
-				typeDefinitionByName={typeDefinitionByName}
-				libraryVersion={this.props.docsVersion}
-				docsInfo={this.props.docsInfo}
-			/>
-		);
-	}
-	private _scrollToHash(): void {
-		const hashWithPrefix = this.props.location.hash;
-		let hash = hashWithPrefix.slice(1);
-		if (_.isEmpty(hash)) {
-			hash = SCROLL_TOP_ID; // scroll to the top
-		}
+        const sortedEvents = _.sortBy(docSection.events, 'name');
+        const eventDefs = _.map(sortedEvents, (event: Event, i: number) => {
+            return (
+                <EventDefinition
+                    key={`event-${event.name}-${i}`}
+                    event={event}
+                    sectionName={sectionName}
+                    docsInfo={this.props.docsInfo}
+                />
+            );
+        });
+        return (
+            <div key={`section-${sectionName}`} className="py2 pr3 md-pl2 sm-pl3">
+                <div className="flex">
+                    <div style={{ marginRight: 7 }}>
+                        <SectionHeader sectionName={sectionName} />
+                    </div>
+                    {this._renderNetworkBadgesIfExists(sectionName)}
+                </div>
+                {docSection.comment && <Comment comment={docSection.comment} />}
+                {docSection.constructors.length > 0 &&
+                    this.props.docsInfo.isVisibleConstructor(sectionName) && (
+                        <div>
+                            <h2 className="thin">Constructor</h2>
+                            {this._renderConstructors(docSection.constructors, sectionName, typeDefinitionByName)}
+                        </div>
+                    )}
+                {docSection.properties.length > 0 && (
+                    <div>
+                        <h2 className="thin">Properties</h2>
+                        <div>{propertyDefs}</div>
+                    </div>
+                )}
+                {docSection.methods.length > 0 && (
+                    <div>
+                        <h2 className="thin">Methods</h2>
+                        <div>{methodDefs}</div>
+                    </div>
+                )}
+                {!_.isUndefined(docSection.events) &&
+                    docSection.events.length > 0 && (
+                        <div>
+                            <h2 className="thin">Events</h2>
+                            <div>{eventDefs}</div>
+                        </div>
+                    )}
+                {!_.isUndefined(typeDefs) &&
+                    typeDefs.length > 0 && (
+                        <div>
+                            <div>{typeDefs}</div>
+                        </div>
+                    )}
+            </div>
+        );
+    }
+    private _renderNetworkBadgesIfExists(sectionName: string) {
+        const networkToAddressByContractName = configs.CONTRACT_ADDRESS[this.props.docsVersion];
+        const badges = _.map(
+            networkToAddressByContractName,
+            (addressByContractName: AddressByContractName, networkName: string) => {
+                const contractAddress = addressByContractName[sectionName];
+                if (_.isUndefined(contractAddress)) {
+                    return null;
+                }
+                const linkIfExists = utils.getEtherScanLinkIfExists(
+                    contractAddress,
+                    constants.NETWORK_ID_BY_NAME[networkName],
+                    EtherscanLinkSuffixes.Address,
+                );
+                return (
+                    <a
+                        key={`badge-${networkName}-${sectionName}`}
+                        href={linkIfExists}
+                        target="_blank"
+                        style={{ color: colors.white, textDecoration: 'none' }}
+                    >
+                        <Badge title={networkName} backgroundColor={networkNameToColor[networkName]} />
+                    </a>
+                );
+            },
+        );
+        return badges;
+    }
+    private _renderConstructors(
+        constructors: SolidityMethod[] | TypescriptMethod[],
+        sectionName: string,
+        typeDefinitionByName: TypeDefinitionByName,
+    ): React.ReactNode {
+        const constructorDefs = _.map(constructors, constructor => {
+            return this._renderMethodBlocks(constructor, sectionName, constructor.isConstructor, typeDefinitionByName);
+        });
+        return <div>{constructorDefs}</div>;
+    }
+    private _renderProperty(sectionName: string, property: Property): React.ReactNode {
+        return (
+            <div key={`property-${property.name}-${property.type.name}`} className="pb3">
+                <code className="hljs">
+                    {property.name}:
+                    <Type type={property.type} sectionName={sectionName} docsInfo={this.props.docsInfo} />
+                </code>
+                {property.source && (
+                    <SourceLink
+                        version={this.props.docsVersion}
+                        source={property.source}
+                        baseUrl={this.props.docsInfo.packageUrl}
+                        subPackageName={this.props.docsInfo.subPackageName}
+                    />
+                )}
+                {property.comment && <Comment comment={property.comment} className="py2" />}
+            </div>
+        );
+    }
+    private _renderMethodBlocks(
+        method: SolidityMethod | TypescriptMethod,
+        sectionName: string,
+        isConstructor: boolean,
+        typeDefinitionByName: TypeDefinitionByName,
+    ): React.ReactNode {
+        return (
+            <MethodBlock
+                key={`method-${method.name}-${sectionName}`}
+                sectionName={sectionName}
+                method={method}
+                typeDefinitionByName={typeDefinitionByName}
+                libraryVersion={this.props.docsVersion}
+                docsInfo={this.props.docsInfo}
+            />
+        );
+    }
+    private _scrollToHash(): void {
+        const hashWithPrefix = this.props.location.hash;
+        let hash = hashWithPrefix.slice(1);
+        if (_.isEmpty(hash)) {
+            hash = SCROLL_TOP_ID; // scroll to the top
+        }
 
-		scroller.scrollTo(hash, {
-			duration: 0,
-			offset: 0,
-			containerId: 'documentation',
-		});
-	}
-	private async _fetchJSONDocsFireAndForgetAsync(preferredVersionIfExists?: string): Promise<void> {
-		const versionToFileName = await docUtils.getVersionToFileNameAsync(this.props.docsInfo.docsJsonRoot);
-		const versions = _.keys(versionToFileName);
-		this.props.dispatcher.updateAvailableDocVersions(versions);
-		const sortedVersions = semverSort.desc(versions);
-		const latestVersion = sortedVersions[0];
+        scroller.scrollTo(hash, {
+            duration: 0,
+            offset: 0,
+            containerId: 'documentation',
+        });
+    }
+    private async _fetchJSONDocsFireAndForgetAsync(preferredVersionIfExists?: string): Promise<void> {
+        const versionToFileName = await docUtils.getVersionToFileNameAsync(this.props.docsInfo.docsJsonRoot);
+        const versions = _.keys(versionToFileName);
+        this.props.dispatcher.updateAvailableDocVersions(versions);
+        const sortedVersions = semverSort.desc(versions);
+        const latestVersion = sortedVersions[0];
 
-		let versionToFetch = latestVersion;
-		if (!_.isUndefined(preferredVersionIfExists)) {
-			const preferredVersionFileNameIfExists = versionToFileName[preferredVersionIfExists];
-			if (!_.isUndefined(preferredVersionFileNameIfExists)) {
-				versionToFetch = preferredVersionIfExists;
-			}
-		}
-		this.props.dispatcher.updateCurrentDocsVersion(versionToFetch);
+        let versionToFetch = latestVersion;
+        if (!_.isUndefined(preferredVersionIfExists)) {
+            const preferredVersionFileNameIfExists = versionToFileName[preferredVersionIfExists];
+            if (!_.isUndefined(preferredVersionFileNameIfExists)) {
+                versionToFetch = preferredVersionIfExists;
+            }
+        }
+        this.props.dispatcher.updateCurrentDocsVersion(versionToFetch);
 
-		const versionFileNameToFetch = versionToFileName[versionToFetch];
-		const versionDocObj = await docUtils.getJSONDocFileAsync(
-			versionFileNameToFetch,
-			this.props.docsInfo.docsJsonRoot,
-		);
-		const docAgnosticFormat = this.props.docsInfo.convertToDocAgnosticFormat(versionDocObj as DoxityDocObj);
+        const versionFileNameToFetch = versionToFileName[versionToFetch];
+        const versionDocObj = await docUtils.getJSONDocFileAsync(
+            versionFileNameToFetch,
+            this.props.docsInfo.docsJsonRoot,
+        );
+        const docAgnosticFormat = this.props.docsInfo.convertToDocAgnosticFormat(versionDocObj as DoxityDocObj);
 
-		this.setState(
-			{
-				docAgnosticFormat,
-			},
-			() => {
-				this._scrollToHash();
-			},
-		);
-	}
+        this.setState(
+            {
+                docAgnosticFormat,
+            },
+            () => {
+                this._scrollToHash();
+            },
+        );
+    }
 }
diff --git a/packages/website/ts/pages/documentation/enum.tsx b/packages/website/ts/pages/documentation/enum.tsx
index cfcc7f8d7..7dfdee771 100644
--- a/packages/website/ts/pages/documentation/enum.tsx
+++ b/packages/website/ts/pages/documentation/enum.tsx
@@ -3,20 +3,20 @@ import * as React from 'react';
 import { EnumValue } from 'ts/types';
 
 interface EnumProps {
-	values: EnumValue[];
+    values: EnumValue[];
 }
 
 export function Enum(props: EnumProps) {
-	const values = _.map(props.values, (value, i) => {
-		const defaultValueIfAny = !_.isUndefined(value.defaultValue) ? ` = ${value.defaultValue}` : '';
-		return `\n\t${value.name}${defaultValueIfAny},`;
-	});
-	return (
-		<span>
-			{`{`}
-			{values}
-			<br />
-			{`}`}
-		</span>
-	);
+    const values = _.map(props.values, (value, i) => {
+        const defaultValueIfAny = !_.isUndefined(value.defaultValue) ? ` = ${value.defaultValue}` : '';
+        return `\n\t${value.name}${defaultValueIfAny},`;
+    });
+    return (
+        <span>
+            {`{`}
+            {values}
+            <br />
+            {`}`}
+        </span>
+    );
 }
diff --git a/packages/website/ts/pages/documentation/event_definition.tsx b/packages/website/ts/pages/documentation/event_definition.tsx
index 9274ae512..0e53e38e7 100644
--- a/packages/website/ts/pages/documentation/event_definition.tsx
+++ b/packages/website/ts/pages/documentation/event_definition.tsx
@@ -7,76 +7,76 @@ import { Event, EventArg, HeaderSizes } from 'ts/types';
 import { colors } from 'ts/utils/colors';
 
 interface EventDefinitionProps {
-	event: Event;
-	sectionName: string;
-	docsInfo: DocsInfo;
+    event: Event;
+    sectionName: string;
+    docsInfo: DocsInfo;
 }
 
 interface EventDefinitionState {
-	shouldShowAnchor: boolean;
+    shouldShowAnchor: boolean;
 }
 
 export class EventDefinition extends React.Component<EventDefinitionProps, EventDefinitionState> {
-	constructor(props: EventDefinitionProps) {
-		super(props);
-		this.state = {
-			shouldShowAnchor: false,
-		};
-	}
-	public render() {
-		const event = this.props.event;
-		return (
-			<div
-				id={`${this.props.sectionName}-${event.name}`}
-				className="pb2"
-				style={{ overflow: 'hidden', width: '100%' }}
-				onMouseOver={this._setAnchorVisibility.bind(this, true)}
-				onMouseOut={this._setAnchorVisibility.bind(this, false)}
-			>
-				<AnchorTitle
-					headerSize={HeaderSizes.H3}
-					title={`Event ${event.name}`}
-					id={event.name}
-					shouldShowAnchor={this.state.shouldShowAnchor}
-				/>
-				<div style={{ fontSize: 16 }}>
-					<pre>
-						<code className="hljs">{this._renderEventCode()}</code>
-					</pre>
-				</div>
-			</div>
-		);
-	}
-	private _renderEventCode() {
-		const indexed = <span style={{ color: colors.green }}> indexed</span>;
-		const eventArgs = _.map(this.props.event.eventArgs, (eventArg: EventArg) => {
-			const type = (
-				<Type type={eventArg.type} sectionName={this.props.sectionName} docsInfo={this.props.docsInfo} />
-			);
-			return (
-				<span key={`eventArg-${eventArg.name}`}>
-					{eventArg.name}
-					{eventArg.isIndexed ? indexed : ''}: {type},
-				</span>
-			);
-		});
-		const argList = _.reduce(eventArgs, (prev: React.ReactNode, curr: React.ReactNode) => {
-			return [prev, '\n\t', curr];
-		});
-		return (
-			<span>
-				{`{`}
-				<br />
-				{'\t'}
-				{argList}
-				<br />
-				{`}`}
-			</span>
-		);
-	}
-	private _setAnchorVisibility(shouldShowAnchor: boolean) {
-		this.setState({
-			shouldShowAnchor,
-		});
-	}
+    constructor(props: EventDefinitionProps) {
+        super(props);
+        this.state = {
+            shouldShowAnchor: false,
+        };
+    }
+    public render() {
+        const event = this.props.event;
+        return (
+            <div
+                id={`${this.props.sectionName}-${event.name}`}
+                className="pb2"
+                style={{ overflow: 'hidden', width: '100%' }}
+                onMouseOver={this._setAnchorVisibility.bind(this, true)}
+                onMouseOut={this._setAnchorVisibility.bind(this, false)}
+            >
+                <AnchorTitle
+                    headerSize={HeaderSizes.H3}
+                    title={`Event ${event.name}`}
+                    id={event.name}
+                    shouldShowAnchor={this.state.shouldShowAnchor}
+                />
+                <div style={{ fontSize: 16 }}>
+                    <pre>
+                        <code className="hljs">{this._renderEventCode()}</code>
+                    </pre>
+                </div>
+            </div>
+        );
+    }
+    private _renderEventCode() {
+        const indexed = <span style={{ color: colors.green }}> indexed</span>;
+        const eventArgs = _.map(this.props.event.eventArgs, (eventArg: EventArg) => {
+            const type = (
+                <Type type={eventArg.type} sectionName={this.props.sectionName} docsInfo={this.props.docsInfo} />
+            );
+            return (
+                <span key={`eventArg-${eventArg.name}`}>
+                    {eventArg.name}
+                    {eventArg.isIndexed ? indexed : ''}: {type},
+                </span>
+            );
+        });
+        const argList = _.reduce(eventArgs, (prev: React.ReactNode, curr: React.ReactNode) => {
+            return [prev, '\n\t', curr];
+        });
+        return (
+            <span>
+                {`{`}
+                <br />
+                {'\t'}
+                {argList}
+                <br />
+                {`}`}
+            </span>
+        );
+    }
+    private _setAnchorVisibility(shouldShowAnchor: boolean) {
+        this.setState({
+            shouldShowAnchor,
+        });
+    }
 }
diff --git a/packages/website/ts/pages/documentation/interface.tsx b/packages/website/ts/pages/documentation/interface.tsx
index ee07a2c50..16a772125 100644
--- a/packages/website/ts/pages/documentation/interface.tsx
+++ b/packages/website/ts/pages/documentation/interface.tsx
@@ -6,56 +6,56 @@ import { Type } from 'ts/pages/documentation/type';
 import { CustomType, TypeDocTypes } from 'ts/types';
 
 interface InterfaceProps {
-	type: CustomType;
-	sectionName: string;
-	docsInfo: DocsInfo;
+    type: CustomType;
+    sectionName: string;
+    docsInfo: DocsInfo;
 }
 
 export function Interface(props: InterfaceProps) {
-	const type = props.type;
-	const properties = _.map(type.children, property => {
-		return (
-			<span key={`property-${property.name}-${property.type}-${type.name}`}>
-				{property.name}:{' '}
-				{property.type.typeDocType !== TypeDocTypes.Reflection ? (
-					<Type type={property.type} sectionName={props.sectionName} docsInfo={props.docsInfo} />
-				) : (
-					<MethodSignature
-						method={property.type.method}
-						sectionName={props.sectionName}
-						shouldHideMethodName={true}
-						shouldUseArrowSyntax={true}
-						docsInfo={props.docsInfo}
-					/>
-				)},
-			</span>
-		);
-	});
-	const hasIndexSignature = !_.isUndefined(type.indexSignature);
-	if (hasIndexSignature) {
-		const is = type.indexSignature;
-		const param = (
-			<span key={`indexSigParams-${is.keyName}-${is.keyType}-${type.name}`}>
-				{is.keyName}: <Type type={is.keyType} sectionName={props.sectionName} docsInfo={props.docsInfo} />
-			</span>
-		);
-		properties.push(
-			<span key={`indexSignature-${type.name}-${is.keyType.name}`}>
-				[{param}]: {is.valueName},
-			</span>,
-		);
-	}
-	const propertyList = _.reduce(properties, (prev: React.ReactNode, curr: React.ReactNode) => {
-		return [prev, '\n\t', curr];
-	});
-	return (
-		<span>
-			{`{`}
-			<br />
-			{'\t'}
-			{propertyList}
-			<br />
-			{`}`}
-		</span>
-	);
+    const type = props.type;
+    const properties = _.map(type.children, property => {
+        return (
+            <span key={`property-${property.name}-${property.type}-${type.name}`}>
+                {property.name}:{' '}
+                {property.type.typeDocType !== TypeDocTypes.Reflection ? (
+                    <Type type={property.type} sectionName={props.sectionName} docsInfo={props.docsInfo} />
+                ) : (
+                    <MethodSignature
+                        method={property.type.method}
+                        sectionName={props.sectionName}
+                        shouldHideMethodName={true}
+                        shouldUseArrowSyntax={true}
+                        docsInfo={props.docsInfo}
+                    />
+                )},
+            </span>
+        );
+    });
+    const hasIndexSignature = !_.isUndefined(type.indexSignature);
+    if (hasIndexSignature) {
+        const is = type.indexSignature;
+        const param = (
+            <span key={`indexSigParams-${is.keyName}-${is.keyType}-${type.name}`}>
+                {is.keyName}: <Type type={is.keyType} sectionName={props.sectionName} docsInfo={props.docsInfo} />
+            </span>
+        );
+        properties.push(
+            <span key={`indexSignature-${type.name}-${is.keyType.name}`}>
+                [{param}]: {is.valueName},
+            </span>,
+        );
+    }
+    const propertyList = _.reduce(properties, (prev: React.ReactNode, curr: React.ReactNode) => {
+        return [prev, '\n\t', curr];
+    });
+    return (
+        <span>
+            {`{`}
+            <br />
+            {'\t'}
+            {propertyList}
+            <br />
+            {`}`}
+        </span>
+    );
 }
diff --git a/packages/website/ts/pages/documentation/method_block.tsx b/packages/website/ts/pages/documentation/method_block.tsx
index fb03cf5be..dfde5931b 100644
--- a/packages/website/ts/pages/documentation/method_block.tsx
+++ b/packages/website/ts/pages/documentation/method_block.tsx
@@ -10,133 +10,133 @@ import { colors } from 'ts/utils/colors';
 import { typeDocUtils } from 'ts/utils/typedoc_utils';
 
 interface MethodBlockProps {
-	method: SolidityMethod | TypescriptMethod;
-	sectionName: string;
-	libraryVersion: string;
-	typeDefinitionByName: TypeDefinitionByName;
-	docsInfo: DocsInfo;
+    method: SolidityMethod | TypescriptMethod;
+    sectionName: string;
+    libraryVersion: string;
+    typeDefinitionByName: TypeDefinitionByName;
+    docsInfo: DocsInfo;
 }
 
 interface MethodBlockState {
-	shouldShowAnchor: boolean;
+    shouldShowAnchor: boolean;
 }
 
 const styles: Styles = {
-	chip: {
-		fontSize: 13,
-		backgroundColor: colors.lightBlueA700,
-		color: colors.white,
-		height: 11,
-		borderRadius: 14,
-		marginTop: 19,
-		lineHeight: 0.8,
-	},
+    chip: {
+        fontSize: 13,
+        backgroundColor: colors.lightBlueA700,
+        color: colors.white,
+        height: 11,
+        borderRadius: 14,
+        marginTop: 19,
+        lineHeight: 0.8,
+    },
 };
 
 export class MethodBlock extends React.Component<MethodBlockProps, MethodBlockState> {
-	constructor(props: MethodBlockProps) {
-		super(props);
-		this.state = {
-			shouldShowAnchor: false,
-		};
-	}
-	public render() {
-		const method = this.props.method;
-		if (typeDocUtils.isPrivateOrProtectedProperty(method.name)) {
-			return null;
-		}
+    constructor(props: MethodBlockProps) {
+        super(props);
+        this.state = {
+            shouldShowAnchor: false,
+        };
+    }
+    public render() {
+        const method = this.props.method;
+        if (typeDocUtils.isPrivateOrProtectedProperty(method.name)) {
+            return null;
+        }
 
-		return (
-			<div
-				id={`${this.props.sectionName}-${method.name}`}
-				style={{ overflow: 'hidden', width: '100%' }}
-				className="pb4"
-				onMouseOver={this._setAnchorVisibility.bind(this, true)}
-				onMouseOut={this._setAnchorVisibility.bind(this, false)}
-			>
-				{!method.isConstructor && (
-					<div className="flex">
-						{(method as TypescriptMethod).isStatic && this._renderChip('Static')}
-						{(method as SolidityMethod).isConstant && this._renderChip('Constant')}
-						{(method as SolidityMethod).isPayable && this._renderChip('Payable')}
-						<AnchorTitle
-							headerSize={HeaderSizes.H3}
-							title={method.name}
-							id={`${this.props.sectionName}-${method.name}`}
-							shouldShowAnchor={this.state.shouldShowAnchor}
-						/>
-					</div>
-				)}
-				<code className="hljs">
-					<MethodSignature
-						method={method}
-						sectionName={this.props.sectionName}
-						typeDefinitionByName={this.props.typeDefinitionByName}
-						docsInfo={this.props.docsInfo}
-					/>
-				</code>
-				{(method as TypescriptMethod).source && (
-					<SourceLink
-						version={this.props.libraryVersion}
-						source={(method as TypescriptMethod).source}
-						baseUrl={this.props.docsInfo.packageUrl}
-						subPackageName={this.props.docsInfo.subPackageName}
-					/>
-				)}
-				{method.comment && <Comment comment={method.comment} className="py2" />}
-				{method.parameters &&
-					!_.isEmpty(method.parameters) && (
-						<div>
-							<h4 className="pb1 thin" style={{ borderBottom: '1px solid #e1e8ed' }}>
-								ARGUMENTS
-							</h4>
-							{this._renderParameterDescriptions(method.parameters)}
-						</div>
-					)}
-				{method.returnComment && (
-					<div className="pt1 comment">
-						<h4 className="pb1 thin" style={{ borderBottom: '1px solid #e1e8ed' }}>
-							RETURNS
-						</h4>
-						<Comment comment={method.returnComment} />
-					</div>
-				)}
-			</div>
-		);
-	}
-	private _renderChip(text: string) {
-		return (
-			<div className="p1 mr1" style={styles.chip}>
-				{text}
-			</div>
-		);
-	}
-	private _renderParameterDescriptions(parameters: Parameter[]) {
-		const descriptions = _.map(parameters, parameter => {
-			const isOptional = parameter.isOptional;
-			return (
-				<div
-					key={`param-description-${parameter.name}`}
-					className="flex pb1 mb2"
-					style={{ borderBottom: '1px solid #f0f4f7' }}
-				>
-					<div className="pl2 col lg-col-4 md-col-4 sm-col-12 col-12">
-						<div className="bold">{parameter.name}</div>
-						<div className="pt1" style={{ color: colors.grey, fontSize: 14 }}>
-							{isOptional && 'optional'}
-						</div>
-					</div>
-					<div className="col lg-col-8 md-col-8 sm-col-12 col-12">
-						{parameter.comment && <Comment comment={parameter.comment} />}
-					</div>
-				</div>
-			);
-		});
-		return descriptions;
-	}
-	private _setAnchorVisibility(shouldShowAnchor: boolean) {
-		this.setState({
-			shouldShowAnchor,
-		});
-	}
+        return (
+            <div
+                id={`${this.props.sectionName}-${method.name}`}
+                style={{ overflow: 'hidden', width: '100%' }}
+                className="pb4"
+                onMouseOver={this._setAnchorVisibility.bind(this, true)}
+                onMouseOut={this._setAnchorVisibility.bind(this, false)}
+            >
+                {!method.isConstructor && (
+                    <div className="flex">
+                        {(method as TypescriptMethod).isStatic && this._renderChip('Static')}
+                        {(method as SolidityMethod).isConstant && this._renderChip('Constant')}
+                        {(method as SolidityMethod).isPayable && this._renderChip('Payable')}
+                        <AnchorTitle
+                            headerSize={HeaderSizes.H3}
+                            title={method.name}
+                            id={`${this.props.sectionName}-${method.name}`}
+                            shouldShowAnchor={this.state.shouldShowAnchor}
+                        />
+                    </div>
+                )}
+                <code className="hljs">
+                    <MethodSignature
+                        method={method}
+                        sectionName={this.props.sectionName}
+                        typeDefinitionByName={this.props.typeDefinitionByName}
+                        docsInfo={this.props.docsInfo}
+                    />
+                </code>
+                {(method as TypescriptMethod).source && (
+                    <SourceLink
+                        version={this.props.libraryVersion}
+                        source={(method as TypescriptMethod).source}
+                        baseUrl={this.props.docsInfo.packageUrl}
+                        subPackageName={this.props.docsInfo.subPackageName}
+                    />
+                )}
+                {method.comment && <Comment comment={method.comment} className="py2" />}
+                {method.parameters &&
+                    !_.isEmpty(method.parameters) && (
+                        <div>
+                            <h4 className="pb1 thin" style={{ borderBottom: '1px solid #e1e8ed' }}>
+                                ARGUMENTS
+                            </h4>
+                            {this._renderParameterDescriptions(method.parameters)}
+                        </div>
+                    )}
+                {method.returnComment && (
+                    <div className="pt1 comment">
+                        <h4 className="pb1 thin" style={{ borderBottom: '1px solid #e1e8ed' }}>
+                            RETURNS
+                        </h4>
+                        <Comment comment={method.returnComment} />
+                    </div>
+                )}
+            </div>
+        );
+    }
+    private _renderChip(text: string) {
+        return (
+            <div className="p1 mr1" style={styles.chip}>
+                {text}
+            </div>
+        );
+    }
+    private _renderParameterDescriptions(parameters: Parameter[]) {
+        const descriptions = _.map(parameters, parameter => {
+            const isOptional = parameter.isOptional;
+            return (
+                <div
+                    key={`param-description-${parameter.name}`}
+                    className="flex pb1 mb2"
+                    style={{ borderBottom: '1px solid #f0f4f7' }}
+                >
+                    <div className="pl2 col lg-col-4 md-col-4 sm-col-12 col-12">
+                        <div className="bold">{parameter.name}</div>
+                        <div className="pt1" style={{ color: colors.grey, fontSize: 14 }}>
+                            {isOptional && 'optional'}
+                        </div>
+                    </div>
+                    <div className="col lg-col-8 md-col-8 sm-col-12 col-12">
+                        {parameter.comment && <Comment comment={parameter.comment} />}
+                    </div>
+                </div>
+            );
+        });
+        return descriptions;
+    }
+    private _setAnchorVisibility(shouldShowAnchor: boolean) {
+        this.setState({
+            shouldShowAnchor,
+        });
+    }
 }
diff --git a/packages/website/ts/pages/documentation/method_signature.tsx b/packages/website/ts/pages/documentation/method_signature.tsx
index 7c6bf96d2..041dcd093 100644
--- a/packages/website/ts/pages/documentation/method_signature.tsx
+++ b/packages/website/ts/pages/documentation/method_signature.tsx
@@ -6,94 +6,94 @@ import { Parameter, SolidityMethod, TypeDefinitionByName, TypescriptMethod } fro
 import { constants } from 'ts/utils/constants';
 
 interface MethodSignatureProps {
-	method: TypescriptMethod | SolidityMethod;
-	sectionName: string;
-	shouldHideMethodName?: boolean;
-	shouldUseArrowSyntax?: boolean;
-	typeDefinitionByName?: TypeDefinitionByName;
-	docsInfo: DocsInfo;
+    method: TypescriptMethod | SolidityMethod;
+    sectionName: string;
+    shouldHideMethodName?: boolean;
+    shouldUseArrowSyntax?: boolean;
+    typeDefinitionByName?: TypeDefinitionByName;
+    docsInfo: DocsInfo;
 }
 
 const defaultProps = {
-	shouldHideMethodName: false,
-	shouldUseArrowSyntax: false,
+    shouldHideMethodName: false,
+    shouldUseArrowSyntax: false,
 };
 
 export const MethodSignature: React.SFC<MethodSignatureProps> = (props: MethodSignatureProps) => {
-	const sectionName = constants.TYPES_SECTION_NAME;
-	const parameters = renderParameters(props.method, props.docsInfo, sectionName, props.typeDefinitionByName);
-	const paramString = _.reduce(parameters, (prev: React.ReactNode, curr: React.ReactNode) => {
-		return [prev, ', ', curr];
-	});
-	const methodName = props.shouldHideMethodName ? '' : props.method.name;
-	const typeParameterIfExists = _.isUndefined((props.method as TypescriptMethod).typeParameter)
-		? undefined
-		: renderTypeParameter(props.method, props.docsInfo, sectionName, props.typeDefinitionByName);
-	return (
-		<span>
-			{props.method.callPath}
-			{methodName}
-			{typeParameterIfExists}({paramString})
-			{props.shouldUseArrowSyntax ? ' => ' : ': '}{' '}
-			{props.method.returnType && (
-				<Type
-					type={props.method.returnType}
-					sectionName={sectionName}
-					typeDefinitionByName={props.typeDefinitionByName}
-					docsInfo={props.docsInfo}
-				/>
-			)}
-		</span>
-	);
+    const sectionName = constants.TYPES_SECTION_NAME;
+    const parameters = renderParameters(props.method, props.docsInfo, sectionName, props.typeDefinitionByName);
+    const paramString = _.reduce(parameters, (prev: React.ReactNode, curr: React.ReactNode) => {
+        return [prev, ', ', curr];
+    });
+    const methodName = props.shouldHideMethodName ? '' : props.method.name;
+    const typeParameterIfExists = _.isUndefined((props.method as TypescriptMethod).typeParameter)
+        ? undefined
+        : renderTypeParameter(props.method, props.docsInfo, sectionName, props.typeDefinitionByName);
+    return (
+        <span>
+            {props.method.callPath}
+            {methodName}
+            {typeParameterIfExists}({paramString})
+            {props.shouldUseArrowSyntax ? ' => ' : ': '}{' '}
+            {props.method.returnType && (
+                <Type
+                    type={props.method.returnType}
+                    sectionName={sectionName}
+                    typeDefinitionByName={props.typeDefinitionByName}
+                    docsInfo={props.docsInfo}
+                />
+            )}
+        </span>
+    );
 };
 
 MethodSignature.defaultProps = defaultProps;
 
 function renderParameters(
-	method: TypescriptMethod | SolidityMethod,
-	docsInfo: DocsInfo,
-	sectionName: string,
-	typeDefinitionByName?: TypeDefinitionByName,
+    method: TypescriptMethod | SolidityMethod,
+    docsInfo: DocsInfo,
+    sectionName: string,
+    typeDefinitionByName?: TypeDefinitionByName,
 ) {
-	const parameters = method.parameters;
-	const params = _.map(parameters, (p: Parameter) => {
-		const isOptional = p.isOptional;
-		const type = (
-			<Type
-				type={p.type}
-				sectionName={sectionName}
-				typeDefinitionByName={typeDefinitionByName}
-				docsInfo={docsInfo}
-			/>
-		);
-		return (
-			<span key={`param-${p.type}-${p.name}`}>
-				{p.name}
-				{isOptional && '?'}: {type}
-			</span>
-		);
-	});
-	return params;
+    const parameters = method.parameters;
+    const params = _.map(parameters, (p: Parameter) => {
+        const isOptional = p.isOptional;
+        const type = (
+            <Type
+                type={p.type}
+                sectionName={sectionName}
+                typeDefinitionByName={typeDefinitionByName}
+                docsInfo={docsInfo}
+            />
+        );
+        return (
+            <span key={`param-${p.type}-${p.name}`}>
+                {p.name}
+                {isOptional && '?'}: {type}
+            </span>
+        );
+    });
+    return params;
 }
 
 function renderTypeParameter(
-	method: TypescriptMethod,
-	docsInfo: DocsInfo,
-	sectionName: string,
-	typeDefinitionByName?: TypeDefinitionByName,
+    method: TypescriptMethod,
+    docsInfo: DocsInfo,
+    sectionName: string,
+    typeDefinitionByName?: TypeDefinitionByName,
 ) {
-	const typeParameter = method.typeParameter;
-	const typeParam = (
-		<span>
-			{`<${typeParameter.name} extends `}
-			<Type
-				type={typeParameter.type}
-				sectionName={sectionName}
-				typeDefinitionByName={typeDefinitionByName}
-				docsInfo={docsInfo}
-			/>
-			{`>`}
-		</span>
-	);
-	return typeParam;
+    const typeParameter = method.typeParameter;
+    const typeParam = (
+        <span>
+            {`<${typeParameter.name} extends `}
+            <Type
+                type={typeParameter.type}
+                sectionName={sectionName}
+                typeDefinitionByName={typeDefinitionByName}
+                docsInfo={docsInfo}
+            />
+            {`>`}
+        </span>
+    );
+    return typeParam;
 }
diff --git a/packages/website/ts/pages/documentation/source_link.tsx b/packages/website/ts/pages/documentation/source_link.tsx
index 32126b7da..6588ee39e 100644
--- a/packages/website/ts/pages/documentation/source_link.tsx
+++ b/packages/website/ts/pages/documentation/source_link.tsx
@@ -4,28 +4,28 @@ import { Source } from 'ts/types';
 import { colors } from 'ts/utils/colors';
 
 interface SourceLinkProps {
-	source: Source;
-	baseUrl: string;
-	version: string;
-	subPackageName: string;
+    source: Source;
+    baseUrl: string;
+    version: string;
+    subPackageName: string;
 }
 
 const packagesWithNamespace = ['connect'];
 
 export function SourceLink(props: SourceLinkProps) {
-	const src = props.source;
-	const url = props.baseUrl;
-	const pkg = props.subPackageName;
-	let tagPrefix = pkg;
-	if (_.includes(packagesWithNamespace, pkg)) {
-		tagPrefix = `@0xproject/${pkg}`;
-	}
-	const sourceCodeUrl = `${url}/blob/${tagPrefix}%40${props.version}/packages/${pkg}/${src.fileName}#L${src.line}`;
-	return (
-		<div className="pt2" style={{ fontSize: 14 }}>
-			<a href={sourceCodeUrl} target="_blank" className="underline" style={{ color: colors.grey }}>
-				Source
-			</a>
-		</div>
-	);
+    const src = props.source;
+    const url = props.baseUrl;
+    const pkg = props.subPackageName;
+    let tagPrefix = pkg;
+    if (_.includes(packagesWithNamespace, pkg)) {
+        tagPrefix = `@0xproject/${pkg}`;
+    }
+    const sourceCodeUrl = `${url}/blob/${tagPrefix}%40${props.version}/packages/${pkg}/${src.fileName}#L${src.line}`;
+    return (
+        <div className="pt2" style={{ fontSize: 14 }}>
+            <a href={sourceCodeUrl} target="_blank" className="underline" style={{ color: colors.grey }}>
+                Source
+            </a>
+        </div>
+    );
 }
diff --git a/packages/website/ts/pages/documentation/type.tsx b/packages/website/ts/pages/documentation/type.tsx
index 9a2696e22..e989e7129 100644
--- a/packages/website/ts/pages/documentation/type.tsx
+++ b/packages/website/ts/pages/documentation/type.tsx
@@ -11,202 +11,202 @@ import { utils } from 'ts/utils/utils';
 
 // Some types reference other libraries. For these types, we want to link the user to the relevant documentation.
 const typeToUrl: { [typeName: string]: string } = {
-	Web3: constants.URL_WEB3_DOCS,
-	Provider: constants.URL_WEB3_PROVIDER_DOCS,
-	BigNumber: constants.URL_BIGNUMBERJS_GITHUB,
-	DecodedLogEntryEvent: constants.URL_WEB3_DECODED_LOG_ENTRY_EVENT,
-	LogEntryEvent: constants.URL_WEB3_LOG_ENTRY_EVENT,
+    Web3: constants.URL_WEB3_DOCS,
+    Provider: constants.URL_WEB3_PROVIDER_DOCS,
+    BigNumber: constants.URL_BIGNUMBERJS_GITHUB,
+    DecodedLogEntryEvent: constants.URL_WEB3_DECODED_LOG_ENTRY_EVENT,
+    LogEntryEvent: constants.URL_WEB3_LOG_ENTRY_EVENT,
 };
 
 const typePrefix: { [typeName: string]: string } = {
-	Provider: 'Web3',
-	DecodedLogEntryEvent: 'Web3',
-	LogEntryEvent: 'Web3',
+    Provider: 'Web3',
+    DecodedLogEntryEvent: 'Web3',
+    LogEntryEvent: 'Web3',
 };
 
 const typeToSection: { [typeName: string]: string } = {
-	ExchangeWrapper: 'exchange',
-	TokenWrapper: 'token',
-	TokenRegistryWrapper: 'tokenRegistry',
-	EtherTokenWrapper: 'etherToken',
-	ProxyWrapper: 'proxy',
-	TokenTransferProxyWrapper: 'proxy',
-	OrderStateWatcher: 'orderWatcher',
+    ExchangeWrapper: 'exchange',
+    TokenWrapper: 'token',
+    TokenRegistryWrapper: 'tokenRegistry',
+    EtherTokenWrapper: 'etherToken',
+    ProxyWrapper: 'proxy',
+    TokenTransferProxyWrapper: 'proxy',
+    OrderStateWatcher: 'orderWatcher',
 };
 
 interface TypeProps {
-	type: TypeDef;
-	docsInfo: DocsInfo;
-	sectionName: string;
-	typeDefinitionByName?: TypeDefinitionByName;
+    type: TypeDef;
+    docsInfo: DocsInfo;
+    sectionName: string;
+    typeDefinitionByName?: TypeDefinitionByName;
 }
 
 // The return type needs to be `any` here so that we can recursively define <Type /> components within
 // <Type /> components (e.g when rendering the union type).
 export function Type(props: TypeProps): any {
-	const type = props.type;
-	const isReference = type.typeDocType === TypeDocTypes.Reference;
-	const isArray = type.typeDocType === TypeDocTypes.Array;
-	let typeNameColor = 'inherit';
-	let typeName: string | React.ReactNode;
-	let typeArgs: React.ReactNode[] = [];
-	switch (type.typeDocType) {
-		case TypeDocTypes.Intrinsic:
-		case TypeDocTypes.Unknown:
-			typeName = type.name;
-			typeNameColor = colors.orange;
-			break;
+    const type = props.type;
+    const isReference = type.typeDocType === TypeDocTypes.Reference;
+    const isArray = type.typeDocType === TypeDocTypes.Array;
+    let typeNameColor = 'inherit';
+    let typeName: string | React.ReactNode;
+    let typeArgs: React.ReactNode[] = [];
+    switch (type.typeDocType) {
+        case TypeDocTypes.Intrinsic:
+        case TypeDocTypes.Unknown:
+            typeName = type.name;
+            typeNameColor = colors.orange;
+            break;
 
-		case TypeDocTypes.Reference:
-			typeName = type.name;
-			typeArgs = _.map(type.typeArguments, (arg: TypeDef) => {
-				if (arg.typeDocType === TypeDocTypes.Array) {
-					const key = `type-${arg.elementType.name}-${arg.elementType.typeDocType}`;
-					return (
-						<span>
-							<Type
-								key={key}
-								type={arg.elementType}
-								sectionName={props.sectionName}
-								typeDefinitionByName={props.typeDefinitionByName}
-								docsInfo={props.docsInfo}
-							/>[]
-						</span>
-					);
-				} else {
-					const subType = (
-						<Type
-							key={`type-${arg.name}-${arg.value}-${arg.typeDocType}`}
-							type={arg}
-							sectionName={props.sectionName}
-							typeDefinitionByName={props.typeDefinitionByName}
-							docsInfo={props.docsInfo}
-						/>
-					);
-					return subType;
-				}
-			});
-			break;
+        case TypeDocTypes.Reference:
+            typeName = type.name;
+            typeArgs = _.map(type.typeArguments, (arg: TypeDef) => {
+                if (arg.typeDocType === TypeDocTypes.Array) {
+                    const key = `type-${arg.elementType.name}-${arg.elementType.typeDocType}`;
+                    return (
+                        <span>
+                            <Type
+                                key={key}
+                                type={arg.elementType}
+                                sectionName={props.sectionName}
+                                typeDefinitionByName={props.typeDefinitionByName}
+                                docsInfo={props.docsInfo}
+                            />[]
+                        </span>
+                    );
+                } else {
+                    const subType = (
+                        <Type
+                            key={`type-${arg.name}-${arg.value}-${arg.typeDocType}`}
+                            type={arg}
+                            sectionName={props.sectionName}
+                            typeDefinitionByName={props.typeDefinitionByName}
+                            docsInfo={props.docsInfo}
+                        />
+                    );
+                    return subType;
+                }
+            });
+            break;
 
-		case TypeDocTypes.StringLiteral:
-			typeName = `'${type.value}'`;
-			typeNameColor = colors.green;
-			break;
+        case TypeDocTypes.StringLiteral:
+            typeName = `'${type.value}'`;
+            typeNameColor = colors.green;
+            break;
 
-		case TypeDocTypes.Array:
-			typeName = type.elementType.name;
-			break;
+        case TypeDocTypes.Array:
+            typeName = type.elementType.name;
+            break;
 
-		case TypeDocTypes.Union:
-			const unionTypes = _.map(type.types, t => {
-				return (
-					<Type
-						key={`type-${t.name}-${t.value}-${t.typeDocType}`}
-						type={t}
-						sectionName={props.sectionName}
-						typeDefinitionByName={props.typeDefinitionByName}
-						docsInfo={props.docsInfo}
-					/>
-				);
-			});
-			typeName = _.reduce(unionTypes, (prev: React.ReactNode, curr: React.ReactNode) => {
-				return [prev, '|', curr];
-			});
-			break;
+        case TypeDocTypes.Union:
+            const unionTypes = _.map(type.types, t => {
+                return (
+                    <Type
+                        key={`type-${t.name}-${t.value}-${t.typeDocType}`}
+                        type={t}
+                        sectionName={props.sectionName}
+                        typeDefinitionByName={props.typeDefinitionByName}
+                        docsInfo={props.docsInfo}
+                    />
+                );
+            });
+            typeName = _.reduce(unionTypes, (prev: React.ReactNode, curr: React.ReactNode) => {
+                return [prev, '|', curr];
+            });
+            break;
 
-		case TypeDocTypes.TypeParameter:
-			typeName = type.name;
-			break;
+        case TypeDocTypes.TypeParameter:
+            typeName = type.name;
+            break;
 
-		default:
-			throw utils.spawnSwitchErr('type.typeDocType', type.typeDocType);
-	}
-	// HACK: Normalize BigNumber to simply BigNumber. For some reason the type
-	// name is unpredictably one or the other.
-	if (typeName === 'BigNumber') {
-		typeName = 'BigNumber';
-	}
-	const commaSeparatedTypeArgs = _.reduce(typeArgs, (prev: React.ReactNode, curr: React.ReactNode) => {
-		return [prev, ', ', curr];
-	});
+        default:
+            throw utils.spawnSwitchErr('type.typeDocType', type.typeDocType);
+    }
+    // HACK: Normalize BigNumber to simply BigNumber. For some reason the type
+    // name is unpredictably one or the other.
+    if (typeName === 'BigNumber') {
+        typeName = 'BigNumber';
+    }
+    const commaSeparatedTypeArgs = _.reduce(typeArgs, (prev: React.ReactNode, curr: React.ReactNode) => {
+        return [prev, ', ', curr];
+    });
 
-	const typeNameUrlIfExists = typeToUrl[typeName as string];
-	const typePrefixIfExists = typePrefix[typeName as string];
-	const sectionNameIfExists = typeToSection[typeName as string];
-	if (!_.isUndefined(typeNameUrlIfExists)) {
-		typeName = (
-			<a
-				href={typeNameUrlIfExists}
-				target="_blank"
-				className="text-decoration-none"
-				style={{ color: colors.lightBlueA700 }}
-			>
-				{!_.isUndefined(typePrefixIfExists) ? `${typePrefixIfExists}.` : ''}
-				{typeName}
-			</a>
-		);
-	} else if (
-		(isReference || isArray) &&
-		(props.docsInfo.isPublicType(typeName as string) || !_.isUndefined(sectionNameIfExists))
-	) {
-		const id = Math.random().toString();
-		const typeDefinitionAnchorId = _.isUndefined(sectionNameIfExists)
-			? `${props.sectionName}-${typeName}`
-			: sectionNameIfExists;
-		let typeDefinition;
-		if (props.typeDefinitionByName) {
-			typeDefinition = props.typeDefinitionByName[typeName as string];
-		}
-		typeName = (
-			<ScrollLink
-				to={typeDefinitionAnchorId}
-				offset={0}
-				duration={constants.DOCS_SCROLL_DURATION_MS}
-				containerId={constants.DOCS_CONTAINER_ID}
-			>
-				{_.isUndefined(typeDefinition) || utils.isUserOnMobile() ? (
-					<span
-						onClick={utils.setUrlHash.bind(null, typeDefinitionAnchorId)}
-						style={{ color: colors.lightBlueA700, cursor: 'pointer' }}
-					>
-						{typeName}
-					</span>
-				) : (
-					<span
-						data-tip={true}
-						data-for={id}
-						onClick={utils.setUrlHash.bind(null, typeDefinitionAnchorId)}
-						style={{
-							color: colors.lightBlueA700,
-							cursor: 'pointer',
-							display: 'inline-block',
-						}}
-					>
-						{typeName}
-						<ReactTooltip type="light" effect="solid" id={id} className="typeTooltip">
-							<TypeDefinition
-								sectionName={props.sectionName}
-								customType={typeDefinition}
-								shouldAddId={false}
-								docsInfo={props.docsInfo}
-							/>
-						</ReactTooltip>
-					</span>
-				)}
-			</ScrollLink>
-		);
-	}
-	return (
-		<span>
-			<span style={{ color: typeNameColor }}>{typeName}</span>
-			{isArray && '[]'}
-			{!_.isEmpty(typeArgs) && (
-				<span>
-					{'<'}
-					{commaSeparatedTypeArgs}
-					{'>'}
-				</span>
-			)}
-		</span>
-	);
+    const typeNameUrlIfExists = typeToUrl[typeName as string];
+    const typePrefixIfExists = typePrefix[typeName as string];
+    const sectionNameIfExists = typeToSection[typeName as string];
+    if (!_.isUndefined(typeNameUrlIfExists)) {
+        typeName = (
+            <a
+                href={typeNameUrlIfExists}
+                target="_blank"
+                className="text-decoration-none"
+                style={{ color: colors.lightBlueA700 }}
+            >
+                {!_.isUndefined(typePrefixIfExists) ? `${typePrefixIfExists}.` : ''}
+                {typeName}
+            </a>
+        );
+    } else if (
+        (isReference || isArray) &&
+        (props.docsInfo.isPublicType(typeName as string) || !_.isUndefined(sectionNameIfExists))
+    ) {
+        const id = Math.random().toString();
+        const typeDefinitionAnchorId = _.isUndefined(sectionNameIfExists)
+            ? `${props.sectionName}-${typeName}`
+            : sectionNameIfExists;
+        let typeDefinition;
+        if (props.typeDefinitionByName) {
+            typeDefinition = props.typeDefinitionByName[typeName as string];
+        }
+        typeName = (
+            <ScrollLink
+                to={typeDefinitionAnchorId}
+                offset={0}
+                duration={constants.DOCS_SCROLL_DURATION_MS}
+                containerId={constants.DOCS_CONTAINER_ID}
+            >
+                {_.isUndefined(typeDefinition) || utils.isUserOnMobile() ? (
+                    <span
+                        onClick={utils.setUrlHash.bind(null, typeDefinitionAnchorId)}
+                        style={{ color: colors.lightBlueA700, cursor: 'pointer' }}
+                    >
+                        {typeName}
+                    </span>
+                ) : (
+                    <span
+                        data-tip={true}
+                        data-for={id}
+                        onClick={utils.setUrlHash.bind(null, typeDefinitionAnchorId)}
+                        style={{
+                            color: colors.lightBlueA700,
+                            cursor: 'pointer',
+                            display: 'inline-block',
+                        }}
+                    >
+                        {typeName}
+                        <ReactTooltip type="light" effect="solid" id={id} className="typeTooltip">
+                            <TypeDefinition
+                                sectionName={props.sectionName}
+                                customType={typeDefinition}
+                                shouldAddId={false}
+                                docsInfo={props.docsInfo}
+                            />
+                        </ReactTooltip>
+                    </span>
+                )}
+            </ScrollLink>
+        );
+    }
+    return (
+        <span>
+            <span style={{ color: typeNameColor }}>{typeName}</span>
+            {isArray && '[]'}
+            {!_.isEmpty(typeArgs) && (
+                <span>
+                    {'<'}
+                    {commaSeparatedTypeArgs}
+                    {'>'}
+                </span>
+            )}
+        </span>
+    );
 }
diff --git a/packages/website/ts/pages/documentation/type_definition.tsx b/packages/website/ts/pages/documentation/type_definition.tsx
index 356926157..d46eec76c 100644
--- a/packages/website/ts/pages/documentation/type_definition.tsx
+++ b/packages/website/ts/pages/documentation/type_definition.tsx
@@ -13,113 +13,113 @@ import { colors } from 'ts/utils/colors';
 import { utils } from 'ts/utils/utils';
 
 interface TypeDefinitionProps {
-	sectionName: string;
-	customType: CustomType;
-	shouldAddId?: boolean;
-	docsInfo: DocsInfo;
+    sectionName: string;
+    customType: CustomType;
+    shouldAddId?: boolean;
+    docsInfo: DocsInfo;
 }
 
 interface TypeDefinitionState {
-	shouldShowAnchor: boolean;
+    shouldShowAnchor: boolean;
 }
 
 export class TypeDefinition extends React.Component<TypeDefinitionProps, TypeDefinitionState> {
-	public static defaultProps: Partial<TypeDefinitionProps> = {
-		shouldAddId: true,
-	};
-	constructor(props: TypeDefinitionProps) {
-		super(props);
-		this.state = {
-			shouldShowAnchor: false,
-		};
-	}
-	public render() {
-		const customType = this.props.customType;
-		if (!this.props.docsInfo.isPublicType(customType.name)) {
-			return null; // no-op
-		}
+    public static defaultProps: Partial<TypeDefinitionProps> = {
+        shouldAddId: true,
+    };
+    constructor(props: TypeDefinitionProps) {
+        super(props);
+        this.state = {
+            shouldShowAnchor: false,
+        };
+    }
+    public render() {
+        const customType = this.props.customType;
+        if (!this.props.docsInfo.isPublicType(customType.name)) {
+            return null; // no-op
+        }
 
-		let typePrefix: string;
-		let codeSnippet: React.ReactNode;
-		switch (customType.kindString) {
-			case KindString.Interface:
-				typePrefix = 'Interface';
-				codeSnippet = (
-					<Interface type={customType} sectionName={this.props.sectionName} docsInfo={this.props.docsInfo} />
-				);
-				break;
+        let typePrefix: string;
+        let codeSnippet: React.ReactNode;
+        switch (customType.kindString) {
+            case KindString.Interface:
+                typePrefix = 'Interface';
+                codeSnippet = (
+                    <Interface type={customType} sectionName={this.props.sectionName} docsInfo={this.props.docsInfo} />
+                );
+                break;
 
-			case KindString.Variable:
-				typePrefix = 'Enum';
-				codeSnippet = <CustomEnum type={customType} />;
-				break;
+            case KindString.Variable:
+                typePrefix = 'Enum';
+                codeSnippet = <CustomEnum type={customType} />;
+                break;
 
-			case KindString.Enumeration:
-				typePrefix = 'Enum';
-				const enumValues = _.map(customType.children, (c: CustomTypeChild) => {
-					return {
-						name: c.name,
-						defaultValue: c.defaultValue,
-					};
-				});
-				codeSnippet = <Enum values={enumValues} />;
-				break;
+            case KindString.Enumeration:
+                typePrefix = 'Enum';
+                const enumValues = _.map(customType.children, (c: CustomTypeChild) => {
+                    return {
+                        name: c.name,
+                        defaultValue: c.defaultValue,
+                    };
+                });
+                codeSnippet = <Enum values={enumValues} />;
+                break;
 
-			case KindString.TypeAlias:
-				typePrefix = 'Type Alias';
-				codeSnippet = (
-					<span>
-						<span style={{ color: colors.lightPurple }}>type</span> {customType.name} ={' '}
-						{customType.type.typeDocType !== TypeDocTypes.Reflection ? (
-							<Type
-								type={customType.type}
-								sectionName={this.props.sectionName}
-								docsInfo={this.props.docsInfo}
-							/>
-						) : (
-							<MethodSignature
-								method={customType.type.method}
-								sectionName={this.props.sectionName}
-								shouldHideMethodName={true}
-								shouldUseArrowSyntax={true}
-								docsInfo={this.props.docsInfo}
-							/>
-						)}
-					</span>
-				);
-				break;
+            case KindString.TypeAlias:
+                typePrefix = 'Type Alias';
+                codeSnippet = (
+                    <span>
+                        <span style={{ color: colors.lightPurple }}>type</span> {customType.name} ={' '}
+                        {customType.type.typeDocType !== TypeDocTypes.Reflection ? (
+                            <Type
+                                type={customType.type}
+                                sectionName={this.props.sectionName}
+                                docsInfo={this.props.docsInfo}
+                            />
+                        ) : (
+                            <MethodSignature
+                                method={customType.type.method}
+                                sectionName={this.props.sectionName}
+                                shouldHideMethodName={true}
+                                shouldUseArrowSyntax={true}
+                                docsInfo={this.props.docsInfo}
+                            />
+                        )}
+                    </span>
+                );
+                break;
 
-			default:
-				throw utils.spawnSwitchErr('type.kindString', customType.kindString);
-		}
+            default:
+                throw utils.spawnSwitchErr('type.kindString', customType.kindString);
+        }
 
-		const typeDefinitionAnchorId = `${this.props.sectionName}-${customType.name}`;
-		return (
-			<div
-				id={this.props.shouldAddId ? typeDefinitionAnchorId : ''}
-				className="pb2"
-				style={{ overflow: 'hidden', width: '100%' }}
-				onMouseOver={this._setAnchorVisibility.bind(this, true)}
-				onMouseOut={this._setAnchorVisibility.bind(this, false)}
-			>
-				<AnchorTitle
-					headerSize={HeaderSizes.H3}
-					title={`${typePrefix} ${customType.name}`}
-					id={this.props.shouldAddId ? typeDefinitionAnchorId : ''}
-					shouldShowAnchor={this.state.shouldShowAnchor}
-				/>
-				<div style={{ fontSize: 16 }}>
-					<pre>
-						<code className="hljs">{codeSnippet}</code>
-					</pre>
-				</div>
-				{customType.comment && <Comment comment={customType.comment} className="py2" />}
-			</div>
-		);
-	}
-	private _setAnchorVisibility(shouldShowAnchor: boolean) {
-		this.setState({
-			shouldShowAnchor,
-		});
-	}
+        const typeDefinitionAnchorId = `${this.props.sectionName}-${customType.name}`;
+        return (
+            <div
+                id={this.props.shouldAddId ? typeDefinitionAnchorId : ''}
+                className="pb2"
+                style={{ overflow: 'hidden', width: '100%' }}
+                onMouseOver={this._setAnchorVisibility.bind(this, true)}
+                onMouseOut={this._setAnchorVisibility.bind(this, false)}
+            >
+                <AnchorTitle
+                    headerSize={HeaderSizes.H3}
+                    title={`${typePrefix} ${customType.name}`}
+                    id={this.props.shouldAddId ? typeDefinitionAnchorId : ''}
+                    shouldShowAnchor={this.state.shouldShowAnchor}
+                />
+                <div style={{ fontSize: 16 }}>
+                    <pre>
+                        <code className="hljs">{codeSnippet}</code>
+                    </pre>
+                </div>
+                {customType.comment && <Comment comment={customType.comment} className="py2" />}
+            </div>
+        );
+    }
+    private _setAnchorVisibility(shouldShowAnchor: boolean) {
+        this.setState({
+            shouldShowAnchor,
+        });
+    }
 }
diff --git a/packages/website/ts/pages/faq/faq.tsx b/packages/website/ts/pages/faq/faq.tsx
index f437f5a8d..b4b5214a2 100644
--- a/packages/website/ts/pages/faq/faq.tsx
+++ b/packages/website/ts/pages/faq/faq.tsx
@@ -10,438 +10,438 @@ import { configs } from 'ts/utils/configs';
 import { constants } from 'ts/utils/constants';
 
 export interface FAQProps {
-	source: string;
-	location: Location;
+    source: string;
+    location: Location;
 }
 
 interface FAQState {}
 
 const styles: Styles = {
-	thin: {
-		fontWeight: 100,
-	},
+    thin: {
+        fontWeight: 100,
+    },
 };
 
 const sections: FAQSection[] = [
-	{
-		name: '0x Protocol',
-		questions: [
-			{
-				prompt: 'What is 0x?',
-				answer: (
-					<div>
-						At its core, 0x is an open and non-rent seeking protocol that facilitates trustless, low
-						friction exchange of Ethereum-based assets. Developers can use 0x as a platform to build
-						exchange applications on top of (<a
-							href={`${configs.BASE_URL}${WebsitePaths.ZeroExJs}#introduction`}
-							target="blank"
-						>
-							0x.js
-						</a>{' '}
-						is a Javascript library for interacting with the 0x protocol). For end users, 0x will be the
-						infrastructure of a wide variety of user-facing applications i.e.{' '}
-						<a href={`${configs.BASE_URL}${WebsitePaths.Portal}`} target="blank">
-							0x Portal
-						</a>, a decentralized application that facilitates trustless trading of Ethereum-based tokens
-						between known counterparties.
-					</div>
-				),
-			},
-			{
-				prompt: 'What problem does 0x solve?',
-				answer: (
-					<div>
-						In the two years since the Ethereum blockchain’s genesis block, numerous decentralized
-						applications (dApps) have created Ethereum smart contracts for peer-to-peer exchange. Rapid
-						iteration and a lack of best practices have left the blockchain scattered with proprietary and
-						application-specific implementations. As a result, end users are exposed to numerous smart
-						contracts of varying quality and security, with unique configuration processes and learning
-						curves, all of which implement the same functionality. This approach imposes unnecessary costs
-						on the network by fragmenting end users according to the particular dApp each user happens to be
-						using, eliminating valuable network effects around liquidity. 0x is the solution to this problem
-						by acting as modular, unopinionated building blocks that may be assembled and reconfigured.
-					</div>
-				),
-			},
-			{
-				prompt: 'How is 0x different from a centralized exchange like Poloniex or ShapeShift?',
-				answer: (
-					<div>
-						<ul>
-							<li>0x is a protocol for exchange, not a user-facing exchange application.</li>
-							<li>
-								0x is decentralized and trustless; there is no central party which can be hacked, run
-								away with customer funds or be subjected to government regulations. Hacks of Mt. Gox,
-								Shapeshift and Bitfinex have demonstrated that these types of systemic risks are
-								palpable.
-							</li>
-							<li>
-								Rather than a proprietary system that exists to extract rent for its owners, 0x is
-								public infrastructure that is funded by a globally distributed community of
-								stakeholders. While the protocol is free to use, it enables for-profit user-facing
-								exchange applications to be built on top of the protocol.
-							</li>
-						</ul>
-					</div>
-				),
-			},
-			{
-				prompt: 'If 0x protocol is free to use, where do transaction fees come in?',
-				answer: (
-					<div>
-						0x protocol uses off-chain order books to massively reduce friction costs for market makers and
-						ensure that the blockchain is only used for trade settlement. Hosting and maintaining an
-						off-chain order book is a service; to incent “Relayers” to provide this service they must be
-						able to charge transaction fees on trading activity. Relayers are free to set their transaction
-						fees to any value they desire. We expect Relayers to be highly competitive and transaction fees
-						to approach an efficient economic equilibrium over time.
-					</div>
-				),
-			},
-			{
-				prompt: 'What are the differences between 0x protocol and state channels?',
-				answer: (
-					<div>
-						<div>
-							Participants in a state channel pass cryptographically signed messages back and forth,
-							accumulating intermediate state changes without publishing them to the canonical chain until
-							the channel is closed. State channels are ideal for “bar tab” applications where numerous
-							intermediate state changes may be accumulated off-chain before being settled by a final
-							on-chain transaction (i.e. day trading, poker, turn-based games).
-						</div>
-						<ul>
-							<li>
-								While state channels drastically reduce the number of on-chain transactions for specific
-								use cases, numerous on-chain transactions and a security deposit are required to open
-								and safely close a state channel making them less efficient than 0x for executing
-								one-time trades.
-							</li>
-							<li>
-								State channels are isolated from the Ethereum blockchain meaning that they cannot
-								interact with smart contracts. 0x is designed to be integrated directly into smart
-								contracts so trades can be executed programmatically in a single line of Solidity code.
-							</li>
-						</ul>
-					</div>
-				),
-			},
-			{
-				prompt: 'What types of digital assets are supported by 0x?',
-				answer: (
-					<div>
-						0x supports all Ethereum-based assets that adhere to the ERC20 token standard. There are many
-						ERC20 tokens, worth a combined $2.2B, and more tokens are created each month. We believe that,
-						by 2020, thousands of assets will be tokenized and moved onto the Ethereum blockchain including
-						traditional securities such as equities, bonds and derivatives, fiat currencies and scarce
-						digital goods such as video game items. In the future, cross-blockchain solutions such as{' '}
-						<a href="https://cosmos.network/" target="_blank">
-							Cosmos
-						</a>{' '}
-						and{' '}
-						<a href="http://polkadot.io/" target="_blank">
-							Polkadot
-						</a>{' '}
-						will allow cryptocurrencies to freely move between blockchains and, naturally, currencies such
-						as Bitcoin will end up being represented as ERC20 tokens on the Ethereum blockchain.
-					</div>
-				),
-			},
-			{
-				prompt: '0x is open source: what prevents someone from forking the protocol?',
-				answer: (
-					<div>
-						Ethereum and Bitcoin are both open source protocols. Each protocol has been forked, but the
-						resulting clone networks have seen little adoption (as measured by transaction count or market
-						cap). This is because users have little to no incentive to switch over to a clone network if the
-						original has initial network effects and a talented developer team behind it. An exception is in
-						the case that a protocol includes a controversial feature such as a method of rent extraction or
-						a monetary policy that favors one group of users over another (Zcash developer subsidy - for
-						better or worse - resulted in Zclassic). Perceived inequality can provide a strong enough
-						incentive that users will fork the original protocol’s codebase and spin up a new network that
-						eliminates the controversial feature. In the case of 0x, there is no rent extraction and no
-						users are given special permissions. 0x protocol is upgradable. Cutting-edge technical
-						capabilities can be integrated into 0x via decentralized governance (see section below),
-						eliminating incentives to fork off of the original protocol and sacrifice the network effects
-						surrounding liquidity that result from the shared protocol and settlement layer.
-					</div>
-				),
-			},
-		],
-	},
-	{
-		name: '0x Token (ZRX)',
-		questions: [
-			{
-				prompt: 'Explain how the 0x protocol token (zrx) works.',
-				answer: (
-					<div>
-						<div>
-							0x protocol token (ZRX) is utilized in two ways: 1) to solve the{' '}
-							<a href="https://en.wikipedia.org/wiki/Coordination_game" target="_blank">
-								coordination problem
-							</a>{' '}
-							and drive network effects around liquidity, creating a feedback loop where early adopters of
-							the protocol benefit from wider adoption and 2) to be used for decentralized governance over
-							0x protocol's update mechanism. In more detail:
-						</div>
-						<ul>
-							<li>
-								ZRX tokens are used by Makers and Takers (market participants that generate and consume
-								orders, respectively) to pay transaction fees to Relayers (entities that host and
-								maintain public order books).
-							</li>
-							<li>
-								ZRX tokens are used for decentralized governance over 0x protocol’s update mechanism
-								which allows its underlying smart contracts to be replaced and improved over time. An
-								update mechanism is needed because 0x is built upon Ethereum’s rapidly evolving
-								technology stack, decentralized governance is needed because 0x protocol’s smart
-								contracts will have access to user funds and numerous dApps will need to plug into 0x
-								smart contracts. Decentralized governance ensures that this update process is secure and
-								minimizes disruption to the network.
-							</li>
-						</ul>
-					</div>
-				),
-			},
-			{
-				prompt: 'Why must transaction fees be denominated in 0x token (ZRX) rather than ETH?',
-				answer: (
-					<div>
-						0x protocol’s decentralized update mechanism is analogous to proof-of-stake. To maximize the
-						alignment of stakeholder and end user incentives, the staked asset must provide utility within
-						the protocol.
-					</div>
-				),
-			},
-			{
-				prompt: 'How will decentralized governance work?',
-				answer: (
-					<div>
-						Decentralized governance is an ongoing focus of research; it will involve token voting with ZRX.
-						Ultimately the solution will maximize security while also maximizing the protocol’s ability to
-						absorb new innovations. Until the governance structure is formalized and encoded within 0x DAO,
-						a multi-sig will be used as a placeholder.
-					</div>
-				),
-			},
-		],
-	},
-	{
-		name: 'ZRX Token Launch and Fund Use',
-		questions: [
-			{
-				prompt: 'What is the total supply of ZRX tokens?',
-				answer: <div>1,000,000,000 ZRX. Fixed supply.</div>,
-			},
-			{
-				prompt: 'When is the Token Launch? will there be a pre-sale?',
-				answer: <div>The token launch will be on August 15th, 2017. There will not be a pre-sale.</div>,
-			},
-			{
-				prompt: 'What will the token launch proceeds be used for?',
-				answer: (
-					<div>
-						100% of the proceeds raised in the token launch will be used to fund the development of free and
-						open source software, tools and infrastructure that support the protocol and surrounding
-						ecosystem. Check out our{' '}
-						<a
-							href="https://docs.google.com/document/d/1_RVa-_bkU92fWRsC8eNy4vYjcTt-WC8GtqyyjbTd-oY"
-							target="_blank"
-						>
-							development roadmap
-						</a>.
-					</div>
-				),
-			},
-			{
-				prompt: 'What will be the initial distribution of ZRX tokens?',
-				answer: (
-					<div>
-						<div className="center" style={{ width: '100%' }}>
-							<img style={{ width: 350 }} src="/images/zrx_pie_chart.png" />
-						</div>
-						<div className="py1">
-							<div className="bold pb1">Token Launch (50%)</div>
-							<div>
-								ZRX is inherently a governance token that plays a critical role in the process of
-								upgrading 0x protocol. We are fully committed to formulating a functional and
-								theoretically sound governance model and we plan to dedicate significant resources to
-								R&D.
-							</div>
-						</div>
-						<div className="py1">
-							<div className="bold pb1">Retained by 0x (15%)</div>
-							<div>
-								The 0x core development team will be able to sustain itself for approximately five years
-								using funds raised through the token launch. If 0x protocol proves to be as foundational
-								a technology as we believe it to be, the retained ZRX tokens will allow the 0x core
-								development team to sustain operations beyond the first 5 years.
-							</div>
-						</div>
-						<div className="py1">
-							<div className="bold pb1">Developer Fund (15%)</div>
-							<div>
-								The Developer Fund will be used to make targeted capital injections into high potential
-								projects and teams that are attempting to grow the 0x ecosystem, strategic partnerships,
-								hackathon prizes and community development activities.
-							</div>
-						</div>
-						<div className="py1">
-							<div className="bold pb1">Founding Team (10%)</div>
-							<div>
-								The founding team’s allocation of ZRX will vest over a traditional 4 year vesting
-								schedule with a one year cliff. We believe this should be standard practice for any team
-								that is committed to making their project a long term success.
-							</div>
-						</div>
-						<div className="py1">
-							<div className="bold pb1">Early Backers & Advisors (10%)</div>
-							<div>
-								Our backers and advisors have provided capital, resources and guidance that have allowed
-								us to fill out our team, setup a robust legal entity and build a fully functional
-								product before launching a token. As a result, we have a proven track record and can
-								offer a token that holds genuine utility.
-							</div>
-						</div>
-					</div>
-				),
-			},
-			{
-				prompt: 'Can I mine ZRX tokens?',
-				answer: (
-					<div>
-						No, the total supply of ZRX tokens is fixed and there is no continuous issuance model. Users
-						that facilitate trading over 0x protocol by operating a Relayer earn transaction fees
-						denominated in ZRX; as more trading activity is generated, more transaction fees are earned.
-					</div>
-				),
-			},
-			{
-				prompt: 'Will there be a lockup period for ZRX tokens sold in the token launch?',
-				answer: <div>No, ZRX tokens sold in the token launch will immediately be liquid.</div>,
-			},
-			{
-				prompt: 'Will there be a lockup period for tokens allocated to the founding team?',
-				answer: (
-					<div>
-						Yes. ZRX tokens allocated to founders, advisors and staff members will be released over a 4 year
-						vesting schedule with a 25% cliff upon completion of the initial token launch and 25% released
-						each subsequent year in monthly installments. Staff members hired after the token launch will
-						have a 4 year vesting schedule with a one year cliff.
-					</div>
-				),
-			},
-			{
-				prompt: 'Which cryptocurrencies will be accepted in the token launch?',
-				answer: <div>ETH.</div>,
-			},
-			{
-				prompt: 'When will 0x be live?',
-				answer: (
-					<div>
-						An alpha version of 0x has been live on our private test network since January 2017. Version 1.0
-						of 0x protocol will be deployed to the canonical Ethereum blockchain after a round of security
-						audits and prior to the public token launch. 0x will be using the 0x protocol during our token
-						launch.
-					</div>
-				),
-			},
-			{
-				prompt: 'Where can I find a development roadmap?',
-				answer: (
-					<div>
-						Check it out{' '}
-						<a
-							href="https://drive.google.com/open?id=14IP1N8mt3YdsAoqYTyruMnZswpklUs3THyS1VXx71fo"
-							target="_blank"
-						>
-							here
-						</a>.
-					</div>
-				),
-			},
-		],
-	},
-	{
-		name: 'Team',
-		questions: [
-			{
-				prompt: 'Where is 0x based?',
-				answer: <div>0x was founded in SF and is driven by a diverse group of contributors.</div>,
-			},
-			{
-				prompt: 'How can I get involved?',
-				answer: (
-					<div>
-						Join our{' '}
-						<a href={constants.URL_ZEROEX_CHAT} target="_blank">
-							Rocket.chat
-						</a>! As an open source project, 0x will rely on a worldwide community of passionate developers
-						to contribute proposals, ideas and code.
-					</div>
-				),
-			},
-			{
-				prompt: 'Why the name 0x?',
-				answer: (
-					<div>
-						0x is the prefix for hexadecimal numeric constants including Ethereum addresses. In a more
-						abstract context, as the first open protocol for exchange 0x represents the beginning of the end
-						for the exchange industry’s rent seeking oligopoly: zero exchange.
-					</div>
-				),
-			},
-			{
-				prompt: 'How do you pronounce 0x?',
-				answer: <div>We pronounce 0x as “zero-ex,” but you are free to pronounce it however you please.</div>,
-			},
-		],
-	},
+    {
+        name: '0x Protocol',
+        questions: [
+            {
+                prompt: 'What is 0x?',
+                answer: (
+                    <div>
+                        At its core, 0x is an open and non-rent seeking protocol that facilitates trustless, low
+                        friction exchange of Ethereum-based assets. Developers can use 0x as a platform to build
+                        exchange applications on top of (<a
+                            href={`${configs.BASE_URL}${WebsitePaths.ZeroExJs}#introduction`}
+                            target="blank"
+                        >
+                            0x.js
+                        </a>{' '}
+                        is a Javascript library for interacting with the 0x protocol). For end users, 0x will be the
+                        infrastructure of a wide variety of user-facing applications i.e.{' '}
+                        <a href={`${configs.BASE_URL}${WebsitePaths.Portal}`} target="blank">
+                            0x Portal
+                        </a>, a decentralized application that facilitates trustless trading of Ethereum-based tokens
+                        between known counterparties.
+                    </div>
+                ),
+            },
+            {
+                prompt: 'What problem does 0x solve?',
+                answer: (
+                    <div>
+                        In the two years since the Ethereum blockchain’s genesis block, numerous decentralized
+                        applications (dApps) have created Ethereum smart contracts for peer-to-peer exchange. Rapid
+                        iteration and a lack of best practices have left the blockchain scattered with proprietary and
+                        application-specific implementations. As a result, end users are exposed to numerous smart
+                        contracts of varying quality and security, with unique configuration processes and learning
+                        curves, all of which implement the same functionality. This approach imposes unnecessary costs
+                        on the network by fragmenting end users according to the particular dApp each user happens to be
+                        using, eliminating valuable network effects around liquidity. 0x is the solution to this problem
+                        by acting as modular, unopinionated building blocks that may be assembled and reconfigured.
+                    </div>
+                ),
+            },
+            {
+                prompt: 'How is 0x different from a centralized exchange like Poloniex or ShapeShift?',
+                answer: (
+                    <div>
+                        <ul>
+                            <li>0x is a protocol for exchange, not a user-facing exchange application.</li>
+                            <li>
+                                0x is decentralized and trustless; there is no central party which can be hacked, run
+                                away with customer funds or be subjected to government regulations. Hacks of Mt. Gox,
+                                Shapeshift and Bitfinex have demonstrated that these types of systemic risks are
+                                palpable.
+                            </li>
+                            <li>
+                                Rather than a proprietary system that exists to extract rent for its owners, 0x is
+                                public infrastructure that is funded by a globally distributed community of
+                                stakeholders. While the protocol is free to use, it enables for-profit user-facing
+                                exchange applications to be built on top of the protocol.
+                            </li>
+                        </ul>
+                    </div>
+                ),
+            },
+            {
+                prompt: 'If 0x protocol is free to use, where do transaction fees come in?',
+                answer: (
+                    <div>
+                        0x protocol uses off-chain order books to massively reduce friction costs for market makers and
+                        ensure that the blockchain is only used for trade settlement. Hosting and maintaining an
+                        off-chain order book is a service; to incent “Relayers” to provide this service they must be
+                        able to charge transaction fees on trading activity. Relayers are free to set their transaction
+                        fees to any value they desire. We expect Relayers to be highly competitive and transaction fees
+                        to approach an efficient economic equilibrium over time.
+                    </div>
+                ),
+            },
+            {
+                prompt: 'What are the differences between 0x protocol and state channels?',
+                answer: (
+                    <div>
+                        <div>
+                            Participants in a state channel pass cryptographically signed messages back and forth,
+                            accumulating intermediate state changes without publishing them to the canonical chain until
+                            the channel is closed. State channels are ideal for “bar tab” applications where numerous
+                            intermediate state changes may be accumulated off-chain before being settled by a final
+                            on-chain transaction (i.e. day trading, poker, turn-based games).
+                        </div>
+                        <ul>
+                            <li>
+                                While state channels drastically reduce the number of on-chain transactions for specific
+                                use cases, numerous on-chain transactions and a security deposit are required to open
+                                and safely close a state channel making them less efficient than 0x for executing
+                                one-time trades.
+                            </li>
+                            <li>
+                                State channels are isolated from the Ethereum blockchain meaning that they cannot
+                                interact with smart contracts. 0x is designed to be integrated directly into smart
+                                contracts so trades can be executed programmatically in a single line of Solidity code.
+                            </li>
+                        </ul>
+                    </div>
+                ),
+            },
+            {
+                prompt: 'What types of digital assets are supported by 0x?',
+                answer: (
+                    <div>
+                        0x supports all Ethereum-based assets that adhere to the ERC20 token standard. There are many
+                        ERC20 tokens, worth a combined $2.2B, and more tokens are created each month. We believe that,
+                        by 2020, thousands of assets will be tokenized and moved onto the Ethereum blockchain including
+                        traditional securities such as equities, bonds and derivatives, fiat currencies and scarce
+                        digital goods such as video game items. In the future, cross-blockchain solutions such as{' '}
+                        <a href="https://cosmos.network/" target="_blank">
+                            Cosmos
+                        </a>{' '}
+                        and{' '}
+                        <a href="http://polkadot.io/" target="_blank">
+                            Polkadot
+                        </a>{' '}
+                        will allow cryptocurrencies to freely move between blockchains and, naturally, currencies such
+                        as Bitcoin will end up being represented as ERC20 tokens on the Ethereum blockchain.
+                    </div>
+                ),
+            },
+            {
+                prompt: '0x is open source: what prevents someone from forking the protocol?',
+                answer: (
+                    <div>
+                        Ethereum and Bitcoin are both open source protocols. Each protocol has been forked, but the
+                        resulting clone networks have seen little adoption (as measured by transaction count or market
+                        cap). This is because users have little to no incentive to switch over to a clone network if the
+                        original has initial network effects and a talented developer team behind it. An exception is in
+                        the case that a protocol includes a controversial feature such as a method of rent extraction or
+                        a monetary policy that favors one group of users over another (Zcash developer subsidy - for
+                        better or worse - resulted in Zclassic). Perceived inequality can provide a strong enough
+                        incentive that users will fork the original protocol’s codebase and spin up a new network that
+                        eliminates the controversial feature. In the case of 0x, there is no rent extraction and no
+                        users are given special permissions. 0x protocol is upgradable. Cutting-edge technical
+                        capabilities can be integrated into 0x via decentralized governance (see section below),
+                        eliminating incentives to fork off of the original protocol and sacrifice the network effects
+                        surrounding liquidity that result from the shared protocol and settlement layer.
+                    </div>
+                ),
+            },
+        ],
+    },
+    {
+        name: '0x Token (ZRX)',
+        questions: [
+            {
+                prompt: 'Explain how the 0x protocol token (zrx) works.',
+                answer: (
+                    <div>
+                        <div>
+                            0x protocol token (ZRX) is utilized in two ways: 1) to solve the{' '}
+                            <a href="https://en.wikipedia.org/wiki/Coordination_game" target="_blank">
+                                coordination problem
+                            </a>{' '}
+                            and drive network effects around liquidity, creating a feedback loop where early adopters of
+                            the protocol benefit from wider adoption and 2) to be used for decentralized governance over
+                            0x protocol's update mechanism. In more detail:
+                        </div>
+                        <ul>
+                            <li>
+                                ZRX tokens are used by Makers and Takers (market participants that generate and consume
+                                orders, respectively) to pay transaction fees to Relayers (entities that host and
+                                maintain public order books).
+                            </li>
+                            <li>
+                                ZRX tokens are used for decentralized governance over 0x protocol’s update mechanism
+                                which allows its underlying smart contracts to be replaced and improved over time. An
+                                update mechanism is needed because 0x is built upon Ethereum’s rapidly evolving
+                                technology stack, decentralized governance is needed because 0x protocol’s smart
+                                contracts will have access to user funds and numerous dApps will need to plug into 0x
+                                smart contracts. Decentralized governance ensures that this update process is secure and
+                                minimizes disruption to the network.
+                            </li>
+                        </ul>
+                    </div>
+                ),
+            },
+            {
+                prompt: 'Why must transaction fees be denominated in 0x token (ZRX) rather than ETH?',
+                answer: (
+                    <div>
+                        0x protocol’s decentralized update mechanism is analogous to proof-of-stake. To maximize the
+                        alignment of stakeholder and end user incentives, the staked asset must provide utility within
+                        the protocol.
+                    </div>
+                ),
+            },
+            {
+                prompt: 'How will decentralized governance work?',
+                answer: (
+                    <div>
+                        Decentralized governance is an ongoing focus of research; it will involve token voting with ZRX.
+                        Ultimately the solution will maximize security while also maximizing the protocol’s ability to
+                        absorb new innovations. Until the governance structure is formalized and encoded within 0x DAO,
+                        a multi-sig will be used as a placeholder.
+                    </div>
+                ),
+            },
+        ],
+    },
+    {
+        name: 'ZRX Token Launch and Fund Use',
+        questions: [
+            {
+                prompt: 'What is the total supply of ZRX tokens?',
+                answer: <div>1,000,000,000 ZRX. Fixed supply.</div>,
+            },
+            {
+                prompt: 'When is the Token Launch? will there be a pre-sale?',
+                answer: <div>The token launch will be on August 15th, 2017. There will not be a pre-sale.</div>,
+            },
+            {
+                prompt: 'What will the token launch proceeds be used for?',
+                answer: (
+                    <div>
+                        100% of the proceeds raised in the token launch will be used to fund the development of free and
+                        open source software, tools and infrastructure that support the protocol and surrounding
+                        ecosystem. Check out our{' '}
+                        <a
+                            href="https://docs.google.com/document/d/1_RVa-_bkU92fWRsC8eNy4vYjcTt-WC8GtqyyjbTd-oY"
+                            target="_blank"
+                        >
+                            development roadmap
+                        </a>.
+                    </div>
+                ),
+            },
+            {
+                prompt: 'What will be the initial distribution of ZRX tokens?',
+                answer: (
+                    <div>
+                        <div className="center" style={{ width: '100%' }}>
+                            <img style={{ width: 350 }} src="/images/zrx_pie_chart.png" />
+                        </div>
+                        <div className="py1">
+                            <div className="bold pb1">Token Launch (50%)</div>
+                            <div>
+                                ZRX is inherently a governance token that plays a critical role in the process of
+                                upgrading 0x protocol. We are fully committed to formulating a functional and
+                                theoretically sound governance model and we plan to dedicate significant resources to
+                                R&D.
+                            </div>
+                        </div>
+                        <div className="py1">
+                            <div className="bold pb1">Retained by 0x (15%)</div>
+                            <div>
+                                The 0x core development team will be able to sustain itself for approximately five years
+                                using funds raised through the token launch. If 0x protocol proves to be as foundational
+                                a technology as we believe it to be, the retained ZRX tokens will allow the 0x core
+                                development team to sustain operations beyond the first 5 years.
+                            </div>
+                        </div>
+                        <div className="py1">
+                            <div className="bold pb1">Developer Fund (15%)</div>
+                            <div>
+                                The Developer Fund will be used to make targeted capital injections into high potential
+                                projects and teams that are attempting to grow the 0x ecosystem, strategic partnerships,
+                                hackathon prizes and community development activities.
+                            </div>
+                        </div>
+                        <div className="py1">
+                            <div className="bold pb1">Founding Team (10%)</div>
+                            <div>
+                                The founding team’s allocation of ZRX will vest over a traditional 4 year vesting
+                                schedule with a one year cliff. We believe this should be standard practice for any team
+                                that is committed to making their project a long term success.
+                            </div>
+                        </div>
+                        <div className="py1">
+                            <div className="bold pb1">Early Backers & Advisors (10%)</div>
+                            <div>
+                                Our backers and advisors have provided capital, resources and guidance that have allowed
+                                us to fill out our team, setup a robust legal entity and build a fully functional
+                                product before launching a token. As a result, we have a proven track record and can
+                                offer a token that holds genuine utility.
+                            </div>
+                        </div>
+                    </div>
+                ),
+            },
+            {
+                prompt: 'Can I mine ZRX tokens?',
+                answer: (
+                    <div>
+                        No, the total supply of ZRX tokens is fixed and there is no continuous issuance model. Users
+                        that facilitate trading over 0x protocol by operating a Relayer earn transaction fees
+                        denominated in ZRX; as more trading activity is generated, more transaction fees are earned.
+                    </div>
+                ),
+            },
+            {
+                prompt: 'Will there be a lockup period for ZRX tokens sold in the token launch?',
+                answer: <div>No, ZRX tokens sold in the token launch will immediately be liquid.</div>,
+            },
+            {
+                prompt: 'Will there be a lockup period for tokens allocated to the founding team?',
+                answer: (
+                    <div>
+                        Yes. ZRX tokens allocated to founders, advisors and staff members will be released over a 4 year
+                        vesting schedule with a 25% cliff upon completion of the initial token launch and 25% released
+                        each subsequent year in monthly installments. Staff members hired after the token launch will
+                        have a 4 year vesting schedule with a one year cliff.
+                    </div>
+                ),
+            },
+            {
+                prompt: 'Which cryptocurrencies will be accepted in the token launch?',
+                answer: <div>ETH.</div>,
+            },
+            {
+                prompt: 'When will 0x be live?',
+                answer: (
+                    <div>
+                        An alpha version of 0x has been live on our private test network since January 2017. Version 1.0
+                        of 0x protocol will be deployed to the canonical Ethereum blockchain after a round of security
+                        audits and prior to the public token launch. 0x will be using the 0x protocol during our token
+                        launch.
+                    </div>
+                ),
+            },
+            {
+                prompt: 'Where can I find a development roadmap?',
+                answer: (
+                    <div>
+                        Check it out{' '}
+                        <a
+                            href="https://drive.google.com/open?id=14IP1N8mt3YdsAoqYTyruMnZswpklUs3THyS1VXx71fo"
+                            target="_blank"
+                        >
+                            here
+                        </a>.
+                    </div>
+                ),
+            },
+        ],
+    },
+    {
+        name: 'Team',
+        questions: [
+            {
+                prompt: 'Where is 0x based?',
+                answer: <div>0x was founded in SF and is driven by a diverse group of contributors.</div>,
+            },
+            {
+                prompt: 'How can I get involved?',
+                answer: (
+                    <div>
+                        Join our{' '}
+                        <a href={constants.URL_ZEROEX_CHAT} target="_blank">
+                            Rocket.chat
+                        </a>! As an open source project, 0x will rely on a worldwide community of passionate developers
+                        to contribute proposals, ideas and code.
+                    </div>
+                ),
+            },
+            {
+                prompt: 'Why the name 0x?',
+                answer: (
+                    <div>
+                        0x is the prefix for hexadecimal numeric constants including Ethereum addresses. In a more
+                        abstract context, as the first open protocol for exchange 0x represents the beginning of the end
+                        for the exchange industry’s rent seeking oligopoly: zero exchange.
+                    </div>
+                ),
+            },
+            {
+                prompt: 'How do you pronounce 0x?',
+                answer: <div>We pronounce 0x as “zero-ex,” but you are free to pronounce it however you please.</div>,
+            },
+        ],
+    },
 ];
 
 export class FAQ extends React.Component<FAQProps, FAQState> {
-	public componentDidMount() {
-		window.scrollTo(0, 0);
-	}
-	public render() {
-		return (
-			<div>
-				<DocumentTitle title="0x FAQ" />
-				<TopBar blockchainIsLoaded={false} location={this.props.location} />
-				<div id="faq" className="mx-auto max-width-4 pt4" style={{ color: colors.grey800 }}>
-					<h1 className="center" style={{ ...styles.thin }}>
-						0x FAQ
-					</h1>
-					<div className="sm-px2 md-px2 lg-px0 pb4">{this._renderSections()}</div>
-				</div>
-				<Footer />
-			</div>
-		);
-	}
-	private _renderSections() {
-		const renderedSections = _.map(sections, (section: FAQSection, i: number) => {
-			const isFirstSection = i === 0;
-			return (
-				<div key={section.name}>
-					<h3>{section.name}</h3>
-					{this._renderQuestions(section.questions, isFirstSection)}
-				</div>
-			);
-		});
-		return renderedSections;
-	}
-	private _renderQuestions(questions: FAQQuestion[], isFirstSection: boolean) {
-		const renderedQuestions = _.map(questions, (question: FAQQuestion, i: number) => {
-			const isFirstQuestion = i === 0;
-			return (
-				<Question
-					key={question.prompt}
-					prompt={question.prompt}
-					answer={question.answer}
-					shouldDisplayExpanded={isFirstSection && isFirstQuestion}
-				/>
-			);
-		});
-		return renderedQuestions;
-	}
+    public componentDidMount() {
+        window.scrollTo(0, 0);
+    }
+    public render() {
+        return (
+            <div>
+                <DocumentTitle title="0x FAQ" />
+                <TopBar blockchainIsLoaded={false} location={this.props.location} />
+                <div id="faq" className="mx-auto max-width-4 pt4" style={{ color: colors.grey800 }}>
+                    <h1 className="center" style={{ ...styles.thin }}>
+                        0x FAQ
+                    </h1>
+                    <div className="sm-px2 md-px2 lg-px0 pb4">{this._renderSections()}</div>
+                </div>
+                <Footer />
+            </div>
+        );
+    }
+    private _renderSections() {
+        const renderedSections = _.map(sections, (section: FAQSection, i: number) => {
+            const isFirstSection = i === 0;
+            return (
+                <div key={section.name}>
+                    <h3>{section.name}</h3>
+                    {this._renderQuestions(section.questions, isFirstSection)}
+                </div>
+            );
+        });
+        return renderedSections;
+    }
+    private _renderQuestions(questions: FAQQuestion[], isFirstSection: boolean) {
+        const renderedQuestions = _.map(questions, (question: FAQQuestion, i: number) => {
+            const isFirstQuestion = i === 0;
+            return (
+                <Question
+                    key={question.prompt}
+                    prompt={question.prompt}
+                    answer={question.answer}
+                    shouldDisplayExpanded={isFirstSection && isFirstQuestion}
+                />
+            );
+        });
+        return renderedQuestions;
+    }
 }
diff --git a/packages/website/ts/pages/faq/question.tsx b/packages/website/ts/pages/faq/question.tsx
index 58cf674ef..988c04bc9 100644
--- a/packages/website/ts/pages/faq/question.tsx
+++ b/packages/website/ts/pages/faq/question.tsx
@@ -4,48 +4,48 @@ import * as React from 'react';
 import { colors } from 'ts/utils/colors';
 
 export interface QuestionProps {
-	prompt: string;
-	answer: React.ReactNode;
-	shouldDisplayExpanded: boolean;
+    prompt: string;
+    answer: React.ReactNode;
+    shouldDisplayExpanded: boolean;
 }
 
 interface QuestionState {
-	isExpanded: boolean;
+    isExpanded: boolean;
 }
 
 export class Question extends React.Component<QuestionProps, QuestionState> {
-	constructor(props: QuestionProps) {
-		super(props);
-		this.state = {
-			isExpanded: props.shouldDisplayExpanded,
-		};
-	}
-	public render() {
-		return (
-			<div className="py1">
-				<Card
-					initiallyExpanded={this.props.shouldDisplayExpanded}
-					onExpandChange={this._onExchangeChange.bind(this)}
-				>
-					<CardHeader
-						title={this.props.prompt}
-						style={{
-							borderBottom: this.state.isExpanded ? '1px solid rgba(0, 0, 0, 0.19)' : 'none',
-						}}
-						titleStyle={{ color: colors.darkerGrey }}
-						actAsExpander={true}
-						showExpandableButton={true}
-					/>
-					<CardText expandable={true}>
-						<div style={{ lineHeight: 1.4 }}>{this.props.answer}</div>
-					</CardText>
-				</Card>
-			</div>
-		);
-	}
-	private _onExchangeChange() {
-		this.setState({
-			isExpanded: !this.state.isExpanded,
-		});
-	}
+    constructor(props: QuestionProps) {
+        super(props);
+        this.state = {
+            isExpanded: props.shouldDisplayExpanded,
+        };
+    }
+    public render() {
+        return (
+            <div className="py1">
+                <Card
+                    initiallyExpanded={this.props.shouldDisplayExpanded}
+                    onExpandChange={this._onExchangeChange.bind(this)}
+                >
+                    <CardHeader
+                        title={this.props.prompt}
+                        style={{
+                            borderBottom: this.state.isExpanded ? '1px solid rgba(0, 0, 0, 0.19)' : 'none',
+                        }}
+                        titleStyle={{ color: colors.darkerGrey }}
+                        actAsExpander={true}
+                        showExpandableButton={true}
+                    />
+                    <CardText expandable={true}>
+                        <div style={{ lineHeight: 1.4 }}>{this.props.answer}</div>
+                    </CardText>
+                </Card>
+            </div>
+        );
+    }
+    private _onExchangeChange() {
+        this.setState({
+            isExpanded: !this.state.isExpanded,
+        });
+    }
 }
diff --git a/packages/website/ts/pages/landing/landing.tsx b/packages/website/ts/pages/landing/landing.tsx
index 742d94a0f..ca76497df 100644
--- a/packages/website/ts/pages/landing/landing.tsx
+++ b/packages/website/ts/pages/landing/landing.tsx
@@ -11,755 +11,755 @@ import { constants } from 'ts/utils/constants';
 import { utils } from 'ts/utils/utils';
 
 interface BoxContent {
-	title: string;
-	description: string;
-	imageUrl: string;
-	classNames: string;
+    title: string;
+    description: string;
+    imageUrl: string;
+    classNames: string;
 }
 interface AssetType {
-	title: string;
-	imageUrl: string;
-	style?: React.CSSProperties;
+    title: string;
+    imageUrl: string;
+    style?: React.CSSProperties;
 }
 interface UseCase {
-	imageUrl: string;
-	type: string;
-	description: string;
-	classNames: string;
-	style?: React.CSSProperties;
-	projectIconUrls: string[];
+    imageUrl: string;
+    type: string;
+    description: string;
+    classNames: string;
+    style?: React.CSSProperties;
+    projectIconUrls: string[];
 }
 interface Project {
-	logoFileName: string;
-	projectUrl: string;
+    logoFileName: string;
+    projectUrl: string;
 }
 
 const THROTTLE_TIMEOUT = 100;
 
 const boxContents: BoxContent[] = [
-	{
-		title: 'Trustless exchange',
-		description:
-			"Built on Ethereum's distributed network with no centralized \
+    {
+        title: 'Trustless exchange',
+        description:
+            "Built on Ethereum's distributed network with no centralized \
                       point of failure and no down time, each trade is settled atomically \
                       and without counterparty risk.",
-		imageUrl: '/images/landing/distributed_network.png',
-		classNames: '',
-	},
-	{
-		title: 'Shared liquidity',
-		description:
-			'By sharing a standard API, relayers can easily aggregate liquidity pools, \
+        imageUrl: '/images/landing/distributed_network.png',
+        classNames: '',
+    },
+    {
+        title: 'Shared liquidity',
+        description:
+            'By sharing a standard API, relayers can easily aggregate liquidity pools, \
                       creating network effects around liquidity that compound as more relayers come online.',
-		imageUrl: '/images/landing/liquidity.png',
-		classNames: 'mx-auto',
-	},
-	{
-		title: 'Open source',
-		description:
-			'0x is open source, permissionless and free to use. Trade directly with a known \
+        imageUrl: '/images/landing/liquidity.png',
+        classNames: 'mx-auto',
+    },
+    {
+        title: 'Open source',
+        description:
+            '0x is open source, permissionless and free to use. Trade directly with a known \
                       counterparty for free or pay a relayer some ZRX tokens to access their liquidity \
                       pool.',
-		imageUrl: '/images/landing/open_source.png',
-		classNames: 'right',
-	},
+        imageUrl: '/images/landing/open_source.png',
+        classNames: 'right',
+    },
 ];
 
 const projects: Project[] = [
-	{
-		logoFileName: 'ethfinex-top.png',
-		projectUrl: constants.PROJECT_URL_ETHFINEX,
-	},
-	{
-		logoFileName: 'radar_relay_top.png',
-		projectUrl: constants.PROJECT_URL_RADAR_RELAY,
-	},
-	{
-		logoFileName: 'paradex_top.png',
-		projectUrl: constants.PROJECT_URL_PARADEX,
-	},
-	{
-		logoFileName: 'the_ocean.png',
-		projectUrl: constants.PROJECT_URL_0CEAN,
-	},
-	{
-		logoFileName: 'dydx.png',
-		projectUrl: constants.PROJECT_URL_DYDX,
-	},
-	{
-		logoFileName: 'melonport.png',
-		projectUrl: constants.PROJECT_URL_MELONPORT,
-	},
-	{
-		logoFileName: 'maker.png',
-		projectUrl: constants.PROJECT_URL_MAKER,
-	},
-	{
-		logoFileName: 'dharma.png',
-		projectUrl: constants.PROJECT_URL_DHARMA,
-	},
-	{
-		logoFileName: 'lendroid.png',
-		projectUrl: constants.PROJECT_URL_LENDROID,
-	},
-	{
-		logoFileName: 'district0x.png',
-		projectUrl: constants.PROJECT_URL_DISTRICT_0X,
-	},
-	{
-		logoFileName: 'aragon.png',
-		projectUrl: constants.PROJECT_URL_ARAGON,
-	},
-	{
-		logoFileName: 'blocknet.png',
-		projectUrl: constants.PROJECT_URL_BLOCKNET,
-	},
-	{
-		logoFileName: 'status.png',
-		projectUrl: constants.PROJECT_URL_STATUS,
-	},
-	{
-		logoFileName: 'augur.png',
-		projectUrl: constants.PROJECT_URL_AUGUR,
-	},
-	{
-		logoFileName: 'anx.png',
-		projectUrl: constants.PROJECT_URL_OPEN_ANX,
-	},
-	{
-		logoFileName: 'auctus.png',
-		projectUrl: constants.PROJECT_URL_AUCTUS,
-	},
+    {
+        logoFileName: 'ethfinex-top.png',
+        projectUrl: constants.PROJECT_URL_ETHFINEX,
+    },
+    {
+        logoFileName: 'radar_relay_top.png',
+        projectUrl: constants.PROJECT_URL_RADAR_RELAY,
+    },
+    {
+        logoFileName: 'paradex_top.png',
+        projectUrl: constants.PROJECT_URL_PARADEX,
+    },
+    {
+        logoFileName: 'the_ocean.png',
+        projectUrl: constants.PROJECT_URL_0CEAN,
+    },
+    {
+        logoFileName: 'dydx.png',
+        projectUrl: constants.PROJECT_URL_DYDX,
+    },
+    {
+        logoFileName: 'melonport.png',
+        projectUrl: constants.PROJECT_URL_MELONPORT,
+    },
+    {
+        logoFileName: 'maker.png',
+        projectUrl: constants.PROJECT_URL_MAKER,
+    },
+    {
+        logoFileName: 'dharma.png',
+        projectUrl: constants.PROJECT_URL_DHARMA,
+    },
+    {
+        logoFileName: 'lendroid.png',
+        projectUrl: constants.PROJECT_URL_LENDROID,
+    },
+    {
+        logoFileName: 'district0x.png',
+        projectUrl: constants.PROJECT_URL_DISTRICT_0X,
+    },
+    {
+        logoFileName: 'aragon.png',
+        projectUrl: constants.PROJECT_URL_ARAGON,
+    },
+    {
+        logoFileName: 'blocknet.png',
+        projectUrl: constants.PROJECT_URL_BLOCKNET,
+    },
+    {
+        logoFileName: 'status.png',
+        projectUrl: constants.PROJECT_URL_STATUS,
+    },
+    {
+        logoFileName: 'augur.png',
+        projectUrl: constants.PROJECT_URL_AUGUR,
+    },
+    {
+        logoFileName: 'anx.png',
+        projectUrl: constants.PROJECT_URL_OPEN_ANX,
+    },
+    {
+        logoFileName: 'auctus.png',
+        projectUrl: constants.PROJECT_URL_AUCTUS,
+    },
 ];
 
 export interface LandingProps {
-	location: Location;
+    location: Location;
 }
 
 interface LandingState {
-	screenWidth: ScreenWidths;
+    screenWidth: ScreenWidths;
 }
 
 export class Landing extends React.Component<LandingProps, LandingState> {
-	private _throttledScreenWidthUpdate: () => void;
-	constructor(props: LandingProps) {
-		super(props);
-		this.state = {
-			screenWidth: utils.getScreenWidth(),
-		};
-		this._throttledScreenWidthUpdate = _.throttle(this._updateScreenWidth.bind(this), THROTTLE_TIMEOUT);
-	}
-	public componentDidMount() {
-		window.addEventListener('resize', this._throttledScreenWidthUpdate);
-		window.scrollTo(0, 0);
-	}
-	public componentWillUnmount() {
-		window.removeEventListener('resize', this._throttledScreenWidthUpdate);
-	}
-	public render() {
-		return (
-			<div id="landing" className="clearfix" style={{ color: colors.grey500 }}>
-				<DocumentTitle title="0x Protocol" />
-				<TopBar
-					blockchainIsLoaded={false}
-					location={this.props.location}
-					isNightVersion={true}
-					style={{ backgroundColor: colors.heroGrey, position: 'relative' }}
-				/>
-				{this._renderHero()}
-				{this._renderProjects()}
-				{this._renderTokenizationSection()}
-				{this._renderProtocolSection()}
-				{this._renderInfoBoxes()}
-				{this._renderBuildingBlocksSection()}
-				{this._renderUseCases()}
-				{this._renderCallToAction()}
-				<Footer />
-			</div>
-		);
-	}
-	private _renderHero() {
-		const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
-		const buttonLabelStyle: React.CSSProperties = {
-			textTransform: 'none',
-			fontSize: isSmallScreen ? 12 : 14,
-			fontWeight: 400,
-		};
-		const lightButtonStyle: React.CSSProperties = {
-			borderRadius: 6,
-			border: '1px solid #D8D8D8',
-			lineHeight: '33px',
-			height: 38,
-		};
-		const left = 'col lg-col-7 md-col-7 col-12 lg-pt4 md-pt4 sm-pt0 mt1 lg-pl4 md-pl4 sm-pl0 sm-px3 sm-center';
-		return (
-			<div className="clearfix py4" style={{ backgroundColor: colors.heroGrey }}>
-				<div className="mx-auto max-width-4 clearfix">
-					<div className="lg-pt4 md-pt4 sm-pt2 lg-pb4 md-pb4 lg-my4 md-my4 sm-mt2 sm-mb4 clearfix">
-						<div className="col lg-col-5 md-col-5 col-12 sm-center">
-							<img src="/images/landing/hero_chip_image.png" height={isSmallScreen ? 300 : 395} />
-						</div>
-						<div className={left} style={{ color: colors.white }}>
-							<div style={{ paddingLeft: isSmallScreen ? 0 : 12 }}>
-								<div
-									className="sm-pb2"
-									style={{
-										fontFamily: 'Roboto Mono',
-										fontSize: isSmallScreen ? 26 : 34,
-									}}
-								>
-									Powering decentralized exchange
-								</div>
-								<div
-									className="pt2 h5 sm-mx-auto"
-									style={{
-										maxWidth: 446,
-										fontFamily: 'Roboto Mono',
-										lineHeight: 1.7,
-										fontWeight: 300,
-									}}
-								>
-									0x is an open, permissionless protocol allowing for ERC20 tokens to be traded on the
-									Ethereum blockchain.
-								</div>
-								<div className="pt3 clearfix sm-mx-auto" style={{ maxWidth: 342 }}>
-									<div className="lg-pr2 md-pr2 col col-6 sm-center">
-										<Link to={WebsitePaths.ZeroExJs} className="text-decoration-none">
-											<RaisedButton
-												style={{ borderRadius: 6, minWidth: 157.36 }}
-												buttonStyle={{ borderRadius: 6 }}
-												labelStyle={buttonLabelStyle}
-												label="Build on 0x"
-												onClick={_.noop}
-											/>
-										</Link>
-									</div>
-									<div className="col col-6 sm-center">
-										<a
-											href={constants.URL_ZEROEX_CHAT}
-											target="_blank"
-											className="text-decoration-none"
-										>
-											<RaisedButton
-												style={{ borderRadius: 6, minWidth: 150 }}
-												buttonStyle={lightButtonStyle}
-												labelColor="white"
-												backgroundColor={colors.heroGrey}
-												labelStyle={buttonLabelStyle}
-												label="Join the community"
-												onClick={_.noop}
-											/>
-										</a>
-									</div>
-								</div>
-							</div>
-						</div>
-					</div>
-				</div>
-			</div>
-		);
-	}
-	private _renderProjects() {
-		const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
-		const isMediumScreen = this.state.screenWidth === ScreenWidths.Md;
-		const projectList = _.map(projects, (project: Project, i: number) => {
-			const colWidth = isSmallScreen ? 3 : isMediumScreen ? 4 : 2 - i % 2;
-			return (
-				<div key={`project-${project.logoFileName}`} className={`col col-${colWidth} center`}>
-					<div>
-						<a href={project.projectUrl} target="_blank" className="text-decoration-none">
-							<img
-								src={`/images/landing/project_logos/${project.logoFileName}`}
-								height={isSmallScreen ? 60 : 92}
-							/>
-						</a>
-					</div>
-				</div>
-			);
-		});
-		const titleStyle: React.CSSProperties = {
-			fontFamily: 'Roboto Mono',
-			color: colors.grey,
-			textTransform: 'uppercase',
-			fontWeight: 300,
-			letterSpacing: 3,
-		};
-		return (
-			<div className="clearfix py4" style={{ backgroundColor: colors.projectsGrey }}>
-				<div className="mx-auto max-width-4 clearfix sm-px3">
-					<div className="h4 pb3 md-pl3 sm-pl2" style={titleStyle}>
-						Projects building on 0x
-					</div>
-					<div className="clearfix">{projectList}</div>
-					<div
-						className="pt3 mx-auto center"
-						style={{
-							color: colors.landingLinkGrey,
-							fontFamily: 'Roboto Mono',
-							maxWidth: 300,
-							fontSize: 14,
-						}}
-					>
-						view the{' '}
-						<Link
-							to={`${WebsitePaths.Wiki}#List-of-Projects-Using-0x-Protocol`}
-							className="text-decoration-none underline"
-							style={{ color: colors.landingLinkGrey }}
-						>
-							full list
-						</Link>
-					</div>
-				</div>
-			</div>
-		);
-	}
-	private _renderTokenizationSection() {
-		const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
-		return (
-			<div className="clearfix lg-py4 md-py4 sm-pb4 sm-pt2" style={{ backgroundColor: colors.grey100 }}>
-				<div className="mx-auto max-width-4 py4 clearfix">
-					{isSmallScreen && this._renderTokenCloud()}
-					<div className="col lg-col-6 md-col-6 col-12">
-						<div className="mx-auto" style={{ maxWidth: 385, paddingTop: 7 }}>
-							<div className="lg-h1 md-h1 sm-h2 sm-center sm-pt3" style={{ fontFamily: 'Roboto Mono' }}>
-								The world's value is becoming tokenized
-							</div>
-							<div
-								className="pb2 lg-pt2 md-pt2 sm-pt3 sm-px3 h5 sm-center"
-								style={{ fontFamily: 'Roboto Mono', lineHeight: 1.7 }}
-							>
-								{isSmallScreen ? (
-									<span>
-										The Ethereum blockchain is an open, borderless financial system that represents
-										a wide variety of assets as cryptographic tokens. In the future, most digital
-										assets and goods will be tokenized.
-									</span>
-								) : (
-									<div>
-										<div>
-											The Ethereum blockchain is an open, borderless financial system that
-											represents
-										</div>
-										<div>
-											a wide variety of assets as cryptographic tokens. In the future, most
-											digital assets and goods will be tokenized.
-										</div>
-									</div>
-								)}
-							</div>
-							<div className="flex pt1 sm-px3">{this._renderAssetTypes()}</div>
-						</div>
-					</div>
-					{!isSmallScreen && this._renderTokenCloud()}
-				</div>
-			</div>
-		);
-	}
-	private _renderProtocolSection() {
-		const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
-		return (
-			<div className="clearfix lg-py4 md-py4 sm-pt4" style={{ backgroundColor: colors.heroGrey }}>
-				<div className="mx-auto max-width-4 lg-py4 md-py4 sm-pt4 clearfix">
-					<div className="col lg-col-6 md-col-6 col-12 sm-center">
-						<img src="/images/landing/relayer_diagram.png" height={isSmallScreen ? 326 : 426} />
-					</div>
-					<div
-						className="col lg-col-6 md-col-6 col-12 lg-pr3 md-pr3 sm-mx-auto"
-						style={{
-							color: colors.beigeWhite,
-							paddingTop: 8,
-							maxWidth: isSmallScreen ? 'none' : 445,
-						}}
-					>
-						<div className="lg-h1 md-h1 sm-h2 pb1 sm-pt3 sm-center" style={{ fontFamily: 'Roboto Mono' }}>
-							<div>Off-chain order relay</div>
-							<div>On-chain settlement</div>
-						</div>
-						<div
-							className="pb2 pt2 h5 sm-center sm-px3 sm-mx-auto"
-							style={{
-								fontFamily: 'Roboto Mono',
-								lineHeight: 1.7,
-								fontWeight: 300,
-								maxWidth: 445,
-							}}
-						>
-							In 0x protocol, orders are transported off-chain, massively reducing gas costs and
-							eliminating blockchain bloat. Relayers help broadcast orders and collect a fee each time
-							they facilitate a trade. Anyone can build a relayer.
-						</div>
-						<div
-							className="pt3 sm-mx-auto sm-px3"
-							style={{
-								color: colors.landingLinkGrey,
-								maxWidth: isSmallScreen ? 412 : 'none',
-							}}
-						>
-							<div className="flex" style={{ fontSize: 18 }}>
-								<div
-									className="lg-h4 md-h4 sm-h5"
-									style={{
-										letterSpacing: isSmallScreen ? 1 : 3,
-										fontFamily: 'Roboto Mono',
-									}}
-								>
-									RELAYERS BUILDING ON 0X
-								</div>
-								<div className="h5" style={{ marginLeft: isSmallScreen ? 26 : 49 }}>
-									<Link
-										to={`${WebsitePaths.Wiki}#List-of-Projects-Using-0x-Protocol`}
-										className="text-decoration-none underline"
-										style={{
-											color: colors.landingLinkGrey,
-											fontFamily: 'Roboto Mono',
-										}}
-									>
-										view all
-									</Link>
-								</div>
-							</div>
-							<div className="lg-flex md-flex sm-clearfix pt3" style={{ opacity: 0.4 }}>
-								<div className="col col-4 sm-center">
-									<img
-										src="/images/landing/ethfinex.png"
-										style={{ height: isSmallScreen ? 85 : 107 }}
-									/>
-								</div>
-								<div className="col col-4 center">
-									<img
-										src="/images/landing/radar_relay.png"
-										style={{ height: isSmallScreen ? 85 : 107 }}
-									/>
-								</div>
-								<div className="col col-4 sm-center" style={{ textAlign: 'right' }}>
-									<img
-										src="/images/landing/paradex.png"
-										style={{ height: isSmallScreen ? 85 : 107 }}
-									/>
-								</div>
-							</div>
-						</div>
-					</div>
-				</div>
-			</div>
-		);
-	}
-	private _renderBuildingBlocksSection() {
-		const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
-		const descriptionStyle: React.CSSProperties = {
-			fontFamily: 'Roboto Mono',
-			lineHeight: isSmallScreen ? 1.5 : 2,
-			fontWeight: 300,
-			fontSize: 15,
-			maxWidth: isSmallScreen ? 375 : 'none',
-		};
-		const callToActionStyle: React.CSSProperties = {
-			fontFamily: 'Roboto Mono',
-			fontSize: 15,
-			fontWeight: 300,
-			maxWidth: isSmallScreen ? 375 : 441,
-		};
-		return (
-			<div className="clearfix lg-pt4 md-pt4" style={{ backgroundColor: colors.heroGrey }}>
-				<div className="mx-auto max-width-4 lg-pt4 md-pt4 lg-mb4 md-mb4 sm-mb2 clearfix">
-					{isSmallScreen && this._renderBlockChipImage()}
-					<div
-						className="col lg-col-6 md-col-6 col-12 lg-pr3 md-pr3 sm-px3"
-						style={{ color: colors.beigeWhite }}
-					>
-						<div
-							className="pb1 lg-pt4 md-pt4 sm-pt3 lg-h1 md-h1 sm-h2 sm-px3 sm-center"
-							style={{ fontFamily: 'Roboto Mono' }}
-						>
-							A building block for dApps
-						</div>
-						<div className="pb3 pt2 sm-mx-auto sm-center" style={descriptionStyle}>
-							0x protocol is a pluggable building block for dApps that require exchange functionality.
-							Join the many developers that are already using 0x in their web applications and smart
-							contracts.
-						</div>
-						<div className="sm-mx-auto sm-center" style={callToActionStyle}>
-							Learn how in our{' '}
-							<Link
-								to={WebsitePaths.ZeroExJs}
-								className="text-decoration-none underline"
-								style={{ color: colors.beigeWhite, fontFamily: 'Roboto Mono' }}
-							>
-								0x.js
-							</Link>{' '}
-							and{' '}
-							<Link
-								to={WebsitePaths.SmartContracts}
-								className="text-decoration-none underline"
-								style={{ color: colors.beigeWhite, fontFamily: 'Roboto Mono' }}
-							>
-								smart contract
-							</Link>{' '}
-							docs
-						</div>
-					</div>
-					{!isSmallScreen && this._renderBlockChipImage()}
-				</div>
-			</div>
-		);
-	}
-	private _renderBlockChipImage() {
-		const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
-		return (
-			<div className="col lg-col-6 md-col-6 col-12 sm-center">
-				<img src="/images/landing/0x_chips.png" height={isSmallScreen ? 240 : 368} />
-			</div>
-		);
-	}
-	private _renderTokenCloud() {
-		const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
-		return (
-			<div className="col lg-col-6 md-col-6 col-12 center">
-				<img src="/images/landing/tokenized_world.png" height={isSmallScreen ? 280 : 364.5} />
-			</div>
-		);
-	}
-	private _renderAssetTypes() {
-		const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
-		const assetTypes: AssetType[] = [
-			{
-				title: 'Currency',
-				imageUrl: '/images/landing/currency.png',
-			},
-			{
-				title: 'Traditional assets',
-				imageUrl: '/images/landing/stocks.png',
-				style: {
-					paddingLeft: isSmallScreen ? 41 : 56,
-					paddingRight: isSmallScreen ? 41 : 56,
-				},
-			},
-			{
-				title: 'Digital goods',
-				imageUrl: '/images/landing/digital_goods.png',
-			},
-		];
-		const assets = _.map(assetTypes, (assetType: AssetType) => {
-			const style = _.isUndefined(assetType.style) ? {} : assetType.style;
-			return (
-				<div key={`asset-${assetType.title}`} className="center" style={{ opacity: 0.8, ...style }}>
-					<div>
-						<img src={assetType.imageUrl} height="80" />
-					</div>
-					<div
-						style={{
-							fontFamily: 'Roboto Mono',
-							fontSize: 13.5,
-							fontWeight: 400,
-							opacity: 0.75,
-						}}
-					>
-						{assetType.title}
-					</div>
-				</div>
-			);
-		});
-		return assets;
-	}
-	private _renderInfoBoxes() {
-		const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
-		const boxStyle: React.CSSProperties = {
-			maxWidth: 252,
-			height: 386,
-			backgroundColor: colors.grey50,
-			borderRadius: 5,
-			padding: '10px 24px 24px',
-		};
-		const boxes = _.map(boxContents, (boxContent: BoxContent) => {
-			return (
-				<div key={`box-${boxContent.title}`} className="col lg-col-4 md-col-4 col-12 sm-pb4">
-					<div className={`center sm-mx-auto ${!isSmallScreen && boxContent.classNames}`} style={boxStyle}>
-						<div>
-							<img src={boxContent.imageUrl} style={{ height: 210 }} />
-						</div>
-						<div className="h3" style={{ color: 'black', fontFamily: 'Roboto Mono' }}>
-							{boxContent.title}
-						</div>
-						<div className="pt2 pb2" style={{ fontFamily: 'Roboto Mono', fontSize: 14 }}>
-							{boxContent.description}
-						</div>
-					</div>
-				</div>
-			);
-		});
-		return (
-			<div className="clearfix" style={{ backgroundColor: colors.heroGrey }}>
-				<div className="mx-auto py4 sm-mt2 clearfix" style={{ maxWidth: '60em' }}>
-					{boxes}
-				</div>
-			</div>
-		);
-	}
-	private _renderUseCases() {
-		const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
+    private _throttledScreenWidthUpdate: () => void;
+    constructor(props: LandingProps) {
+        super(props);
+        this.state = {
+            screenWidth: utils.getScreenWidth(),
+        };
+        this._throttledScreenWidthUpdate = _.throttle(this._updateScreenWidth.bind(this), THROTTLE_TIMEOUT);
+    }
+    public componentDidMount() {
+        window.addEventListener('resize', this._throttledScreenWidthUpdate);
+        window.scrollTo(0, 0);
+    }
+    public componentWillUnmount() {
+        window.removeEventListener('resize', this._throttledScreenWidthUpdate);
+    }
+    public render() {
+        return (
+            <div id="landing" className="clearfix" style={{ color: colors.grey500 }}>
+                <DocumentTitle title="0x Protocol" />
+                <TopBar
+                    blockchainIsLoaded={false}
+                    location={this.props.location}
+                    isNightVersion={true}
+                    style={{ backgroundColor: colors.heroGrey, position: 'relative' }}
+                />
+                {this._renderHero()}
+                {this._renderProjects()}
+                {this._renderTokenizationSection()}
+                {this._renderProtocolSection()}
+                {this._renderInfoBoxes()}
+                {this._renderBuildingBlocksSection()}
+                {this._renderUseCases()}
+                {this._renderCallToAction()}
+                <Footer />
+            </div>
+        );
+    }
+    private _renderHero() {
+        const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
+        const buttonLabelStyle: React.CSSProperties = {
+            textTransform: 'none',
+            fontSize: isSmallScreen ? 12 : 14,
+            fontWeight: 400,
+        };
+        const lightButtonStyle: React.CSSProperties = {
+            borderRadius: 6,
+            border: '1px solid #D8D8D8',
+            lineHeight: '33px',
+            height: 38,
+        };
+        const left = 'col lg-col-7 md-col-7 col-12 lg-pt4 md-pt4 sm-pt0 mt1 lg-pl4 md-pl4 sm-pl0 sm-px3 sm-center';
+        return (
+            <div className="clearfix py4" style={{ backgroundColor: colors.heroGrey }}>
+                <div className="mx-auto max-width-4 clearfix">
+                    <div className="lg-pt4 md-pt4 sm-pt2 lg-pb4 md-pb4 lg-my4 md-my4 sm-mt2 sm-mb4 clearfix">
+                        <div className="col lg-col-5 md-col-5 col-12 sm-center">
+                            <img src="/images/landing/hero_chip_image.png" height={isSmallScreen ? 300 : 395} />
+                        </div>
+                        <div className={left} style={{ color: colors.white }}>
+                            <div style={{ paddingLeft: isSmallScreen ? 0 : 12 }}>
+                                <div
+                                    className="sm-pb2"
+                                    style={{
+                                        fontFamily: 'Roboto Mono',
+                                        fontSize: isSmallScreen ? 26 : 34,
+                                    }}
+                                >
+                                    Powering decentralized exchange
+                                </div>
+                                <div
+                                    className="pt2 h5 sm-mx-auto"
+                                    style={{
+                                        maxWidth: 446,
+                                        fontFamily: 'Roboto Mono',
+                                        lineHeight: 1.7,
+                                        fontWeight: 300,
+                                    }}
+                                >
+                                    0x is an open, permissionless protocol allowing for ERC20 tokens to be traded on the
+                                    Ethereum blockchain.
+                                </div>
+                                <div className="pt3 clearfix sm-mx-auto" style={{ maxWidth: 342 }}>
+                                    <div className="lg-pr2 md-pr2 col col-6 sm-center">
+                                        <Link to={WebsitePaths.ZeroExJs} className="text-decoration-none">
+                                            <RaisedButton
+                                                style={{ borderRadius: 6, minWidth: 157.36 }}
+                                                buttonStyle={{ borderRadius: 6 }}
+                                                labelStyle={buttonLabelStyle}
+                                                label="Build on 0x"
+                                                onClick={_.noop}
+                                            />
+                                        </Link>
+                                    </div>
+                                    <div className="col col-6 sm-center">
+                                        <a
+                                            href={constants.URL_ZEROEX_CHAT}
+                                            target="_blank"
+                                            className="text-decoration-none"
+                                        >
+                                            <RaisedButton
+                                                style={{ borderRadius: 6, minWidth: 150 }}
+                                                buttonStyle={lightButtonStyle}
+                                                labelColor="white"
+                                                backgroundColor={colors.heroGrey}
+                                                labelStyle={buttonLabelStyle}
+                                                label="Join the community"
+                                                onClick={_.noop}
+                                            />
+                                        </a>
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        );
+    }
+    private _renderProjects() {
+        const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
+        const isMediumScreen = this.state.screenWidth === ScreenWidths.Md;
+        const projectList = _.map(projects, (project: Project, i: number) => {
+            const colWidth = isSmallScreen ? 3 : isMediumScreen ? 4 : 2 - i % 2;
+            return (
+                <div key={`project-${project.logoFileName}`} className={`col col-${colWidth} center`}>
+                    <div>
+                        <a href={project.projectUrl} target="_blank" className="text-decoration-none">
+                            <img
+                                src={`/images/landing/project_logos/${project.logoFileName}`}
+                                height={isSmallScreen ? 60 : 92}
+                            />
+                        </a>
+                    </div>
+                </div>
+            );
+        });
+        const titleStyle: React.CSSProperties = {
+            fontFamily: 'Roboto Mono',
+            color: colors.grey,
+            textTransform: 'uppercase',
+            fontWeight: 300,
+            letterSpacing: 3,
+        };
+        return (
+            <div className="clearfix py4" style={{ backgroundColor: colors.projectsGrey }}>
+                <div className="mx-auto max-width-4 clearfix sm-px3">
+                    <div className="h4 pb3 md-pl3 sm-pl2" style={titleStyle}>
+                        Projects building on 0x
+                    </div>
+                    <div className="clearfix">{projectList}</div>
+                    <div
+                        className="pt3 mx-auto center"
+                        style={{
+                            color: colors.landingLinkGrey,
+                            fontFamily: 'Roboto Mono',
+                            maxWidth: 300,
+                            fontSize: 14,
+                        }}
+                    >
+                        view the{' '}
+                        <Link
+                            to={`${WebsitePaths.Wiki}#List-of-Projects-Using-0x-Protocol`}
+                            className="text-decoration-none underline"
+                            style={{ color: colors.landingLinkGrey }}
+                        >
+                            full list
+                        </Link>
+                    </div>
+                </div>
+            </div>
+        );
+    }
+    private _renderTokenizationSection() {
+        const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
+        return (
+            <div className="clearfix lg-py4 md-py4 sm-pb4 sm-pt2" style={{ backgroundColor: colors.grey100 }}>
+                <div className="mx-auto max-width-4 py4 clearfix">
+                    {isSmallScreen && this._renderTokenCloud()}
+                    <div className="col lg-col-6 md-col-6 col-12">
+                        <div className="mx-auto" style={{ maxWidth: 385, paddingTop: 7 }}>
+                            <div className="lg-h1 md-h1 sm-h2 sm-center sm-pt3" style={{ fontFamily: 'Roboto Mono' }}>
+                                The world's value is becoming tokenized
+                            </div>
+                            <div
+                                className="pb2 lg-pt2 md-pt2 sm-pt3 sm-px3 h5 sm-center"
+                                style={{ fontFamily: 'Roboto Mono', lineHeight: 1.7 }}
+                            >
+                                {isSmallScreen ? (
+                                    <span>
+                                        The Ethereum blockchain is an open, borderless financial system that represents
+                                        a wide variety of assets as cryptographic tokens. In the future, most digital
+                                        assets and goods will be tokenized.
+                                    </span>
+                                ) : (
+                                    <div>
+                                        <div>
+                                            The Ethereum blockchain is an open, borderless financial system that
+                                            represents
+                                        </div>
+                                        <div>
+                                            a wide variety of assets as cryptographic tokens. In the future, most
+                                            digital assets and goods will be tokenized.
+                                        </div>
+                                    </div>
+                                )}
+                            </div>
+                            <div className="flex pt1 sm-px3">{this._renderAssetTypes()}</div>
+                        </div>
+                    </div>
+                    {!isSmallScreen && this._renderTokenCloud()}
+                </div>
+            </div>
+        );
+    }
+    private _renderProtocolSection() {
+        const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
+        return (
+            <div className="clearfix lg-py4 md-py4 sm-pt4" style={{ backgroundColor: colors.heroGrey }}>
+                <div className="mx-auto max-width-4 lg-py4 md-py4 sm-pt4 clearfix">
+                    <div className="col lg-col-6 md-col-6 col-12 sm-center">
+                        <img src="/images/landing/relayer_diagram.png" height={isSmallScreen ? 326 : 426} />
+                    </div>
+                    <div
+                        className="col lg-col-6 md-col-6 col-12 lg-pr3 md-pr3 sm-mx-auto"
+                        style={{
+                            color: colors.beigeWhite,
+                            paddingTop: 8,
+                            maxWidth: isSmallScreen ? 'none' : 445,
+                        }}
+                    >
+                        <div className="lg-h1 md-h1 sm-h2 pb1 sm-pt3 sm-center" style={{ fontFamily: 'Roboto Mono' }}>
+                            <div>Off-chain order relay</div>
+                            <div>On-chain settlement</div>
+                        </div>
+                        <div
+                            className="pb2 pt2 h5 sm-center sm-px3 sm-mx-auto"
+                            style={{
+                                fontFamily: 'Roboto Mono',
+                                lineHeight: 1.7,
+                                fontWeight: 300,
+                                maxWidth: 445,
+                            }}
+                        >
+                            In 0x protocol, orders are transported off-chain, massively reducing gas costs and
+                            eliminating blockchain bloat. Relayers help broadcast orders and collect a fee each time
+                            they facilitate a trade. Anyone can build a relayer.
+                        </div>
+                        <div
+                            className="pt3 sm-mx-auto sm-px3"
+                            style={{
+                                color: colors.landingLinkGrey,
+                                maxWidth: isSmallScreen ? 412 : 'none',
+                            }}
+                        >
+                            <div className="flex" style={{ fontSize: 18 }}>
+                                <div
+                                    className="lg-h4 md-h4 sm-h5"
+                                    style={{
+                                        letterSpacing: isSmallScreen ? 1 : 3,
+                                        fontFamily: 'Roboto Mono',
+                                    }}
+                                >
+                                    RELAYERS BUILDING ON 0X
+                                </div>
+                                <div className="h5" style={{ marginLeft: isSmallScreen ? 26 : 49 }}>
+                                    <Link
+                                        to={`${WebsitePaths.Wiki}#List-of-Projects-Using-0x-Protocol`}
+                                        className="text-decoration-none underline"
+                                        style={{
+                                            color: colors.landingLinkGrey,
+                                            fontFamily: 'Roboto Mono',
+                                        }}
+                                    >
+                                        view all
+                                    </Link>
+                                </div>
+                            </div>
+                            <div className="lg-flex md-flex sm-clearfix pt3" style={{ opacity: 0.4 }}>
+                                <div className="col col-4 sm-center">
+                                    <img
+                                        src="/images/landing/ethfinex.png"
+                                        style={{ height: isSmallScreen ? 85 : 107 }}
+                                    />
+                                </div>
+                                <div className="col col-4 center">
+                                    <img
+                                        src="/images/landing/radar_relay.png"
+                                        style={{ height: isSmallScreen ? 85 : 107 }}
+                                    />
+                                </div>
+                                <div className="col col-4 sm-center" style={{ textAlign: 'right' }}>
+                                    <img
+                                        src="/images/landing/paradex.png"
+                                        style={{ height: isSmallScreen ? 85 : 107 }}
+                                    />
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        );
+    }
+    private _renderBuildingBlocksSection() {
+        const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
+        const descriptionStyle: React.CSSProperties = {
+            fontFamily: 'Roboto Mono',
+            lineHeight: isSmallScreen ? 1.5 : 2,
+            fontWeight: 300,
+            fontSize: 15,
+            maxWidth: isSmallScreen ? 375 : 'none',
+        };
+        const callToActionStyle: React.CSSProperties = {
+            fontFamily: 'Roboto Mono',
+            fontSize: 15,
+            fontWeight: 300,
+            maxWidth: isSmallScreen ? 375 : 441,
+        };
+        return (
+            <div className="clearfix lg-pt4 md-pt4" style={{ backgroundColor: colors.heroGrey }}>
+                <div className="mx-auto max-width-4 lg-pt4 md-pt4 lg-mb4 md-mb4 sm-mb2 clearfix">
+                    {isSmallScreen && this._renderBlockChipImage()}
+                    <div
+                        className="col lg-col-6 md-col-6 col-12 lg-pr3 md-pr3 sm-px3"
+                        style={{ color: colors.beigeWhite }}
+                    >
+                        <div
+                            className="pb1 lg-pt4 md-pt4 sm-pt3 lg-h1 md-h1 sm-h2 sm-px3 sm-center"
+                            style={{ fontFamily: 'Roboto Mono' }}
+                        >
+                            A building block for dApps
+                        </div>
+                        <div className="pb3 pt2 sm-mx-auto sm-center" style={descriptionStyle}>
+                            0x protocol is a pluggable building block for dApps that require exchange functionality.
+                            Join the many developers that are already using 0x in their web applications and smart
+                            contracts.
+                        </div>
+                        <div className="sm-mx-auto sm-center" style={callToActionStyle}>
+                            Learn how in our{' '}
+                            <Link
+                                to={WebsitePaths.ZeroExJs}
+                                className="text-decoration-none underline"
+                                style={{ color: colors.beigeWhite, fontFamily: 'Roboto Mono' }}
+                            >
+                                0x.js
+                            </Link>{' '}
+                            and{' '}
+                            <Link
+                                to={WebsitePaths.SmartContracts}
+                                className="text-decoration-none underline"
+                                style={{ color: colors.beigeWhite, fontFamily: 'Roboto Mono' }}
+                            >
+                                smart contract
+                            </Link>{' '}
+                            docs
+                        </div>
+                    </div>
+                    {!isSmallScreen && this._renderBlockChipImage()}
+                </div>
+            </div>
+        );
+    }
+    private _renderBlockChipImage() {
+        const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
+        return (
+            <div className="col lg-col-6 md-col-6 col-12 sm-center">
+                <img src="/images/landing/0x_chips.png" height={isSmallScreen ? 240 : 368} />
+            </div>
+        );
+    }
+    private _renderTokenCloud() {
+        const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
+        return (
+            <div className="col lg-col-6 md-col-6 col-12 center">
+                <img src="/images/landing/tokenized_world.png" height={isSmallScreen ? 280 : 364.5} />
+            </div>
+        );
+    }
+    private _renderAssetTypes() {
+        const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
+        const assetTypes: AssetType[] = [
+            {
+                title: 'Currency',
+                imageUrl: '/images/landing/currency.png',
+            },
+            {
+                title: 'Traditional assets',
+                imageUrl: '/images/landing/stocks.png',
+                style: {
+                    paddingLeft: isSmallScreen ? 41 : 56,
+                    paddingRight: isSmallScreen ? 41 : 56,
+                },
+            },
+            {
+                title: 'Digital goods',
+                imageUrl: '/images/landing/digital_goods.png',
+            },
+        ];
+        const assets = _.map(assetTypes, (assetType: AssetType) => {
+            const style = _.isUndefined(assetType.style) ? {} : assetType.style;
+            return (
+                <div key={`asset-${assetType.title}`} className="center" style={{ opacity: 0.8, ...style }}>
+                    <div>
+                        <img src={assetType.imageUrl} height="80" />
+                    </div>
+                    <div
+                        style={{
+                            fontFamily: 'Roboto Mono',
+                            fontSize: 13.5,
+                            fontWeight: 400,
+                            opacity: 0.75,
+                        }}
+                    >
+                        {assetType.title}
+                    </div>
+                </div>
+            );
+        });
+        return assets;
+    }
+    private _renderInfoBoxes() {
+        const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
+        const boxStyle: React.CSSProperties = {
+            maxWidth: 252,
+            height: 386,
+            backgroundColor: colors.grey50,
+            borderRadius: 5,
+            padding: '10px 24px 24px',
+        };
+        const boxes = _.map(boxContents, (boxContent: BoxContent) => {
+            return (
+                <div key={`box-${boxContent.title}`} className="col lg-col-4 md-col-4 col-12 sm-pb4">
+                    <div className={`center sm-mx-auto ${!isSmallScreen && boxContent.classNames}`} style={boxStyle}>
+                        <div>
+                            <img src={boxContent.imageUrl} style={{ height: 210 }} />
+                        </div>
+                        <div className="h3" style={{ color: 'black', fontFamily: 'Roboto Mono' }}>
+                            {boxContent.title}
+                        </div>
+                        <div className="pt2 pb2" style={{ fontFamily: 'Roboto Mono', fontSize: 14 }}>
+                            {boxContent.description}
+                        </div>
+                    </div>
+                </div>
+            );
+        });
+        return (
+            <div className="clearfix" style={{ backgroundColor: colors.heroGrey }}>
+                <div className="mx-auto py4 sm-mt2 clearfix" style={{ maxWidth: '60em' }}>
+                    {boxes}
+                </div>
+            </div>
+        );
+    }
+    private _renderUseCases() {
+        const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
 
-		const useCases: UseCase[] = [
-			{
-				imageUrl: '/images/landing/governance_icon.png',
-				type: 'Decentralized governance',
-				description:
-					'Decentralized organizations use tokens to represent ownership and \
+        const useCases: UseCase[] = [
+            {
+                imageUrl: '/images/landing/governance_icon.png',
+                type: 'Decentralized governance',
+                description:
+                    'Decentralized organizations use tokens to represent ownership and \
                               guide their governance logic. 0x allows decentralized organizations \
                               to seamlessly and safely trade ownership for startup capital.',
-				projectIconUrls: ['/images/landing/aragon.png'],
-				classNames: 'lg-px2 md-px2',
-			},
-			{
-				imageUrl: '/images/landing/prediction_market_icon.png',
-				type: 'Prediction markets',
-				description:
-					'Decentralized prediction market platforms generate sets of tokens that \
+                projectIconUrls: ['/images/landing/aragon.png'],
+                classNames: 'lg-px2 md-px2',
+            },
+            {
+                imageUrl: '/images/landing/prediction_market_icon.png',
+                type: 'Prediction markets',
+                description:
+                    'Decentralized prediction market platforms generate sets of tokens that \
                               represent a financial stake in the outcomes of real-world events. 0x allows \
                               these tokens to be instantly tradable.',
-				projectIconUrls: ['/images/landing/augur.png'],
-				classNames: 'lg-px2 md-px2',
-			},
-			{
-				imageUrl: '/images/landing/stable_tokens_icon.png',
-				type: 'Stable tokens',
-				description:
-					'Novel economic constructs such as stable coins require efficient, liquid \
+                projectIconUrls: ['/images/landing/augur.png'],
+                classNames: 'lg-px2 md-px2',
+            },
+            {
+                imageUrl: '/images/landing/stable_tokens_icon.png',
+                type: 'Stable tokens',
+                description:
+                    'Novel economic constructs such as stable coins require efficient, liquid \
                               markets to succeed. 0x will facilitate the underlying economic mechanisms \
                               that allow these tokens to remain stable.',
-				projectIconUrls: ['/images/landing/maker.png'],
-				classNames: 'lg-px2 md-px2',
-			},
-			{
-				imageUrl: '/images/landing/loans_icon.png',
-				type: 'Decentralized loans',
-				description:
-					'Efficient lending requires liquid markets where investors can buy and re-sell loans. \
+                projectIconUrls: ['/images/landing/maker.png'],
+                classNames: 'lg-px2 md-px2',
+            },
+            {
+                imageUrl: '/images/landing/loans_icon.png',
+                type: 'Decentralized loans',
+                description:
+                    'Efficient lending requires liquid markets where investors can buy and re-sell loans. \
                               0x enables an ecosystem of lenders to self-organize and efficiently determine \
                               market prices for all outstanding loans.',
-				projectIconUrls: ['/images/landing/dharma.png', '/images/landing/lendroid.png'],
-				classNames: 'lg-pr2 md-pr2 lg-col-6 md-col-6',
-				style: {
-					width: 291,
-					float: 'right',
-					marginTop: !isSmallScreen ? 38 : 0,
-				},
-			},
-			{
-				imageUrl: '/images/landing/fund_management_icon.png',
-				type: 'Fund management',
-				description:
-					'Decentralized fund management limits fund managers to investing in pre-agreed \
+                projectIconUrls: ['/images/landing/dharma.png', '/images/landing/lendroid.png'],
+                classNames: 'lg-pr2 md-pr2 lg-col-6 md-col-6',
+                style: {
+                    width: 291,
+                    float: 'right',
+                    marginTop: !isSmallScreen ? 38 : 0,
+                },
+            },
+            {
+                imageUrl: '/images/landing/fund_management_icon.png',
+                type: 'Fund management',
+                description:
+                    'Decentralized fund management limits fund managers to investing in pre-agreed \
                               upon asset classes. Embedding 0x into fund management smart contracts enables \
                               them to enforce these security constraints.',
-				projectIconUrls: ['/images/landing/melonport.png'],
-				classNames: 'lg-pl2 md-pl2 lg-col-6 md-col-6',
-				style: { width: 291, marginTop: !isSmallScreen ? 38 : 0 },
-			},
-		];
+                projectIconUrls: ['/images/landing/melonport.png'],
+                classNames: 'lg-pl2 md-pl2 lg-col-6 md-col-6',
+                style: { width: 291, marginTop: !isSmallScreen ? 38 : 0 },
+            },
+        ];
 
-		const cases = _.map(useCases, (useCase: UseCase) => {
-			const style = _.isUndefined(useCase.style) || isSmallScreen ? {} : useCase.style;
-			const useCaseBoxStyle = {
-				color: colors.grey,
-				border: '1px solid #565656',
-				borderRadius: 4,
-				maxWidth: isSmallScreen ? 375 : 'none',
-				...style,
-			};
-			const typeStyle: React.CSSProperties = {
-				color: colors.lightGrey,
-				fontSize: 13,
-				textTransform: 'uppercase',
-				fontFamily: 'Roboto Mono',
-				fontWeight: 300,
-			};
-			return (
-				<div
-					key={`useCase-${useCase.type}`}
-					className={`col lg-col-4 md-col-4 col-12 sm-pt3 sm-px3 sm-pb3 ${useCase.classNames}`}
-				>
-					<div className="relative p2 pb2 sm-mx-auto" style={useCaseBoxStyle}>
-						<div className="absolute center" style={{ top: -35, width: 'calc(100% - 32px)' }}>
-							<img src={useCase.imageUrl} style={{ height: 50 }} />
-						</div>
-						<div className="pt2 center" style={typeStyle}>
-							{useCase.type}
-						</div>
-						<div
-							className="pt2"
-							style={{
-								lineHeight: 1.5,
-								fontSize: 14,
-								overflow: 'hidden',
-								height: 104,
-							}}
-						>
-							{useCase.description}
-						</div>
-					</div>
-				</div>
-			);
-		});
-		return (
-			<div className="clearfix pb4 lg-pt2 md-pt2 sm-pt4" style={{ backgroundColor: colors.heroGrey }}>
-				<div className="mx-auto pb4 pt3 mt1 sm-mt2 clearfix" style={{ maxWidth: '67em' }}>
-					{cases}
-				</div>
-			</div>
-		);
-	}
-	private _renderCallToAction() {
-		const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
-		const buttonLabelStyle: React.CSSProperties = {
-			textTransform: 'none',
-			fontSize: 15,
-			fontWeight: 400,
-		};
-		const lightButtonStyle: React.CSSProperties = {
-			borderRadius: 6,
-			border: '1px solid #a0a0a0',
-			lineHeight: '33px',
-			height: 49,
-		};
-		const callToActionClassNames =
-			'col lg-col-8 md-col-8 col-12 lg-pr3 md-pr3 \
+        const cases = _.map(useCases, (useCase: UseCase) => {
+            const style = _.isUndefined(useCase.style) || isSmallScreen ? {} : useCase.style;
+            const useCaseBoxStyle = {
+                color: colors.grey,
+                border: '1px solid #565656',
+                borderRadius: 4,
+                maxWidth: isSmallScreen ? 375 : 'none',
+                ...style,
+            };
+            const typeStyle: React.CSSProperties = {
+                color: colors.lightGrey,
+                fontSize: 13,
+                textTransform: 'uppercase',
+                fontFamily: 'Roboto Mono',
+                fontWeight: 300,
+            };
+            return (
+                <div
+                    key={`useCase-${useCase.type}`}
+                    className={`col lg-col-4 md-col-4 col-12 sm-pt3 sm-px3 sm-pb3 ${useCase.classNames}`}
+                >
+                    <div className="relative p2 pb2 sm-mx-auto" style={useCaseBoxStyle}>
+                        <div className="absolute center" style={{ top: -35, width: 'calc(100% - 32px)' }}>
+                            <img src={useCase.imageUrl} style={{ height: 50 }} />
+                        </div>
+                        <div className="pt2 center" style={typeStyle}>
+                            {useCase.type}
+                        </div>
+                        <div
+                            className="pt2"
+                            style={{
+                                lineHeight: 1.5,
+                                fontSize: 14,
+                                overflow: 'hidden',
+                                height: 104,
+                            }}
+                        >
+                            {useCase.description}
+                        </div>
+                    </div>
+                </div>
+            );
+        });
+        return (
+            <div className="clearfix pb4 lg-pt2 md-pt2 sm-pt4" style={{ backgroundColor: colors.heroGrey }}>
+                <div className="mx-auto pb4 pt3 mt1 sm-mt2 clearfix" style={{ maxWidth: '67em' }}>
+                    {cases}
+                </div>
+            </div>
+        );
+    }
+    private _renderCallToAction() {
+        const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
+        const buttonLabelStyle: React.CSSProperties = {
+            textTransform: 'none',
+            fontSize: 15,
+            fontWeight: 400,
+        };
+        const lightButtonStyle: React.CSSProperties = {
+            borderRadius: 6,
+            border: '1px solid #a0a0a0',
+            lineHeight: '33px',
+            height: 49,
+        };
+        const callToActionClassNames =
+            'col lg-col-8 md-col-8 col-12 lg-pr3 md-pr3 \
                                         lg-right-align md-right-align sm-center sm-px3 h4';
-		return (
-			<div className="clearfix pb4" style={{ backgroundColor: colors.heroGrey }}>
-				<div className="mx-auto max-width-4 pb4 mb3 clearfix">
-					<div
-						className={callToActionClassNames}
-						style={{
-							fontFamily: 'Roboto Mono',
-							color: colors.white,
-							lineHeight: isSmallScreen ? 1.7 : 3,
-						}}
-					>
-						Get started on building the decentralized future
-					</div>
-					<div className="col lg-col-4 md-col-4 col-12 sm-center sm-pt2">
-						<Link to={WebsitePaths.ZeroExJs} className="text-decoration-none">
-							<RaisedButton
-								style={{ borderRadius: 6, minWidth: 150 }}
-								buttonStyle={lightButtonStyle}
-								labelColor={colors.white}
-								backgroundColor={colors.heroGrey}
-								labelStyle={buttonLabelStyle}
-								label="Build on 0x"
-								onClick={_.noop}
-							/>
-						</Link>
-					</div>
-				</div>
-			</div>
-		);
-	}
-	private _updateScreenWidth() {
-		const newScreenWidth = utils.getScreenWidth();
-		if (newScreenWidth !== this.state.screenWidth) {
-			this.setState({
-				screenWidth: newScreenWidth,
-			});
-		}
-	}
+        return (
+            <div className="clearfix pb4" style={{ backgroundColor: colors.heroGrey }}>
+                <div className="mx-auto max-width-4 pb4 mb3 clearfix">
+                    <div
+                        className={callToActionClassNames}
+                        style={{
+                            fontFamily: 'Roboto Mono',
+                            color: colors.white,
+                            lineHeight: isSmallScreen ? 1.7 : 3,
+                        }}
+                    >
+                        Get started on building the decentralized future
+                    </div>
+                    <div className="col lg-col-4 md-col-4 col-12 sm-center sm-pt2">
+                        <Link to={WebsitePaths.ZeroExJs} className="text-decoration-none">
+                            <RaisedButton
+                                style={{ borderRadius: 6, minWidth: 150 }}
+                                buttonStyle={lightButtonStyle}
+                                labelColor={colors.white}
+                                backgroundColor={colors.heroGrey}
+                                labelStyle={buttonLabelStyle}
+                                label="Build on 0x"
+                                onClick={_.noop}
+                            />
+                        </Link>
+                    </div>
+                </div>
+            </div>
+        );
+    }
+    private _updateScreenWidth() {
+        const newScreenWidth = utils.getScreenWidth();
+        if (newScreenWidth !== this.state.screenWidth) {
+            this.setState({
+                screenWidth: newScreenWidth,
+            });
+        }
+    }
 } // tslint:disable:max-file-line-count
diff --git a/packages/website/ts/pages/not_found.tsx b/packages/website/ts/pages/not_found.tsx
index 9d8d4142d..ff277c377 100644
--- a/packages/website/ts/pages/not_found.tsx
+++ b/packages/website/ts/pages/not_found.tsx
@@ -5,38 +5,38 @@ import { TopBar } from 'ts/components/top_bar';
 import { Styles } from 'ts/types';
 
 export interface NotFoundProps {
-	location: Location;
+    location: Location;
 }
 
 interface NotFoundState {}
 
 const styles: Styles = {
-	thin: {
-		fontWeight: 100,
-	},
+    thin: {
+        fontWeight: 100,
+    },
 };
 
 export class NotFound extends React.Component<NotFoundProps, NotFoundState> {
-	public render() {
-		return (
-			<div>
-				<TopBar blockchainIsLoaded={false} location={this.props.location} />
-				<div className="mx-auto max-width-4 py4">
-					<div className="center py4">
-						<div className="py4">
-							<div className="py4">
-								<h1 style={{ ...styles.thin }}>404 Not Found</h1>
-								<div className="py1">
-									<div className="py3">
-										Hm... looks like we couldn't find what you are looking for.
-									</div>
-								</div>
-							</div>
-						</div>
-					</div>
-				</div>
-				<Footer />
-			</div>
-		);
-	}
+    public render() {
+        return (
+            <div>
+                <TopBar blockchainIsLoaded={false} location={this.props.location} />
+                <div className="mx-auto max-width-4 py4">
+                    <div className="center py4">
+                        <div className="py4">
+                            <div className="py4">
+                                <h1 style={{ ...styles.thin }}>404 Not Found</h1>
+                                <div className="py1">
+                                    <div className="py3">
+                                        Hm... looks like we couldn't find what you are looking for.
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                <Footer />
+            </div>
+        );
+    }
 }
diff --git a/packages/website/ts/pages/shared/anchor_title.tsx b/packages/website/ts/pages/shared/anchor_title.tsx
index 118aa0ea5..db5be1f59 100644
--- a/packages/website/ts/pages/shared/anchor_title.tsx
+++ b/packages/website/ts/pages/shared/anchor_title.tsx
@@ -5,87 +5,87 @@ import { constants } from 'ts/utils/constants';
 import { utils } from 'ts/utils/utils';
 
 const headerSizeToScrollOffset: { [headerSize: string]: number } = {
-	h2: -20,
-	h3: 0,
+    h2: -20,
+    h3: 0,
 };
 
 interface AnchorTitleProps {
-	title: string | React.ReactNode;
-	id: string;
-	headerSize: HeaderSizes;
-	shouldShowAnchor: boolean;
+    title: string | React.ReactNode;
+    id: string;
+    headerSize: HeaderSizes;
+    shouldShowAnchor: boolean;
 }
 
 interface AnchorTitleState {
-	isHovering: boolean;
+    isHovering: boolean;
 }
 
 const styles: Styles = {
-	anchor: {
-		fontSize: 20,
-		transform: 'rotate(45deg)',
-		cursor: 'pointer',
-	},
-	headers: {
-		WebkitMarginStart: 0,
-		WebkitMarginEnd: 0,
-		fontWeight: 'bold',
-		display: 'block',
-	},
-	h1: {
-		fontSize: '1.8em',
-		WebkitMarginBefore: '0.83em',
-		WebkitMarginAfter: '0.83em',
-	},
-	h2: {
-		fontSize: '1.5em',
-		WebkitMarginBefore: '0.83em',
-		WebkitMarginAfter: '0.83em',
-	},
-	h3: {
-		fontSize: '1.17em',
-		WebkitMarginBefore: '1em',
-		WebkitMarginAfter: '1em',
-	},
+    anchor: {
+        fontSize: 20,
+        transform: 'rotate(45deg)',
+        cursor: 'pointer',
+    },
+    headers: {
+        WebkitMarginStart: 0,
+        WebkitMarginEnd: 0,
+        fontWeight: 'bold',
+        display: 'block',
+    },
+    h1: {
+        fontSize: '1.8em',
+        WebkitMarginBefore: '0.83em',
+        WebkitMarginAfter: '0.83em',
+    },
+    h2: {
+        fontSize: '1.5em',
+        WebkitMarginBefore: '0.83em',
+        WebkitMarginAfter: '0.83em',
+    },
+    h3: {
+        fontSize: '1.17em',
+        WebkitMarginBefore: '1em',
+        WebkitMarginAfter: '1em',
+    },
 };
 
 export class AnchorTitle extends React.Component<AnchorTitleProps, AnchorTitleState> {
-	constructor(props: AnchorTitleProps) {
-		super(props);
-		this.state = {
-			isHovering: false,
-		};
-	}
-	public render() {
-		let opacity = 0;
-		if (this.props.shouldShowAnchor) {
-			opacity = this.state.isHovering ? 0.6 : 1;
-		}
-		return (
-			<div className="relative flex" style={{ ...styles[this.props.headerSize], ...styles.headers }}>
-				<div className="inline-block" style={{ paddingRight: 4 }}>
-					{this.props.title}
-				</div>
-				<ScrollLink
-					to={this.props.id}
-					offset={headerSizeToScrollOffset[this.props.headerSize]}
-					duration={constants.DOCS_SCROLL_DURATION_MS}
-					containerId={constants.DOCS_CONTAINER_ID}
-				>
-					<i
-						className="zmdi zmdi-link"
-						onClick={utils.setUrlHash.bind(utils, this.props.id)}
-						style={{ ...styles.anchor, opacity }}
-						onMouseOver={this._setHoverState.bind(this, true)}
-						onMouseOut={this._setHoverState.bind(this, false)}
-					/>
-				</ScrollLink>
-			</div>
-		);
-	}
-	private _setHoverState(isHovering: boolean) {
-		this.setState({
-			isHovering,
-		});
-	}
+    constructor(props: AnchorTitleProps) {
+        super(props);
+        this.state = {
+            isHovering: false,
+        };
+    }
+    public render() {
+        let opacity = 0;
+        if (this.props.shouldShowAnchor) {
+            opacity = this.state.isHovering ? 0.6 : 1;
+        }
+        return (
+            <div className="relative flex" style={{ ...styles[this.props.headerSize], ...styles.headers }}>
+                <div className="inline-block" style={{ paddingRight: 4 }}>
+                    {this.props.title}
+                </div>
+                <ScrollLink
+                    to={this.props.id}
+                    offset={headerSizeToScrollOffset[this.props.headerSize]}
+                    duration={constants.DOCS_SCROLL_DURATION_MS}
+                    containerId={constants.DOCS_CONTAINER_ID}
+                >
+                    <i
+                        className="zmdi zmdi-link"
+                        onClick={utils.setUrlHash.bind(utils, this.props.id)}
+                        style={{ ...styles.anchor, opacity }}
+                        onMouseOver={this._setHoverState.bind(this, true)}
+                        onMouseOut={this._setHoverState.bind(this, false)}
+                    />
+                </ScrollLink>
+            </div>
+        );
+    }
+    private _setHoverState(isHovering: boolean) {
+        this.setState({
+            isHovering,
+        });
+    }
 }
diff --git a/packages/website/ts/pages/shared/markdown_code_block.tsx b/packages/website/ts/pages/shared/markdown_code_block.tsx
index a9d95979b..be96fda16 100644
--- a/packages/website/ts/pages/shared/markdown_code_block.tsx
+++ b/packages/website/ts/pages/shared/markdown_code_block.tsx
@@ -3,23 +3,23 @@ import * as React from 'react';
 import * as HighLight from 'react-highlight';
 
 interface MarkdownCodeBlockProps {
-	literal: string;
-	language: string;
+    literal: string;
+    language: string;
 }
 
 interface MarkdownCodeBlockState {}
 
 export class MarkdownCodeBlock extends React.Component<MarkdownCodeBlockProps, MarkdownCodeBlockState> {
-	// Re-rendering a codeblock causes any use selection to become de-selected. This is annoying when trying
-	// to copy-paste code examples. We therefore noop re-renders on this component if it's props haven't changed.
-	public shouldComponentUpdate(nextProps: MarkdownCodeBlockProps, nextState: MarkdownCodeBlockState) {
-		return nextProps.literal !== this.props.literal || nextProps.language !== this.props.language;
-	}
-	public render() {
-		return (
-			<span style={{ fontSize: 16 }}>
-				<HighLight className={this.props.language || 'javascript'}>{this.props.literal}</HighLight>
-			</span>
-		);
-	}
+    // Re-rendering a codeblock causes any use selection to become de-selected. This is annoying when trying
+    // to copy-paste code examples. We therefore noop re-renders on this component if it's props haven't changed.
+    public shouldComponentUpdate(nextProps: MarkdownCodeBlockProps, nextState: MarkdownCodeBlockState) {
+        return nextProps.literal !== this.props.literal || nextProps.language !== this.props.language;
+    }
+    public render() {
+        return (
+            <span style={{ fontSize: 16 }}>
+                <HighLight className={this.props.language || 'javascript'}>{this.props.literal}</HighLight>
+            </span>
+        );
+    }
 }
diff --git a/packages/website/ts/pages/shared/markdown_section.tsx b/packages/website/ts/pages/shared/markdown_section.tsx
index c875ab736..5487dc8cc 100644
--- a/packages/website/ts/pages/shared/markdown_section.tsx
+++ b/packages/website/ts/pages/shared/markdown_section.tsx
@@ -9,66 +9,66 @@ import { HeaderSizes } from 'ts/types';
 import { utils } from 'ts/utils/utils';
 
 interface MarkdownSectionProps {
-	sectionName: string;
-	markdownContent: string;
-	headerSize?: HeaderSizes;
-	githubLink?: string;
+    sectionName: string;
+    markdownContent: string;
+    headerSize?: HeaderSizes;
+    githubLink?: string;
 }
 
 interface MarkdownSectionState {
-	shouldShowAnchor: boolean;
+    shouldShowAnchor: boolean;
 }
 
 export class MarkdownSection extends React.Component<MarkdownSectionProps, MarkdownSectionState> {
-	public static defaultProps: Partial<MarkdownSectionProps> = {
-		headerSize: HeaderSizes.H3,
-	};
-	constructor(props: MarkdownSectionProps) {
-		super(props);
-		this.state = {
-			shouldShowAnchor: false,
-		};
-	}
-	public render() {
-		const sectionName = this.props.sectionName;
-		const id = utils.getIdFromName(sectionName);
-		return (
-			<div
-				className="pt2 pr3 md-pl2 sm-pl3 overflow-hidden"
-				onMouseOver={this._setAnchorVisibility.bind(this, true)}
-				onMouseOut={this._setAnchorVisibility.bind(this, false)}
-			>
-				<ScrollElement name={id}>
-					<div className="clearfix">
-						<div className="col lg-col-8 md-col-8 sm-col-12">
-							<span style={{ textTransform: 'capitalize' }}>
-								<AnchorTitle
-									headerSize={this.props.headerSize}
-									title={sectionName}
-									id={id}
-									shouldShowAnchor={this.state.shouldShowAnchor}
-								/>
-							</span>
-						</div>
-						<div className="col col-4 sm-hide xs-hide py2 right-align">
-							{!_.isUndefined(this.props.githubLink) && (
-								<RaisedButton
-									href={this.props.githubLink}
-									target="_blank"
-									label="Edit on Github"
-									icon={<i className="zmdi zmdi-github" style={{ fontSize: 23 }} />}
-								/>
-							)}
-						</div>
-					</div>
-					<ReactMarkdown source={this.props.markdownContent} renderers={{ CodeBlock: MarkdownCodeBlock }} />
-				</ScrollElement>
-			</div>
-		);
-	}
-	private _setAnchorVisibility(shouldShowAnchor: boolean) {
-		this.setState({
-			shouldShowAnchor,
-		});
-	}
+    public static defaultProps: Partial<MarkdownSectionProps> = {
+        headerSize: HeaderSizes.H3,
+    };
+    constructor(props: MarkdownSectionProps) {
+        super(props);
+        this.state = {
+            shouldShowAnchor: false,
+        };
+    }
+    public render() {
+        const sectionName = this.props.sectionName;
+        const id = utils.getIdFromName(sectionName);
+        return (
+            <div
+                className="pt2 pr3 md-pl2 sm-pl3 overflow-hidden"
+                onMouseOver={this._setAnchorVisibility.bind(this, true)}
+                onMouseOut={this._setAnchorVisibility.bind(this, false)}
+            >
+                <ScrollElement name={id}>
+                    <div className="clearfix">
+                        <div className="col lg-col-8 md-col-8 sm-col-12">
+                            <span style={{ textTransform: 'capitalize' }}>
+                                <AnchorTitle
+                                    headerSize={this.props.headerSize}
+                                    title={sectionName}
+                                    id={id}
+                                    shouldShowAnchor={this.state.shouldShowAnchor}
+                                />
+                            </span>
+                        </div>
+                        <div className="col col-4 sm-hide xs-hide py2 right-align">
+                            {!_.isUndefined(this.props.githubLink) && (
+                                <RaisedButton
+                                    href={this.props.githubLink}
+                                    target="_blank"
+                                    label="Edit on Github"
+                                    icon={<i className="zmdi zmdi-github" style={{ fontSize: 23 }} />}
+                                />
+                            )}
+                        </div>
+                    </div>
+                    <ReactMarkdown source={this.props.markdownContent} renderers={{ CodeBlock: MarkdownCodeBlock }} />
+                </ScrollElement>
+            </div>
+        );
+    }
+    private _setAnchorVisibility(shouldShowAnchor: boolean) {
+        this.setState({
+            shouldShowAnchor,
+        });
+    }
 }
diff --git a/packages/website/ts/pages/shared/nested_sidebar_menu.tsx b/packages/website/ts/pages/shared/nested_sidebar_menu.tsx
index cd7ea68e6..849c33504 100644
--- a/packages/website/ts/pages/shared/nested_sidebar_menu.tsx
+++ b/packages/website/ts/pages/shared/nested_sidebar_menu.tsx
@@ -9,146 +9,146 @@ import { constants } from 'ts/utils/constants';
 import { utils } from 'ts/utils/utils';
 
 interface NestedSidebarMenuProps {
-	topLevelMenu: { [topLevel: string]: string[] };
-	menuSubsectionsBySection: MenuSubsectionsBySection;
-	shouldDisplaySectionHeaders?: boolean;
-	onMenuItemClick?: () => void;
-	selectedVersion?: string;
-	versions?: string[];
-	docPath?: string;
-	isSectionHeaderClickable?: boolean;
+    topLevelMenu: { [topLevel: string]: string[] };
+    menuSubsectionsBySection: MenuSubsectionsBySection;
+    shouldDisplaySectionHeaders?: boolean;
+    onMenuItemClick?: () => void;
+    selectedVersion?: string;
+    versions?: string[];
+    docPath?: string;
+    isSectionHeaderClickable?: boolean;
 }
 
 interface NestedSidebarMenuState {}
 
 const styles: Styles = {
-	menuItemWithHeaders: {
-		minHeight: 0,
-	},
-	menuItemWithoutHeaders: {
-		minHeight: 48,
-	},
-	menuItemInnerDivWithHeaders: {
-		lineHeight: 2,
-	},
+    menuItemWithHeaders: {
+        minHeight: 0,
+    },
+    menuItemWithoutHeaders: {
+        minHeight: 48,
+    },
+    menuItemInnerDivWithHeaders: {
+        lineHeight: 2,
+    },
 };
 
 export class NestedSidebarMenu extends React.Component<NestedSidebarMenuProps, NestedSidebarMenuState> {
-	public static defaultProps: Partial<NestedSidebarMenuProps> = {
-		shouldDisplaySectionHeaders: true,
-		onMenuItemClick: _.noop,
-	};
-	public render() {
-		const navigation = _.map(this.props.topLevelMenu, (menuItems: string[], sectionName: string) => {
-			const finalSectionName = sectionName.replace(/-/g, ' ');
-			if (this.props.shouldDisplaySectionHeaders) {
-				const id = utils.getIdFromName(sectionName);
-				return (
-					<div key={`section-${sectionName}`} className="py1">
-						<ScrollLink
-							to={id}
-							offset={-20}
-							duration={constants.DOCS_SCROLL_DURATION_MS}
-							containerId={constants.DOCS_CONTAINER_ID}
-						>
-							<div style={{ color: colors.grey, cursor: 'pointer' }} className="pb1">
-								{finalSectionName.toUpperCase()}
-							</div>
-						</ScrollLink>
-						{this._renderMenuItems(menuItems)}
-					</div>
-				);
-			} else {
-				return <div key={`section-${sectionName}`}>{this._renderMenuItems(menuItems)}</div>;
-			}
-		});
-		return (
-			<div>
-				{!_.isUndefined(this.props.versions) &&
-					!_.isUndefined(this.props.selectedVersion) &&
-					!_.isUndefined(this.props.docPath) && (
-						<VersionDropDown
-							selectedVersion={this.props.selectedVersion}
-							versions={this.props.versions}
-							docPath={this.props.docPath}
-						/>
-					)}
-				{navigation}
-			</div>
-		);
-	}
-	private _renderMenuItems(menuItemNames: string[]): React.ReactNode[] {
-		const menuItemStyles = this.props.shouldDisplaySectionHeaders
-			? styles.menuItemWithHeaders
-			: styles.menuItemWithoutHeaders;
-		const menuItemInnerDivStyles = this.props.shouldDisplaySectionHeaders ? styles.menuItemInnerDivWithHeaders : {};
-		const menuItems = _.map(menuItemNames, menuItemName => {
-			const id = utils.getIdFromName(menuItemName);
-			return (
-				<div key={menuItemName}>
-					<ScrollLink
-						key={`menuItem-${menuItemName}`}
-						to={id}
-						offset={-10}
-						duration={constants.DOCS_SCROLL_DURATION_MS}
-						containerId={constants.DOCS_CONTAINER_ID}
-					>
-						<MenuItem
-							onTouchTap={this._onMenuItemClick.bind(this, menuItemName)}
-							style={menuItemStyles}
-							innerDivStyle={menuItemInnerDivStyles}
-						>
-							<span style={{ textTransform: 'capitalize' }}>{menuItemName}</span>
-						</MenuItem>
-					</ScrollLink>
-					{this._renderMenuItemSubsections(menuItemName)}
-				</div>
-			);
-		});
-		return menuItems;
-	}
-	private _renderMenuItemSubsections(menuItemName: string): React.ReactNode {
-		if (_.isUndefined(this.props.menuSubsectionsBySection[menuItemName])) {
-			return null;
-		}
-		return this._renderMenuSubsectionsBySection(menuItemName, this.props.menuSubsectionsBySection[menuItemName]);
-	}
-	private _renderMenuSubsectionsBySection(menuItemName: string, entityNames: string[]): React.ReactNode {
-		return (
-			<ul style={{ margin: 0, listStyleType: 'none', paddingLeft: 0 }} key={menuItemName}>
-				{_.map(entityNames, entityName => {
-					const name = `${menuItemName}-${entityName}`;
-					const id = utils.getIdFromName(name);
-					return (
-						<li key={`menuItem-${entityName}`}>
-							<ScrollLink
-								to={id}
-								offset={0}
-								duration={constants.DOCS_SCROLL_DURATION_MS}
-								containerId={constants.DOCS_CONTAINER_ID}
-								onTouchTap={this._onMenuItemClick.bind(this, name)}
-							>
-								<MenuItem
-									onTouchTap={this._onMenuItemClick.bind(this, name)}
-									style={{ minHeight: 35 }}
-									innerDivStyle={{
-										paddingLeft: 36,
-										fontSize: 14,
-										lineHeight: '35px',
-									}}
-								>
-									{entityName}
-								</MenuItem>
-							</ScrollLink>
-						</li>
-					);
-				})}
-			</ul>
-		);
-	}
-	private _onMenuItemClick(name: string): void {
-		const id = utils.getIdFromName(name);
-		utils.setUrlHash(id);
-		this.props.onMenuItemClick();
-	}
+    public static defaultProps: Partial<NestedSidebarMenuProps> = {
+        shouldDisplaySectionHeaders: true,
+        onMenuItemClick: _.noop,
+    };
+    public render() {
+        const navigation = _.map(this.props.topLevelMenu, (menuItems: string[], sectionName: string) => {
+            const finalSectionName = sectionName.replace(/-/g, ' ');
+            if (this.props.shouldDisplaySectionHeaders) {
+                const id = utils.getIdFromName(sectionName);
+                return (
+                    <div key={`section-${sectionName}`} className="py1">
+                        <ScrollLink
+                            to={id}
+                            offset={-20}
+                            duration={constants.DOCS_SCROLL_DURATION_MS}
+                            containerId={constants.DOCS_CONTAINER_ID}
+                        >
+                            <div style={{ color: colors.grey, cursor: 'pointer' }} className="pb1">
+                                {finalSectionName.toUpperCase()}
+                            </div>
+                        </ScrollLink>
+                        {this._renderMenuItems(menuItems)}
+                    </div>
+                );
+            } else {
+                return <div key={`section-${sectionName}`}>{this._renderMenuItems(menuItems)}</div>;
+            }
+        });
+        return (
+            <div>
+                {!_.isUndefined(this.props.versions) &&
+                    !_.isUndefined(this.props.selectedVersion) &&
+                    !_.isUndefined(this.props.docPath) && (
+                        <VersionDropDown
+                            selectedVersion={this.props.selectedVersion}
+                            versions={this.props.versions}
+                            docPath={this.props.docPath}
+                        />
+                    )}
+                {navigation}
+            </div>
+        );
+    }
+    private _renderMenuItems(menuItemNames: string[]): React.ReactNode[] {
+        const menuItemStyles = this.props.shouldDisplaySectionHeaders
+            ? styles.menuItemWithHeaders
+            : styles.menuItemWithoutHeaders;
+        const menuItemInnerDivStyles = this.props.shouldDisplaySectionHeaders ? styles.menuItemInnerDivWithHeaders : {};
+        const menuItems = _.map(menuItemNames, menuItemName => {
+            const id = utils.getIdFromName(menuItemName);
+            return (
+                <div key={menuItemName}>
+                    <ScrollLink
+                        key={`menuItem-${menuItemName}`}
+                        to={id}
+                        offset={-10}
+                        duration={constants.DOCS_SCROLL_DURATION_MS}
+                        containerId={constants.DOCS_CONTAINER_ID}
+                    >
+                        <MenuItem
+                            onTouchTap={this._onMenuItemClick.bind(this, menuItemName)}
+                            style={menuItemStyles}
+                            innerDivStyle={menuItemInnerDivStyles}
+                        >
+                            <span style={{ textTransform: 'capitalize' }}>{menuItemName}</span>
+                        </MenuItem>
+                    </ScrollLink>
+                    {this._renderMenuItemSubsections(menuItemName)}
+                </div>
+            );
+        });
+        return menuItems;
+    }
+    private _renderMenuItemSubsections(menuItemName: string): React.ReactNode {
+        if (_.isUndefined(this.props.menuSubsectionsBySection[menuItemName])) {
+            return null;
+        }
+        return this._renderMenuSubsectionsBySection(menuItemName, this.props.menuSubsectionsBySection[menuItemName]);
+    }
+    private _renderMenuSubsectionsBySection(menuItemName: string, entityNames: string[]): React.ReactNode {
+        return (
+            <ul style={{ margin: 0, listStyleType: 'none', paddingLeft: 0 }} key={menuItemName}>
+                {_.map(entityNames, entityName => {
+                    const name = `${menuItemName}-${entityName}`;
+                    const id = utils.getIdFromName(name);
+                    return (
+                        <li key={`menuItem-${entityName}`}>
+                            <ScrollLink
+                                to={id}
+                                offset={0}
+                                duration={constants.DOCS_SCROLL_DURATION_MS}
+                                containerId={constants.DOCS_CONTAINER_ID}
+                                onTouchTap={this._onMenuItemClick.bind(this, name)}
+                            >
+                                <MenuItem
+                                    onTouchTap={this._onMenuItemClick.bind(this, name)}
+                                    style={{ minHeight: 35 }}
+                                    innerDivStyle={{
+                                        paddingLeft: 36,
+                                        fontSize: 14,
+                                        lineHeight: '35px',
+                                    }}
+                                >
+                                    {entityName}
+                                </MenuItem>
+                            </ScrollLink>
+                        </li>
+                    );
+                })}
+            </ul>
+        );
+    }
+    private _onMenuItemClick(name: string): void {
+        const id = utils.getIdFromName(name);
+        utils.setUrlHash(id);
+        this.props.onMenuItemClick();
+    }
 }
diff --git a/packages/website/ts/pages/shared/section_header.tsx b/packages/website/ts/pages/shared/section_header.tsx
index f9aa1a5e6..a5f5f52cf 100644
--- a/packages/website/ts/pages/shared/section_header.tsx
+++ b/packages/website/ts/pages/shared/section_header.tsx
@@ -5,46 +5,46 @@ import { HeaderSizes } from 'ts/types';
 import { utils } from 'ts/utils/utils';
 
 interface SectionHeaderProps {
-	sectionName: string;
-	headerSize?: HeaderSizes;
+    sectionName: string;
+    headerSize?: HeaderSizes;
 }
 
 interface SectionHeaderState {
-	shouldShowAnchor: boolean;
+    shouldShowAnchor: boolean;
 }
 
 export class SectionHeader extends React.Component<SectionHeaderProps, SectionHeaderState> {
-	public static defaultProps: Partial<SectionHeaderProps> = {
-		headerSize: HeaderSizes.H2,
-	};
-	constructor(props: SectionHeaderProps) {
-		super(props);
-		this.state = {
-			shouldShowAnchor: false,
-		};
-	}
-	public render() {
-		const sectionName = this.props.sectionName.replace(/-/g, ' ');
-		const id = utils.getIdFromName(sectionName);
-		return (
-			<div
-				onMouseOver={this._setAnchorVisibility.bind(this, true)}
-				onMouseOut={this._setAnchorVisibility.bind(this, false)}
-			>
-				<ScrollElement name={id}>
-					<AnchorTitle
-						headerSize={this.props.headerSize}
-						title={<span style={{ textTransform: 'capitalize' }}>{sectionName}</span>}
-						id={id}
-						shouldShowAnchor={this.state.shouldShowAnchor}
-					/>
-				</ScrollElement>
-			</div>
-		);
-	}
-	private _setAnchorVisibility(shouldShowAnchor: boolean) {
-		this.setState({
-			shouldShowAnchor,
-		});
-	}
+    public static defaultProps: Partial<SectionHeaderProps> = {
+        headerSize: HeaderSizes.H2,
+    };
+    constructor(props: SectionHeaderProps) {
+        super(props);
+        this.state = {
+            shouldShowAnchor: false,
+        };
+    }
+    public render() {
+        const sectionName = this.props.sectionName.replace(/-/g, ' ');
+        const id = utils.getIdFromName(sectionName);
+        return (
+            <div
+                onMouseOver={this._setAnchorVisibility.bind(this, true)}
+                onMouseOut={this._setAnchorVisibility.bind(this, false)}
+            >
+                <ScrollElement name={id}>
+                    <AnchorTitle
+                        headerSize={this.props.headerSize}
+                        title={<span style={{ textTransform: 'capitalize' }}>{sectionName}</span>}
+                        id={id}
+                        shouldShowAnchor={this.state.shouldShowAnchor}
+                    />
+                </ScrollElement>
+            </div>
+        );
+    }
+    private _setAnchorVisibility(shouldShowAnchor: boolean) {
+        this.setState({
+            shouldShowAnchor,
+        });
+    }
 }
diff --git a/packages/website/ts/pages/shared/version_drop_down.tsx b/packages/website/ts/pages/shared/version_drop_down.tsx
index a647252ba..b922e1048 100644
--- a/packages/website/ts/pages/shared/version_drop_down.tsx
+++ b/packages/website/ts/pages/shared/version_drop_down.tsx
@@ -4,34 +4,34 @@ import MenuItem from 'material-ui/MenuItem';
 import * as React from 'react';
 
 interface VersionDropDownProps {
-	selectedVersion: string;
-	versions: string[];
-	docPath: string;
+    selectedVersion: string;
+    versions: string[];
+    docPath: string;
 }
 
 interface VersionDropDownState {}
 
 export class VersionDropDown extends React.Component<VersionDropDownProps, VersionDropDownState> {
-	public render() {
-		return (
-			<div className="mx-auto" style={{ width: 120 }}>
-				<DropDownMenu
-					maxHeight={300}
-					value={this.props.selectedVersion}
-					onChange={this._updateSelectedVersion.bind(this)}
-				>
-					{this._renderDropDownItems()}
-				</DropDownMenu>
-			</div>
-		);
-	}
-	private _renderDropDownItems() {
-		const items = _.map(this.props.versions, version => {
-			return <MenuItem key={version} value={version} primaryText={`v${version}`} />;
-		});
-		return items;
-	}
-	private _updateSelectedVersion(e: any, index: number, value: string) {
-		window.location.href = `${this.props.docPath}/${value}${window.location.hash}`;
-	}
+    public render() {
+        return (
+            <div className="mx-auto" style={{ width: 120 }}>
+                <DropDownMenu
+                    maxHeight={300}
+                    value={this.props.selectedVersion}
+                    onChange={this._updateSelectedVersion.bind(this)}
+                >
+                    {this._renderDropDownItems()}
+                </DropDownMenu>
+            </div>
+        );
+    }
+    private _renderDropDownItems() {
+        const items = _.map(this.props.versions, version => {
+            return <MenuItem key={version} value={version} primaryText={`v${version}`} />;
+        });
+        return items;
+    }
+    private _updateSelectedVersion(e: any, index: number, value: string) {
+        window.location.href = `${this.props.docPath}/${value}${window.location.hash}`;
+    }
 }
diff --git a/packages/website/ts/pages/wiki/wiki.tsx b/packages/website/ts/pages/wiki/wiki.tsx
index dba5ed6a0..d065614ba 100644
--- a/packages/website/ts/pages/wiki/wiki.tsx
+++ b/packages/website/ts/pages/wiki/wiki.tsx
@@ -16,186 +16,186 @@ import { utils } from 'ts/utils/utils';
 const WIKI_NOT_READY_BACKOUT_TIMEOUT_MS = 5000;
 
 export interface WikiProps {
-	source: string;
-	location: Location;
+    source: string;
+    location: Location;
 }
 
 interface WikiState {
-	articlesBySection: ArticlesBySection;
+    articlesBySection: ArticlesBySection;
 }
 
 const styles: Styles = {
-	mainContainers: {
-		position: 'absolute',
-		top: 1,
-		left: 0,
-		bottom: 0,
-		right: 0,
-		overflowZ: 'hidden',
-		overflowY: 'scroll',
-		minHeight: 'calc(100vh - 1px)',
-		WebkitOverflowScrolling: 'touch',
-	},
-	menuContainer: {
-		borderColor: colors.grey300,
-		maxWidth: 330,
-		marginLeft: 20,
-	},
+    mainContainers: {
+        position: 'absolute',
+        top: 1,
+        left: 0,
+        bottom: 0,
+        right: 0,
+        overflowZ: 'hidden',
+        overflowY: 'scroll',
+        minHeight: 'calc(100vh - 1px)',
+        WebkitOverflowScrolling: 'touch',
+    },
+    menuContainer: {
+        borderColor: colors.grey300,
+        maxWidth: 330,
+        marginLeft: 20,
+    },
 };
 
 export class Wiki extends React.Component<WikiProps, WikiState> {
-	private _wikiBackoffTimeoutId: number;
-	constructor(props: WikiProps) {
-		super(props);
-		this.state = {
-			articlesBySection: undefined,
-		};
-	}
-	public componentWillMount() {
-		// tslint:disable-next-line:no-floating-promises
-		this._fetchArticlesBySectionAsync();
-	}
-	public componentWillUnmount() {
-		clearTimeout(this._wikiBackoffTimeoutId);
-	}
-	public render() {
-		const menuSubsectionsBySection = _.isUndefined(this.state.articlesBySection)
-			? {}
-			: this._getMenuSubsectionsBySection(this.state.articlesBySection);
-		return (
-			<div>
-				<DocumentTitle title="0x Protocol Wiki" />
-				<TopBar
-					blockchainIsLoaded={false}
-					location={this.props.location}
-					menuSubsectionsBySection={menuSubsectionsBySection}
-					shouldFullWidth={true}
-				/>
-				{_.isUndefined(this.state.articlesBySection) ? (
-					<div className="col col-12" style={styles.mainContainers}>
-						<div
-							className="relative sm-px2 sm-pt2 sm-m1"
-							style={{ height: 122, top: '50%', transform: 'translateY(-50%)' }}
-						>
-							<div className="center pb2">
-								<CircularProgress size={40} thickness={5} />
-							</div>
-							<div className="center pt2" style={{ paddingBottom: 11 }}>
-								Loading wiki...
-							</div>
-						</div>
-					</div>
-				) : (
-					<div className="mx-auto flex" style={{ color: colors.grey800, height: 43 }}>
-						<div className="relative col md-col-3 lg-col-3 lg-pl0 md-pl1 sm-hide xs-hide">
-							<div
-								className="border-right absolute pt2"
-								style={{ ...styles.menuContainer, ...styles.mainContainers }}
-							>
-								<NestedSidebarMenu
-									topLevelMenu={menuSubsectionsBySection}
-									menuSubsectionsBySection={menuSubsectionsBySection}
-									isSectionHeaderClickable={true}
-								/>
-							</div>
-						</div>
-						<div className="relative col lg-col-9 md-col-9 sm-col-12 col-12">
-							<div id="documentation" style={styles.mainContainers} className="absolute">
-								<div id="0xProtocolWiki" />
-								<h1 className="md-pl2 sm-pl3">
-									<a href={constants.URL_GITHUB_WIKI} target="_blank">
-										0x Protocol Wiki
-									</a>
-								</h1>
-								<div id="wiki">{this._renderWikiArticles()}</div>
-							</div>
-						</div>
-					</div>
-				)}
-			</div>
-		);
-	}
-	private _renderWikiArticles(): React.ReactNode {
-		const sectionNames = _.keys(this.state.articlesBySection);
-		const sections = _.map(sectionNames, sectionName => this._renderSection(sectionName));
-		return sections;
-	}
-	private _renderSection(sectionName: string) {
-		const articles = this.state.articlesBySection[sectionName];
-		const renderedArticles = _.map(articles, (article: Article) => {
-			const githubLink = `${constants.URL_GITHUB_WIKI}/edit/master/${sectionName}/${article.fileName}`;
-			return (
-				<div key={`markdown-section-${article.title}`}>
-					<MarkdownSection
-						sectionName={article.title}
-						markdownContent={article.content}
-						headerSize={HeaderSizes.H2}
-						githubLink={githubLink}
-					/>
-					<div className="mb4 mt3 p3 center" style={{ backgroundColor: colors.lightestGrey }}>
-						See a way to make this article better?{' '}
-						<a href={githubLink} target="_blank">
-							Edit here →
-						</a>
-					</div>
-				</div>
-			);
-		});
-		return (
-			<div key={`section-${sectionName}`} className="py2 pr3 md-pl2 sm-pl3">
-				<SectionHeader sectionName={sectionName} headerSize={HeaderSizes.H1} />
-				{renderedArticles}
-			</div>
-		);
-	}
-	private _scrollToHash(): void {
-		const hashWithPrefix = this.props.location.hash;
-		let hash = hashWithPrefix.slice(1);
-		if (_.isEmpty(hash)) {
-			hash = '0xProtocolWiki'; // scroll to the top
-		}
+    private _wikiBackoffTimeoutId: number;
+    constructor(props: WikiProps) {
+        super(props);
+        this.state = {
+            articlesBySection: undefined,
+        };
+    }
+    public componentWillMount() {
+        // tslint:disable-next-line:no-floating-promises
+        this._fetchArticlesBySectionAsync();
+    }
+    public componentWillUnmount() {
+        clearTimeout(this._wikiBackoffTimeoutId);
+    }
+    public render() {
+        const menuSubsectionsBySection = _.isUndefined(this.state.articlesBySection)
+            ? {}
+            : this._getMenuSubsectionsBySection(this.state.articlesBySection);
+        return (
+            <div>
+                <DocumentTitle title="0x Protocol Wiki" />
+                <TopBar
+                    blockchainIsLoaded={false}
+                    location={this.props.location}
+                    menuSubsectionsBySection={menuSubsectionsBySection}
+                    shouldFullWidth={true}
+                />
+                {_.isUndefined(this.state.articlesBySection) ? (
+                    <div className="col col-12" style={styles.mainContainers}>
+                        <div
+                            className="relative sm-px2 sm-pt2 sm-m1"
+                            style={{ height: 122, top: '50%', transform: 'translateY(-50%)' }}
+                        >
+                            <div className="center pb2">
+                                <CircularProgress size={40} thickness={5} />
+                            </div>
+                            <div className="center pt2" style={{ paddingBottom: 11 }}>
+                                Loading wiki...
+                            </div>
+                        </div>
+                    </div>
+                ) : (
+                    <div className="mx-auto flex" style={{ color: colors.grey800, height: 43 }}>
+                        <div className="relative col md-col-3 lg-col-3 lg-pl0 md-pl1 sm-hide xs-hide">
+                            <div
+                                className="border-right absolute pt2"
+                                style={{ ...styles.menuContainer, ...styles.mainContainers }}
+                            >
+                                <NestedSidebarMenu
+                                    topLevelMenu={menuSubsectionsBySection}
+                                    menuSubsectionsBySection={menuSubsectionsBySection}
+                                    isSectionHeaderClickable={true}
+                                />
+                            </div>
+                        </div>
+                        <div className="relative col lg-col-9 md-col-9 sm-col-12 col-12">
+                            <div id="documentation" style={styles.mainContainers} className="absolute">
+                                <div id="0xProtocolWiki" />
+                                <h1 className="md-pl2 sm-pl3">
+                                    <a href={constants.URL_GITHUB_WIKI} target="_blank">
+                                        0x Protocol Wiki
+                                    </a>
+                                </h1>
+                                <div id="wiki">{this._renderWikiArticles()}</div>
+                            </div>
+                        </div>
+                    </div>
+                )}
+            </div>
+        );
+    }
+    private _renderWikiArticles(): React.ReactNode {
+        const sectionNames = _.keys(this.state.articlesBySection);
+        const sections = _.map(sectionNames, sectionName => this._renderSection(sectionName));
+        return sections;
+    }
+    private _renderSection(sectionName: string) {
+        const articles = this.state.articlesBySection[sectionName];
+        const renderedArticles = _.map(articles, (article: Article) => {
+            const githubLink = `${constants.URL_GITHUB_WIKI}/edit/master/${sectionName}/${article.fileName}`;
+            return (
+                <div key={`markdown-section-${article.title}`}>
+                    <MarkdownSection
+                        sectionName={article.title}
+                        markdownContent={article.content}
+                        headerSize={HeaderSizes.H2}
+                        githubLink={githubLink}
+                    />
+                    <div className="mb4 mt3 p3 center" style={{ backgroundColor: colors.lightestGrey }}>
+                        See a way to make this article better?{' '}
+                        <a href={githubLink} target="_blank">
+                            Edit here →
+                        </a>
+                    </div>
+                </div>
+            );
+        });
+        return (
+            <div key={`section-${sectionName}`} className="py2 pr3 md-pl2 sm-pl3">
+                <SectionHeader sectionName={sectionName} headerSize={HeaderSizes.H1} />
+                {renderedArticles}
+            </div>
+        );
+    }
+    private _scrollToHash(): void {
+        const hashWithPrefix = this.props.location.hash;
+        let hash = hashWithPrefix.slice(1);
+        if (_.isEmpty(hash)) {
+            hash = '0xProtocolWiki'; // scroll to the top
+        }
 
-		scroller.scrollTo(hash, {
-			duration: 0,
-			offset: 0,
-			containerId: 'documentation',
-		});
-	}
-	private async _fetchArticlesBySectionAsync(): Promise<void> {
-		const endpoint = `${configs.BACKEND_BASE_URL}${WebsitePaths.Wiki}`;
-		const response = await fetch(endpoint);
-		if (response.status === constants.HTTP_NO_CONTENT_STATUS_CODE) {
-			// We need to backoff and try fetching again later
-			this._wikiBackoffTimeoutId = window.setTimeout(() => {
-				// tslint:disable-next-line:no-floating-promises
-				this._fetchArticlesBySectionAsync();
-			}, WIKI_NOT_READY_BACKOUT_TIMEOUT_MS);
-			return;
-		}
-		if (response.status !== 200) {
-			// TODO: Show the user an error message when the wiki fail to load
-			const errMsg = await response.text();
-			utils.consoleLog(`Failed to load wiki: ${response.status} ${errMsg}`);
-			return;
-		}
-		const articlesBySection = await response.json();
-		this.setState(
-			{
-				articlesBySection,
-			},
-			() => {
-				this._scrollToHash();
-			},
-		);
-	}
-	private _getMenuSubsectionsBySection(articlesBySection: ArticlesBySection) {
-		const sectionNames = _.keys(articlesBySection);
-		const menuSubsectionsBySection: { [section: string]: string[] } = {};
-		for (const sectionName of sectionNames) {
-			const articles = articlesBySection[sectionName];
-			const articleNames = _.map(articles, article => article.title);
-			menuSubsectionsBySection[sectionName] = articleNames;
-		}
-		return menuSubsectionsBySection;
-	}
+        scroller.scrollTo(hash, {
+            duration: 0,
+            offset: 0,
+            containerId: 'documentation',
+        });
+    }
+    private async _fetchArticlesBySectionAsync(): Promise<void> {
+        const endpoint = `${configs.BACKEND_BASE_URL}${WebsitePaths.Wiki}`;
+        const response = await fetch(endpoint);
+        if (response.status === constants.HTTP_NO_CONTENT_STATUS_CODE) {
+            // We need to backoff and try fetching again later
+            this._wikiBackoffTimeoutId = window.setTimeout(() => {
+                // tslint:disable-next-line:no-floating-promises
+                this._fetchArticlesBySectionAsync();
+            }, WIKI_NOT_READY_BACKOUT_TIMEOUT_MS);
+            return;
+        }
+        if (response.status !== 200) {
+            // TODO: Show the user an error message when the wiki fail to load
+            const errMsg = await response.text();
+            utils.consoleLog(`Failed to load wiki: ${response.status} ${errMsg}`);
+            return;
+        }
+        const articlesBySection = await response.json();
+        this.setState(
+            {
+                articlesBySection,
+            },
+            () => {
+                this._scrollToHash();
+            },
+        );
+    }
+    private _getMenuSubsectionsBySection(articlesBySection: ArticlesBySection) {
+        const sectionNames = _.keys(articlesBySection);
+        const menuSubsectionsBySection: { [section: string]: string[] } = {};
+        for (const sectionName of sectionNames) {
+            const articles = articlesBySection[sectionName];
+            const articleNames = _.map(articles, article => article.title);
+            menuSubsectionsBySection[sectionName] = articleNames;
+        }
+        return menuSubsectionsBySection;
+    }
 }
diff --git a/packages/website/ts/redux/dispatcher.ts b/packages/website/ts/redux/dispatcher.ts
index 19300e242..42989e5e1 100644
--- a/packages/website/ts/redux/dispatcher.ts
+++ b/packages/website/ts/redux/dispatcher.ts
@@ -2,235 +2,235 @@ import { BigNumber } from '@0xproject/utils';
 import { Dispatch } from 'redux';
 import { State } from 'ts/redux/reducer';
 import {
-	ActionTypes,
-	AssetToken,
-	BlockchainErrs,
-	Order,
-	ProviderType,
-	ScreenWidths,
-	Side,
-	SignatureData,
-	Token,
-	TokenStateByAddress,
+    ActionTypes,
+    AssetToken,
+    BlockchainErrs,
+    Order,
+    ProviderType,
+    ScreenWidths,
+    Side,
+    SignatureData,
+    Token,
+    TokenStateByAddress,
 } from 'ts/types';
 
 export class Dispatcher {
-	private _dispatch: Dispatch<State>;
-	constructor(dispatch: Dispatch<State>) {
-		this._dispatch = dispatch;
-	}
-	// Portal
-	public resetState() {
-		this._dispatch({
-			type: ActionTypes.ResetState,
-		});
-	}
-	public updateNodeVersion(nodeVersion: string) {
-		this._dispatch({
-			data: nodeVersion,
-			type: ActionTypes.UpdateNodeVersion,
-		});
-	}
-	public updateScreenWidth(screenWidth: ScreenWidths) {
-		this._dispatch({
-			data: screenWidth,
-			type: ActionTypes.UpdateScreenWidth,
-		});
-	}
-	public swapAssetTokenSymbols() {
-		this._dispatch({
-			type: ActionTypes.SwapAssetTokens,
-		});
-	}
-	public updateOrderSalt(salt: BigNumber) {
-		this._dispatch({
-			data: salt,
-			type: ActionTypes.UpdateOrderSalt,
-		});
-	}
-	public updateUserSuppliedOrderCache(order: Order) {
-		this._dispatch({
-			data: order,
-			type: ActionTypes.UpdateUserSuppliedOrderCache,
-		});
-	}
-	public updateShouldBlockchainErrDialogBeOpen(shouldBeOpen: boolean) {
-		this._dispatch({
-			data: shouldBeOpen,
-			type: ActionTypes.UpdateShouldBlockchainErrDialogBeOpen,
-		});
-	}
-	public updateChosenAssetToken(side: Side, token: AssetToken) {
-		this._dispatch({
-			data: {
-				side,
-				token,
-			},
-			type: ActionTypes.UpdateChosenAssetToken,
-		});
-	}
-	public updateChosenAssetTokenAddress(side: Side, address: string) {
-		this._dispatch({
-			data: {
-				address,
-				side,
-			},
-			type: ActionTypes.UpdateChosenAssetTokenAddress,
-		});
-	}
-	public updateOrderTakerAddress(address: string) {
-		this._dispatch({
-			data: address,
-			type: ActionTypes.UpdateOrderTakerAddress,
-		});
-	}
-	public updateUserAddress(address: string) {
-		this._dispatch({
-			data: address,
-			type: ActionTypes.UpdateUserAddress,
-		});
-	}
-	public updateOrderExpiry(unixTimestampSec: BigNumber) {
-		this._dispatch({
-			data: unixTimestampSec,
-			type: ActionTypes.UpdateOrderExpiry,
-		});
-	}
-	public encounteredBlockchainError(err: BlockchainErrs) {
-		this._dispatch({
-			data: err,
-			type: ActionTypes.BlockchainErrEncountered,
-		});
-	}
-	public updateBlockchainIsLoaded(isLoaded: boolean) {
-		this._dispatch({
-			data: isLoaded,
-			type: ActionTypes.UpdateBlockchainIsLoaded,
-		});
-	}
-	public addTokenToTokenByAddress(token: Token) {
-		this._dispatch({
-			data: token,
-			type: ActionTypes.AddTokenToTokenByAddress,
-		});
-	}
-	public removeTokenToTokenByAddress(token: Token) {
-		this._dispatch({
-			data: token,
-			type: ActionTypes.RemoveTokenFromTokenByAddress,
-		});
-	}
-	public clearTokenByAddress() {
-		this._dispatch({
-			type: ActionTypes.ClearTokenByAddress,
-		});
-	}
-	public updateTokenByAddress(tokens: Token[]) {
-		this._dispatch({
-			data: tokens,
-			type: ActionTypes.UpdateTokenByAddress,
-		});
-	}
-	public updateTokenStateByAddress(tokenStateByAddress: TokenStateByAddress) {
-		this._dispatch({
-			data: tokenStateByAddress,
-			type: ActionTypes.UpdateTokenStateByAddress,
-		});
-	}
-	public removeFromTokenStateByAddress(tokenAddress: string) {
-		this._dispatch({
-			data: tokenAddress,
-			type: ActionTypes.RemoveFromTokenStateByAddress,
-		});
-	}
-	public replaceTokenAllowanceByAddress(address: string, allowance: BigNumber) {
-		this._dispatch({
-			data: {
-				address,
-				allowance,
-			},
-			type: ActionTypes.ReplaceTokenAllowanceByAddress,
-		});
-	}
-	public replaceTokenBalanceByAddress(address: string, balance: BigNumber) {
-		this._dispatch({
-			data: {
-				address,
-				balance,
-			},
-			type: ActionTypes.ReplaceTokenBalanceByAddress,
-		});
-	}
-	public updateTokenBalanceByAddress(address: string, balanceDelta: BigNumber) {
-		this._dispatch({
-			data: {
-				address,
-				balanceDelta,
-			},
-			type: ActionTypes.UpdateTokenBalanceByAddress,
-		});
-	}
-	public updateSignatureData(signatureData: SignatureData) {
-		this._dispatch({
-			data: signatureData,
-			type: ActionTypes.UpdateOrderSignatureData,
-		});
-	}
-	public updateUserEtherBalance(balance: BigNumber) {
-		this._dispatch({
-			data: balance,
-			type: ActionTypes.UpdateUserEtherBalance,
-		});
-	}
-	public updateNetworkId(networkId: number) {
-		this._dispatch({
-			data: networkId,
-			type: ActionTypes.UpdateNetworkId,
-		});
-	}
-	public updateOrderFillAmount(amount: BigNumber) {
-		this._dispatch({
-			data: amount,
-			type: ActionTypes.UpdateOrderFillAmount,
-		});
-	}
+    private _dispatch: Dispatch<State>;
+    constructor(dispatch: Dispatch<State>) {
+        this._dispatch = dispatch;
+    }
+    // Portal
+    public resetState() {
+        this._dispatch({
+            type: ActionTypes.ResetState,
+        });
+    }
+    public updateNodeVersion(nodeVersion: string) {
+        this._dispatch({
+            data: nodeVersion,
+            type: ActionTypes.UpdateNodeVersion,
+        });
+    }
+    public updateScreenWidth(screenWidth: ScreenWidths) {
+        this._dispatch({
+            data: screenWidth,
+            type: ActionTypes.UpdateScreenWidth,
+        });
+    }
+    public swapAssetTokenSymbols() {
+        this._dispatch({
+            type: ActionTypes.SwapAssetTokens,
+        });
+    }
+    public updateOrderSalt(salt: BigNumber) {
+        this._dispatch({
+            data: salt,
+            type: ActionTypes.UpdateOrderSalt,
+        });
+    }
+    public updateUserSuppliedOrderCache(order: Order) {
+        this._dispatch({
+            data: order,
+            type: ActionTypes.UpdateUserSuppliedOrderCache,
+        });
+    }
+    public updateShouldBlockchainErrDialogBeOpen(shouldBeOpen: boolean) {
+        this._dispatch({
+            data: shouldBeOpen,
+            type: ActionTypes.UpdateShouldBlockchainErrDialogBeOpen,
+        });
+    }
+    public updateChosenAssetToken(side: Side, token: AssetToken) {
+        this._dispatch({
+            data: {
+                side,
+                token,
+            },
+            type: ActionTypes.UpdateChosenAssetToken,
+        });
+    }
+    public updateChosenAssetTokenAddress(side: Side, address: string) {
+        this._dispatch({
+            data: {
+                address,
+                side,
+            },
+            type: ActionTypes.UpdateChosenAssetTokenAddress,
+        });
+    }
+    public updateOrderTakerAddress(address: string) {
+        this._dispatch({
+            data: address,
+            type: ActionTypes.UpdateOrderTakerAddress,
+        });
+    }
+    public updateUserAddress(address: string) {
+        this._dispatch({
+            data: address,
+            type: ActionTypes.UpdateUserAddress,
+        });
+    }
+    public updateOrderExpiry(unixTimestampSec: BigNumber) {
+        this._dispatch({
+            data: unixTimestampSec,
+            type: ActionTypes.UpdateOrderExpiry,
+        });
+    }
+    public encounteredBlockchainError(err: BlockchainErrs) {
+        this._dispatch({
+            data: err,
+            type: ActionTypes.BlockchainErrEncountered,
+        });
+    }
+    public updateBlockchainIsLoaded(isLoaded: boolean) {
+        this._dispatch({
+            data: isLoaded,
+            type: ActionTypes.UpdateBlockchainIsLoaded,
+        });
+    }
+    public addTokenToTokenByAddress(token: Token) {
+        this._dispatch({
+            data: token,
+            type: ActionTypes.AddTokenToTokenByAddress,
+        });
+    }
+    public removeTokenToTokenByAddress(token: Token) {
+        this._dispatch({
+            data: token,
+            type: ActionTypes.RemoveTokenFromTokenByAddress,
+        });
+    }
+    public clearTokenByAddress() {
+        this._dispatch({
+            type: ActionTypes.ClearTokenByAddress,
+        });
+    }
+    public updateTokenByAddress(tokens: Token[]) {
+        this._dispatch({
+            data: tokens,
+            type: ActionTypes.UpdateTokenByAddress,
+        });
+    }
+    public updateTokenStateByAddress(tokenStateByAddress: TokenStateByAddress) {
+        this._dispatch({
+            data: tokenStateByAddress,
+            type: ActionTypes.UpdateTokenStateByAddress,
+        });
+    }
+    public removeFromTokenStateByAddress(tokenAddress: string) {
+        this._dispatch({
+            data: tokenAddress,
+            type: ActionTypes.RemoveFromTokenStateByAddress,
+        });
+    }
+    public replaceTokenAllowanceByAddress(address: string, allowance: BigNumber) {
+        this._dispatch({
+            data: {
+                address,
+                allowance,
+            },
+            type: ActionTypes.ReplaceTokenAllowanceByAddress,
+        });
+    }
+    public replaceTokenBalanceByAddress(address: string, balance: BigNumber) {
+        this._dispatch({
+            data: {
+                address,
+                balance,
+            },
+            type: ActionTypes.ReplaceTokenBalanceByAddress,
+        });
+    }
+    public updateTokenBalanceByAddress(address: string, balanceDelta: BigNumber) {
+        this._dispatch({
+            data: {
+                address,
+                balanceDelta,
+            },
+            type: ActionTypes.UpdateTokenBalanceByAddress,
+        });
+    }
+    public updateSignatureData(signatureData: SignatureData) {
+        this._dispatch({
+            data: signatureData,
+            type: ActionTypes.UpdateOrderSignatureData,
+        });
+    }
+    public updateUserEtherBalance(balance: BigNumber) {
+        this._dispatch({
+            data: balance,
+            type: ActionTypes.UpdateUserEtherBalance,
+        });
+    }
+    public updateNetworkId(networkId: number) {
+        this._dispatch({
+            data: networkId,
+            type: ActionTypes.UpdateNetworkId,
+        });
+    }
+    public updateOrderFillAmount(amount: BigNumber) {
+        this._dispatch({
+            data: amount,
+            type: ActionTypes.UpdateOrderFillAmount,
+        });
+    }
 
-	// Docs
-	public updateCurrentDocsVersion(version: string) {
-		this._dispatch({
-			data: version,
-			type: ActionTypes.UpdateLibraryVersion,
-		});
-	}
-	public updateAvailableDocVersions(versions: string[]) {
-		this._dispatch({
-			data: versions,
-			type: ActionTypes.UpdateAvailableLibraryVersions,
-		});
-	}
+    // Docs
+    public updateCurrentDocsVersion(version: string) {
+        this._dispatch({
+            data: version,
+            type: ActionTypes.UpdateLibraryVersion,
+        });
+    }
+    public updateAvailableDocVersions(versions: string[]) {
+        this._dispatch({
+            data: versions,
+            type: ActionTypes.UpdateAvailableLibraryVersions,
+        });
+    }
 
-	// Shared
-	public showFlashMessage(msg: string | React.ReactNode) {
-		this._dispatch({
-			data: msg,
-			type: ActionTypes.ShowFlashMessage,
-		});
-	}
-	public hideFlashMessage() {
-		this._dispatch({
-			type: ActionTypes.HideFlashMessage,
-		});
-	}
-	public updateProviderType(providerType: ProviderType) {
-		this._dispatch({
-			type: ActionTypes.UpdateProviderType,
-			data: providerType,
-		});
-	}
-	public updateInjectedProviderName(injectedProviderName: string) {
-		this._dispatch({
-			type: ActionTypes.UpdateInjectedProviderName,
-			data: injectedProviderName,
-		});
-	}
+    // Shared
+    public showFlashMessage(msg: string | React.ReactNode) {
+        this._dispatch({
+            data: msg,
+            type: ActionTypes.ShowFlashMessage,
+        });
+    }
+    public hideFlashMessage() {
+        this._dispatch({
+            type: ActionTypes.HideFlashMessage,
+        });
+    }
+    public updateProviderType(providerType: ProviderType) {
+        this._dispatch({
+            type: ActionTypes.UpdateProviderType,
+            data: providerType,
+        });
+    }
+    public updateInjectedProviderName(injectedProviderName: string) {
+        this._dispatch({
+            type: ActionTypes.UpdateInjectedProviderName,
+            data: injectedProviderName,
+        });
+    }
 }
diff --git a/packages/website/ts/redux/reducer.ts b/packages/website/ts/redux/reducer.ts
index cc467eadd..06ac8b670 100644
--- a/packages/website/ts/redux/reducer.ts
+++ b/packages/website/ts/redux/reducer.ts
@@ -2,18 +2,18 @@ import { ZeroEx } from '0x.js';
 import { BigNumber } from '@0xproject/utils';
 import * as _ from 'lodash';
 import {
-	Action,
-	ActionTypes,
-	BlockchainErrs,
-	Order,
-	ProviderType,
-	ScreenWidths,
-	Side,
-	SideToAssetToken,
-	SignatureData,
-	TokenByAddress,
-	TokenState,
-	TokenStateByAddress,
+    Action,
+    ActionTypes,
+    BlockchainErrs,
+    Order,
+    ProviderType,
+    ScreenWidths,
+    Side,
+    SideToAssetToken,
+    SignatureData,
+    TokenByAddress,
+    TokenState,
+    TokenStateByAddress,
 } from 'ts/types';
 import { utils } from 'ts/utils/utils';
 
@@ -23,367 +23,367 @@ import { utils } from 'ts/utils/utils';
 const DEFAULT_DOCS_VERSION = '0.0.0';
 
 export interface State {
-	// Portal
-	blockchainErr: BlockchainErrs;
-	blockchainIsLoaded: boolean;
-	networkId: number;
-	orderExpiryTimestamp: BigNumber;
-	orderFillAmount: BigNumber;
-	orderTakerAddress: string;
-	orderSignatureData: SignatureData;
-	orderSalt: BigNumber;
-	nodeVersion: string;
-	screenWidth: ScreenWidths;
-	shouldBlockchainErrDialogBeOpen: boolean;
-	sideToAssetToken: SideToAssetToken;
-	tokenByAddress: TokenByAddress;
-	tokenStateByAddress: TokenStateByAddress;
-	userAddress: string;
-	userEtherBalance: BigNumber;
-	// Note: cache of supplied orderJSON in fill order step. Do not use for anything else.
-	userSuppliedOrderCache: Order;
-
-	// Docs
-	docsVersion: string;
-	availableDocVersions: string[];
-
-	// Shared
-	flashMessage: string | React.ReactNode;
-	providerType: ProviderType;
-	injectedProviderName: string;
+    // Portal
+    blockchainErr: BlockchainErrs;
+    blockchainIsLoaded: boolean;
+    networkId: number;
+    orderExpiryTimestamp: BigNumber;
+    orderFillAmount: BigNumber;
+    orderTakerAddress: string;
+    orderSignatureData: SignatureData;
+    orderSalt: BigNumber;
+    nodeVersion: string;
+    screenWidth: ScreenWidths;
+    shouldBlockchainErrDialogBeOpen: boolean;
+    sideToAssetToken: SideToAssetToken;
+    tokenByAddress: TokenByAddress;
+    tokenStateByAddress: TokenStateByAddress;
+    userAddress: string;
+    userEtherBalance: BigNumber;
+    // Note: cache of supplied orderJSON in fill order step. Do not use for anything else.
+    userSuppliedOrderCache: Order;
+
+    // Docs
+    docsVersion: string;
+    availableDocVersions: string[];
+
+    // Shared
+    flashMessage: string | React.ReactNode;
+    providerType: ProviderType;
+    injectedProviderName: string;
 }
 
 const INITIAL_STATE: State = {
-	// Portal
-	blockchainErr: BlockchainErrs.NoError,
-	blockchainIsLoaded: false,
-	networkId: undefined,
-	orderExpiryTimestamp: utils.initialOrderExpiryUnixTimestampSec(),
-	orderFillAmount: undefined,
-	orderSignatureData: {
-		hash: '',
-		r: '',
-		s: '',
-		v: 27,
-	},
-	orderTakerAddress: '',
-	orderSalt: ZeroEx.generatePseudoRandomSalt(),
-	nodeVersion: undefined,
-	screenWidth: utils.getScreenWidth(),
-	shouldBlockchainErrDialogBeOpen: false,
-	sideToAssetToken: {
-		[Side.Deposit]: {},
-		[Side.Receive]: {},
-	},
-	tokenByAddress: {},
-	tokenStateByAddress: {},
-	userAddress: '',
-	userEtherBalance: new BigNumber(0),
-	userSuppliedOrderCache: undefined,
-
-	// Docs
-	docsVersion: DEFAULT_DOCS_VERSION,
-	availableDocVersions: [DEFAULT_DOCS_VERSION],
-
-	// Shared
-	flashMessage: undefined,
-	providerType: ProviderType.Injected,
-	injectedProviderName: '',
+    // Portal
+    blockchainErr: BlockchainErrs.NoError,
+    blockchainIsLoaded: false,
+    networkId: undefined,
+    orderExpiryTimestamp: utils.initialOrderExpiryUnixTimestampSec(),
+    orderFillAmount: undefined,
+    orderSignatureData: {
+        hash: '',
+        r: '',
+        s: '',
+        v: 27,
+    },
+    orderTakerAddress: '',
+    orderSalt: ZeroEx.generatePseudoRandomSalt(),
+    nodeVersion: undefined,
+    screenWidth: utils.getScreenWidth(),
+    shouldBlockchainErrDialogBeOpen: false,
+    sideToAssetToken: {
+        [Side.Deposit]: {},
+        [Side.Receive]: {},
+    },
+    tokenByAddress: {},
+    tokenStateByAddress: {},
+    userAddress: '',
+    userEtherBalance: new BigNumber(0),
+    userSuppliedOrderCache: undefined,
+
+    // Docs
+    docsVersion: DEFAULT_DOCS_VERSION,
+    availableDocVersions: [DEFAULT_DOCS_VERSION],
+
+    // Shared
+    flashMessage: undefined,
+    providerType: ProviderType.Injected,
+    injectedProviderName: '',
 };
 
 export function reducer(state: State = INITIAL_STATE, action: Action) {
-	switch (action.type) {
-		// Portal
-		case ActionTypes.ResetState:
-			return INITIAL_STATE;
-
-		case ActionTypes.UpdateOrderSalt: {
-			return {
-				...state,
-				orderSalt: action.data,
-			};
-		}
-
-		case ActionTypes.UpdateNodeVersion: {
-			return {
-				...state,
-				nodeVersion: action.data,
-			};
-		}
-
-		case ActionTypes.UpdateOrderFillAmount: {
-			return {
-				...state,
-				orderFillAmount: action.data,
-			};
-		}
-
-		case ActionTypes.UpdateShouldBlockchainErrDialogBeOpen: {
-			return {
-				...state,
-				shouldBlockchainErrDialogBeOpen: action.data,
-			};
-		}
-
-		case ActionTypes.UpdateUserEtherBalance: {
-			return {
-				...state,
-				userEtherBalance: action.data,
-			};
-		}
-
-		case ActionTypes.UpdateUserSuppliedOrderCache: {
-			return {
-				...state,
-				userSuppliedOrderCache: action.data,
-			};
-		}
-
-		case ActionTypes.ClearTokenByAddress: {
-			return {
-				...state,
-				tokenByAddress: {},
-			};
-		}
-
-		case ActionTypes.AddTokenToTokenByAddress: {
-			const newTokenByAddress = state.tokenByAddress;
-			newTokenByAddress[action.data.address] = action.data;
-			return {
-				...state,
-				tokenByAddress: newTokenByAddress,
-			};
-		}
-
-		case ActionTypes.RemoveTokenFromTokenByAddress: {
-			const newTokenByAddress = state.tokenByAddress;
-			delete newTokenByAddress[action.data.address];
-			return {
-				...state,
-				tokenByAddress: newTokenByAddress,
-			};
-		}
-
-		case ActionTypes.UpdateTokenByAddress: {
-			const tokenByAddress = state.tokenByAddress;
-			const tokens = action.data;
-			_.each(tokens, token => {
-				const updatedToken = {
-					...tokenByAddress[token.address],
-					...token,
-				};
-				tokenByAddress[token.address] = updatedToken;
-			});
-			return {
-				...state,
-				tokenByAddress,
-			};
-		}
-
-		case ActionTypes.UpdateTokenStateByAddress: {
-			const tokenStateByAddress = state.tokenStateByAddress;
-			const updatedTokenStateByAddress = action.data;
-			_.each(updatedTokenStateByAddress, (tokenState: TokenState, address: string) => {
-				const updatedTokenState = {
-					...tokenStateByAddress[address],
-					...tokenState,
-				};
-				tokenStateByAddress[address] = updatedTokenState;
-			});
-			return {
-				...state,
-				tokenStateByAddress,
-			};
-		}
-
-		case ActionTypes.RemoveFromTokenStateByAddress: {
-			const tokenStateByAddress = state.tokenStateByAddress;
-			const tokenAddress = action.data;
-			delete tokenStateByAddress[tokenAddress];
-			return {
-				...state,
-				tokenStateByAddress,
-			};
-		}
-
-		case ActionTypes.ReplaceTokenAllowanceByAddress: {
-			const tokenStateByAddress = state.tokenStateByAddress;
-			const allowance = action.data.allowance;
-			const tokenAddress = action.data.address;
-			tokenStateByAddress[tokenAddress] = {
-				...tokenStateByAddress[tokenAddress],
-				allowance,
-			};
-			return {
-				...state,
-				tokenStateByAddress,
-			};
-		}
-
-		case ActionTypes.ReplaceTokenBalanceByAddress: {
-			const tokenStateByAddress = state.tokenStateByAddress;
-			const balance = action.data.balance;
-			const tokenAddress = action.data.address;
-			tokenStateByAddress[tokenAddress] = {
-				...tokenStateByAddress[tokenAddress],
-				balance,
-			};
-			return {
-				...state,
-				tokenStateByAddress,
-			};
-		}
-
-		case ActionTypes.UpdateTokenBalanceByAddress: {
-			const tokenStateByAddress = state.tokenStateByAddress;
-			const balanceDelta = action.data.balanceDelta;
-			const tokenAddress = action.data.address;
-			const currBalance = tokenStateByAddress[tokenAddress].balance;
-			tokenStateByAddress[tokenAddress] = {
-				...tokenStateByAddress[tokenAddress],
-				balance: currBalance.plus(balanceDelta),
-			};
-			return {
-				...state,
-				tokenStateByAddress,
-			};
-		}
-
-		case ActionTypes.UpdateOrderSignatureData: {
-			return {
-				...state,
-				orderSignatureData: action.data,
-			};
-		}
-
-		case ActionTypes.UpdateScreenWidth: {
-			return {
-				...state,
-				screenWidth: action.data,
-			};
-		}
-
-		case ActionTypes.UpdateBlockchainIsLoaded: {
-			return {
-				...state,
-				blockchainIsLoaded: action.data,
-			};
-		}
-
-		case ActionTypes.BlockchainErrEncountered: {
-			return {
-				...state,
-				blockchainErr: action.data,
-			};
-		}
-
-		case ActionTypes.UpdateNetworkId: {
-			return {
-				...state,
-				networkId: action.data,
-			};
-		}
-
-		case ActionTypes.UpdateChosenAssetToken: {
-			const newSideToAssetToken = {
-				...state.sideToAssetToken,
-				[action.data.side]: action.data.token,
-			};
-			return {
-				...state,
-				sideToAssetToken: newSideToAssetToken,
-			};
-		}
-
-		case ActionTypes.UpdateChosenAssetTokenAddress: {
-			const newAssetToken = state.sideToAssetToken[action.data.side];
-			newAssetToken.address = action.data.address;
-			const newSideToAssetToken = {
-				...state.sideToAssetToken,
-				[action.data.side]: newAssetToken,
-			};
-			return {
-				...state,
-				sideToAssetToken: newSideToAssetToken,
-			};
-		}
-
-		case ActionTypes.SwapAssetTokens: {
-			const newSideToAssetToken = {
-				[Side.Deposit]: state.sideToAssetToken[Side.Receive],
-				[Side.Receive]: state.sideToAssetToken[Side.Deposit],
-			};
-			return {
-				...state,
-				sideToAssetToken: newSideToAssetToken,
-			};
-		}
-
-		case ActionTypes.UpdateOrderExpiry: {
-			return {
-				...state,
-				orderExpiryTimestamp: action.data,
-			};
-		}
-
-		case ActionTypes.UpdateOrderTakerAddress: {
-			return {
-				...state,
-				orderTakerAddress: action.data,
-			};
-		}
-
-		case ActionTypes.UpdateUserAddress: {
-			return {
-				...state,
-				userAddress: action.data,
-			};
-		}
-
-		// Docs
-		case ActionTypes.UpdateLibraryVersion: {
-			return {
-				...state,
-				docsVersion: action.data,
-			};
-		}
-		case ActionTypes.UpdateAvailableLibraryVersions: {
-			return {
-				...state,
-				availableDocVersions: action.data,
-			};
-		}
-
-		// Shared
-		case ActionTypes.ShowFlashMessage: {
-			return {
-				...state,
-				flashMessage: action.data,
-			};
-		}
-
-		case ActionTypes.HideFlashMessage: {
-			return {
-				...state,
-				flashMessage: undefined,
-			};
-		}
-
-		case ActionTypes.UpdateProviderType: {
-			return {
-				...state,
-				providerType: action.data,
-			};
-		}
-
-		case ActionTypes.UpdateInjectedProviderName: {
-			return {
-				...state,
-				injectedProviderName: action.data,
-			};
-		}
-
-		default:
-			return state;
-	}
+    switch (action.type) {
+        // Portal
+        case ActionTypes.ResetState:
+            return INITIAL_STATE;
+
+        case ActionTypes.UpdateOrderSalt: {
+            return {
+                ...state,
+                orderSalt: action.data,
+            };
+        }
+
+        case ActionTypes.UpdateNodeVersion: {
+            return {
+                ...state,
+                nodeVersion: action.data,
+            };
+        }
+
+        case ActionTypes.UpdateOrderFillAmount: {
+            return {
+                ...state,
+                orderFillAmount: action.data,
+            };
+        }
+
+        case ActionTypes.UpdateShouldBlockchainErrDialogBeOpen: {
+            return {
+                ...state,
+                shouldBlockchainErrDialogBeOpen: action.data,
+            };
+        }
+
+        case ActionTypes.UpdateUserEtherBalance: {
+            return {
+                ...state,
+                userEtherBalance: action.data,
+            };
+        }
+
+        case ActionTypes.UpdateUserSuppliedOrderCache: {
+            return {
+                ...state,
+                userSuppliedOrderCache: action.data,
+            };
+        }
+
+        case ActionTypes.ClearTokenByAddress: {
+            return {
+                ...state,
+                tokenByAddress: {},
+            };
+        }
+
+        case ActionTypes.AddTokenToTokenByAddress: {
+            const newTokenByAddress = state.tokenByAddress;
+            newTokenByAddress[action.data.address] = action.data;
+            return {
+                ...state,
+                tokenByAddress: newTokenByAddress,
+            };
+        }
+
+        case ActionTypes.RemoveTokenFromTokenByAddress: {
+            const newTokenByAddress = state.tokenByAddress;
+            delete newTokenByAddress[action.data.address];
+            return {
+                ...state,
+                tokenByAddress: newTokenByAddress,
+            };
+        }
+
+        case ActionTypes.UpdateTokenByAddress: {
+            const tokenByAddress = state.tokenByAddress;
+            const tokens = action.data;
+            _.each(tokens, token => {
+                const updatedToken = {
+                    ...tokenByAddress[token.address],
+                    ...token,
+                };
+                tokenByAddress[token.address] = updatedToken;
+            });
+            return {
+                ...state,
+                tokenByAddress,
+            };
+        }
+
+        case ActionTypes.UpdateTokenStateByAddress: {
+            const tokenStateByAddress = state.tokenStateByAddress;
+            const updatedTokenStateByAddress = action.data;
+            _.each(updatedTokenStateByAddress, (tokenState: TokenState, address: string) => {
+                const updatedTokenState = {
+                    ...tokenStateByAddress[address],
+                    ...tokenState,
+                };
+                tokenStateByAddress[address] = updatedTokenState;
+            });
+            return {
+                ...state,
+                tokenStateByAddress,
+            };
+        }
+
+        case ActionTypes.RemoveFromTokenStateByAddress: {
+            const tokenStateByAddress = state.tokenStateByAddress;
+            const tokenAddress = action.data;
+            delete tokenStateByAddress[tokenAddress];
+            return {
+                ...state,
+                tokenStateByAddress,
+            };
+        }
+
+        case ActionTypes.ReplaceTokenAllowanceByAddress: {
+            const tokenStateByAddress = state.tokenStateByAddress;
+            const allowance = action.data.allowance;
+            const tokenAddress = action.data.address;
+            tokenStateByAddress[tokenAddress] = {
+                ...tokenStateByAddress[tokenAddress],
+                allowance,
+            };
+            return {
+                ...state,
+                tokenStateByAddress,
+            };
+        }
+
+        case ActionTypes.ReplaceTokenBalanceByAddress: {
+            const tokenStateByAddress = state.tokenStateByAddress;
+            const balance = action.data.balance;
+            const tokenAddress = action.data.address;
+            tokenStateByAddress[tokenAddress] = {
+                ...tokenStateByAddress[tokenAddress],
+                balance,
+            };
+            return {
+                ...state,
+                tokenStateByAddress,
+            };
+        }
+
+        case ActionTypes.UpdateTokenBalanceByAddress: {
+            const tokenStateByAddress = state.tokenStateByAddress;
+            const balanceDelta = action.data.balanceDelta;
+            const tokenAddress = action.data.address;
+            const currBalance = tokenStateByAddress[tokenAddress].balance;
+            tokenStateByAddress[tokenAddress] = {
+                ...tokenStateByAddress[tokenAddress],
+                balance: currBalance.plus(balanceDelta),
+            };
+            return {
+                ...state,
+                tokenStateByAddress,
+            };
+        }
+
+        case ActionTypes.UpdateOrderSignatureData: {
+            return {
+                ...state,
+                orderSignatureData: action.data,
+            };
+        }
+
+        case ActionTypes.UpdateScreenWidth: {
+            return {
+                ...state,
+                screenWidth: action.data,
+            };
+        }
+
+        case ActionTypes.UpdateBlockchainIsLoaded: {
+            return {
+                ...state,
+                blockchainIsLoaded: action.data,
+            };
+        }
+
+        case ActionTypes.BlockchainErrEncountered: {
+            return {
+                ...state,
+                blockchainErr: action.data,
+            };
+        }
+
+        case ActionTypes.UpdateNetworkId: {
+            return {
+                ...state,
+                networkId: action.data,
+            };
+        }
+
+        case ActionTypes.UpdateChosenAssetToken: {
+            const newSideToAssetToken = {
+                ...state.sideToAssetToken,
+                [action.data.side]: action.data.token,
+            };
+            return {
+                ...state,
+                sideToAssetToken: newSideToAssetToken,
+            };
+        }
+
+        case ActionTypes.UpdateChosenAssetTokenAddress: {
+            const newAssetToken = state.sideToAssetToken[action.data.side];
+            newAssetToken.address = action.data.address;
+            const newSideToAssetToken = {
+                ...state.sideToAssetToken,
+                [action.data.side]: newAssetToken,
+            };
+            return {
+                ...state,
+                sideToAssetToken: newSideToAssetToken,
+            };
+        }
+
+        case ActionTypes.SwapAssetTokens: {
+            const newSideToAssetToken = {
+                [Side.Deposit]: state.sideToAssetToken[Side.Receive],
+                [Side.Receive]: state.sideToAssetToken[Side.Deposit],
+            };
+            return {
+                ...state,
+                sideToAssetToken: newSideToAssetToken,
+            };
+        }
+
+        case ActionTypes.UpdateOrderExpiry: {
+            return {
+                ...state,
+                orderExpiryTimestamp: action.data,
+            };
+        }
+
+        case ActionTypes.UpdateOrderTakerAddress: {
+            return {
+                ...state,
+                orderTakerAddress: action.data,
+            };
+        }
+
+        case ActionTypes.UpdateUserAddress: {
+            return {
+                ...state,
+                userAddress: action.data,
+            };
+        }
+
+        // Docs
+        case ActionTypes.UpdateLibraryVersion: {
+            return {
+                ...state,
+                docsVersion: action.data,
+            };
+        }
+        case ActionTypes.UpdateAvailableLibraryVersions: {
+            return {
+                ...state,
+                availableDocVersions: action.data,
+            };
+        }
+
+        // Shared
+        case ActionTypes.ShowFlashMessage: {
+            return {
+                ...state,
+                flashMessage: action.data,
+            };
+        }
+
+        case ActionTypes.HideFlashMessage: {
+            return {
+                ...state,
+                flashMessage: undefined,
+            };
+        }
+
+        case ActionTypes.UpdateProviderType: {
+            return {
+                ...state,
+                providerType: action.data,
+            };
+        }
+
+        case ActionTypes.UpdateInjectedProviderName: {
+            return {
+                ...state,
+                injectedProviderName: action.data,
+            };
+        }
+
+        default:
+            return state;
+    }
 }
diff --git a/packages/website/ts/schemas/order_schema.ts b/packages/website/ts/schemas/order_schema.ts
index fd0bf113a..bfbf9eb8b 100644
--- a/packages/website/ts/schemas/order_schema.ts
+++ b/packages/website/ts/schemas/order_schema.ts
@@ -1,15 +1,15 @@
 export const orderSchema = {
-	id: '/Order',
-	properties: {
-		maker: { $ref: '/OrderTaker' },
-		taker: { $ref: '/OrderTaker' },
-		salt: { type: 'string' },
-		signature: { $ref: '/SignatureData' },
-		expiration: { type: 'string' },
-		feeRecipient: { type: 'string' },
-		exchangeContract: { type: 'string' },
-		networkId: { type: 'number' },
-	},
-	required: ['maker', 'taker', 'salt', 'signature', 'expiration', 'feeRecipient', 'exchangeContract', 'networkId'],
-	type: 'object',
+    id: '/Order',
+    properties: {
+        maker: { $ref: '/OrderTaker' },
+        taker: { $ref: '/OrderTaker' },
+        salt: { type: 'string' },
+        signature: { $ref: '/SignatureData' },
+        expiration: { type: 'string' },
+        feeRecipient: { type: 'string' },
+        exchangeContract: { type: 'string' },
+        networkId: { type: 'number' },
+    },
+    required: ['maker', 'taker', 'salt', 'signature', 'expiration', 'feeRecipient', 'exchangeContract', 'networkId'],
+    type: 'object',
 };
diff --git a/packages/website/ts/schemas/order_taker_schema.ts b/packages/website/ts/schemas/order_taker_schema.ts
index c84ec4a9f..c784c29c5 100644
--- a/packages/website/ts/schemas/order_taker_schema.ts
+++ b/packages/website/ts/schemas/order_taker_schema.ts
@@ -1,11 +1,11 @@
 export const orderTakerSchema = {
-	id: '/OrderTaker',
-	properties: {
-		address: { type: 'string' },
-		token: { $ref: '/Token' },
-		amount: { type: 'string' },
-		feeAmount: { type: 'string' },
-	},
-	required: ['address', 'token', 'amount', 'feeAmount'],
-	type: 'object',
+    id: '/OrderTaker',
+    properties: {
+        address: { type: 'string' },
+        token: { $ref: '/Token' },
+        amount: { type: 'string' },
+        feeAmount: { type: 'string' },
+    },
+    required: ['address', 'token', 'amount', 'feeAmount'],
+    type: 'object',
 };
diff --git a/packages/website/ts/schemas/signature_data_schema.ts b/packages/website/ts/schemas/signature_data_schema.ts
index 8cafff9e8..8d3f15926 100644
--- a/packages/website/ts/schemas/signature_data_schema.ts
+++ b/packages/website/ts/schemas/signature_data_schema.ts
@@ -1,11 +1,11 @@
 export const signatureDataSchema = {
-	id: '/SignatureData',
-	properties: {
-		hash: { type: 'string' },
-		r: { type: 'string' },
-		s: { type: 'string' },
-		v: { type: 'number' },
-	},
-	required: ['hash', 'r', 's', 'v'],
-	type: 'object',
+    id: '/SignatureData',
+    properties: {
+        hash: { type: 'string' },
+        r: { type: 'string' },
+        s: { type: 'string' },
+        v: { type: 'number' },
+    },
+    required: ['hash', 'r', 's', 'v'],
+    type: 'object',
 };
diff --git a/packages/website/ts/schemas/token_schema.ts b/packages/website/ts/schemas/token_schema.ts
index 6a3bed786..92b53a463 100644
--- a/packages/website/ts/schemas/token_schema.ts
+++ b/packages/website/ts/schemas/token_schema.ts
@@ -1,11 +1,11 @@
 export const tokenSchema = {
-	id: '/Token',
-	properties: {
-		name: { type: 'string' },
-		symbol: { type: 'string' },
-		decimals: { type: 'number' },
-		address: { type: 'string' },
-	},
-	required: ['name', 'symbol', 'decimals', 'address'],
-	type: 'object',
+    id: '/Token',
+    properties: {
+        name: { type: 'string' },
+        symbol: { type: 'string' },
+        decimals: { type: 'number' },
+        address: { type: 'string' },
+    },
+    required: ['name', 'symbol', 'decimals', 'address'],
+    type: 'object',
 };
diff --git a/packages/website/ts/schemas/validator.ts b/packages/website/ts/schemas/validator.ts
index a3aaafc98..5177501c6 100644
--- a/packages/website/ts/schemas/validator.ts
+++ b/packages/website/ts/schemas/validator.ts
@@ -5,15 +5,15 @@ import { signatureDataSchema } from 'ts/schemas/signature_data_schema';
 import { tokenSchema } from 'ts/schemas/token_schema';
 
 export class SchemaValidator {
-	private _validator: Validator;
-	constructor() {
-		this._validator = new Validator();
-		this._validator.addSchema(signatureDataSchema as JSONSchema, signatureDataSchema.id);
-		this._validator.addSchema(tokenSchema as JSONSchema, tokenSchema.id);
-		this._validator.addSchema(orderTakerSchema as JSONSchema, orderTakerSchema.id);
-		this._validator.addSchema(orderSchema as JSONSchema, orderSchema.id);
-	}
-	public validate(instance: object, schema: Schema) {
-		return this._validator.validate(instance, schema);
-	}
+    private _validator: Validator;
+    constructor() {
+        this._validator = new Validator();
+        this._validator.addSchema(signatureDataSchema as JSONSchema, signatureDataSchema.id);
+        this._validator.addSchema(tokenSchema as JSONSchema, tokenSchema.id);
+        this._validator.addSchema(orderTakerSchema as JSONSchema, orderTakerSchema.id);
+        this._validator.addSchema(orderSchema as JSONSchema, orderSchema.id);
+    }
+    public validate(instance: object, schema: Schema) {
+        return this._validator.validate(instance, schema);
+    }
 }
diff --git a/packages/website/ts/types.ts b/packages/website/ts/types.ts
index a853792cb..f873f95fa 100644
--- a/packages/website/ts/types.ts
+++ b/packages/website/ts/types.ts
@@ -2,680 +2,680 @@ import { BigNumber } from '@0xproject/utils';
 import * as _ from 'lodash';
 
 export enum Side {
-	Receive = 'RECEIVE',
-	Deposit = 'DEPOSIT',
+    Receive = 'RECEIVE',
+    Deposit = 'DEPOSIT',
 }
 
 export interface Token {
-	iconUrl?: string;
-	name: string;
-	address: string;
-	symbol: string;
-	decimals: number;
-	isTracked: boolean;
-	isRegistered: boolean;
+    iconUrl?: string;
+    name: string;
+    address: string;
+    symbol: string;
+    decimals: number;
+    isTracked: boolean;
+    isRegistered: boolean;
 }
 
 export interface TokenByAddress {
-	[address: string]: Token;
+    [address: string]: Token;
 }
 
 export interface TokenState {
-	allowance: BigNumber;
-	balance: BigNumber;
+    allowance: BigNumber;
+    balance: BigNumber;
 }
 
 export interface TokenStateByAddress {
-	[address: string]: TokenState;
+    [address: string]: TokenState;
 }
 
 export interface AssetToken {
-	address?: string;
-	amount?: BigNumber;
+    address?: string;
+    amount?: BigNumber;
 }
 
 export interface SideToAssetToken {
-	[side: string]: AssetToken;
+    [side: string]: AssetToken;
 }
 
 export interface SignatureData {
-	hash: string;
-	r: string;
-	s: string;
-	v: number;
+    hash: string;
+    r: string;
+    s: string;
+    v: number;
 }
 
 export interface HashData {
-	depositAmount: BigNumber;
-	depositTokenContractAddr: string;
-	feeRecipientAddress: string;
-	makerFee: BigNumber;
-	orderExpiryTimestamp: BigNumber;
-	orderMakerAddress: string;
-	orderTakerAddress: string;
-	receiveAmount: BigNumber;
-	receiveTokenContractAddr: string;
-	takerFee: BigNumber;
-	orderSalt: BigNumber;
+    depositAmount: BigNumber;
+    depositTokenContractAddr: string;
+    feeRecipientAddress: string;
+    makerFee: BigNumber;
+    orderExpiryTimestamp: BigNumber;
+    orderMakerAddress: string;
+    orderTakerAddress: string;
+    receiveAmount: BigNumber;
+    receiveTokenContractAddr: string;
+    takerFee: BigNumber;
+    orderSalt: BigNumber;
 }
 
 export interface OrderToken {
-	name: string;
-	symbol: string;
-	decimals: number;
-	address: string;
+    name: string;
+    symbol: string;
+    decimals: number;
+    address: string;
 }
 
 export interface OrderParty {
-	address: string;
-	token: OrderToken;
-	amount: string;
-	feeAmount: string;
+    address: string;
+    token: OrderToken;
+    amount: string;
+    feeAmount: string;
 }
 
 export interface Order {
-	maker: OrderParty;
-	taker: OrderParty;
-	expiration: string;
-	feeRecipient: string;
-	salt: string;
-	signature: SignatureData;
-	exchangeContract: string;
-	networkId: number;
+    maker: OrderParty;
+    taker: OrderParty;
+    expiration: string;
+    feeRecipient: string;
+    salt: string;
+    signature: SignatureData;
+    exchangeContract: string;
+    networkId: number;
 }
 
 export interface Fill {
-	logIndex: number;
-	maker: string;
-	taker: string;
-	makerToken: string;
-	takerToken: string;
-	filledMakerTokenAmount: BigNumber;
-	filledTakerTokenAmount: BigNumber;
-	paidMakerFee: BigNumber;
-	paidTakerFee: BigNumber;
-	orderHash: string;
-	transactionHash: string;
-	blockTimestamp: number;
+    logIndex: number;
+    maker: string;
+    taker: string;
+    makerToken: string;
+    takerToken: string;
+    filledMakerTokenAmount: BigNumber;
+    filledTakerTokenAmount: BigNumber;
+    paidMakerFee: BigNumber;
+    paidTakerFee: BigNumber;
+    orderHash: string;
+    transactionHash: string;
+    blockTimestamp: number;
 }
 
 export enum BalanceErrs {
-	incorrectNetworkForFaucet,
-	faucetRequestFailed,
-	faucetQueueIsFull,
-	mintingFailed,
-	sendFailed,
-	allowanceSettingFailed,
+    incorrectNetworkForFaucet,
+    faucetRequestFailed,
+    faucetQueueIsFull,
+    mintingFailed,
+    sendFailed,
+    allowanceSettingFailed,
 }
 
 export enum ActionTypes {
-	// Portal
-	UpdateScreenWidth = 'UPDATE_SCREEN_WIDTH',
-	UpdateNodeVersion = 'UPDATE_NODE_VERSION',
-	ResetState = 'RESET_STATE',
-	AddTokenToTokenByAddress = 'ADD_TOKEN_TO_TOKEN_BY_ADDRESS',
-	BlockchainErrEncountered = 'BLOCKCHAIN_ERR_ENCOUNTERED',
-	ClearTokenByAddress = 'CLEAR_TOKEN_BY_ADDRESS',
-	UpdateBlockchainIsLoaded = 'UPDATE_BLOCKCHAIN_IS_LOADED',
-	UpdateNetworkId = 'UPDATE_NETWORK_ID',
-	UpdateChosenAssetToken = 'UPDATE_CHOSEN_ASSET_TOKEN',
-	UpdateChosenAssetTokenAddress = 'UPDATE_CHOSEN_ASSET_TOKEN_ADDRESS',
-	UpdateOrderTakerAddress = 'UPDATE_ORDER_TAKER_ADDRESS',
-	UpdateOrderSalt = 'UPDATE_ORDER_SALT',
-	UpdateOrderSignatureData = 'UPDATE_ORDER_SIGNATURE_DATA',
-	UpdateTokenByAddress = 'UPDATE_TOKEN_BY_ADDRESS',
-	RemoveTokenFromTokenByAddress = 'REMOVE_TOKEN_FROM_TOKEN_BY_ADDRESS',
-	UpdateTokenStateByAddress = 'UPDATE_TOKEN_STATE_BY_ADDRESS',
-	RemoveFromTokenStateByAddress = 'REMOVE_FROM_TOKEN_STATE_BY_ADDRESS',
-	ReplaceTokenAllowanceByAddress = 'REPLACE_TOKEN_ALLOWANCE_BY_ADDRESS',
-	ReplaceTokenBalanceByAddress = 'REPLACE_TOKEN_BALANCE_BY_ADDRESS',
-	UpdateTokenBalanceByAddress = 'UPDATE_TOKEN_BALANCE_BY_ADDRESS',
-	UpdateOrderExpiry = 'UPDATE_ORDER_EXPIRY',
-	SwapAssetTokens = 'SWAP_ASSET_TOKENS',
-	UpdateUserAddress = 'UPDATE_USER_ADDRESS',
-	UpdateUserEtherBalance = 'UPDATE_USER_ETHER_BALANCE',
-	UpdateUserSuppliedOrderCache = 'UPDATE_USER_SUPPLIED_ORDER_CACHE',
-	UpdateOrderFillAmount = 'UPDATE_ORDER_FILL_AMOUNT',
-	UpdateShouldBlockchainErrDialogBeOpen = 'UPDATE_SHOULD_BLOCKCHAIN_ERR_DIALOG_BE_OPEN',
-
-	// Docs
-	UpdateLibraryVersion = 'UPDATE_LIBRARY_VERSION',
-	UpdateAvailableLibraryVersions = 'UPDATE_AVAILABLE_LIBRARY_VERSIONS',
-
-	// Shared
-	ShowFlashMessage = 'SHOW_FLASH_MESSAGE',
-	HideFlashMessage = 'HIDE_FLASH_MESSAGE',
-	UpdateProviderType = 'UPDATE_PROVIDER_TYPE',
-	UpdateInjectedProviderName = 'UPDATE_INJECTED_PROVIDER_NAME',
+    // Portal
+    UpdateScreenWidth = 'UPDATE_SCREEN_WIDTH',
+    UpdateNodeVersion = 'UPDATE_NODE_VERSION',
+    ResetState = 'RESET_STATE',
+    AddTokenToTokenByAddress = 'ADD_TOKEN_TO_TOKEN_BY_ADDRESS',
+    BlockchainErrEncountered = 'BLOCKCHAIN_ERR_ENCOUNTERED',
+    ClearTokenByAddress = 'CLEAR_TOKEN_BY_ADDRESS',
+    UpdateBlockchainIsLoaded = 'UPDATE_BLOCKCHAIN_IS_LOADED',
+    UpdateNetworkId = 'UPDATE_NETWORK_ID',
+    UpdateChosenAssetToken = 'UPDATE_CHOSEN_ASSET_TOKEN',
+    UpdateChosenAssetTokenAddress = 'UPDATE_CHOSEN_ASSET_TOKEN_ADDRESS',
+    UpdateOrderTakerAddress = 'UPDATE_ORDER_TAKER_ADDRESS',
+    UpdateOrderSalt = 'UPDATE_ORDER_SALT',
+    UpdateOrderSignatureData = 'UPDATE_ORDER_SIGNATURE_DATA',
+    UpdateTokenByAddress = 'UPDATE_TOKEN_BY_ADDRESS',
+    RemoveTokenFromTokenByAddress = 'REMOVE_TOKEN_FROM_TOKEN_BY_ADDRESS',
+    UpdateTokenStateByAddress = 'UPDATE_TOKEN_STATE_BY_ADDRESS',
+    RemoveFromTokenStateByAddress = 'REMOVE_FROM_TOKEN_STATE_BY_ADDRESS',
+    ReplaceTokenAllowanceByAddress = 'REPLACE_TOKEN_ALLOWANCE_BY_ADDRESS',
+    ReplaceTokenBalanceByAddress = 'REPLACE_TOKEN_BALANCE_BY_ADDRESS',
+    UpdateTokenBalanceByAddress = 'UPDATE_TOKEN_BALANCE_BY_ADDRESS',
+    UpdateOrderExpiry = 'UPDATE_ORDER_EXPIRY',
+    SwapAssetTokens = 'SWAP_ASSET_TOKENS',
+    UpdateUserAddress = 'UPDATE_USER_ADDRESS',
+    UpdateUserEtherBalance = 'UPDATE_USER_ETHER_BALANCE',
+    UpdateUserSuppliedOrderCache = 'UPDATE_USER_SUPPLIED_ORDER_CACHE',
+    UpdateOrderFillAmount = 'UPDATE_ORDER_FILL_AMOUNT',
+    UpdateShouldBlockchainErrDialogBeOpen = 'UPDATE_SHOULD_BLOCKCHAIN_ERR_DIALOG_BE_OPEN',
+
+    // Docs
+    UpdateLibraryVersion = 'UPDATE_LIBRARY_VERSION',
+    UpdateAvailableLibraryVersions = 'UPDATE_AVAILABLE_LIBRARY_VERSIONS',
+
+    // Shared
+    ShowFlashMessage = 'SHOW_FLASH_MESSAGE',
+    HideFlashMessage = 'HIDE_FLASH_MESSAGE',
+    UpdateProviderType = 'UPDATE_PROVIDER_TYPE',
+    UpdateInjectedProviderName = 'UPDATE_INJECTED_PROVIDER_NAME',
 }
 
 export interface Action {
-	type: ActionTypes;
-	data?: any;
+    type: ActionTypes;
+    data?: any;
 }
 
 export interface TrackedTokensByNetworkId {
-	[networkId: number]: Token[];
+    [networkId: number]: Token[];
 }
 
 export interface TrackedTokensByUserAddress {
-	[userAddress: string]: TrackedTokensByNetworkId;
+    [userAddress: string]: TrackedTokensByNetworkId;
 }
 
 export interface Styles {
-	[name: string]: React.CSSProperties;
+    [name: string]: React.CSSProperties;
 }
 
 export interface ProfileInfo {
-	name: string;
-	title?: string;
-	description: string;
-	image: string;
-	linkedIn?: string;
-	github?: string;
-	angellist?: string;
-	medium?: string;
-	twitter?: string;
+    name: string;
+    title?: string;
+    description: string;
+    image: string;
+    linkedIn?: string;
+    github?: string;
+    angellist?: string;
+    medium?: string;
+    twitter?: string;
 }
 
 export interface Partner {
-	name: string;
-	logo: string;
-	url: string;
+    name: string;
+    logo: string;
+    url: string;
 }
 
 export interface Statistic {
-	title: string;
-	figure: string;
+    title: string;
+    figure: string;
 }
 
 export interface StatisticByKey {
-	[key: string]: Statistic;
+    [key: string]: Statistic;
 }
 
 export interface ERC20MarketInfo {
-	etherMarketCapUsd: number;
-	numLiquidERC20Tokens: number;
-	marketCapERC20TokensUsd: number;
+    etherMarketCapUsd: number;
+    numLiquidERC20Tokens: number;
+    marketCapERC20TokensUsd: number;
 }
 
 export enum ExchangeContractErrs {
-	OrderFillExpired = 'ORDER_FILL_EXPIRED',
-	OrderAlreadyCancelledOrFilled = 'ORDER_ALREADY_CANCELLED_OR_FILLED',
-	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',
-	TransactionSenderIsNotFillOrderTaker = 'TRANSACTION_SENDER_IS_NOT_FILL_ORDER_TAKER',
-	InsufficientRemainingFillAmount = 'INSUFFICIENT_REMAINING_FILL_AMOUNT',
+    OrderFillExpired = 'ORDER_FILL_EXPIRED',
+    OrderAlreadyCancelledOrFilled = 'ORDER_ALREADY_CANCELLED_OR_FILLED',
+    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',
+    TransactionSenderIsNotFillOrderTaker = 'TRANSACTION_SENDER_IS_NOT_FILL_ORDER_TAKER',
+    InsufficientRemainingFillAmount = 'INSUFFICIENT_REMAINING_FILL_AMOUNT',
 }
 
 export interface ContractResponse {
-	logs: ContractEvent[];
+    logs: ContractEvent[];
 }
 
 export interface ContractEvent {
-	event: string;
-	args: any;
+    event: string;
+    args: any;
 }
 
 export type InputErrMsg = React.ReactNode | string | undefined;
 export type ValidatedBigNumberCallback = (isValid: boolean, amount?: BigNumber) => void;
 export enum ScreenWidths {
-	Sm = 'SM',
-	Md = 'MD',
-	Lg = 'LG',
+    Sm = 'SM',
+    Md = 'MD',
+    Lg = 'LG',
 }
 
 export enum AlertTypes {
-	ERROR,
-	SUCCESS,
+    ERROR,
+    SUCCESS,
 }
 
 export enum EtherscanLinkSuffixes {
-	Address = 'address',
-	Tx = 'tx',
+    Address = 'address',
+    Tx = 'tx',
 }
 
 export enum BlockchainErrs {
-	AContractNotDeployedOnNetwork = 'A_CONTRACT_NOT_DEPLOYED_ON_NETWORK',
-	DisconnectedFromEthereumNode = 'DISCONNECTED_FROM_ETHEREUM_NODE',
-	NoError = 'NO_ERROR',
+    AContractNotDeployedOnNetwork = 'A_CONTRACT_NOT_DEPLOYED_ON_NETWORK',
+    DisconnectedFromEthereumNode = 'DISCONNECTED_FROM_ETHEREUM_NODE',
+    NoError = 'NO_ERROR',
 }
 
 export enum BlockchainCallErrs {
-	ContractDoesNotExist = 'CONTRACT_DOES_NOT_EXIST',
-	UserHasNoAssociatedAddresses = 'USER_HAS_NO_ASSOCIATED_ADDRESSES',
-	UnhandledError = 'UNHANDLED_ERROR',
-	TokenAddressIsInvalid = 'TOKEN_ADDRESS_IS_INVALID',
+    ContractDoesNotExist = 'CONTRACT_DOES_NOT_EXIST',
+    UserHasNoAssociatedAddresses = 'USER_HAS_NO_ASSOCIATED_ADDRESSES',
+    UnhandledError = 'UNHANDLED_ERROR',
+    TokenAddressIsInvalid = 'TOKEN_ADDRESS_IS_INVALID',
 }
 
 // Exception: We don't make the values uppercase because these KindString's need to
 // match up those returned by TypeDoc
 export enum KindString {
-	Constructor = 'Constructor',
-	Property = 'Property',
-	Method = 'Method',
-	Interface = 'Interface',
-	TypeAlias = 'Type alias',
-	Variable = 'Variable',
-	Function = 'Function',
-	Enumeration = 'Enumeration',
+    Constructor = 'Constructor',
+    Property = 'Property',
+    Method = 'Method',
+    Interface = 'Interface',
+    TypeAlias = 'Type alias',
+    Variable = 'Variable',
+    Function = 'Function',
+    Enumeration = 'Enumeration',
 }
 
 export interface EnumValue {
-	name: string;
-	defaultValue?: string;
+    name: string;
+    defaultValue?: string;
 }
 
 export enum Environments {
-	DEVELOPMENT,
-	PRODUCTION,
+    DEVELOPMENT,
+    PRODUCTION,
 }
 
 export type ContractInstance = any; // TODO: add type definition for Contract
 
 export interface TypeDocType {
-	type: TypeDocTypes;
-	value: string;
-	name: string;
-	types: TypeDocType[];
-	typeArguments?: TypeDocType[];
-	declaration: TypeDocNode;
-	elementType?: TypeDocType;
+    type: TypeDocTypes;
+    value: string;
+    name: string;
+    types: TypeDocType[];
+    typeArguments?: TypeDocType[];
+    declaration: TypeDocNode;
+    elementType?: TypeDocType;
 }
 
 export interface TypeDocFlags {
-	isStatic?: boolean;
-	isOptional?: boolean;
-	isPublic?: boolean;
+    isStatic?: boolean;
+    isOptional?: boolean;
+    isPublic?: boolean;
 }
 
 export interface TypeDocGroup {
-	title: string;
-	children: number[];
+    title: string;
+    children: number[];
 }
 
 export interface TypeDocNode {
-	id?: number;
-	name?: string;
-	kind?: string;
-	defaultValue?: string;
-	kindString?: string;
-	type?: TypeDocType;
-	fileName?: string;
-	line?: number;
-	comment?: TypeDocNode;
-	text?: string;
-	shortText?: string;
-	returns?: string;
-	declaration: TypeDocNode;
-	flags?: TypeDocFlags;
-	indexSignature?: TypeDocNode[];
-	signatures?: TypeDocNode[];
-	parameters?: TypeDocNode[];
-	typeParameter?: TypeDocNode[];
-	sources?: TypeDocNode[];
-	children?: TypeDocNode[];
-	groups?: TypeDocGroup[];
+    id?: number;
+    name?: string;
+    kind?: string;
+    defaultValue?: string;
+    kindString?: string;
+    type?: TypeDocType;
+    fileName?: string;
+    line?: number;
+    comment?: TypeDocNode;
+    text?: string;
+    shortText?: string;
+    returns?: string;
+    declaration: TypeDocNode;
+    flags?: TypeDocFlags;
+    indexSignature?: TypeDocNode[];
+    signatures?: TypeDocNode[];
+    parameters?: TypeDocNode[];
+    typeParameter?: TypeDocNode[];
+    sources?: TypeDocNode[];
+    children?: TypeDocNode[];
+    groups?: TypeDocGroup[];
 }
 
 export enum TypeDocTypes {
-	Intrinsic = 'intrinsic',
-	Reference = 'reference',
-	Array = 'array',
-	StringLiteral = 'stringLiteral',
-	Reflection = 'reflection',
-	Union = 'union',
-	TypeParameter = 'typeParameter',
-	Unknown = 'unknown',
+    Intrinsic = 'intrinsic',
+    Reference = 'reference',
+    Array = 'array',
+    StringLiteral = 'stringLiteral',
+    Reflection = 'reflection',
+    Union = 'union',
+    TypeParameter = 'typeParameter',
+    Unknown = 'unknown',
 }
 
 export interface DocAgnosticFormat {
-	[sectionName: string]: DocSection;
+    [sectionName: string]: DocSection;
 }
 
 export interface DocSection {
-	comment: string;
-	constructors: Array<TypescriptMethod | SolidityMethod>;
-	methods: Array<TypescriptMethod | SolidityMethod>;
-	properties: Property[];
-	types: CustomType[];
-	events?: Event[];
+    comment: string;
+    constructors: Array<TypescriptMethod | SolidityMethod>;
+    methods: Array<TypescriptMethod | SolidityMethod>;
+    properties: Property[];
+    types: CustomType[];
+    events?: Event[];
 }
 
 export interface Event {
-	name: string;
-	eventArgs: EventArg[];
+    name: string;
+    eventArgs: EventArg[];
 }
 
 export interface EventArg {
-	isIndexed: boolean;
-	name: string;
-	type: Type;
+    isIndexed: boolean;
+    name: string;
+    type: Type;
 }
 
 export interface Property {
-	name: string;
-	type: Type;
-	source?: Source;
-	comment?: string;
+    name: string;
+    type: Type;
+    source?: Source;
+    comment?: string;
 }
 
 export interface BaseMethod {
-	isConstructor: boolean;
-	name: string;
-	returnComment?: string | undefined;
-	callPath: string;
-	parameters: Parameter[];
-	returnType: Type;
-	comment?: string;
+    isConstructor: boolean;
+    name: string;
+    returnComment?: string | undefined;
+    callPath: string;
+    parameters: Parameter[];
+    returnType: Type;
+    comment?: string;
 }
 
 export interface TypescriptMethod extends BaseMethod {
-	source?: Source;
-	isStatic?: boolean;
-	typeParameter?: TypeParameter;
+    source?: Source;
+    isStatic?: boolean;
+    typeParameter?: TypeParameter;
 }
 
 export interface SolidityMethod extends BaseMethod {
-	isConstant?: boolean;
-	isPayable?: boolean;
+    isConstant?: boolean;
+    isPayable?: boolean;
 }
 
 export interface Source {
-	fileName: string;
-	line: number;
+    fileName: string;
+    line: number;
 }
 
 export interface Parameter {
-	name: string;
-	comment: string;
-	isOptional: boolean;
-	type: Type;
+    name: string;
+    comment: string;
+    isOptional: boolean;
+    type: Type;
 }
 
 export interface TypeParameter {
-	name: string;
-	type: Type;
+    name: string;
+    type: Type;
 }
 
 export interface Type {
-	name: string;
-	typeDocType: TypeDocTypes;
-	value?: string;
-	typeArguments?: Type[];
-	elementType?: ElementType;
-	types?: Type[];
-	method?: TypescriptMethod;
+    name: string;
+    typeDocType: TypeDocTypes;
+    value?: string;
+    typeArguments?: Type[];
+    elementType?: ElementType;
+    types?: Type[];
+    method?: TypescriptMethod;
 }
 
 export interface ElementType {
-	name: string;
-	typeDocType: TypeDocTypes;
+    name: string;
+    typeDocType: TypeDocTypes;
 }
 
 export interface IndexSignature {
-	keyName: string;
-	keyType: Type;
-	valueName: string;
+    keyName: string;
+    keyType: Type;
+    valueName: string;
 }
 
 export interface CustomType {
-	name: string;
-	kindString: string;
-	type?: Type;
-	method?: TypescriptMethod;
-	indexSignature?: IndexSignature;
-	defaultValue?: string;
-	comment?: string;
-	children?: CustomTypeChild[];
+    name: string;
+    kindString: string;
+    type?: Type;
+    method?: TypescriptMethod;
+    indexSignature?: IndexSignature;
+    defaultValue?: string;
+    comment?: string;
+    children?: CustomTypeChild[];
 }
 
 export interface CustomTypeChild {
-	name: string;
-	type?: Type;
-	defaultValue?: string;
+    name: string;
+    type?: Type;
+    defaultValue?: string;
 }
 
 export interface FAQQuestion {
-	prompt: string;
-	answer: React.ReactNode;
+    prompt: string;
+    answer: React.ReactNode;
 }
 export interface FAQSection {
-	name: string;
-	questions: FAQQuestion[];
+    name: string;
+    questions: FAQQuestion[];
 }
 
 export interface S3FileObject {
-	Key: {
-		_text: string;
-	};
+    Key: {
+        _text: string;
+    };
 }
 
 export interface MenuSubsectionsBySection {
-	[section: string]: string[];
+    [section: string]: string[];
 }
 
 export enum ProviderType {
-	Injected = 'INJECTED',
-	Ledger = 'LEDGER',
+    Injected = 'INJECTED',
+    Ledger = 'LEDGER',
 }
 
 export interface Fact {
-	title: string;
-	explanation: string;
-	image: string;
+    title: string;
+    explanation: string;
+    image: string;
 }
 
 interface LedgerGetAddressResult {
-	address: string;
+    address: string;
 }
 interface LedgerSignResult {
-	v: string;
-	r: string;
-	s: string;
+    v: string;
+    r: string;
+    s: string;
 }
 interface LedgerCommunication {
-	close_async: () => Promise<void>;
+    close_async: () => Promise<void>;
 }
 export interface LedgerEthConnection {
-	getAddress_async: (
-		derivationPath: string,
-		askForDeviceConfirmation: boolean,
-		shouldGetChainCode: boolean,
-	) => Promise<LedgerGetAddressResult>;
-	signPersonalMessage_async: (derivationPath: string, messageHex: string) => Promise<LedgerSignResult>;
-	signTransaction_async: (derivationPath: string, txHex: string) => Promise<LedgerSignResult>;
-	comm: LedgerCommunication;
+    getAddress_async: (
+        derivationPath: string,
+        askForDeviceConfirmation: boolean,
+        shouldGetChainCode: boolean,
+    ) => Promise<LedgerGetAddressResult>;
+    signPersonalMessage_async: (derivationPath: string, messageHex: string) => Promise<LedgerSignResult>;
+    signTransaction_async: (derivationPath: string, txHex: string) => Promise<LedgerSignResult>;
+    comm: LedgerCommunication;
 }
 export interface SignPersonalMessageParams {
-	data: string;
+    data: string;
 }
 
 export interface TxParams {
-	nonce: string;
-	gasPrice?: number;
-	gasLimit: string;
-	to: string;
-	value?: string;
-	data?: string;
-	chainId: number; // EIP 155 chainId - mainnet: 1, ropsten: 3
+    nonce: string;
+    gasPrice?: number;
+    gasLimit: string;
+    to: string;
+    value?: string;
+    data?: string;
+    chainId: number; // EIP 155 chainId - mainnet: 1, ropsten: 3
 }
 
 export interface PublicNodeUrlsByNetworkId {
-	[networkId: number]: string[];
+    [networkId: number]: string[];
 }
 
 export interface JSONRPCPayload {
-	params: any[];
-	method: string;
+    params: any[];
+    method: string;
 }
 
 export interface BlogPost {
-	image: string;
-	date: string;
-	title: string;
-	description: string;
-	url: string;
+    image: string;
+    date: string;
+    title: string;
+    description: string;
+    url: string;
 }
 
 export interface TypeDefinitionByName {
-	[typeName: string]: CustomType;
+    [typeName: string]: CustomType;
 }
 
 export interface Article {
-	section: string;
-	title: string;
-	content: string;
-	fileName: string;
+    section: string;
+    title: string;
+    content: string;
+    fileName: string;
 }
 
 export interface ArticlesBySection {
-	[section: string]: Article[];
+    [section: string]: Article[];
 }
 
 export interface DialogConfigs {
-	title: string;
-	isModal: boolean;
-	actions: any[];
+    title: string;
+    isModal: boolean;
+    actions: any[];
 }
 
 export enum TokenVisibility {
-	ALL = 'ALL',
-	UNTRACKED = 'UNTRACKED',
-	TRACKED = 'TRACKED',
+    ALL = 'ALL',
+    UNTRACKED = 'UNTRACKED',
+    TRACKED = 'TRACKED',
 }
 
 export enum HeaderSizes {
-	H1 = 'h1',
-	H2 = 'h2',
-	H3 = 'h3',
+    H1 = 'h1',
+    H2 = 'h2',
+    H3 = 'h3',
 }
 
 export interface DoxityDocObj {
-	[contractName: string]: DoxityContractObj;
+    [contractName: string]: DoxityContractObj;
 }
 
 export interface DoxityContractObj {
-	title: string;
-	fileName: string;
-	name: string;
-	abiDocs: DoxityAbiDoc[];
+    title: string;
+    fileName: string;
+    name: string;
+    abiDocs: DoxityAbiDoc[];
 }
 
 export interface DoxityAbiDoc {
-	constant: boolean;
-	inputs: DoxityInput[];
-	name: string;
-	outputs: DoxityOutput[];
-	payable: boolean;
-	type: string;
-	details?: string;
-	return?: string;
+    constant: boolean;
+    inputs: DoxityInput[];
+    name: string;
+    outputs: DoxityOutput[];
+    payable: boolean;
+    type: string;
+    details?: string;
+    return?: string;
 }
 
 export interface DoxityOutput {
-	name: string;
-	type: string;
+    name: string;
+    type: string;
 }
 
 export interface DoxityInput {
-	name: string;
-	type: string;
-	description: string;
-	indexed?: boolean;
+    name: string;
+    type: string;
+    description: string;
+    indexed?: boolean;
 }
 
 export interface VersionToFileName {
-	[version: string]: string;
+    [version: string]: string;
 }
 
 export enum Docs {
-	ZeroExJs,
-	SmartContracts,
+    ZeroExJs,
+    SmartContracts,
 }
 
 export interface ContractAddresses {
-	[version: string]: {
-		[network: string]: AddressByContractName;
-	};
+    [version: string]: {
+        [network: string]: AddressByContractName;
+    };
 }
 
 export interface AddressByContractName {
-	[contractName: string]: string;
+    [contractName: string]: string;
 }
 
 export enum Networks {
-	mainnet = 'Mainnet',
-	kovan = 'Kovan',
-	ropsten = 'Ropsten',
-	rinkeby = 'Rinkeby',
+    mainnet = 'Mainnet',
+    kovan = 'Kovan',
+    ropsten = 'Ropsten',
+    rinkeby = 'Rinkeby',
 }
 
 export enum AbiTypes {
-	Constructor = 'constructor',
-	Function = 'function',
-	Event = 'event',
+    Constructor = 'constructor',
+    Function = 'function',
+    Event = 'event',
 }
 
 export enum WebsitePaths {
-	Portal = '/portal',
-	Wiki = '/wiki',
-	ZeroExJs = '/docs/0xjs',
-	Home = '/',
-	FAQ = '/faq',
-	About = '/about',
-	Whitepaper = '/pdfs/0x_white_paper.pdf',
-	SmartContracts = '/docs/contracts',
-	Connect = '/docs/connect',
+    Portal = '/portal',
+    Wiki = '/wiki',
+    ZeroExJs = '/docs/0xjs',
+    Home = '/',
+    FAQ = '/faq',
+    About = '/about',
+    Whitepaper = '/pdfs/0x_white_paper.pdf',
+    SmartContracts = '/docs/contracts',
+    Connect = '/docs/connect',
 }
 
 export interface DocsMenu {
-	[sectionName: string]: string[];
+    [sectionName: string]: string[];
 }
 
 export interface SectionsMap {
-	[sectionName: string]: string;
+    [sectionName: string]: string;
 }
 
 export interface DocsInfoConfig {
-	displayName: string;
-	packageUrl: string;
-	websitePath: string;
-	docsJsonRoot: string;
-	menu: DocsMenu;
-	sections: SectionsMap;
-	sectionNameToMarkdown: { [sectionName: string]: string };
-	visibleConstructors: string[];
-	convertToDocAgnosticFormatFn: (docObj: DoxityDocObj | TypeDocNode, docsInfo?: any) => DocAgnosticFormat;
-	subPackageName?: string;
-	publicTypes?: string[];
-	sectionNameToModulePath?: { [sectionName: string]: string[] };
-	menuSubsectionToVersionWhenIntroduced?: { [sectionName: string]: string };
+    displayName: string;
+    packageUrl: string;
+    websitePath: string;
+    docsJsonRoot: string;
+    menu: DocsMenu;
+    sections: SectionsMap;
+    sectionNameToMarkdown: { [sectionName: string]: string };
+    visibleConstructors: string[];
+    convertToDocAgnosticFormatFn: (docObj: DoxityDocObj | TypeDocNode, docsInfo?: any) => DocAgnosticFormat;
+    subPackageName?: string;
+    publicTypes?: string[];
+    sectionNameToModulePath?: { [sectionName: string]: string[] };
+    menuSubsectionToVersionWhenIntroduced?: { [sectionName: string]: string };
 }
 
 export interface TimestampMsRange {
-	startTimestampMs: number;
-	endTimestampMs: number;
+    startTimestampMs: number;
+    endTimestampMs: number;
 }
 
 export interface OutdatedWrappedEtherByNetworkId {
-	[networkId: number]: {
-		address: string;
-		timestampMsRange: TimestampMsRange;
-	};
+    [networkId: number]: {
+        address: string;
+        timestampMsRange: TimestampMsRange;
+    };
 }
 
 export enum SmartContractDocSections {
-	Introduction = 'Introduction',
-	Exchange = 'Exchange',
-	TokenTransferProxy = 'TokenTransferProxy',
-	TokenRegistry = 'TokenRegistry',
-	ZRXToken = 'ZRXToken',
+    Introduction = 'Introduction',
+    Exchange = 'Exchange',
+    TokenTransferProxy = 'TokenTransferProxy',
+    TokenRegistry = 'TokenRegistry',
+    ZRXToken = 'ZRXToken',
 }
 
 // tslint:disable:max-file-line-count
diff --git a/packages/website/ts/utils/colors.ts b/packages/website/ts/utils/colors.ts
index dabc1fd54..58ce667e3 100644
--- a/packages/website/ts/utils/colors.ts
+++ b/packages/website/ts/utils/colors.ts
@@ -1,43 +1,43 @@
 import { colors as materialUiColors } from 'material-ui/styles';
 
 export const colors = {
-	...materialUiColors,
-	grey50: '#FAFAFA',
-	grey100: '#F5F5F5',
-	lightestGrey: '#F0F0F0',
-	greyishPink: '#E6E5E5',
-	grey300: '#E0E0E0',
-	beigeWhite: '#E4E4E4',
-	grey400: '#BDBDBD',
-	lightGrey: '#BBBBBB',
-	grey500: '#9E9E9E',
-	grey: '#A5A5A5',
-	darkGrey: '#818181',
-	landingLinkGrey: '#919191',
-	grey700: '#616161',
-	grey800: '#424242',
-	darkerGrey: '#393939',
-	heroGrey: '#404040',
-	projectsGrey: '#343333',
-	darkestGrey: '#272727',
-	dharmaDarkGrey: '#252525',
-	lightBlue: '#60A4F4',
-	lightBlueA700: '#0091EA',
-	darkBlue: '#4D5481',
-	turquois: '#058789',
-	lightPurple: '#A81CA6',
-	purple: '#690596',
-	red200: '#EF9A9A',
-	red: '#E91751',
-	red500: '#F44336',
-	red600: '#E53935',
-	limeGreen: '#66DE75',
-	lightGreen: '#4DC55C',
-	lightestGreen: '#89C774',
-	brightGreen: '#00C33E',
-	green400: '#66BB6A',
-	green: '#4DA24B',
-	amber600: '#FFB300',
-	orange: '#E69D00',
-	amber800: '#FF8F00',
+    ...materialUiColors,
+    grey50: '#FAFAFA',
+    grey100: '#F5F5F5',
+    lightestGrey: '#F0F0F0',
+    greyishPink: '#E6E5E5',
+    grey300: '#E0E0E0',
+    beigeWhite: '#E4E4E4',
+    grey400: '#BDBDBD',
+    lightGrey: '#BBBBBB',
+    grey500: '#9E9E9E',
+    grey: '#A5A5A5',
+    darkGrey: '#818181',
+    landingLinkGrey: '#919191',
+    grey700: '#616161',
+    grey800: '#424242',
+    darkerGrey: '#393939',
+    heroGrey: '#404040',
+    projectsGrey: '#343333',
+    darkestGrey: '#272727',
+    dharmaDarkGrey: '#252525',
+    lightBlue: '#60A4F4',
+    lightBlueA700: '#0091EA',
+    darkBlue: '#4D5481',
+    turquois: '#058789',
+    lightPurple: '#A81CA6',
+    purple: '#690596',
+    red200: '#EF9A9A',
+    red: '#E91751',
+    red500: '#F44336',
+    red600: '#E53935',
+    limeGreen: '#66DE75',
+    lightGreen: '#4DC55C',
+    lightestGreen: '#89C774',
+    brightGreen: '#00C33E',
+    green400: '#66BB6A',
+    green: '#4DA24B',
+    amber600: '#FFB300',
+    orange: '#E69D00',
+    amber800: '#FF8F00',
 };
diff --git a/packages/website/ts/utils/configs.ts b/packages/website/ts/utils/configs.ts
index 6327ea05a..3d37a89ab 100644
--- a/packages/website/ts/utils/configs.ts
+++ b/packages/website/ts/utils/configs.ts
@@ -1,126 +1,126 @@
 import * as _ from 'lodash';
 import {
-	ContractAddresses,
-	Environments,
-	Networks,
-	OutdatedWrappedEtherByNetworkId,
-	PublicNodeUrlsByNetworkId,
-	SmartContractDocSections,
+    ContractAddresses,
+    Environments,
+    Networks,
+    OutdatedWrappedEtherByNetworkId,
+    PublicNodeUrlsByNetworkId,
+    SmartContractDocSections,
 } from 'ts/types';
 
 const BASE_URL = window.location.origin;
 const isDevelopment = _.includes(
-	['https://0xproject.localhost:3572', 'https://localhost:3572', 'https://127.0.0.1'],
-	BASE_URL,
+    ['https://0xproject.localhost:3572', 'https://localhost:3572', 'https://127.0.0.1'],
+    BASE_URL,
 );
 const INFURA_API_KEY = 'T5WSC8cautR4KXyYgsRs';
 
 export const configs = {
-	BACKEND_BASE_URL: isDevelopment ? 'https://localhost:3001' : 'https://website-api.0xproject.com',
-	BASE_URL,
-	BITLY_ACCESS_TOKEN: 'ffc4c1a31e5143848fb7c523b39f91b9b213d208',
-	CONTRACT_ADDRESS: {
-		'1.0.0': {
-			[Networks.mainnet]: {
-				[SmartContractDocSections.Exchange]: '0x12459c951127e0c374ff9105dda097662a027093',
-				[SmartContractDocSections.TokenTransferProxy]: '0x8da0d80f5007ef1e431dd2127178d224e32c2ef4',
-				[SmartContractDocSections.ZRXToken]: '0xe41d2489571d322189246dafa5ebde1f4699f498',
-				[SmartContractDocSections.TokenRegistry]: '0x926a74c5c36adf004c87399e65f75628b0f98d2c',
-			},
-			[Networks.ropsten]: {
-				[SmartContractDocSections.Exchange]: '0x479cc461fecd078f766ecc58533d6f69580cf3ac',
-				[SmartContractDocSections.TokenTransferProxy]: '0x4e9aad8184de8833365fea970cd9149372fdf1e6',
-				[SmartContractDocSections.ZRXToken]: '0xa8e9fa8f91e5ae138c74648c9c304f1c75003a8d',
-				[SmartContractDocSections.TokenRegistry]: '0x6b1a50f0bb5a7995444bd3877b22dc89c62843ed',
-			},
-			[Networks.kovan]: {
-				[SmartContractDocSections.Exchange]: '0x90fe2af704b34e0224bf2299c838e04d4dcf1364',
-				[SmartContractDocSections.TokenTransferProxy]: '0x087Eed4Bc1ee3DE49BeFbd66C662B434B15d49d4',
-				[SmartContractDocSections.ZRXToken]: '0x6ff6c0ff1d68b964901f986d4c9fa3ac68346570',
-				[SmartContractDocSections.TokenRegistry]: '0xf18e504561f4347bea557f3d4558f559dddbae7f',
-			},
-		},
-	} as ContractAddresses,
-	DEFAULT_DERIVATION_PATH: `44'/60'/0'`,
-	// WARNING: ZRX & WETH MUST always be default trackedTokens
-	DEFAULT_TRACKED_TOKEN_SYMBOLS: ['WETH', 'ZRX'],
-	DOMAIN_STAGING: 'staging-0xproject.s3-website-us-east-1.amazonaws.com',
-	DOMAIN_DEVELOPMENT: '0xproject.localhost:3572',
-	DOMAIN_PRODUCTION: '0xproject.com',
-	ENVIRONMENT: isDevelopment ? Environments.DEVELOPMENT : Environments.PRODUCTION,
-	ICON_URL_BY_SYMBOL: {
-		REP: '/images/token_icons/augur.png',
-		DGD: '/images/token_icons/digixdao.png',
-		WETH: '/images/token_icons/ether_erc20.png',
-		MLN: '/images/token_icons/melon.png',
-		GNT: '/images/token_icons/golem.png',
-		MKR: '/images/token_icons/makerdao.png',
-		ZRX: '/images/token_icons/zero_ex.png',
-		ANT: '/images/token_icons/aragon.png',
-		BNT: '/images/token_icons/bancor.png',
-		BAT: '/images/token_icons/basicattentiontoken.png',
-		CVC: '/images/token_icons/civic.png',
-		EOS: '/images/token_icons/eos.png',
-		FUN: '/images/token_icons/funfair.png',
-		GNO: '/images/token_icons/gnosis.png',
-		ICN: '/images/token_icons/iconomi.png',
-		OMG: '/images/token_icons/omisego.png',
-		SNT: '/images/token_icons/status.png',
-		STORJ: '/images/token_icons/storjcoinx.png',
-		PAY: '/images/token_icons/tenx.png',
-		QTUM: '/images/token_icons/qtum.png',
-		DNT: '/images/token_icons/district0x.png',
-		SNGLS: '/images/token_icons/singularity.png',
-		EDG: '/images/token_icons/edgeless.png',
-		'1ST': '/images/token_icons/firstblood.jpg',
-		WINGS: '/images/token_icons/wings.png',
-		BQX: '/images/token_icons/bitquence.png',
-		LUN: '/images/token_icons/lunyr.png',
-		RLC: '/images/token_icons/iexec.png',
-		MCO: '/images/token_icons/monaco.png',
-		ADT: '/images/token_icons/adtoken.png',
-		CFI: '/images/token_icons/cofound-it.png',
-		ROL: '/images/token_icons/etheroll.png',
-		WGNT: '/images/token_icons/golem.png',
-		MTL: '/images/token_icons/metal.png',
-		NMR: '/images/token_icons/numeraire.png',
-		SAN: '/images/token_icons/santiment.png',
-		TAAS: '/images/token_icons/taas.png',
-		TKN: '/images/token_icons/tokencard.png',
-		TRST: '/images/token_icons/trust.png',
-	} as { [symbol: string]: string },
-	IS_MAINNET_ENABLED: true,
-	LAST_LOCAL_STORAGE_FILL_CLEARANCE_DATE: '2017-11-22',
-	LAST_LOCAL_STORAGE_TRACKED_TOKEN_CLEARANCE_DATE: '2017-12-19',
-	// NEW_WRAPPED_ETHERS is temporary until we remove the SHOULD_DEPRECATE_OLD_WETH_TOKEN flag
-	// and add the new WETHs to the tokenRegistry
-	NEW_WRAPPED_ETHERS: {
-		1: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
-		42: '0xd0a1e359811322d97991e03f863a0c30c2cf029c',
-	} as { [networkId: string]: string },
-	OUTDATED_WRAPPED_ETHERS: [
-		{
-			42: {
-				address: '0x05d090b51c40b020eab3bfcb6a2dff130df22e9c',
-				timestampMsRange: {
-					startTimestampMs: 1502455607000,
-					endTimestampMs: 1513790926000,
-				},
-			},
-			1: {
-				address: '0x2956356cd2a2bf3202f771f50d3d14a367b48070',
-				timestampMsRange: {
-					startTimestampMs: 1502455607000,
-					endTimestampMs: 1513790926000,
-				},
-			},
-		},
-	] as OutdatedWrappedEtherByNetworkId[],
-	// The order matters. We first try first node and only then fall back to others.
-	PUBLIC_NODE_URLS_BY_NETWORK_ID: {
-		[1]: [`https://mainnet.infura.io/${INFURA_API_KEY}`, 'https://mainnet.0xproject.com'],
-		[42]: [`https://kovan.infura.io/${INFURA_API_KEY}`, 'https://kovan.0xproject.com'],
-	} as PublicNodeUrlsByNetworkId,
-	SHOULD_DEPRECATE_OLD_WETH_TOKEN: true,
-	SYMBOLS_OF_MINTABLE_TOKENS: ['MKR', 'MLN', 'GNT', 'DGD', 'REP'],
+    BACKEND_BASE_URL: isDevelopment ? 'https://localhost:3001' : 'https://website-api.0xproject.com',
+    BASE_URL,
+    BITLY_ACCESS_TOKEN: 'ffc4c1a31e5143848fb7c523b39f91b9b213d208',
+    CONTRACT_ADDRESS: {
+        '1.0.0': {
+            [Networks.mainnet]: {
+                [SmartContractDocSections.Exchange]: '0x12459c951127e0c374ff9105dda097662a027093',
+                [SmartContractDocSections.TokenTransferProxy]: '0x8da0d80f5007ef1e431dd2127178d224e32c2ef4',
+                [SmartContractDocSections.ZRXToken]: '0xe41d2489571d322189246dafa5ebde1f4699f498',
+                [SmartContractDocSections.TokenRegistry]: '0x926a74c5c36adf004c87399e65f75628b0f98d2c',
+            },
+            [Networks.ropsten]: {
+                [SmartContractDocSections.Exchange]: '0x479cc461fecd078f766ecc58533d6f69580cf3ac',
+                [SmartContractDocSections.TokenTransferProxy]: '0x4e9aad8184de8833365fea970cd9149372fdf1e6',
+                [SmartContractDocSections.ZRXToken]: '0xa8e9fa8f91e5ae138c74648c9c304f1c75003a8d',
+                [SmartContractDocSections.TokenRegistry]: '0x6b1a50f0bb5a7995444bd3877b22dc89c62843ed',
+            },
+            [Networks.kovan]: {
+                [SmartContractDocSections.Exchange]: '0x90fe2af704b34e0224bf2299c838e04d4dcf1364',
+                [SmartContractDocSections.TokenTransferProxy]: '0x087Eed4Bc1ee3DE49BeFbd66C662B434B15d49d4',
+                [SmartContractDocSections.ZRXToken]: '0x6ff6c0ff1d68b964901f986d4c9fa3ac68346570',
+                [SmartContractDocSections.TokenRegistry]: '0xf18e504561f4347bea557f3d4558f559dddbae7f',
+            },
+        },
+    } as ContractAddresses,
+    DEFAULT_DERIVATION_PATH: `44'/60'/0'`,
+    // WARNING: ZRX & WETH MUST always be default trackedTokens
+    DEFAULT_TRACKED_TOKEN_SYMBOLS: ['WETH', 'ZRX'],
+    DOMAIN_STAGING: 'staging-0xproject.s3-website-us-east-1.amazonaws.com',
+    DOMAIN_DEVELOPMENT: '0xproject.localhost:3572',
+    DOMAIN_PRODUCTION: '0xproject.com',
+    ENVIRONMENT: isDevelopment ? Environments.DEVELOPMENT : Environments.PRODUCTION,
+    ICON_URL_BY_SYMBOL: {
+        REP: '/images/token_icons/augur.png',
+        DGD: '/images/token_icons/digixdao.png',
+        WETH: '/images/token_icons/ether_erc20.png',
+        MLN: '/images/token_icons/melon.png',
+        GNT: '/images/token_icons/golem.png',
+        MKR: '/images/token_icons/makerdao.png',
+        ZRX: '/images/token_icons/zero_ex.png',
+        ANT: '/images/token_icons/aragon.png',
+        BNT: '/images/token_icons/bancor.png',
+        BAT: '/images/token_icons/basicattentiontoken.png',
+        CVC: '/images/token_icons/civic.png',
+        EOS: '/images/token_icons/eos.png',
+        FUN: '/images/token_icons/funfair.png',
+        GNO: '/images/token_icons/gnosis.png',
+        ICN: '/images/token_icons/iconomi.png',
+        OMG: '/images/token_icons/omisego.png',
+        SNT: '/images/token_icons/status.png',
+        STORJ: '/images/token_icons/storjcoinx.png',
+        PAY: '/images/token_icons/tenx.png',
+        QTUM: '/images/token_icons/qtum.png',
+        DNT: '/images/token_icons/district0x.png',
+        SNGLS: '/images/token_icons/singularity.png',
+        EDG: '/images/token_icons/edgeless.png',
+        '1ST': '/images/token_icons/firstblood.jpg',
+        WINGS: '/images/token_icons/wings.png',
+        BQX: '/images/token_icons/bitquence.png',
+        LUN: '/images/token_icons/lunyr.png',
+        RLC: '/images/token_icons/iexec.png',
+        MCO: '/images/token_icons/monaco.png',
+        ADT: '/images/token_icons/adtoken.png',
+        CFI: '/images/token_icons/cofound-it.png',
+        ROL: '/images/token_icons/etheroll.png',
+        WGNT: '/images/token_icons/golem.png',
+        MTL: '/images/token_icons/metal.png',
+        NMR: '/images/token_icons/numeraire.png',
+        SAN: '/images/token_icons/santiment.png',
+        TAAS: '/images/token_icons/taas.png',
+        TKN: '/images/token_icons/tokencard.png',
+        TRST: '/images/token_icons/trust.png',
+    } as { [symbol: string]: string },
+    IS_MAINNET_ENABLED: true,
+    LAST_LOCAL_STORAGE_FILL_CLEARANCE_DATE: '2017-11-22',
+    LAST_LOCAL_STORAGE_TRACKED_TOKEN_CLEARANCE_DATE: '2017-12-19',
+    // NEW_WRAPPED_ETHERS is temporary until we remove the SHOULD_DEPRECATE_OLD_WETH_TOKEN flag
+    // and add the new WETHs to the tokenRegistry
+    NEW_WRAPPED_ETHERS: {
+        1: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
+        42: '0xd0a1e359811322d97991e03f863a0c30c2cf029c',
+    } as { [networkId: string]: string },
+    OUTDATED_WRAPPED_ETHERS: [
+        {
+            42: {
+                address: '0x05d090b51c40b020eab3bfcb6a2dff130df22e9c',
+                timestampMsRange: {
+                    startTimestampMs: 1502455607000,
+                    endTimestampMs: 1513790926000,
+                },
+            },
+            1: {
+                address: '0x2956356cd2a2bf3202f771f50d3d14a367b48070',
+                timestampMsRange: {
+                    startTimestampMs: 1502455607000,
+                    endTimestampMs: 1513790926000,
+                },
+            },
+        },
+    ] as OutdatedWrappedEtherByNetworkId[],
+    // The order matters. We first try first node and only then fall back to others.
+    PUBLIC_NODE_URLS_BY_NETWORK_ID: {
+        [1]: [`https://mainnet.infura.io/${INFURA_API_KEY}`, 'https://mainnet.0xproject.com'],
+        [42]: [`https://kovan.infura.io/${INFURA_API_KEY}`, 'https://kovan.0xproject.com'],
+    } as PublicNodeUrlsByNetworkId,
+    SHOULD_DEPRECATE_OLD_WETH_TOKEN: true,
+    SYMBOLS_OF_MINTABLE_TOKENS: ['MKR', 'MLN', 'GNT', 'DGD', 'REP'],
 };
diff --git a/packages/website/ts/utils/constants.ts b/packages/website/ts/utils/constants.ts
index bb6407ec5..dded82114 100644
--- a/packages/website/ts/utils/constants.ts
+++ b/packages/website/ts/utils/constants.ts
@@ -2,86 +2,86 @@ import { BigNumber } from '@0xproject/utils';
 import { Networks } from 'ts/types';
 
 export const constants = {
-	DECIMAL_PLACES_ETH: 18,
-	DECIMAL_PLACES_ZRX: 18,
-	DOCS_SCROLL_DURATION_MS: 0,
-	DOCS_CONTAINER_ID: 'documentation',
-	GENESIS_ORDER_BLOCK_BY_NETWORK_ID: {
-		1: 4145578,
-		42: 3117574,
-		50: 0,
-	} as { [networkId: number]: number },
-	HOME_SCROLL_DURATION_MS: 500,
-	HTTP_NO_CONTENT_STATUS_CODE: 204,
-	LOCAL_STORAGE_KEY_ACCEPT_DISCLAIMER: 'didAcceptPortalDisclaimer',
-	LOCAL_STORAGE_KEY_DISMISS_WETH_NOTICE: 'hasDismissedWethNotice',
-	MAKER_FEE: new BigNumber(0),
-	MAINNET_NAME: 'Main network',
-	MINT_AMOUNT: new BigNumber('100000000000000000000'),
-	NETWORK_ID_MAINNET: 1,
-	NETWORK_ID_TESTNET: 42,
-	NETWORK_ID_TESTRPC: 50,
-	NETWORK_NAME_BY_ID: {
-		1: Networks.mainnet,
-		3: Networks.ropsten,
-		4: Networks.rinkeby,
-		42: Networks.kovan,
-	} as { [symbol: number]: string },
-	NETWORK_ID_BY_NAME: {
-		[Networks.mainnet]: 1,
-		[Networks.ropsten]: 3,
-		[Networks.rinkeby]: 4,
-		[Networks.kovan]: 42,
-	} as { [networkName: string]: number },
-	NULL_ADDRESS: '0x0000000000000000000000000000000000000000',
-	PROVIDER_NAME_LEDGER: 'Ledger',
-	PROVIDER_NAME_METAMASK: 'Metamask',
-	PROVIDER_NAME_PARITY_SIGNER: 'Parity Signer',
-	PROVIDER_NAME_GENERIC: 'Injected Web3',
-	PROVIDER_NAME_PUBLIC: '0x Public',
-	ROLLBAR_ACCESS_TOKEN: 'a6619002b51c4464928201e6ea94de65',
-	SUCCESS_STATUS: 200,
-	UNAVAILABLE_STATUS: 503,
-	TAKER_FEE: new BigNumber(0),
-	TESTNET_NAME: 'Kovan',
-	TYPES_SECTION_NAME: 'types',
-	PROJECT_URL_ETHFINEX: 'https://www.bitfinex.com/ethfinex',
-	PROJECT_URL_RADAR_RELAY: 'https://radarrelay.com',
-	PROJECT_URL_PARADEX: 'https://paradex.io',
-	PROJECT_URL_DYDX: 'https://dydx.exchange',
-	PROJECT_URL_MELONPORT: 'https://melonport.com',
-	PROJECT_URL_DISTRICT_0X: 'https://district0x.io',
-	PROJECT_URL_DHARMA: 'https://dharma.io',
-	PROJECT_URL_LENDROID: 'https://lendroid.com',
-	PROJECT_URL_MAKER: 'https://makerdao.com',
-	PROJECT_URL_ARAGON: 'https://aragon.one',
-	PROJECT_URL_BLOCKNET: 'https://blocknet.co',
-	PROJECT_URL_0CEAN: 'http://the0cean.com',
-	PROJECT_URL_STATUS: 'https://status.im',
-	PROJECT_URL_AUGUR: 'https://augur.net',
-	PROJECT_URL_AUCTUS: 'https://auctus.org',
-	PROJECT_URL_OPEN_ANX: 'https://www.openanx.org',
-	URL_ANGELLIST: 'https://angel.co/0xproject/jobs',
-	URL_BIGNUMBERJS_GITHUB: 'http://mikemcl.github.io/bignumber.js',
-	URL_BITLY_API: 'https://api-ssl.bitly.com',
-	URL_BLOG: 'https://blog.0xproject.com/latest',
-	URL_DISCOURSE_FORUM: 'https://forum.0xproject.com',
-	URL_FIREFOX_U2F_ADDON: 'https://addons.mozilla.org/en-US/firefox/addon/u2f-support-add-on/',
-	URL_ETHER_FAUCET: 'https://faucet.0xproject.com',
-	URL_GITHUB_ORG: 'https://github.com/0xProject',
-	URL_GITHUB_WIKI: 'https://github.com/0xProject/wiki',
-	URL_METAMASK_CHROME_STORE: 'https://chrome.google.com/webstore/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn',
-	URL_MIST_DOWNLOAD: 'https://github.com/ethereum/mist/releases',
-	URL_PARITY_CHROME_STORE:
-		'https://chrome.google.com/webstore/detail/parity-ethereum-integrati/himekenlppkgeaoeddcliojfddemadig',
-	URL_REDDIT: 'https://reddit.com/r/0xproject',
-	URL_STANDARD_RELAYER_API_GITHUB: 'https://github.com/0xProject/standard-relayer-api/blob/master/README.md',
-	URL_TWITTER: 'https://twitter.com/0xproject',
-	URL_WEB3_DOCS: 'https://github.com/ethereum/wiki/wiki/JavaScript-API',
-	URL_WEB3_DECODED_LOG_ENTRY_EVENT:
-		'https://github.com/0xProject/web3-typescript-typings/blob/f5bcb96/index.d.ts#L123',
-	URL_WEB3_LOG_ENTRY_EVENT: 'https://github.com/0xProject/web3-typescript-typings/blob/f5bcb96/index.d.ts#L127',
-	URL_WEB3_PROVIDER_DOCS: 'https://github.com/0xProject/web3-typescript-typings/blob/f5bcb96/index.d.ts#L150',
-	URL_WETH_IO: 'https://weth.io/',
-	URL_ZEROEX_CHAT: 'https://chat.0xproject.com',
+    DECIMAL_PLACES_ETH: 18,
+    DECIMAL_PLACES_ZRX: 18,
+    DOCS_SCROLL_DURATION_MS: 0,
+    DOCS_CONTAINER_ID: 'documentation',
+    GENESIS_ORDER_BLOCK_BY_NETWORK_ID: {
+        1: 4145578,
+        42: 3117574,
+        50: 0,
+    } as { [networkId: number]: number },
+    HOME_SCROLL_DURATION_MS: 500,
+    HTTP_NO_CONTENT_STATUS_CODE: 204,
+    LOCAL_STORAGE_KEY_ACCEPT_DISCLAIMER: 'didAcceptPortalDisclaimer',
+    LOCAL_STORAGE_KEY_DISMISS_WETH_NOTICE: 'hasDismissedWethNotice',
+    MAKER_FEE: new BigNumber(0),
+    MAINNET_NAME: 'Main network',
+    MINT_AMOUNT: new BigNumber('100000000000000000000'),
+    NETWORK_ID_MAINNET: 1,
+    NETWORK_ID_TESTNET: 42,
+    NETWORK_ID_TESTRPC: 50,
+    NETWORK_NAME_BY_ID: {
+        1: Networks.mainnet,
+        3: Networks.ropsten,
+        4: Networks.rinkeby,
+        42: Networks.kovan,
+    } as { [symbol: number]: string },
+    NETWORK_ID_BY_NAME: {
+        [Networks.mainnet]: 1,
+        [Networks.ropsten]: 3,
+        [Networks.rinkeby]: 4,
+        [Networks.kovan]: 42,
+    } as { [networkName: string]: number },
+    NULL_ADDRESS: '0x0000000000000000000000000000000000000000',
+    PROVIDER_NAME_LEDGER: 'Ledger',
+    PROVIDER_NAME_METAMASK: 'Metamask',
+    PROVIDER_NAME_PARITY_SIGNER: 'Parity Signer',
+    PROVIDER_NAME_GENERIC: 'Injected Web3',
+    PROVIDER_NAME_PUBLIC: '0x Public',
+    ROLLBAR_ACCESS_TOKEN: 'a6619002b51c4464928201e6ea94de65',
+    SUCCESS_STATUS: 200,
+    UNAVAILABLE_STATUS: 503,
+    TAKER_FEE: new BigNumber(0),
+    TESTNET_NAME: 'Kovan',
+    TYPES_SECTION_NAME: 'types',
+    PROJECT_URL_ETHFINEX: 'https://www.bitfinex.com/ethfinex',
+    PROJECT_URL_RADAR_RELAY: 'https://radarrelay.com',
+    PROJECT_URL_PARADEX: 'https://paradex.io',
+    PROJECT_URL_DYDX: 'https://dydx.exchange',
+    PROJECT_URL_MELONPORT: 'https://melonport.com',
+    PROJECT_URL_DISTRICT_0X: 'https://district0x.io',
+    PROJECT_URL_DHARMA: 'https://dharma.io',
+    PROJECT_URL_LENDROID: 'https://lendroid.com',
+    PROJECT_URL_MAKER: 'https://makerdao.com',
+    PROJECT_URL_ARAGON: 'https://aragon.one',
+    PROJECT_URL_BLOCKNET: 'https://blocknet.co',
+    PROJECT_URL_0CEAN: 'http://the0cean.com',
+    PROJECT_URL_STATUS: 'https://status.im',
+    PROJECT_URL_AUGUR: 'https://augur.net',
+    PROJECT_URL_AUCTUS: 'https://auctus.org',
+    PROJECT_URL_OPEN_ANX: 'https://www.openanx.org',
+    URL_ANGELLIST: 'https://angel.co/0xproject/jobs',
+    URL_BIGNUMBERJS_GITHUB: 'http://mikemcl.github.io/bignumber.js',
+    URL_BITLY_API: 'https://api-ssl.bitly.com',
+    URL_BLOG: 'https://blog.0xproject.com/latest',
+    URL_DISCOURSE_FORUM: 'https://forum.0xproject.com',
+    URL_FIREFOX_U2F_ADDON: 'https://addons.mozilla.org/en-US/firefox/addon/u2f-support-add-on/',
+    URL_ETHER_FAUCET: 'https://faucet.0xproject.com',
+    URL_GITHUB_ORG: 'https://github.com/0xProject',
+    URL_GITHUB_WIKI: 'https://github.com/0xProject/wiki',
+    URL_METAMASK_CHROME_STORE: 'https://chrome.google.com/webstore/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn',
+    URL_MIST_DOWNLOAD: 'https://github.com/ethereum/mist/releases',
+    URL_PARITY_CHROME_STORE:
+        'https://chrome.google.com/webstore/detail/parity-ethereum-integrati/himekenlppkgeaoeddcliojfddemadig',
+    URL_REDDIT: 'https://reddit.com/r/0xproject',
+    URL_STANDARD_RELAYER_API_GITHUB: 'https://github.com/0xProject/standard-relayer-api/blob/master/README.md',
+    URL_TWITTER: 'https://twitter.com/0xproject',
+    URL_WEB3_DOCS: 'https://github.com/ethereum/wiki/wiki/JavaScript-API',
+    URL_WEB3_DECODED_LOG_ENTRY_EVENT:
+        'https://github.com/0xProject/web3-typescript-typings/blob/f5bcb96/index.d.ts#L123',
+    URL_WEB3_LOG_ENTRY_EVENT: 'https://github.com/0xProject/web3-typescript-typings/blob/f5bcb96/index.d.ts#L127',
+    URL_WEB3_PROVIDER_DOCS: 'https://github.com/0xProject/web3-typescript-typings/blob/f5bcb96/index.d.ts#L150',
+    URL_WETH_IO: 'https://weth.io/',
+    URL_ZEROEX_CHAT: 'https://chat.0xproject.com',
 };
diff --git a/packages/website/ts/utils/doc_utils.ts b/packages/website/ts/utils/doc_utils.ts
index 18bf276b4..1f5f75ee2 100644
--- a/packages/website/ts/utils/doc_utils.ts
+++ b/packages/website/ts/utils/doc_utils.ts
@@ -5,47 +5,47 @@ import { utils } from 'ts/utils/utils';
 import convert = require('xml-js');
 
 export const docUtils = {
-	async getVersionToFileNameAsync(s3DocJsonRoot: string): Promise<VersionToFileName> {
-		const versionFileNames = await this.getVersionFileNamesAsync(s3DocJsonRoot);
-		const versionToFileName: VersionToFileName = {};
-		_.each(versionFileNames, fileName => {
-			const [version] = findVersions(fileName);
-			versionToFileName[version] = fileName;
-		});
-		return versionToFileName;
-	},
-	async getVersionFileNamesAsync(s3DocJsonRoot: string): Promise<string[]> {
-		const response = await fetch(s3DocJsonRoot);
-		if (response.status !== 200) {
-			// TODO: Show the user an error message when the docs fail to load
-			const errMsg = await response.text();
-			utils.consoleLog(`Failed to load JSON file list: ${response.status} ${errMsg}`);
-			throw new Error(errMsg);
-		}
-		const responseXML = await response.text();
-		const responseJSONString = convert.xml2json(responseXML, {
-			compact: true,
-		});
-		const responseObj = JSON.parse(responseJSONString);
-		const fileObjs: S3FileObject[] = _.isArray(responseObj.ListBucketResult.Contents)
-			? (responseObj.ListBucketResult.Contents as S3FileObject[])
-			: [responseObj.ListBucketResult.Contents];
+    async getVersionToFileNameAsync(s3DocJsonRoot: string): Promise<VersionToFileName> {
+        const versionFileNames = await this.getVersionFileNamesAsync(s3DocJsonRoot);
+        const versionToFileName: VersionToFileName = {};
+        _.each(versionFileNames, fileName => {
+            const [version] = findVersions(fileName);
+            versionToFileName[version] = fileName;
+        });
+        return versionToFileName;
+    },
+    async getVersionFileNamesAsync(s3DocJsonRoot: string): Promise<string[]> {
+        const response = await fetch(s3DocJsonRoot);
+        if (response.status !== 200) {
+            // TODO: Show the user an error message when the docs fail to load
+            const errMsg = await response.text();
+            utils.consoleLog(`Failed to load JSON file list: ${response.status} ${errMsg}`);
+            throw new Error(errMsg);
+        }
+        const responseXML = await response.text();
+        const responseJSONString = convert.xml2json(responseXML, {
+            compact: true,
+        });
+        const responseObj = JSON.parse(responseJSONString);
+        const fileObjs: S3FileObject[] = _.isArray(responseObj.ListBucketResult.Contents)
+            ? (responseObj.ListBucketResult.Contents as S3FileObject[])
+            : [responseObj.ListBucketResult.Contents];
 
-		const versionFileNames = _.map(fileObjs, fileObj => {
-			return fileObj.Key._text;
-		});
-		return versionFileNames;
-	},
-	async getJSONDocFileAsync(fileName: string, s3DocJsonRoot: string): Promise<TypeDocNode | DoxityDocObj> {
-		const endpoint = `${s3DocJsonRoot}/${fileName}`;
-		const response = await fetch(endpoint);
-		if (response.status !== 200) {
-			// TODO: Show the user an error message when the docs fail to load
-			const errMsg = await response.text();
-			utils.consoleLog(`Failed to load Doc JSON: ${response.status} ${errMsg}`);
-			throw new Error(errMsg);
-		}
-		const jsonDocObj = await response.json();
-		return jsonDocObj;
-	},
+        const versionFileNames = _.map(fileObjs, fileObj => {
+            return fileObj.Key._text;
+        });
+        return versionFileNames;
+    },
+    async getJSONDocFileAsync(fileName: string, s3DocJsonRoot: string): Promise<TypeDocNode | DoxityDocObj> {
+        const endpoint = `${s3DocJsonRoot}/${fileName}`;
+        const response = await fetch(endpoint);
+        if (response.status !== 200) {
+            // TODO: Show the user an error message when the docs fail to load
+            const errMsg = await response.text();
+            utils.consoleLog(`Failed to load Doc JSON: ${response.status} ${errMsg}`);
+            throw new Error(errMsg);
+        }
+        const jsonDocObj = await response.json();
+        return jsonDocObj;
+    },
 };
diff --git a/packages/website/ts/utils/doxity_utils.ts b/packages/website/ts/utils/doxity_utils.ts
index f26534d51..5f1d02132 100644
--- a/packages/website/ts/utils/doxity_utils.ts
+++ b/packages/website/ts/utils/doxity_utils.ts
@@ -1,168 +1,168 @@
 import * as _ from 'lodash';
 import {
-	AbiTypes,
-	DocAgnosticFormat,
-	DocSection,
-	DoxityAbiDoc,
-	DoxityContractObj,
-	DoxityDocObj,
-	DoxityInput,
-	EventArg,
-	Parameter,
-	Property,
-	SolidityMethod,
-	Type,
-	TypeDocTypes,
+    AbiTypes,
+    DocAgnosticFormat,
+    DocSection,
+    DoxityAbiDoc,
+    DoxityContractObj,
+    DoxityDocObj,
+    DoxityInput,
+    EventArg,
+    Parameter,
+    Property,
+    SolidityMethod,
+    Type,
+    TypeDocTypes,
 } from 'ts/types';
 
 export const doxityUtils = {
-	convertToDocAgnosticFormat(doxityDocObj: DoxityDocObj): DocAgnosticFormat {
-		const docAgnosticFormat: DocAgnosticFormat = {};
-		_.each(doxityDocObj, (doxityContractObj: DoxityContractObj, contractName: string) => {
-			const doxityConstructor = _.find(doxityContractObj.abiDocs, (abiDoc: DoxityAbiDoc) => {
-				return abiDoc.type === AbiTypes.Constructor;
-			});
-			const constructors = [];
-			if (!_.isUndefined(doxityConstructor)) {
-				const constructor = {
-					isConstructor: true,
-					name: doxityContractObj.name,
-					comment: doxityConstructor.details,
-					returnComment: doxityConstructor.return,
-					callPath: '',
-					parameters: this._convertParameters(doxityConstructor.inputs),
-					returnType: this._convertType(doxityContractObj.name),
-				};
-				constructors.push(constructor);
-			}
+    convertToDocAgnosticFormat(doxityDocObj: DoxityDocObj): DocAgnosticFormat {
+        const docAgnosticFormat: DocAgnosticFormat = {};
+        _.each(doxityDocObj, (doxityContractObj: DoxityContractObj, contractName: string) => {
+            const doxityConstructor = _.find(doxityContractObj.abiDocs, (abiDoc: DoxityAbiDoc) => {
+                return abiDoc.type === AbiTypes.Constructor;
+            });
+            const constructors = [];
+            if (!_.isUndefined(doxityConstructor)) {
+                const constructor = {
+                    isConstructor: true,
+                    name: doxityContractObj.name,
+                    comment: doxityConstructor.details,
+                    returnComment: doxityConstructor.return,
+                    callPath: '',
+                    parameters: this._convertParameters(doxityConstructor.inputs),
+                    returnType: this._convertType(doxityContractObj.name),
+                };
+                constructors.push(constructor);
+            }
 
-			const doxityMethods: DoxityAbiDoc[] = _.filter<DoxityAbiDoc>(
-				doxityContractObj.abiDocs,
-				(abiDoc: DoxityAbiDoc) => {
-					return this._isMethod(abiDoc);
-				},
-			);
-			const methods: SolidityMethod[] = _.map<DoxityAbiDoc, SolidityMethod>(
-				doxityMethods,
-				(doxityMethod: DoxityAbiDoc) => {
-					// We assume that none of our functions returns more then a single value
-					const outputIfExists = !_.isUndefined(doxityMethod.outputs) ? doxityMethod.outputs[0] : undefined;
-					const returnTypeIfExists = !_.isUndefined(outputIfExists)
-						? this._convertType(outputIfExists.type)
-						: undefined;
-					// For ZRXToken, we want to convert it to zrxToken, rather then simply zRXToken
-					const callPath =
-						contractName !== 'ZRXToken'
-							? `${contractName[0].toLowerCase()}${contractName.slice(1)}.`
-							: `${contractName.slice(0, 3).toLowerCase()}${contractName.slice(3)}.`;
-					const method = {
-						isConstructor: false,
-						isConstant: doxityMethod.constant,
-						isPayable: doxityMethod.payable,
-						name: doxityMethod.name,
-						comment: doxityMethod.details,
-						returnComment: doxityMethod.return,
-						callPath,
-						parameters: this._convertParameters(doxityMethod.inputs),
-						returnType: returnTypeIfExists,
-					};
-					return method;
-				},
-			);
+            const doxityMethods: DoxityAbiDoc[] = _.filter<DoxityAbiDoc>(
+                doxityContractObj.abiDocs,
+                (abiDoc: DoxityAbiDoc) => {
+                    return this._isMethod(abiDoc);
+                },
+            );
+            const methods: SolidityMethod[] = _.map<DoxityAbiDoc, SolidityMethod>(
+                doxityMethods,
+                (doxityMethod: DoxityAbiDoc) => {
+                    // We assume that none of our functions returns more then a single value
+                    const outputIfExists = !_.isUndefined(doxityMethod.outputs) ? doxityMethod.outputs[0] : undefined;
+                    const returnTypeIfExists = !_.isUndefined(outputIfExists)
+                        ? this._convertType(outputIfExists.type)
+                        : undefined;
+                    // For ZRXToken, we want to convert it to zrxToken, rather then simply zRXToken
+                    const callPath =
+                        contractName !== 'ZRXToken'
+                            ? `${contractName[0].toLowerCase()}${contractName.slice(1)}.`
+                            : `${contractName.slice(0, 3).toLowerCase()}${contractName.slice(3)}.`;
+                    const method = {
+                        isConstructor: false,
+                        isConstant: doxityMethod.constant,
+                        isPayable: doxityMethod.payable,
+                        name: doxityMethod.name,
+                        comment: doxityMethod.details,
+                        returnComment: doxityMethod.return,
+                        callPath,
+                        parameters: this._convertParameters(doxityMethod.inputs),
+                        returnType: returnTypeIfExists,
+                    };
+                    return method;
+                },
+            );
 
-			const doxityProperties: DoxityAbiDoc[] = _.filter<DoxityAbiDoc>(
-				doxityContractObj.abiDocs,
-				(abiDoc: DoxityAbiDoc) => {
-					return this._isProperty(abiDoc);
-				},
-			);
-			const properties = _.map<DoxityAbiDoc, Property>(doxityProperties, (doxityProperty: DoxityAbiDoc) => {
-				// We assume that none of our functions return more then a single return value
-				let typeName = doxityProperty.outputs[0].type;
-				if (!_.isEmpty(doxityProperty.inputs)) {
-					// Properties never have more then a single input
-					typeName = `(${doxityProperty.inputs[0].type} => ${typeName})`;
-				}
-				const property = {
-					name: doxityProperty.name,
-					type: this._convertType(typeName),
-					comment: doxityProperty.details,
-				};
-				return property;
-			});
+            const doxityProperties: DoxityAbiDoc[] = _.filter<DoxityAbiDoc>(
+                doxityContractObj.abiDocs,
+                (abiDoc: DoxityAbiDoc) => {
+                    return this._isProperty(abiDoc);
+                },
+            );
+            const properties = _.map<DoxityAbiDoc, Property>(doxityProperties, (doxityProperty: DoxityAbiDoc) => {
+                // We assume that none of our functions return more then a single return value
+                let typeName = doxityProperty.outputs[0].type;
+                if (!_.isEmpty(doxityProperty.inputs)) {
+                    // Properties never have more then a single input
+                    typeName = `(${doxityProperty.inputs[0].type} => ${typeName})`;
+                }
+                const property = {
+                    name: doxityProperty.name,
+                    type: this._convertType(typeName),
+                    comment: doxityProperty.details,
+                };
+                return property;
+            });
 
-			const doxityEvents = _.filter(
-				doxityContractObj.abiDocs,
-				(abiDoc: DoxityAbiDoc) => abiDoc.type === AbiTypes.Event,
-			);
-			const events = _.map(doxityEvents, doxityEvent => {
-				const event = {
-					name: doxityEvent.name,
-					eventArgs: this._convertEventArgs(doxityEvent.inputs),
-				};
-				return event;
-			});
+            const doxityEvents = _.filter(
+                doxityContractObj.abiDocs,
+                (abiDoc: DoxityAbiDoc) => abiDoc.type === AbiTypes.Event,
+            );
+            const events = _.map(doxityEvents, doxityEvent => {
+                const event = {
+                    name: doxityEvent.name,
+                    eventArgs: this._convertEventArgs(doxityEvent.inputs),
+                };
+                return event;
+            });
 
-			const docSection: DocSection = {
-				comment: doxityContractObj.title,
-				constructors,
-				methods,
-				properties,
-				types: [],
-				events,
-			};
-			docAgnosticFormat[contractName] = docSection;
-		});
-		return docAgnosticFormat;
-	},
-	_convertParameters(inputs: DoxityInput[]): Parameter[] {
-		const parameters = _.map(inputs, input => {
-			const parameter = {
-				name: input.name,
-				comment: input.description,
-				isOptional: false,
-				type: this._convertType(input.type),
-			};
-			return parameter;
-		});
-		return parameters;
-	},
-	_convertType(typeName: string): Type {
-		const type = {
-			name: typeName,
-			typeDocType: TypeDocTypes.Intrinsic,
-		};
-		return type;
-	},
-	_isMethod(abiDoc: DoxityAbiDoc) {
-		if (abiDoc.type !== AbiTypes.Function) {
-			return false;
-		}
-		const hasInputs = !_.isEmpty(abiDoc.inputs);
-		const hasNamedOutputIfExists = !hasInputs || !_.isEmpty(abiDoc.inputs[0].name);
-		const isNameAllCaps = abiDoc.name === abiDoc.name.toUpperCase();
-		const isMethod = hasNamedOutputIfExists && !isNameAllCaps;
-		return isMethod;
-	},
-	_isProperty(abiDoc: DoxityAbiDoc) {
-		if (abiDoc.type !== AbiTypes.Function) {
-			return false;
-		}
-		const hasInputs = !_.isEmpty(abiDoc.inputs);
-		const hasNamedOutputIfExists = !hasInputs || !_.isEmpty(abiDoc.inputs[0].name);
-		const isNameAllCaps = abiDoc.name === abiDoc.name.toUpperCase();
-		const isProperty = !hasNamedOutputIfExists || isNameAllCaps;
-		return isProperty;
-	},
-	_convertEventArgs(inputs: DoxityInput[]): EventArg[] {
-		const eventArgs = _.map(inputs, input => {
-			const eventArg = {
-				isIndexed: input.indexed,
-				name: input.name,
-				type: this._convertType(input.type),
-			};
-			return eventArg;
-		});
-		return eventArgs;
-	},
+            const docSection: DocSection = {
+                comment: doxityContractObj.title,
+                constructors,
+                methods,
+                properties,
+                types: [],
+                events,
+            };
+            docAgnosticFormat[contractName] = docSection;
+        });
+        return docAgnosticFormat;
+    },
+    _convertParameters(inputs: DoxityInput[]): Parameter[] {
+        const parameters = _.map(inputs, input => {
+            const parameter = {
+                name: input.name,
+                comment: input.description,
+                isOptional: false,
+                type: this._convertType(input.type),
+            };
+            return parameter;
+        });
+        return parameters;
+    },
+    _convertType(typeName: string): Type {
+        const type = {
+            name: typeName,
+            typeDocType: TypeDocTypes.Intrinsic,
+        };
+        return type;
+    },
+    _isMethod(abiDoc: DoxityAbiDoc) {
+        if (abiDoc.type !== AbiTypes.Function) {
+            return false;
+        }
+        const hasInputs = !_.isEmpty(abiDoc.inputs);
+        const hasNamedOutputIfExists = !hasInputs || !_.isEmpty(abiDoc.inputs[0].name);
+        const isNameAllCaps = abiDoc.name === abiDoc.name.toUpperCase();
+        const isMethod = hasNamedOutputIfExists && !isNameAllCaps;
+        return isMethod;
+    },
+    _isProperty(abiDoc: DoxityAbiDoc) {
+        if (abiDoc.type !== AbiTypes.Function) {
+            return false;
+        }
+        const hasInputs = !_.isEmpty(abiDoc.inputs);
+        const hasNamedOutputIfExists = !hasInputs || !_.isEmpty(abiDoc.inputs[0].name);
+        const isNameAllCaps = abiDoc.name === abiDoc.name.toUpperCase();
+        const isProperty = !hasNamedOutputIfExists || isNameAllCaps;
+        return isProperty;
+    },
+    _convertEventArgs(inputs: DoxityInput[]): EventArg[] {
+        const eventArgs = _.map(inputs, input => {
+            const eventArg = {
+                isIndexed: input.indexed,
+                name: input.name,
+                type: this._convertType(input.type),
+            };
+            return eventArg;
+        });
+        return eventArgs;
+    },
 };
diff --git a/packages/website/ts/utils/error_reporter.ts b/packages/website/ts/utils/error_reporter.ts
index 08d99e405..0bd247c5b 100644
--- a/packages/website/ts/utils/error_reporter.ts
+++ b/packages/website/ts/utils/error_reporter.ts
@@ -6,47 +6,47 @@ import { utils } from 'ts/utils/utils';
 // Suggested way to include Rollbar with Webpack
 // https://github.com/rollbar/rollbar.js/tree/master/examples/webpack
 const rollbarConfig = {
-	accessToken: constants.ROLLBAR_ACCESS_TOKEN,
-	captureUncaught: true,
-	captureUnhandledRejections: true,
-	itemsPerMinute: 10,
-	maxItems: 500,
-	payload: {
-		environment: configs.ENVIRONMENT,
-	},
-	uncaughtErrorLevel: 'error',
-	hostWhiteList: [configs.DOMAIN_PRODUCTION, configs.DOMAIN_STAGING],
-	ignoredMessages: [
-		// Errors from the third-party scripts
-		'Script error',
-		// Network errors or ad-blockers
-		'TypeError: Failed to fetch',
-		'Exchange has not been deployed to detected network (network/artifact mismatch)',
-		// Source: https://groups.google.com/a/chromium.org/forum/#!topic/chromium-discuss/7VU0_VvC7mE
-		"undefined is not an object (evaluating '__gCrWeb.autofill.extractForms')",
-		// Source: http://stackoverflow.com/questions/43399818/securityerror-from-facebook-and-cross-domain-messaging
-		'SecurityError (DOM Exception 18)',
-	],
+    accessToken: constants.ROLLBAR_ACCESS_TOKEN,
+    captureUncaught: true,
+    captureUnhandledRejections: true,
+    itemsPerMinute: 10,
+    maxItems: 500,
+    payload: {
+        environment: configs.ENVIRONMENT,
+    },
+    uncaughtErrorLevel: 'error',
+    hostWhiteList: [configs.DOMAIN_PRODUCTION, configs.DOMAIN_STAGING],
+    ignoredMessages: [
+        // Errors from the third-party scripts
+        'Script error',
+        // Network errors or ad-blockers
+        'TypeError: Failed to fetch',
+        'Exchange has not been deployed to detected network (network/artifact mismatch)',
+        // Source: https://groups.google.com/a/chromium.org/forum/#!topic/chromium-discuss/7VU0_VvC7mE
+        "undefined is not an object (evaluating '__gCrWeb.autofill.extractForms')",
+        // Source: http://stackoverflow.com/questions/43399818/securityerror-from-facebook-and-cross-domain-messaging
+        'SecurityError (DOM Exception 18)',
+    ],
 };
 import Rollbar = require('../../public/js/rollbar.umd.nojson.min.js');
 const rollbar = Rollbar.init(rollbarConfig);
 
 export const errorReporter = {
-	async reportAsync(err: Error): Promise<any> {
-		if (configs.ENVIRONMENT === Environments.DEVELOPMENT) {
-			return; // Let's not log development errors to rollbar
-		}
+    async reportAsync(err: Error): Promise<any> {
+        if (configs.ENVIRONMENT === Environments.DEVELOPMENT) {
+            return; // Let's not log development errors to rollbar
+        }
 
-		return new Promise((resolve, reject) => {
-			rollbar.error(err, (rollbarErr: Error) => {
-				if (rollbarErr) {
-					utils.consoleLog(`Error reporting to rollbar, ignoring: ${rollbarErr}`);
-					// We never want to reject and cause the app to throw because of rollbar
-					resolve();
-				} else {
-					resolve();
-				}
-			});
-		});
-	},
+        return new Promise((resolve, reject) => {
+            rollbar.error(err, (rollbarErr: Error) => {
+                if (rollbarErr) {
+                    utils.consoleLog(`Error reporting to rollbar, ignoring: ${rollbarErr}`);
+                    // We never want to reject and cause the app to throw because of rollbar
+                    resolve();
+                } else {
+                    resolve();
+                }
+            });
+        });
+    },
 };
diff --git a/packages/website/ts/utils/mui_theme.ts b/packages/website/ts/utils/mui_theme.ts
index 565d1ae4f..d73e80606 100644
--- a/packages/website/ts/utils/mui_theme.ts
+++ b/packages/website/ts/utils/mui_theme.ts
@@ -2,34 +2,34 @@ import { getMuiTheme } from 'material-ui/styles';
 import { colors } from 'ts/utils/colors';
 
 export const muiTheme = getMuiTheme({
-	appBar: {
-		height: 45,
-		color: colors.white,
-		textColor: colors.black,
-	},
-	palette: {
-		pickerHeaderColor: colors.lightBlue,
-		primary1Color: colors.lightBlue,
-		primary2Color: colors.lightBlue,
-		textColor: colors.grey700,
-	},
-	datePicker: {
-		color: colors.grey700,
-		textColor: colors.white,
-		calendarTextColor: colors.white,
-		selectColor: colors.darkestGrey,
-		selectTextColor: colors.white,
-	},
-	timePicker: {
-		color: colors.grey700,
-		textColor: colors.white,
-		accentColor: colors.white,
-		headerColor: colors.darkestGrey,
-		selectColor: colors.darkestGrey,
-		selectTextColor: colors.darkestGrey,
-	},
-	toggle: {
-		thumbOnColor: colors.limeGreen,
-		trackOnColor: colors.lightGreen,
-	},
+    appBar: {
+        height: 45,
+        color: colors.white,
+        textColor: colors.black,
+    },
+    palette: {
+        pickerHeaderColor: colors.lightBlue,
+        primary1Color: colors.lightBlue,
+        primary2Color: colors.lightBlue,
+        textColor: colors.grey700,
+    },
+    datePicker: {
+        color: colors.grey700,
+        textColor: colors.white,
+        calendarTextColor: colors.white,
+        selectColor: colors.darkestGrey,
+        selectTextColor: colors.white,
+    },
+    timePicker: {
+        color: colors.grey700,
+        textColor: colors.white,
+        accentColor: colors.white,
+        headerColor: colors.darkestGrey,
+        selectColor: colors.darkestGrey,
+        selectTextColor: colors.darkestGrey,
+    },
+    toggle: {
+        thumbOnColor: colors.limeGreen,
+        trackOnColor: colors.lightGreen,
+    },
 });
diff --git a/packages/website/ts/utils/typedoc_utils.ts b/packages/website/ts/utils/typedoc_utils.ts
index b0c152891..11ec8da58 100644
--- a/packages/website/ts/utils/typedoc_utils.ts
+++ b/packages/website/ts/utils/typedoc_utils.ts
@@ -1,365 +1,365 @@
 import * as _ from 'lodash';
 import { DocsInfo } from 'ts/pages/documentation/docs_info';
 import {
-	CustomType,
-	CustomTypeChild,
-	DocAgnosticFormat,
-	DocSection,
-	IndexSignature,
-	KindString,
-	Parameter,
-	Property,
-	SectionsMap,
-	Type,
-	TypeDocNode,
-	TypeDocType,
-	TypeParameter,
-	TypescriptMethod,
+    CustomType,
+    CustomTypeChild,
+    DocAgnosticFormat,
+    DocSection,
+    IndexSignature,
+    KindString,
+    Parameter,
+    Property,
+    SectionsMap,
+    Type,
+    TypeDocNode,
+    TypeDocType,
+    TypeParameter,
+    TypescriptMethod,
 } from 'ts/types';
 import { utils } from 'ts/utils/utils';
 
 export const typeDocUtils = {
-	isType(entity: TypeDocNode): boolean {
-		return (
-			entity.kindString === KindString.Interface ||
-			entity.kindString === KindString.Function ||
-			entity.kindString === KindString.TypeAlias ||
-			entity.kindString === KindString.Variable ||
-			entity.kindString === KindString.Enumeration
-		);
-	},
-	isMethod(entity: TypeDocNode): boolean {
-		return entity.kindString === KindString.Method;
-	},
-	isConstructor(entity: TypeDocNode): boolean {
-		return entity.kindString === KindString.Constructor;
-	},
-	isProperty(entity: TypeDocNode): boolean {
-		return entity.kindString === KindString.Property;
-	},
-	isPrivateOrProtectedProperty(propertyName: string): boolean {
-		return _.startsWith(propertyName, '_');
-	},
-	getModuleDefinitionBySectionNameIfExists(
-		versionDocObj: TypeDocNode,
-		modulePaths: string[],
-	): TypeDocNode | undefined {
-		const modules = versionDocObj.children;
-		for (const mod of modules) {
-			if (_.includes(modulePaths, mod.name)) {
-				const moduleWithName = mod;
-				return moduleWithName;
-			}
-		}
-		return undefined;
-	},
-	convertToDocAgnosticFormat(typeDocJson: TypeDocNode, docsInfo: DocsInfo): DocAgnosticFormat {
-		const subMenus = _.values(docsInfo.getMenu());
-		const orderedSectionNames = _.flatten(subMenus);
-		const docAgnosticFormat: DocAgnosticFormat = {};
-		_.each(orderedSectionNames, sectionName => {
-			const modulePathsIfExists = docsInfo.getModulePathsIfExists(sectionName);
-			if (_.isUndefined(modulePathsIfExists)) {
-				return; // no-op
-			}
-			const packageDefinitionIfExists = typeDocUtils.getModuleDefinitionBySectionNameIfExists(
-				typeDocJson,
-				modulePathsIfExists,
-			);
-			if (_.isUndefined(packageDefinitionIfExists)) {
-				return; // no-op
-			}
+    isType(entity: TypeDocNode): boolean {
+        return (
+            entity.kindString === KindString.Interface ||
+            entity.kindString === KindString.Function ||
+            entity.kindString === KindString.TypeAlias ||
+            entity.kindString === KindString.Variable ||
+            entity.kindString === KindString.Enumeration
+        );
+    },
+    isMethod(entity: TypeDocNode): boolean {
+        return entity.kindString === KindString.Method;
+    },
+    isConstructor(entity: TypeDocNode): boolean {
+        return entity.kindString === KindString.Constructor;
+    },
+    isProperty(entity: TypeDocNode): boolean {
+        return entity.kindString === KindString.Property;
+    },
+    isPrivateOrProtectedProperty(propertyName: string): boolean {
+        return _.startsWith(propertyName, '_');
+    },
+    getModuleDefinitionBySectionNameIfExists(
+        versionDocObj: TypeDocNode,
+        modulePaths: string[],
+    ): TypeDocNode | undefined {
+        const modules = versionDocObj.children;
+        for (const mod of modules) {
+            if (_.includes(modulePaths, mod.name)) {
+                const moduleWithName = mod;
+                return moduleWithName;
+            }
+        }
+        return undefined;
+    },
+    convertToDocAgnosticFormat(typeDocJson: TypeDocNode, docsInfo: DocsInfo): DocAgnosticFormat {
+        const subMenus = _.values(docsInfo.getMenu());
+        const orderedSectionNames = _.flatten(subMenus);
+        const docAgnosticFormat: DocAgnosticFormat = {};
+        _.each(orderedSectionNames, sectionName => {
+            const modulePathsIfExists = docsInfo.getModulePathsIfExists(sectionName);
+            if (_.isUndefined(modulePathsIfExists)) {
+                return; // no-op
+            }
+            const packageDefinitionIfExists = typeDocUtils.getModuleDefinitionBySectionNameIfExists(
+                typeDocJson,
+                modulePathsIfExists,
+            );
+            if (_.isUndefined(packageDefinitionIfExists)) {
+                return; // no-op
+            }
 
-			// Since the `types.ts` file is the only file that does not export a module/class but
-			// instead has each type export itself, we do not need to go down two levels of nesting
-			// for it.
-			let entities;
-			let packageComment = '';
-			if (sectionName === docsInfo.sections.types) {
-				entities = packageDefinitionIfExists.children;
-			} else {
-				entities = packageDefinitionIfExists.children[0].children;
-				const commentObj = packageDefinitionIfExists.children[0].comment;
-				packageComment = !_.isUndefined(commentObj) ? commentObj.shortText : packageComment;
-			}
+            // Since the `types.ts` file is the only file that does not export a module/class but
+            // instead has each type export itself, we do not need to go down two levels of nesting
+            // for it.
+            let entities;
+            let packageComment = '';
+            if (sectionName === docsInfo.sections.types) {
+                entities = packageDefinitionIfExists.children;
+            } else {
+                entities = packageDefinitionIfExists.children[0].children;
+                const commentObj = packageDefinitionIfExists.children[0].comment;
+                packageComment = !_.isUndefined(commentObj) ? commentObj.shortText : packageComment;
+            }
 
-			const docSection = typeDocUtils._convertEntitiesToDocSection(entities, docsInfo, sectionName);
-			docSection.comment = packageComment;
-			docAgnosticFormat[sectionName] = docSection;
-		});
-		return docAgnosticFormat;
-	},
-	_convertEntitiesToDocSection(entities: TypeDocNode[], docsInfo: DocsInfo, sectionName: string) {
-		const docSection: DocSection = {
-			comment: '',
-			constructors: [],
-			methods: [],
-			properties: [],
-			types: [],
-		};
+            const docSection = typeDocUtils._convertEntitiesToDocSection(entities, docsInfo, sectionName);
+            docSection.comment = packageComment;
+            docAgnosticFormat[sectionName] = docSection;
+        });
+        return docAgnosticFormat;
+    },
+    _convertEntitiesToDocSection(entities: TypeDocNode[], docsInfo: DocsInfo, sectionName: string) {
+        const docSection: DocSection = {
+            comment: '',
+            constructors: [],
+            methods: [],
+            properties: [],
+            types: [],
+        };
 
-		let isConstructor;
-		_.each(entities, entity => {
-			switch (entity.kindString) {
-				case KindString.Constructor:
-					isConstructor = true;
-					const constructor = typeDocUtils._convertMethod(
-						entity,
-						isConstructor,
-						docsInfo.sections,
-						sectionName,
-						docsInfo.subPackageName,
-					);
-					docSection.constructors.push(constructor);
-					break;
+        let isConstructor;
+        _.each(entities, entity => {
+            switch (entity.kindString) {
+                case KindString.Constructor:
+                    isConstructor = true;
+                    const constructor = typeDocUtils._convertMethod(
+                        entity,
+                        isConstructor,
+                        docsInfo.sections,
+                        sectionName,
+                        docsInfo.subPackageName,
+                    );
+                    docSection.constructors.push(constructor);
+                    break;
 
-				case KindString.Method:
-					if (entity.flags.isPublic) {
-						isConstructor = false;
-						const method = typeDocUtils._convertMethod(
-							entity,
-							isConstructor,
-							docsInfo.sections,
-							sectionName,
-							docsInfo.subPackageName,
-						);
-						docSection.methods.push(method);
-					}
-					break;
+                case KindString.Method:
+                    if (entity.flags.isPublic) {
+                        isConstructor = false;
+                        const method = typeDocUtils._convertMethod(
+                            entity,
+                            isConstructor,
+                            docsInfo.sections,
+                            sectionName,
+                            docsInfo.subPackageName,
+                        );
+                        docSection.methods.push(method);
+                    }
+                    break;
 
-				case KindString.Property:
-					if (!typeDocUtils.isPrivateOrProtectedProperty(entity.name)) {
-						const property = typeDocUtils._convertProperty(
-							entity,
-							docsInfo.sections,
-							sectionName,
-							docsInfo.subPackageName,
-						);
-						docSection.properties.push(property);
-					}
-					break;
+                case KindString.Property:
+                    if (!typeDocUtils.isPrivateOrProtectedProperty(entity.name)) {
+                        const property = typeDocUtils._convertProperty(
+                            entity,
+                            docsInfo.sections,
+                            sectionName,
+                            docsInfo.subPackageName,
+                        );
+                        docSection.properties.push(property);
+                    }
+                    break;
 
-				case KindString.Interface:
-				case KindString.Function:
-				case KindString.Variable:
-				case KindString.Enumeration:
-				case KindString.TypeAlias:
-					if (docsInfo.isPublicType(entity.name)) {
-						const customType = typeDocUtils._convertCustomType(
-							entity,
-							docsInfo.sections,
-							sectionName,
-							docsInfo.subPackageName,
-						);
-						docSection.types.push(customType);
-					}
-					break;
+                case KindString.Interface:
+                case KindString.Function:
+                case KindString.Variable:
+                case KindString.Enumeration:
+                case KindString.TypeAlias:
+                    if (docsInfo.isPublicType(entity.name)) {
+                        const customType = typeDocUtils._convertCustomType(
+                            entity,
+                            docsInfo.sections,
+                            sectionName,
+                            docsInfo.subPackageName,
+                        );
+                        docSection.types.push(customType);
+                    }
+                    break;
 
-				default:
-					throw utils.spawnSwitchErr('kindString', entity.kindString);
-			}
-		});
-		return docSection;
-	},
-	_convertCustomType(
-		entity: TypeDocNode,
-		sections: SectionsMap,
-		sectionName: string,
-		subPackageName: string,
-	): CustomType {
-		const typeIfExists = !_.isUndefined(entity.type)
-			? typeDocUtils._convertType(entity.type, sections, sectionName, subPackageName)
-			: undefined;
-		const isConstructor = false;
-		const methodIfExists = !_.isUndefined(entity.declaration)
-			? typeDocUtils._convertMethod(entity.declaration, isConstructor, sections, sectionName, subPackageName)
-			: undefined;
-		const indexSignatureIfExists = !_.isUndefined(entity.indexSignature)
-			? typeDocUtils._convertIndexSignature(entity.indexSignature[0], sections, sectionName, subPackageName)
-			: undefined;
-		const commentIfExists =
-			!_.isUndefined(entity.comment) && !_.isUndefined(entity.comment.shortText)
-				? entity.comment.shortText
-				: undefined;
+                default:
+                    throw utils.spawnSwitchErr('kindString', entity.kindString);
+            }
+        });
+        return docSection;
+    },
+    _convertCustomType(
+        entity: TypeDocNode,
+        sections: SectionsMap,
+        sectionName: string,
+        subPackageName: string,
+    ): CustomType {
+        const typeIfExists = !_.isUndefined(entity.type)
+            ? typeDocUtils._convertType(entity.type, sections, sectionName, subPackageName)
+            : undefined;
+        const isConstructor = false;
+        const methodIfExists = !_.isUndefined(entity.declaration)
+            ? typeDocUtils._convertMethod(entity.declaration, isConstructor, sections, sectionName, subPackageName)
+            : undefined;
+        const indexSignatureIfExists = !_.isUndefined(entity.indexSignature)
+            ? typeDocUtils._convertIndexSignature(entity.indexSignature[0], sections, sectionName, subPackageName)
+            : undefined;
+        const commentIfExists =
+            !_.isUndefined(entity.comment) && !_.isUndefined(entity.comment.shortText)
+                ? entity.comment.shortText
+                : undefined;
 
-		const childrenIfExist = !_.isUndefined(entity.children)
-			? _.map(entity.children, (child: TypeDocNode) => {
-					const childTypeIfExists = !_.isUndefined(child.type)
-						? typeDocUtils._convertType(child.type, sections, sectionName, subPackageName)
-						: undefined;
-					const c: CustomTypeChild = {
-						name: child.name,
-						type: childTypeIfExists,
-						defaultValue: child.defaultValue,
-					};
-					return c;
-				})
-			: undefined;
+        const childrenIfExist = !_.isUndefined(entity.children)
+            ? _.map(entity.children, (child: TypeDocNode) => {
+                  const childTypeIfExists = !_.isUndefined(child.type)
+                      ? typeDocUtils._convertType(child.type, sections, sectionName, subPackageName)
+                      : undefined;
+                  const c: CustomTypeChild = {
+                      name: child.name,
+                      type: childTypeIfExists,
+                      defaultValue: child.defaultValue,
+                  };
+                  return c;
+              })
+            : undefined;
 
-		const customType = {
-			name: entity.name,
-			kindString: entity.kindString,
-			type: typeIfExists,
-			method: methodIfExists,
-			indexSignature: indexSignatureIfExists,
-			defaultValue: entity.defaultValue,
-			comment: commentIfExists,
-			children: childrenIfExist,
-		};
-		return customType;
-	},
-	_convertIndexSignature(
-		entity: TypeDocNode,
-		sections: SectionsMap,
-		sectionName: string,
-		subPackageName: string,
-	): IndexSignature {
-		const key = entity.parameters[0];
-		const indexSignature = {
-			keyName: key.name,
-			keyType: typeDocUtils._convertType(key.type, sections, sectionName, subPackageName),
-			valueName: entity.type.name,
-		};
-		return indexSignature;
-	},
-	_convertProperty(
-		entity: TypeDocNode,
-		sections: SectionsMap,
-		sectionName: string,
-		subPackageName: string,
-	): Property {
-		const source = entity.sources[0];
-		const commentIfExists = !_.isUndefined(entity.comment) ? entity.comment.shortText : undefined;
-		const property = {
-			name: entity.name,
-			type: typeDocUtils._convertType(entity.type, sections, sectionName, subPackageName),
-			source: {
-				fileName: source.fileName,
-				line: source.line,
-			},
-			comment: commentIfExists,
-		};
-		return property;
-	},
-	_convertMethod(
-		entity: TypeDocNode,
-		isConstructor: boolean,
-		sections: SectionsMap,
-		sectionName: string,
-		subPackageName: string,
-	): TypescriptMethod {
-		const signature = entity.signatures[0];
-		const source = entity.sources[0];
-		const hasComment = !_.isUndefined(signature.comment);
-		const isStatic = _.isUndefined(entity.flags.isStatic) ? false : entity.flags.isStatic;
+        const customType = {
+            name: entity.name,
+            kindString: entity.kindString,
+            type: typeIfExists,
+            method: methodIfExists,
+            indexSignature: indexSignatureIfExists,
+            defaultValue: entity.defaultValue,
+            comment: commentIfExists,
+            children: childrenIfExist,
+        };
+        return customType;
+    },
+    _convertIndexSignature(
+        entity: TypeDocNode,
+        sections: SectionsMap,
+        sectionName: string,
+        subPackageName: string,
+    ): IndexSignature {
+        const key = entity.parameters[0];
+        const indexSignature = {
+            keyName: key.name,
+            keyType: typeDocUtils._convertType(key.type, sections, sectionName, subPackageName),
+            valueName: entity.type.name,
+        };
+        return indexSignature;
+    },
+    _convertProperty(
+        entity: TypeDocNode,
+        sections: SectionsMap,
+        sectionName: string,
+        subPackageName: string,
+    ): Property {
+        const source = entity.sources[0];
+        const commentIfExists = !_.isUndefined(entity.comment) ? entity.comment.shortText : undefined;
+        const property = {
+            name: entity.name,
+            type: typeDocUtils._convertType(entity.type, sections, sectionName, subPackageName),
+            source: {
+                fileName: source.fileName,
+                line: source.line,
+            },
+            comment: commentIfExists,
+        };
+        return property;
+    },
+    _convertMethod(
+        entity: TypeDocNode,
+        isConstructor: boolean,
+        sections: SectionsMap,
+        sectionName: string,
+        subPackageName: string,
+    ): TypescriptMethod {
+        const signature = entity.signatures[0];
+        const source = entity.sources[0];
+        const hasComment = !_.isUndefined(signature.comment);
+        const isStatic = _.isUndefined(entity.flags.isStatic) ? false : entity.flags.isStatic;
 
-		// HACK: we use the fact that the sectionName is the same as the property name at the top-level
-		// of the public interface. In the future, we shouldn't use this hack but rather get it from the JSON.
-		let callPath;
-		if (isConstructor || entity.name === '__type') {
-			callPath = '';
-		} else if (subPackageName === '0x.js') {
-			const topLevelInterface = isStatic ? 'ZeroEx.' : 'zeroEx.';
-			callPath =
-				!_.isUndefined(sections.zeroEx) && sectionName !== sections.zeroEx
-					? `${topLevelInterface}${sectionName}.`
-					: topLevelInterface;
-		} else {
-			callPath = `${sectionName}.`;
-		}
+        // HACK: we use the fact that the sectionName is the same as the property name at the top-level
+        // of the public interface. In the future, we shouldn't use this hack but rather get it from the JSON.
+        let callPath;
+        if (isConstructor || entity.name === '__type') {
+            callPath = '';
+        } else if (subPackageName === '0x.js') {
+            const topLevelInterface = isStatic ? 'ZeroEx.' : 'zeroEx.';
+            callPath =
+                !_.isUndefined(sections.zeroEx) && sectionName !== sections.zeroEx
+                    ? `${topLevelInterface}${sectionName}.`
+                    : topLevelInterface;
+        } else {
+            callPath = `${sectionName}.`;
+        }
 
-		const parameters = _.map(signature.parameters, param => {
-			return typeDocUtils._convertParameter(param, sections, sectionName, subPackageName);
-		});
-		const returnType = typeDocUtils._convertType(signature.type, sections, sectionName, subPackageName);
-		const typeParameter = _.isUndefined(signature.typeParameter)
-			? undefined
-			: typeDocUtils._convertTypeParameter(signature.typeParameter[0], sections, sectionName, subPackageName);
+        const parameters = _.map(signature.parameters, param => {
+            return typeDocUtils._convertParameter(param, sections, sectionName, subPackageName);
+        });
+        const returnType = typeDocUtils._convertType(signature.type, sections, sectionName, subPackageName);
+        const typeParameter = _.isUndefined(signature.typeParameter)
+            ? undefined
+            : typeDocUtils._convertTypeParameter(signature.typeParameter[0], sections, sectionName, subPackageName);
 
-		const method = {
-			isConstructor,
-			isStatic,
-			name: signature.name,
-			comment: hasComment ? signature.comment.shortText : undefined,
-			returnComment: hasComment && signature.comment.returns ? signature.comment.returns : undefined,
-			source: {
-				fileName: source.fileName,
-				line: source.line,
-			},
-			callPath,
-			parameters,
-			returnType,
-			typeParameter,
-		};
-		return method;
-	},
-	_convertTypeParameter(
-		entity: TypeDocNode,
-		sections: SectionsMap,
-		sectionName: string,
-		subPackageName: string,
-	): TypeParameter {
-		const type = typeDocUtils._convertType(entity.type, sections, sectionName, subPackageName);
-		const parameter = {
-			name: entity.name,
-			type,
-		};
-		return parameter;
-	},
-	_convertParameter(
-		entity: TypeDocNode,
-		sections: SectionsMap,
-		sectionName: string,
-		subPackageName: string,
-	): Parameter {
-		let comment = '<No comment>';
-		if (entity.comment && entity.comment.shortText) {
-			comment = entity.comment.shortText;
-		} else if (entity.comment && entity.comment.text) {
-			comment = entity.comment.text;
-		}
+        const method = {
+            isConstructor,
+            isStatic,
+            name: signature.name,
+            comment: hasComment ? signature.comment.shortText : undefined,
+            returnComment: hasComment && signature.comment.returns ? signature.comment.returns : undefined,
+            source: {
+                fileName: source.fileName,
+                line: source.line,
+            },
+            callPath,
+            parameters,
+            returnType,
+            typeParameter,
+        };
+        return method;
+    },
+    _convertTypeParameter(
+        entity: TypeDocNode,
+        sections: SectionsMap,
+        sectionName: string,
+        subPackageName: string,
+    ): TypeParameter {
+        const type = typeDocUtils._convertType(entity.type, sections, sectionName, subPackageName);
+        const parameter = {
+            name: entity.name,
+            type,
+        };
+        return parameter;
+    },
+    _convertParameter(
+        entity: TypeDocNode,
+        sections: SectionsMap,
+        sectionName: string,
+        subPackageName: string,
+    ): Parameter {
+        let comment = '<No comment>';
+        if (entity.comment && entity.comment.shortText) {
+            comment = entity.comment.shortText;
+        } else if (entity.comment && entity.comment.text) {
+            comment = entity.comment.text;
+        }
 
-		const isOptional = !_.isUndefined(entity.flags.isOptional) ? entity.flags.isOptional : false;
+        const isOptional = !_.isUndefined(entity.flags.isOptional) ? entity.flags.isOptional : false;
 
-		const type = typeDocUtils._convertType(entity.type, sections, sectionName, subPackageName);
+        const type = typeDocUtils._convertType(entity.type, sections, sectionName, subPackageName);
 
-		const parameter = {
-			name: entity.name,
-			comment,
-			isOptional,
-			type,
-		};
-		return parameter;
-	},
-	_convertType(entity: TypeDocType, sections: SectionsMap, sectionName: string, subPackageName: string): Type {
-		const typeArguments = _.map(entity.typeArguments, typeArgument => {
-			return typeDocUtils._convertType(typeArgument, sections, sectionName, subPackageName);
-		});
-		const types = _.map(entity.types, t => {
-			return typeDocUtils._convertType(t, sections, sectionName, subPackageName);
-		});
+        const parameter = {
+            name: entity.name,
+            comment,
+            isOptional,
+            type,
+        };
+        return parameter;
+    },
+    _convertType(entity: TypeDocType, sections: SectionsMap, sectionName: string, subPackageName: string): Type {
+        const typeArguments = _.map(entity.typeArguments, typeArgument => {
+            return typeDocUtils._convertType(typeArgument, sections, sectionName, subPackageName);
+        });
+        const types = _.map(entity.types, t => {
+            return typeDocUtils._convertType(t, sections, sectionName, subPackageName);
+        });
 
-		const isConstructor = false;
-		const methodIfExists = !_.isUndefined(entity.declaration)
-			? typeDocUtils._convertMethod(entity.declaration, isConstructor, sections, sectionName, subPackageName)
-			: undefined;
+        const isConstructor = false;
+        const methodIfExists = !_.isUndefined(entity.declaration)
+            ? typeDocUtils._convertMethod(entity.declaration, isConstructor, sections, sectionName, subPackageName)
+            : undefined;
 
-		const elementTypeIfExists = !_.isUndefined(entity.elementType)
-			? {
-					name: entity.elementType.name,
-					typeDocType: entity.elementType.type,
-				}
-			: undefined;
+        const elementTypeIfExists = !_.isUndefined(entity.elementType)
+            ? {
+                  name: entity.elementType.name,
+                  typeDocType: entity.elementType.type,
+              }
+            : undefined;
 
-		const type = {
-			name: entity.name,
-			value: entity.value,
-			typeDocType: entity.type,
-			typeArguments,
-			elementType: elementTypeIfExists,
-			types,
-			method: methodIfExists,
-		};
-		return type;
-	},
+        const type = {
+            name: entity.name,
+            value: entity.value,
+            typeDocType: entity.type,
+            typeArguments,
+            elementType: elementTypeIfExists,
+            types,
+            method: methodIfExists,
+        };
+        return type;
+    },
 };
diff --git a/packages/website/ts/utils/utils.ts b/packages/website/ts/utils/utils.ts
index ea5b689ae..13a6d6ae2 100644
--- a/packages/website/ts/utils/utils.ts
+++ b/packages/website/ts/utils/utils.ts
@@ -5,15 +5,15 @@ import isMobile = require('is-mobile');
 import * as _ from 'lodash';
 import * as moment from 'moment';
 import {
-	EtherscanLinkSuffixes,
-	Networks,
-	Order,
-	ScreenWidths,
-	Side,
-	SideToAssetToken,
-	SignatureData,
-	Token,
-	TokenByAddress,
+    EtherscanLinkSuffixes,
+    Networks,
+    Order,
+    ScreenWidths,
+    Side,
+    SideToAssetToken,
+    SignatureData,
+    Token,
+    TokenByAddress,
 } from 'ts/types';
 import { configs } from 'ts/utils/configs';
 import { constants } from 'ts/utils/constants';
@@ -23,257 +23,257 @@ const LG_MIN_EM = 64;
 const MD_MIN_EM = 52;
 
 export const utils = {
-	assert(condition: boolean, message: string) {
-		if (!condition) {
-			throw new Error(message);
-		}
-	},
-	spawnSwitchErr(name: string, value: any) {
-		return new Error(`Unexpected switch value: ${value} encountered for ${name}`);
-	},
-	isNumeric(n: string) {
-		return !isNaN(parseFloat(n)) && isFinite(Number(n));
-	},
-	// This default unix timestamp is used for orders where the user does not specify an expiry date.
-	// It is a fixed constant so that both the redux store's INITIAL_STATE and components can check for
-	// whether a user has set an expiry date or not. It is set unrealistically high so as not to collide
-	// with actual values a user would select.
-	initialOrderExpiryUnixTimestampSec(): BigNumber {
-		const m = moment('2050-01-01');
-		return new BigNumber(m.unix());
-	},
-	convertToUnixTimestampSeconds(date: moment.Moment, time?: moment.Moment): BigNumber {
-		const finalMoment = date;
-		if (!_.isUndefined(time)) {
-			finalMoment.hours(time.hours());
-			finalMoment.minutes(time.minutes());
-		}
-		return new BigNumber(finalMoment.unix());
-	},
-	convertToMomentFromUnixTimestamp(unixTimestampSec: BigNumber): moment.Moment {
-		return moment.unix(unixTimestampSec.toNumber());
-	},
-	convertToReadableDateTimeFromUnixTimestamp(unixTimestampSec: BigNumber): string {
-		const m = this.convertToMomentFromUnixTimestamp(unixTimestampSec);
-		const formattedDate: string = m.format('h:MMa MMMM D YYYY');
-		return formattedDate;
-	},
-	generateOrder(
-		networkId: number,
-		exchangeContract: string,
-		sideToAssetToken: SideToAssetToken,
-		orderExpiryTimestamp: BigNumber,
-		orderTakerAddress: string,
-		orderMakerAddress: string,
-		makerFee: BigNumber,
-		takerFee: BigNumber,
-		feeRecipient: string,
-		signatureData: SignatureData,
-		tokenByAddress: TokenByAddress,
-		orderSalt: BigNumber,
-	): Order {
-		const makerToken = tokenByAddress[sideToAssetToken[Side.Deposit].address];
-		const takerToken = tokenByAddress[sideToAssetToken[Side.Receive].address];
-		const order = {
-			maker: {
-				address: orderMakerAddress,
-				token: {
-					name: makerToken.name,
-					symbol: makerToken.symbol,
-					decimals: makerToken.decimals,
-					address: makerToken.address,
-				},
-				amount: sideToAssetToken[Side.Deposit].amount.toString(),
-				feeAmount: makerFee.toString(),
-			},
-			taker: {
-				address: orderTakerAddress,
-				token: {
-					name: takerToken.name,
-					symbol: takerToken.symbol,
-					decimals: takerToken.decimals,
-					address: takerToken.address,
-				},
-				amount: sideToAssetToken[Side.Receive].amount.toString(),
-				feeAmount: takerFee.toString(),
-			},
-			expiration: orderExpiryTimestamp.toString(),
-			feeRecipient,
-			salt: orderSalt.toString(),
-			signature: signatureData,
-			exchangeContract,
-			networkId,
-		};
-		return order;
-	},
-	consoleLog(message: string) {
-		/* tslint:disable */
-		console.log(message);
-		/* tslint:enable */
-	},
-	async sleepAsync(ms: number) {
-		return new Promise(resolve => setTimeout(resolve, ms));
-	},
-	deepEqual(actual: any, expected: any, opts?: { strict: boolean }) {
-		return deepEqual(actual, expected, opts);
-	},
-	getColSize(items: number) {
-		const bassCssGridSize = 12; // Source: http://basscss.com/#basscss-grid
-		const colSize = bassCssGridSize / items;
-		if (!_.isInteger(colSize)) {
-			throw new Error(`Number of cols must be divisible by ${bassCssGridSize}`);
-		}
-		return colSize;
-	},
-	getScreenWidth() {
-		const documentEl = document.documentElement;
-		const body = document.getElementsByTagName('body')[0];
-		const widthInPx = window.innerWidth || documentEl.clientWidth || body.clientWidth;
-		const bodyStyles: any = window.getComputedStyle(document.querySelector('body'));
-		const widthInEm = widthInPx / parseFloat(bodyStyles['font-size']);
+    assert(condition: boolean, message: string) {
+        if (!condition) {
+            throw new Error(message);
+        }
+    },
+    spawnSwitchErr(name: string, value: any) {
+        return new Error(`Unexpected switch value: ${value} encountered for ${name}`);
+    },
+    isNumeric(n: string) {
+        return !isNaN(parseFloat(n)) && isFinite(Number(n));
+    },
+    // This default unix timestamp is used for orders where the user does not specify an expiry date.
+    // It is a fixed constant so that both the redux store's INITIAL_STATE and components can check for
+    // whether a user has set an expiry date or not. It is set unrealistically high so as not to collide
+    // with actual values a user would select.
+    initialOrderExpiryUnixTimestampSec(): BigNumber {
+        const m = moment('2050-01-01');
+        return new BigNumber(m.unix());
+    },
+    convertToUnixTimestampSeconds(date: moment.Moment, time?: moment.Moment): BigNumber {
+        const finalMoment = date;
+        if (!_.isUndefined(time)) {
+            finalMoment.hours(time.hours());
+            finalMoment.minutes(time.minutes());
+        }
+        return new BigNumber(finalMoment.unix());
+    },
+    convertToMomentFromUnixTimestamp(unixTimestampSec: BigNumber): moment.Moment {
+        return moment.unix(unixTimestampSec.toNumber());
+    },
+    convertToReadableDateTimeFromUnixTimestamp(unixTimestampSec: BigNumber): string {
+        const m = this.convertToMomentFromUnixTimestamp(unixTimestampSec);
+        const formattedDate: string = m.format('h:MMa MMMM D YYYY');
+        return formattedDate;
+    },
+    generateOrder(
+        networkId: number,
+        exchangeContract: string,
+        sideToAssetToken: SideToAssetToken,
+        orderExpiryTimestamp: BigNumber,
+        orderTakerAddress: string,
+        orderMakerAddress: string,
+        makerFee: BigNumber,
+        takerFee: BigNumber,
+        feeRecipient: string,
+        signatureData: SignatureData,
+        tokenByAddress: TokenByAddress,
+        orderSalt: BigNumber,
+    ): Order {
+        const makerToken = tokenByAddress[sideToAssetToken[Side.Deposit].address];
+        const takerToken = tokenByAddress[sideToAssetToken[Side.Receive].address];
+        const order = {
+            maker: {
+                address: orderMakerAddress,
+                token: {
+                    name: makerToken.name,
+                    symbol: makerToken.symbol,
+                    decimals: makerToken.decimals,
+                    address: makerToken.address,
+                },
+                amount: sideToAssetToken[Side.Deposit].amount.toString(),
+                feeAmount: makerFee.toString(),
+            },
+            taker: {
+                address: orderTakerAddress,
+                token: {
+                    name: takerToken.name,
+                    symbol: takerToken.symbol,
+                    decimals: takerToken.decimals,
+                    address: takerToken.address,
+                },
+                amount: sideToAssetToken[Side.Receive].amount.toString(),
+                feeAmount: takerFee.toString(),
+            },
+            expiration: orderExpiryTimestamp.toString(),
+            feeRecipient,
+            salt: orderSalt.toString(),
+            signature: signatureData,
+            exchangeContract,
+            networkId,
+        };
+        return order;
+    },
+    consoleLog(message: string) {
+        /* tslint:disable */
+        console.log(message);
+        /* tslint:enable */
+    },
+    async sleepAsync(ms: number) {
+        return new Promise(resolve => setTimeout(resolve, ms));
+    },
+    deepEqual(actual: any, expected: any, opts?: { strict: boolean }) {
+        return deepEqual(actual, expected, opts);
+    },
+    getColSize(items: number) {
+        const bassCssGridSize = 12; // Source: http://basscss.com/#basscss-grid
+        const colSize = bassCssGridSize / items;
+        if (!_.isInteger(colSize)) {
+            throw new Error(`Number of cols must be divisible by ${bassCssGridSize}`);
+        }
+        return colSize;
+    },
+    getScreenWidth() {
+        const documentEl = document.documentElement;
+        const body = document.getElementsByTagName('body')[0];
+        const widthInPx = window.innerWidth || documentEl.clientWidth || body.clientWidth;
+        const bodyStyles: any = window.getComputedStyle(document.querySelector('body'));
+        const widthInEm = widthInPx / parseFloat(bodyStyles['font-size']);
 
-		// This logic mirrors the CSS media queries in BassCSS for the `lg-`, `md-` and `sm-` CSS
-		// class prefixes. Do not edit these.
-		if (widthInEm > LG_MIN_EM) {
-			return ScreenWidths.Lg;
-		} else if (widthInEm > MD_MIN_EM) {
-			return ScreenWidths.Md;
-		} else {
-			return ScreenWidths.Sm;
-		}
-	},
-	isUserOnMobile(): boolean {
-		const isUserOnMobile = isMobile();
-		return isUserOnMobile;
-	},
-	getEtherScanLinkIfExists(addressOrTxHash: string, networkId: number, suffix: EtherscanLinkSuffixes): string {
-		const networkName = constants.NETWORK_NAME_BY_ID[networkId];
-		if (_.isUndefined(networkName)) {
-			return undefined;
-		}
-		const etherScanPrefix = networkName === Networks.mainnet ? '' : `${networkName.toLowerCase()}.`;
-		return `https://${etherScanPrefix}etherscan.io/${suffix}/${addressOrTxHash}`;
-	},
-	setUrlHash(anchorId: string) {
-		window.location.hash = anchorId;
-	},
-	async isU2FSupportedAsync(): Promise<boolean> {
-		const w = window as any;
-		return new Promise((resolve: (isSupported: boolean) => void) => {
-			if (w.u2f && !w.u2f.getApiVersion) {
-				// u2f object was found (Firefox with extension)
-				resolve(true);
-			} else {
-				// u2f object was not found. Using Google polyfill
-				// HACK: u2f.getApiVersion will simply not return a version if the
-				// U2F call fails for any reason. Because of this, we set a hard 3sec
-				// timeout to the request on our end.
-				const getApiVersionTimeoutMs = 3000;
-				const intervalId = setTimeout(() => {
-					resolve(false);
-				}, getApiVersionTimeoutMs);
-				u2f.getApiVersion((version: number) => {
-					clearTimeout(intervalId);
-					resolve(true);
-				});
-			}
-		});
-	},
-	// This checks the error message returned from an injected Web3 instance on the page
-	// after a user was prompted to sign a message or send a transaction and decided to
-	// reject the request.
-	didUserDenyWeb3Request(errMsg: string) {
-		const metamaskDenialErrMsg = 'User denied message';
-		const paritySignerDenialErrMsg = 'Request has been rejected';
-		const ledgerDenialErrMsg = 'Invalid status 6985';
-		const isUserDeniedErrMsg =
-			_.includes(errMsg, metamaskDenialErrMsg) ||
-			_.includes(errMsg, paritySignerDenialErrMsg) ||
-			_.includes(errMsg, ledgerDenialErrMsg);
-		return isUserDeniedErrMsg;
-	},
-	getCurrentEnvironment() {
-		switch (location.host) {
-			case configs.DOMAIN_DEVELOPMENT:
-				return 'development';
-			case configs.DOMAIN_STAGING:
-				return 'staging';
-			case configs.DOMAIN_PRODUCTION:
-				return 'production';
-			default:
-				return 'production';
-		}
-	},
-	getIdFromName(name: string) {
-		const id = name.replace(/ /g, '-');
-		return id;
-	},
-	getAddressBeginAndEnd(address: string): string {
-		const truncatedAddress = `${address.substring(0, 6)}...${address.substr(-4)}`; // 0x3d5a...b287
-		return truncatedAddress;
-	},
-	hasUniqueNameAndSymbol(tokens: Token[], token: Token) {
-		if (token.isRegistered) {
-			return true; // Since it's registered, it is the canonical token
-		}
-		const registeredTokens = _.filter(tokens, t => t.isRegistered);
-		const tokenWithSameNameIfExists = _.find(registeredTokens, {
-			name: token.name,
-		});
-		const isUniqueName = _.isUndefined(tokenWithSameNameIfExists);
-		const tokenWithSameSymbolIfExists = _.find(registeredTokens, {
-			name: token.symbol,
-		});
-		const isUniqueSymbol = _.isUndefined(tokenWithSameSymbolIfExists);
-		return isUniqueName && isUniqueSymbol;
-	},
-	zeroExErrToHumanReadableErrMsg(error: ZeroExError | ExchangeContractErrs, takerAddress: string): string {
-		const ZeroExErrorToHumanReadableError: { [error: string]: string } = {
-			[ZeroExError.ExchangeContractDoesNotExist]: 'Exchange contract does not exist',
-			[ZeroExError.EtherTokenContractDoesNotExist]: 'EtherToken contract does not exist',
-			[ZeroExError.TokenTransferProxyContractDoesNotExist]: 'TokenTransferProxy contract does not exist',
-			[ZeroExError.TokenRegistryContractDoesNotExist]: 'TokenRegistry contract does not exist',
-			[ZeroExError.TokenContractDoesNotExist]: 'Token contract does not exist',
-			[ZeroExError.ZRXContractDoesNotExist]: 'ZRX contract does not exist',
-			[ZeroExError.UnhandledError]: 'Unhandled error occured',
-			[ZeroExError.UserHasNoAssociatedAddress]: 'User has no addresses available',
-			[ZeroExError.InvalidSignature]: 'Order signature is not valid',
-			[ZeroExError.ContractNotDeployedOnNetwork]: 'Contract is not deployed on the detected network',
-			[ZeroExError.InvalidJump]: 'Invalid jump occured while executing the transaction',
-			[ZeroExError.OutOfGas]: 'Transaction ran out of gas',
-			[ZeroExError.NoNetworkId]: 'No network id detected',
-		};
-		const exchangeContractErrorToHumanReadableError: {
-			[error: string]: string;
-		} = {
-			[ExchangeContractErrs.OrderFillExpired]: 'This order has expired',
-			[ExchangeContractErrs.OrderCancelExpired]: 'This order has expired',
-			[ExchangeContractErrs.OrderCancelAmountZero]: "Order cancel amount can't be 0",
-			[ExchangeContractErrs.OrderAlreadyCancelledOrFilled]:
-				'This order has already been completely filled or cancelled',
-			[ExchangeContractErrs.OrderFillAmountZero]: "Order fill amount can't be 0",
-			[ExchangeContractErrs.OrderRemainingFillAmountZero]:
-				'This order has already been completely filled or cancelled',
-			[ExchangeContractErrs.OrderFillRoundingError]: 'Rounding error will occur when filling this order',
-			[ExchangeContractErrs.InsufficientTakerBalance]:
-				'Taker no longer has a sufficient balance to complete this order',
-			[ExchangeContractErrs.InsufficientTakerAllowance]:
-				'Taker no longer has a sufficient allowance to complete this order',
-			[ExchangeContractErrs.InsufficientMakerBalance]:
-				'Maker no longer has a sufficient balance to complete this order',
-			[ExchangeContractErrs.InsufficientMakerAllowance]:
-				'Maker no longer has a sufficient allowance to complete this order',
-			[ExchangeContractErrs.InsufficientTakerFeeBalance]: 'Taker no longer has a sufficient balance to pay fees',
-			[ExchangeContractErrs.InsufficientTakerFeeAllowance]:
-				'Taker no longer has a sufficient allowance to pay fees',
-			[ExchangeContractErrs.InsufficientMakerFeeBalance]: 'Maker no longer has a sufficient balance to pay fees',
-			[ExchangeContractErrs.InsufficientMakerFeeAllowance]:
-				'Maker no longer has a sufficient allowance to pay fees',
-			[ExchangeContractErrs.TransactionSenderIsNotFillOrderTaker]: `This order can only be filled by ${takerAddress}`,
-			[ExchangeContractErrs.InsufficientRemainingFillAmount]: 'Insufficient remaining fill amount',
-		};
-		const humanReadableErrorMsg =
-			exchangeContractErrorToHumanReadableError[error] || ZeroExErrorToHumanReadableError[error];
-		return humanReadableErrorMsg;
-	},
+        // This logic mirrors the CSS media queries in BassCSS for the `lg-`, `md-` and `sm-` CSS
+        // class prefixes. Do not edit these.
+        if (widthInEm > LG_MIN_EM) {
+            return ScreenWidths.Lg;
+        } else if (widthInEm > MD_MIN_EM) {
+            return ScreenWidths.Md;
+        } else {
+            return ScreenWidths.Sm;
+        }
+    },
+    isUserOnMobile(): boolean {
+        const isUserOnMobile = isMobile();
+        return isUserOnMobile;
+    },
+    getEtherScanLinkIfExists(addressOrTxHash: string, networkId: number, suffix: EtherscanLinkSuffixes): string {
+        const networkName = constants.NETWORK_NAME_BY_ID[networkId];
+        if (_.isUndefined(networkName)) {
+            return undefined;
+        }
+        const etherScanPrefix = networkName === Networks.mainnet ? '' : `${networkName.toLowerCase()}.`;
+        return `https://${etherScanPrefix}etherscan.io/${suffix}/${addressOrTxHash}`;
+    },
+    setUrlHash(anchorId: string) {
+        window.location.hash = anchorId;
+    },
+    async isU2FSupportedAsync(): Promise<boolean> {
+        const w = window as any;
+        return new Promise((resolve: (isSupported: boolean) => void) => {
+            if (w.u2f && !w.u2f.getApiVersion) {
+                // u2f object was found (Firefox with extension)
+                resolve(true);
+            } else {
+                // u2f object was not found. Using Google polyfill
+                // HACK: u2f.getApiVersion will simply not return a version if the
+                // U2F call fails for any reason. Because of this, we set a hard 3sec
+                // timeout to the request on our end.
+                const getApiVersionTimeoutMs = 3000;
+                const intervalId = setTimeout(() => {
+                    resolve(false);
+                }, getApiVersionTimeoutMs);
+                u2f.getApiVersion((version: number) => {
+                    clearTimeout(intervalId);
+                    resolve(true);
+                });
+            }
+        });
+    },
+    // This checks the error message returned from an injected Web3 instance on the page
+    // after a user was prompted to sign a message or send a transaction and decided to
+    // reject the request.
+    didUserDenyWeb3Request(errMsg: string) {
+        const metamaskDenialErrMsg = 'User denied message';
+        const paritySignerDenialErrMsg = 'Request has been rejected';
+        const ledgerDenialErrMsg = 'Invalid status 6985';
+        const isUserDeniedErrMsg =
+            _.includes(errMsg, metamaskDenialErrMsg) ||
+            _.includes(errMsg, paritySignerDenialErrMsg) ||
+            _.includes(errMsg, ledgerDenialErrMsg);
+        return isUserDeniedErrMsg;
+    },
+    getCurrentEnvironment() {
+        switch (location.host) {
+            case configs.DOMAIN_DEVELOPMENT:
+                return 'development';
+            case configs.DOMAIN_STAGING:
+                return 'staging';
+            case configs.DOMAIN_PRODUCTION:
+                return 'production';
+            default:
+                return 'production';
+        }
+    },
+    getIdFromName(name: string) {
+        const id = name.replace(/ /g, '-');
+        return id;
+    },
+    getAddressBeginAndEnd(address: string): string {
+        const truncatedAddress = `${address.substring(0, 6)}...${address.substr(-4)}`; // 0x3d5a...b287
+        return truncatedAddress;
+    },
+    hasUniqueNameAndSymbol(tokens: Token[], token: Token) {
+        if (token.isRegistered) {
+            return true; // Since it's registered, it is the canonical token
+        }
+        const registeredTokens = _.filter(tokens, t => t.isRegistered);
+        const tokenWithSameNameIfExists = _.find(registeredTokens, {
+            name: token.name,
+        });
+        const isUniqueName = _.isUndefined(tokenWithSameNameIfExists);
+        const tokenWithSameSymbolIfExists = _.find(registeredTokens, {
+            name: token.symbol,
+        });
+        const isUniqueSymbol = _.isUndefined(tokenWithSameSymbolIfExists);
+        return isUniqueName && isUniqueSymbol;
+    },
+    zeroExErrToHumanReadableErrMsg(error: ZeroExError | ExchangeContractErrs, takerAddress: string): string {
+        const ZeroExErrorToHumanReadableError: { [error: string]: string } = {
+            [ZeroExError.ExchangeContractDoesNotExist]: 'Exchange contract does not exist',
+            [ZeroExError.EtherTokenContractDoesNotExist]: 'EtherToken contract does not exist',
+            [ZeroExError.TokenTransferProxyContractDoesNotExist]: 'TokenTransferProxy contract does not exist',
+            [ZeroExError.TokenRegistryContractDoesNotExist]: 'TokenRegistry contract does not exist',
+            [ZeroExError.TokenContractDoesNotExist]: 'Token contract does not exist',
+            [ZeroExError.ZRXContractDoesNotExist]: 'ZRX contract does not exist',
+            [ZeroExError.UnhandledError]: 'Unhandled error occured',
+            [ZeroExError.UserHasNoAssociatedAddress]: 'User has no addresses available',
+            [ZeroExError.InvalidSignature]: 'Order signature is not valid',
+            [ZeroExError.ContractNotDeployedOnNetwork]: 'Contract is not deployed on the detected network',
+            [ZeroExError.InvalidJump]: 'Invalid jump occured while executing the transaction',
+            [ZeroExError.OutOfGas]: 'Transaction ran out of gas',
+            [ZeroExError.NoNetworkId]: 'No network id detected',
+        };
+        const exchangeContractErrorToHumanReadableError: {
+            [error: string]: string;
+        } = {
+            [ExchangeContractErrs.OrderFillExpired]: 'This order has expired',
+            [ExchangeContractErrs.OrderCancelExpired]: 'This order has expired',
+            [ExchangeContractErrs.OrderCancelAmountZero]: "Order cancel amount can't be 0",
+            [ExchangeContractErrs.OrderAlreadyCancelledOrFilled]:
+                'This order has already been completely filled or cancelled',
+            [ExchangeContractErrs.OrderFillAmountZero]: "Order fill amount can't be 0",
+            [ExchangeContractErrs.OrderRemainingFillAmountZero]:
+                'This order has already been completely filled or cancelled',
+            [ExchangeContractErrs.OrderFillRoundingError]: 'Rounding error will occur when filling this order',
+            [ExchangeContractErrs.InsufficientTakerBalance]:
+                'Taker no longer has a sufficient balance to complete this order',
+            [ExchangeContractErrs.InsufficientTakerAllowance]:
+                'Taker no longer has a sufficient allowance to complete this order',
+            [ExchangeContractErrs.InsufficientMakerBalance]:
+                'Maker no longer has a sufficient balance to complete this order',
+            [ExchangeContractErrs.InsufficientMakerAllowance]:
+                'Maker no longer has a sufficient allowance to complete this order',
+            [ExchangeContractErrs.InsufficientTakerFeeBalance]: 'Taker no longer has a sufficient balance to pay fees',
+            [ExchangeContractErrs.InsufficientTakerFeeAllowance]:
+                'Taker no longer has a sufficient allowance to pay fees',
+            [ExchangeContractErrs.InsufficientMakerFeeBalance]: 'Maker no longer has a sufficient balance to pay fees',
+            [ExchangeContractErrs.InsufficientMakerFeeAllowance]:
+                'Maker no longer has a sufficient allowance to pay fees',
+            [ExchangeContractErrs.TransactionSenderIsNotFillOrderTaker]: `This order can only be filled by ${takerAddress}`,
+            [ExchangeContractErrs.InsufficientRemainingFillAmount]: 'Insufficient remaining fill amount',
+        };
+        const humanReadableErrorMsg =
+            exchangeContractErrorToHumanReadableError[error] || ZeroExErrorToHumanReadableError[error];
+        return humanReadableErrorMsg;
+    },
 };
diff --git a/packages/website/ts/web3_wrapper.ts b/packages/website/ts/web3_wrapper.ts
index 0cd2a5cc2..415df6e8b 100644
--- a/packages/website/ts/web3_wrapper.ts
+++ b/packages/website/ts/web3_wrapper.ts
@@ -5,154 +5,154 @@ import { utils } from 'ts/utils/utils';
 import * as Web3 from 'web3';
 
 export class Web3Wrapper {
-	private _dispatcher: Dispatcher;
-	private _web3: Web3;
-	private _prevNetworkId: number;
-	private _shouldPollUserAddress: boolean;
-	private _watchNetworkAndBalanceIntervalId: NodeJS.Timer;
-	private _prevUserEtherBalanceInEth: BigNumber;
-	private _prevUserAddress: string;
-	constructor(
-		dispatcher: Dispatcher,
-		provider: Web3.Provider,
-		networkIdIfExists: number,
-		shouldPollUserAddress: boolean,
-	) {
-		this._dispatcher = dispatcher;
-		this._prevNetworkId = networkIdIfExists;
-		this._shouldPollUserAddress = shouldPollUserAddress;
+    private _dispatcher: Dispatcher;
+    private _web3: Web3;
+    private _prevNetworkId: number;
+    private _shouldPollUserAddress: boolean;
+    private _watchNetworkAndBalanceIntervalId: NodeJS.Timer;
+    private _prevUserEtherBalanceInEth: BigNumber;
+    private _prevUserAddress: string;
+    constructor(
+        dispatcher: Dispatcher,
+        provider: Web3.Provider,
+        networkIdIfExists: number,
+        shouldPollUserAddress: boolean,
+    ) {
+        this._dispatcher = dispatcher;
+        this._prevNetworkId = networkIdIfExists;
+        this._shouldPollUserAddress = shouldPollUserAddress;
 
-		this._web3 = new Web3();
-		this._web3.setProvider(provider);
+        this._web3 = new Web3();
+        this._web3.setProvider(provider);
 
-		// tslint:disable-next-line:no-floating-promises
-		this._startEmittingNetworkConnectionAndUserBalanceStateAsync();
-	}
-	public isAddress(address: string) {
-		return this._web3.isAddress(address);
-	}
-	public async getAccountsAsync(): Promise<string[]> {
-		const addresses = await promisify<string[]>(this._web3.eth.getAccounts)();
-		return addresses;
-	}
-	public async getFirstAccountIfExistsAsync() {
-		const addresses = await this.getAccountsAsync();
-		if (_.isEmpty(addresses)) {
-			return '';
-		}
-		return addresses[0];
-	}
-	public async getNodeVersionAsync(): Promise<string> {
-		const nodeVersion = await promisify<string>(this._web3.version.getNode)();
-		return nodeVersion;
-	}
-	public getProviderObj() {
-		return this._web3.currentProvider;
-	}
-	public async getNetworkIdIfExists() {
-		try {
-			const networkId = await this._getNetworkAsync();
-			return Number(networkId);
-		} catch (err) {
-			return undefined;
-		}
-	}
-	public async getBalanceInEthAsync(owner: string): Promise<BigNumber> {
-		const balanceInWei: BigNumber = await promisify<BigNumber>(this._web3.eth.getBalance)(owner);
-		const balanceEthOldBigNumber = this._web3.fromWei(balanceInWei, 'ether');
-		const balanceEth = new BigNumber(balanceEthOldBigNumber);
-		return balanceEth;
-	}
-	public async doesContractExistAtAddressAsync(address: string): Promise<boolean> {
-		const code = await promisify<string>(this._web3.eth.getCode)(address);
-		// Regex matches 0x0, 0x00, 0x in order to accomodate poorly implemented clients
-		const zeroHexAddressRegex = /^0[xX][0]*$/;
-		const didFindCode = _.isNull(code.match(zeroHexAddressRegex));
-		return didFindCode;
-	}
-	public async signTransactionAsync(address: string, message: string): Promise<string> {
-		const signData = await promisify<string>(this._web3.eth.sign)(address, message);
-		return signData;
-	}
-	public async getBlockTimestampAsync(blockHash: string): Promise<number> {
-		const { timestamp } = await promisify<Web3.BlockWithoutTransactionData>(this._web3.eth.getBlock)(blockHash);
-		return timestamp;
-	}
-	public destroy() {
-		this._stopEmittingNetworkConnectionAndUserBalanceStateAsync();
-		// HACK: stop() is only available on providerEngine instances
-		const provider = this._web3.currentProvider;
-		if (!_.isUndefined((provider as any).stop)) {
-			(provider as any).stop();
-		}
-	}
-	// This should only be called from the LedgerConfigDialog
-	public updatePrevUserAddress(userAddress: string) {
-		this._prevUserAddress = userAddress;
-	}
-	private async _getNetworkAsync() {
-		const networkId = await promisify(this._web3.version.getNetwork)();
-		return networkId;
-	}
-	private async _startEmittingNetworkConnectionAndUserBalanceStateAsync() {
-		if (!_.isUndefined(this._watchNetworkAndBalanceIntervalId)) {
-			return; // we are already emitting the state
-		}
+        // tslint:disable-next-line:no-floating-promises
+        this._startEmittingNetworkConnectionAndUserBalanceStateAsync();
+    }
+    public isAddress(address: string) {
+        return this._web3.isAddress(address);
+    }
+    public async getAccountsAsync(): Promise<string[]> {
+        const addresses = await promisify<string[]>(this._web3.eth.getAccounts)();
+        return addresses;
+    }
+    public async getFirstAccountIfExistsAsync() {
+        const addresses = await this.getAccountsAsync();
+        if (_.isEmpty(addresses)) {
+            return '';
+        }
+        return addresses[0];
+    }
+    public async getNodeVersionAsync(): Promise<string> {
+        const nodeVersion = await promisify<string>(this._web3.version.getNode)();
+        return nodeVersion;
+    }
+    public getProviderObj() {
+        return this._web3.currentProvider;
+    }
+    public async getNetworkIdIfExists() {
+        try {
+            const networkId = await this._getNetworkAsync();
+            return Number(networkId);
+        } catch (err) {
+            return undefined;
+        }
+    }
+    public async getBalanceInEthAsync(owner: string): Promise<BigNumber> {
+        const balanceInWei: BigNumber = await promisify<BigNumber>(this._web3.eth.getBalance)(owner);
+        const balanceEthOldBigNumber = this._web3.fromWei(balanceInWei, 'ether');
+        const balanceEth = new BigNumber(balanceEthOldBigNumber);
+        return balanceEth;
+    }
+    public async doesContractExistAtAddressAsync(address: string): Promise<boolean> {
+        const code = await promisify<string>(this._web3.eth.getCode)(address);
+        // Regex matches 0x0, 0x00, 0x in order to accomodate poorly implemented clients
+        const zeroHexAddressRegex = /^0[xX][0]*$/;
+        const didFindCode = _.isNull(code.match(zeroHexAddressRegex));
+        return didFindCode;
+    }
+    public async signTransactionAsync(address: string, message: string): Promise<string> {
+        const signData = await promisify<string>(this._web3.eth.sign)(address, message);
+        return signData;
+    }
+    public async getBlockTimestampAsync(blockHash: string): Promise<number> {
+        const { timestamp } = await promisify<Web3.BlockWithoutTransactionData>(this._web3.eth.getBlock)(blockHash);
+        return timestamp;
+    }
+    public destroy() {
+        this._stopEmittingNetworkConnectionAndUserBalanceStateAsync();
+        // HACK: stop() is only available on providerEngine instances
+        const provider = this._web3.currentProvider;
+        if (!_.isUndefined((provider as any).stop)) {
+            (provider as any).stop();
+        }
+    }
+    // This should only be called from the LedgerConfigDialog
+    public updatePrevUserAddress(userAddress: string) {
+        this._prevUserAddress = userAddress;
+    }
+    private async _getNetworkAsync() {
+        const networkId = await promisify(this._web3.version.getNetwork)();
+        return networkId;
+    }
+    private async _startEmittingNetworkConnectionAndUserBalanceStateAsync() {
+        if (!_.isUndefined(this._watchNetworkAndBalanceIntervalId)) {
+            return; // we are already emitting the state
+        }
 
-		let prevNodeVersion: string;
-		this._prevUserEtherBalanceInEth = new BigNumber(0);
-		this._dispatcher.updateNetworkId(this._prevNetworkId);
-		this._watchNetworkAndBalanceIntervalId = intervalUtils.setAsyncExcludingInterval(
-			async () => {
-				// Check for network state changes
-				const currentNetworkId = await this.getNetworkIdIfExists();
-				if (currentNetworkId !== this._prevNetworkId) {
-					this._prevNetworkId = currentNetworkId;
-					this._dispatcher.updateNetworkId(currentNetworkId);
-				}
+        let prevNodeVersion: string;
+        this._prevUserEtherBalanceInEth = new BigNumber(0);
+        this._dispatcher.updateNetworkId(this._prevNetworkId);
+        this._watchNetworkAndBalanceIntervalId = intervalUtils.setAsyncExcludingInterval(
+            async () => {
+                // Check for network state changes
+                const currentNetworkId = await this.getNetworkIdIfExists();
+                if (currentNetworkId !== this._prevNetworkId) {
+                    this._prevNetworkId = currentNetworkId;
+                    this._dispatcher.updateNetworkId(currentNetworkId);
+                }
 
-				// Check for node version changes
-				const currentNodeVersion = await this.getNodeVersionAsync();
-				if (currentNodeVersion !== prevNodeVersion) {
-					prevNodeVersion = currentNodeVersion;
-					this._dispatcher.updateNodeVersion(currentNodeVersion);
-				}
+                // Check for node version changes
+                const currentNodeVersion = await this.getNodeVersionAsync();
+                if (currentNodeVersion !== prevNodeVersion) {
+                    prevNodeVersion = currentNodeVersion;
+                    this._dispatcher.updateNodeVersion(currentNodeVersion);
+                }
 
-				if (this._shouldPollUserAddress) {
-					const userAddressIfExists = await this.getFirstAccountIfExistsAsync();
-					// Update makerAddress on network change
-					if (this._prevUserAddress !== userAddressIfExists) {
-						this._prevUserAddress = userAddressIfExists;
-						this._dispatcher.updateUserAddress(userAddressIfExists);
-					}
+                if (this._shouldPollUserAddress) {
+                    const userAddressIfExists = await this.getFirstAccountIfExistsAsync();
+                    // Update makerAddress on network change
+                    if (this._prevUserAddress !== userAddressIfExists) {
+                        this._prevUserAddress = userAddressIfExists;
+                        this._dispatcher.updateUserAddress(userAddressIfExists);
+                    }
 
-					// Check for user ether balance changes
-					if (userAddressIfExists !== '') {
-						await this._updateUserEtherBalanceAsync(userAddressIfExists);
-					}
-				} else {
-					// This logic is primarily for the Ledger, since we don't regularly poll for the address
-					// we simply update the balance for the last fetched address.
-					if (!_.isEmpty(this._prevUserAddress)) {
-						await this._updateUserEtherBalanceAsync(this._prevUserAddress);
-					}
-				}
-			},
-			5000,
-			(err: Error) => {
-				utils.consoleLog(`Watching network and balances failed: ${err}`);
-				this._stopEmittingNetworkConnectionAndUserBalanceStateAsync();
-			},
-		);
-	}
-	private async _updateUserEtherBalanceAsync(userAddress: string) {
-		const balance = await this.getBalanceInEthAsync(userAddress);
-		if (!balance.eq(this._prevUserEtherBalanceInEth)) {
-			this._prevUserEtherBalanceInEth = balance;
-			this._dispatcher.updateUserEtherBalance(balance);
-		}
-	}
-	private _stopEmittingNetworkConnectionAndUserBalanceStateAsync() {
-		intervalUtils.clearAsyncExcludingInterval(this._watchNetworkAndBalanceIntervalId);
-	}
+                    // Check for user ether balance changes
+                    if (userAddressIfExists !== '') {
+                        await this._updateUserEtherBalanceAsync(userAddressIfExists);
+                    }
+                } else {
+                    // This logic is primarily for the Ledger, since we don't regularly poll for the address
+                    // we simply update the balance for the last fetched address.
+                    if (!_.isEmpty(this._prevUserAddress)) {
+                        await this._updateUserEtherBalanceAsync(this._prevUserAddress);
+                    }
+                }
+            },
+            5000,
+            (err: Error) => {
+                utils.consoleLog(`Watching network and balances failed: ${err}`);
+                this._stopEmittingNetworkConnectionAndUserBalanceStateAsync();
+            },
+        );
+    }
+    private async _updateUserEtherBalanceAsync(userAddress: string) {
+        const balance = await this.getBalanceInEthAsync(userAddress);
+        if (!balance.eq(this._prevUserEtherBalanceInEth)) {
+            this._prevUserEtherBalanceInEth = balance;
+            this._dispatcher.updateUserEtherBalance(balance);
+        }
+    }
+    private _stopEmittingNetworkConnectionAndUserBalanceStateAsync() {
+        intervalUtils.clearAsyncExcludingInterval(this._watchNetworkAndBalanceIntervalId);
+    }
 }
diff --git a/packages/website/tsconfig.json b/packages/website/tsconfig.json
index 0ed2794d8..38b177d0b 100644
--- a/packages/website/tsconfig.json
+++ b/packages/website/tsconfig.json
@@ -1,17 +1,17 @@
 {
-	"extends": "../../tsconfig",
-	"compilerOptions": {
-		"allowSyntheticDefaultImports": true,
-		"outDir": "./transpiled/",
-		"jsx": "react",
-		"baseUrl": "./",
-		"allowJs": true,
-		"strictNullChecks": false,
-		"noImplicitThis": false,
-		"declaration": false,
-		"paths": {
-			"*": ["node_modules/@types/*", "*"]
-		}
-	},
-	"include": ["./ts/**/*", "../../node_modules/web3-typescript-typings/index.d.ts"]
+    "extends": "../../tsconfig",
+    "compilerOptions": {
+        "allowSyntheticDefaultImports": true,
+        "outDir": "./transpiled/",
+        "jsx": "react",
+        "baseUrl": "./",
+        "allowJs": true,
+        "strictNullChecks": false,
+        "noImplicitThis": false,
+        "declaration": false,
+        "paths": {
+            "*": ["node_modules/@types/*", "*"]
+        }
+    },
+    "include": ["./ts/**/*", "../../node_modules/web3-typescript-typings/index.d.ts"]
 }
diff --git a/packages/website/tslint.json b/packages/website/tslint.json
index fcbd0391e..d6a5f5031 100644
--- a/packages/website/tslint.json
+++ b/packages/website/tslint.json
@@ -1,9 +1,9 @@
 {
-	"extends": ["@0xproject/tslint-config"],
-	"rules": {
-		"no-implicit-dependencies": false,
-		"no-object-literal-type-assertion": false,
-		"completed-docs": false,
-		"prefer-function-over-method": false
-	}
+    "extends": ["@0xproject/tslint-config"],
+    "rules": {
+        "no-implicit-dependencies": false,
+        "no-object-literal-type-assertion": false,
+        "completed-docs": false,
+        "prefer-function-over-method": false
+    }
 }
diff --git a/tsconfig.json b/tsconfig.json
index 937240b76..b6f95e64d 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,13 +1,13 @@
 {
-	"compilerOptions": {
-		"module": "commonjs",
-		"target": "es5",
-		"lib": ["es2017", "dom"],
-		"sourceMap": true,
-		"declaration": true,
-		"experimentalDecorators": true,
-		"noImplicitReturns": true,
-		"pretty": true,
-		"strict": true
-	}
+    "compilerOptions": {
+        "module": "commonjs",
+        "target": "es5",
+        "lib": ["es2017", "dom"],
+        "sourceMap": true,
+        "declaration": true,
+        "experimentalDecorators": true,
+        "noImplicitReturns": true,
+        "pretty": true,
+        "strict": true
+    }
 }
-- 
cgit v1.2.3


From be370c4e192b642eeaf52a970a2f0addf459605c Mon Sep 17 00:00:00 2001
From: Fabio Berger <me@fabioberger.com>
Date: Tue, 30 Jan 2018 13:45:20 +0100
Subject: Add PR number

---
 packages/0x.js/CHANGELOG.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/0x.js/CHANGELOG.md b/packages/0x.js/CHANGELOG.md
index 1acc202e2..83c33ee1c 100644
--- a/packages/0x.js/CHANGELOG.md
+++ b/packages/0x.js/CHANGELOG.md
@@ -5,7 +5,7 @@
     * Add the `shouldAddPersonalMessagePrefix` parameter to `signOrderHashAsync` so that the
     caller can decide on whether to add the personalMessage prefix before relaying the request
     to the signer. Parity Signer, Ledger and TestRPC add the prefix themselves, Metamask expects
-    it to have already been added.
+    it to have already been added. (#349)
 
 ## v0.30.2 - _January 29, 2018_
 
-- 
cgit v1.2.3