aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFabio Berger <me@fabioberger.com>2018-05-23 00:25:02 +0800
committerFabio Berger <me@fabioberger.com>2018-05-23 00:25:02 +0800
commit4a0c8d72b05152ee2fd71245873d5a70f7281058 (patch)
tree2c28ad8214aaaa10913a621509d0ae4020ee4d3d
parentd460c0e8b9c6f4081803fff4e2d2347be8cd5ce3 (diff)
parentab9cfd293b3ccc2aacb4238aebe2b033e55b7935 (diff)
downloaddexon-sol-tools-4a0c8d72b05152ee2fd71245873d5a70f7281058.tar
dexon-sol-tools-4a0c8d72b05152ee2fd71245873d5a70f7281058.tar.gz
dexon-sol-tools-4a0c8d72b05152ee2fd71245873d5a70f7281058.tar.bz2
dexon-sol-tools-4a0c8d72b05152ee2fd71245873d5a70f7281058.tar.lz
dexon-sol-tools-4a0c8d72b05152ee2fd71245873d5a70f7281058.tar.xz
dexon-sol-tools-4a0c8d72b05152ee2fd71245873d5a70f7281058.tar.zst
dexon-sol-tools-4a0c8d72b05152ee2fd71245873d5a70f7281058.zip
merge development
-rw-r--r--packages/0x.js/src/schemas/zero_ex_public_network_config_schema.ts16
-rw-r--r--packages/0x.js/test/global_hooks.ts3
-rw-r--r--packages/assert/test/assert_test.ts2
-rw-r--r--packages/contract-wrappers/src/schemas/contract_wrappers_public_network_config_schema.ts16
-rw-r--r--packages/contract-wrappers/src/utils/constants.ts1
-rw-r--r--packages/contract-wrappers/src/utils/filter_utils.ts8
-rw-r--r--packages/contract-wrappers/src/utils/utils.ts3
-rw-r--r--packages/contract-wrappers/test/ether_token_wrapper_test.ts4
-rw-r--r--packages/contract-wrappers/test/global_hooks.ts3
-rw-r--r--packages/contract-wrappers/test/order_validation_test.ts7
-rw-r--r--packages/contracts/test/unlimited_allowance_token.ts4
-rw-r--r--packages/contracts/test/zrx_token.ts4
-rw-r--r--packages/contracts/tslint.json5
-rw-r--r--packages/json-schemas/test/schema_test.ts11
-rw-r--r--packages/migrations/package.json2
-rw-r--r--packages/migrations/src/migration.ts5
-rw-r--r--packages/monorepo-scripts/src/postpublish_utils.ts1
-rw-r--r--packages/monorepo-scripts/src/publish.ts4
-rw-r--r--packages/order-utils/src/order_hash.ts3
-rw-r--r--packages/order-utils/src/signature_utils.ts17
-rw-r--r--packages/order-utils/test/signature_utils_test.ts12
-rw-r--r--packages/order-watcher/src/order_watcher/order_watcher.ts4
-rw-r--r--packages/order-watcher/src/utils/utils.ts3
-rw-r--r--packages/order-watcher/test/expiration_watcher_test.ts33
-rw-r--r--packages/order-watcher/test/global_hooks.ts3
-rw-r--r--packages/order-watcher/test/order_watcher_test.ts4
-rw-r--r--packages/react-docs/src/docs_info.ts4
-rw-r--r--packages/react-docs/tslint.json3
-rw-r--r--packages/react-shared/tslint.json3
-rw-r--r--packages/sol-compiler/src/compiler.ts3
-rw-r--r--packages/sol-compiler/test/compiler_test.ts9
-rw-r--r--packages/sol-cov/test/collect_coverage_entries_test.ts3
-rw-r--r--packages/sol-cov/test/instructions_test.ts1
-rw-r--r--packages/sra-report/src/index.ts13
-rw-r--r--packages/sra-report/src/postman_environment_factory.ts14
-rw-r--r--packages/sra-report/test/test_runner.ts11
-rw-r--r--packages/subproviders/src/subproviders/ledger.ts18
-rw-r--r--packages/subproviders/src/subproviders/nonce_tracker.ts3
-rw-r--r--packages/subproviders/src/subproviders/subprovider.ts5
-rw-r--r--packages/subproviders/src/utils/wallet_utils.ts4
-rw-r--r--packages/subproviders/test/integration/ledger_subprovider_test.ts13
-rw-r--r--packages/subproviders/test/unit/ledger_subprovider_test.ts8
-rw-r--r--packages/subproviders/test/unit/mnemonic_wallet_subprovider_test.ts5
-rw-r--r--packages/subproviders/test/unit/redundant_rpc_subprovider_test.ts5
-rw-r--r--packages/testnet-faucets/src/ts/constants.ts5
-rw-r--r--packages/testnet-faucets/src/ts/handler.ts11
-rw-r--r--packages/testnet-faucets/src/ts/parameter_transformer.ts5
-rw-r--r--packages/testnet-faucets/src/ts/server.ts6
-rw-r--r--packages/tslint-config/package.json3
-rw-r--r--packages/tslint-config/rules/booleanNamingRule.ts68
-rw-r--r--packages/tslint-config/rules/customNoMagicNumbersRule.ts76
-rw-r--r--packages/tslint-config/tslint.json3
-rw-r--r--packages/utils/src/abi_decoder.ts12
-rw-r--r--packages/utils/src/address_utils.ts11
-rw-r--r--packages/utils/src/interval_utils.ts8
-rw-r--r--packages/web3-wrapper/src/web3_wrapper.ts16
-rw-r--r--packages/website/ts/components/generate_order/new_token_form.tsx8
-rw-r--r--packages/website/ts/components/relayer_index/relayer_index.tsx4
-rw-r--r--packages/website/tslint.json3
59 files changed, 418 insertions, 124 deletions
diff --git a/packages/0x.js/src/schemas/zero_ex_public_network_config_schema.ts b/packages/0x.js/src/schemas/zero_ex_public_network_config_schema.ts
index 9da31481a..f7f6727f0 100644
--- a/packages/0x.js/src/schemas/zero_ex_public_network_config_schema.ts
+++ b/packages/0x.js/src/schemas/zero_ex_public_network_config_schema.ts
@@ -1,9 +1,23 @@
+const networkNameToId: { [networkName: string]: number } = {
+ mainnet: 1,
+ ropsten: 3,
+ rinkeby: 4,
+ kovan: 42,
+ ganache: 50,
+};
+
export const zeroExPublicNetworkConfigSchema = {
id: '/ZeroExPublicNetworkConfig',
properties: {
networkId: {
type: 'number',
- enum: [1, 3, 4, 42, 50],
+ enum: [
+ networkNameToId.mainnet,
+ networkNameToId.ropsten,
+ networkNameToId.rinkeby,
+ networkNameToId.kovan,
+ networkNameToId.ganache,
+ ],
},
gasPrice: { $ref: '/Number' },
zrxContractAddress: { $ref: '/Address' },
diff --git a/packages/0x.js/test/global_hooks.ts b/packages/0x.js/test/global_hooks.ts
index 53b3ef545..fa1dfae38 100644
--- a/packages/0x.js/test/global_hooks.ts
+++ b/packages/0x.js/test/global_hooks.ts
@@ -8,7 +8,8 @@ import { provider } from './utils/web3_wrapper';
before('migrate contracts', async function(): Promise<void> {
// HACK: Since the migrations take longer then our global mocha timeout limit
// we manually increase it for this before hook.
- this.timeout(20000);
+ const mochaTestTimeoutMs = 20000;
+ this.timeout(mochaTestTimeoutMs);
const txDefaults = {
gas: devConstants.GAS_ESTIMATE,
from: devConstants.TESTRPC_FIRST_ADDRESS,
diff --git a/packages/assert/test/assert_test.ts b/packages/assert/test/assert_test.ts
index 58d3e53b5..e61ec93e0 100644
--- a/packages/assert/test/assert_test.ts
+++ b/packages/assert/test/assert_test.ts
@@ -11,6 +11,7 @@ chai.config.includeStack = true;
chai.use(dirtyChai);
const expect = chai.expect;
+// tslint:disable:custom-no-magic-numbers
describe('Assertions', () => {
const variableName = 'variable';
describe('#isBigNumber', () => {
@@ -252,3 +253,4 @@ describe('Assertions', () => {
});
});
});
+// tslint:enable:custom-no-magic-numbers
diff --git a/packages/contract-wrappers/src/schemas/contract_wrappers_public_network_config_schema.ts b/packages/contract-wrappers/src/schemas/contract_wrappers_public_network_config_schema.ts
index bf1000afa..304cd100b 100644
--- a/packages/contract-wrappers/src/schemas/contract_wrappers_public_network_config_schema.ts
+++ b/packages/contract-wrappers/src/schemas/contract_wrappers_public_network_config_schema.ts
@@ -1,9 +1,23 @@
+const networkNameToId: { [networkName: string]: number } = {
+ mainnet: 1,
+ ropsten: 3,
+ rinkeby: 4,
+ kovan: 42,
+ ganache: 50,
+};
+
export const contractWrappersPublicNetworkConfigSchema = {
id: '/ZeroExContractPublicNetworkConfig',
properties: {
networkId: {
type: 'number',
- enum: [1, 3, 4, 42, 50],
+ enum: [
+ networkNameToId.mainnet,
+ networkNameToId.kovan,
+ networkNameToId.ropsten,
+ networkNameToId.rinkeby,
+ networkNameToId.ganache,
+ ],
},
gasPrice: { $ref: '/Number' },
zrxContractAddress: { $ref: '/Address' },
diff --git a/packages/contract-wrappers/src/utils/constants.ts b/packages/contract-wrappers/src/utils/constants.ts
index 07da6745d..76d805cac 100644
--- a/packages/contract-wrappers/src/utils/constants.ts
+++ b/packages/contract-wrappers/src/utils/constants.ts
@@ -6,6 +6,7 @@ export const constants = {
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',
+ // tslint:disable-next-line:custom-no-magic-numbers
UNLIMITED_ALLOWANCE_IN_BASE_UNITS: new BigNumber(2).pow(256).minus(1),
DEFAULT_BLOCK_POLLING_INTERVAL: 1000,
};
diff --git a/packages/contract-wrappers/src/utils/filter_utils.ts b/packages/contract-wrappers/src/utils/filter_utils.ts
index c5df7321e..4ec9e256b 100644
--- a/packages/contract-wrappers/src/utils/filter_utils.ts
+++ b/packages/contract-wrappers/src/utils/filter_utils.ts
@@ -73,14 +73,14 @@ export const filterUtils = {
return false;
}
if (!_.isUndefined(filter.topics)) {
- return filterUtils.matchesTopics(log.topics, filter.topics);
+ return filterUtils.doesMatchTopics(log.topics, filter.topics);
}
return true;
},
- matchesTopics(logTopics: string[], filterTopics: Array<string[] | string | null>): boolean {
+ doesMatchTopics(logTopics: string[], filterTopics: Array<string[] | string | null>): boolean {
const matchesTopic = _.zipWith(logTopics, filterTopics, filterUtils.matchesTopic.bind(filterUtils));
- const matchesTopics = _.every(matchesTopic);
- return matchesTopics;
+ const doesMatchTopics = _.every(matchesTopic);
+ return doesMatchTopics;
},
matchesTopic(logTopic: string, filterTopic: string[] | string | null): boolean {
if (_.isArray(filterTopic)) {
diff --git a/packages/contract-wrappers/src/utils/utils.ts b/packages/contract-wrappers/src/utils/utils.ts
index af1125632..7cf9450a0 100644
--- a/packages/contract-wrappers/src/utils/utils.ts
+++ b/packages/contract-wrappers/src/utils/utils.ts
@@ -5,7 +5,8 @@ export const utils = {
return new Error(`Unexpected switch value: ${value} encountered for ${name}`);
},
getCurrentUnixTimestampSec(): BigNumber {
- return new BigNumber(Date.now() / 1000).round();
+ const milisecondsInSecond = 1000;
+ return new BigNumber(Date.now() / milisecondsInSecond).round();
},
getCurrentUnixTimestampMs(): BigNumber {
return new BigNumber(Date.now());
diff --git a/packages/contract-wrappers/test/ether_token_wrapper_test.ts b/packages/contract-wrappers/test/ether_token_wrapper_test.ts
index 974db34b1..e06fe96e5 100644
--- a/packages/contract-wrappers/test/ether_token_wrapper_test.ts
+++ b/packages/contract-wrappers/test/ether_token_wrapper_test.ts
@@ -42,7 +42,7 @@ describe('EtherTokenWrapper', () => {
let addressWithETH: string;
let wethContractAddress: string;
let depositWeiAmount: BigNumber;
- let decimalPlaces: number;
+ const decimalPlaces = 7;
let addressWithoutFunds: string;
const gasPrice = new BigNumber(1);
const zeroExConfig = {
@@ -60,7 +60,6 @@ describe('EtherTokenWrapper', () => {
addressWithETH = userAddresses[0];
wethContractAddress = contractWrappers.etherToken.getContractAddressIfExists() as string;
depositWeiAmount = Web3Wrapper.toWei(new BigNumber(5));
- decimalPlaces = 7;
addressWithoutFunds = userAddresses[1];
});
beforeEach(async () => {
@@ -155,6 +154,7 @@ describe('EtherTokenWrapper', () => {
const preWETHBalance = await contractWrappers.token.getBalanceAsync(wethContractAddress, addressWithETH);
expect(preWETHBalance).to.be.bignumber.equal(0);
+ // tslint:disable-next-line:custom-no-magic-numbers
const overWETHBalance = preWETHBalance.add(999999999);
return expect(
diff --git a/packages/contract-wrappers/test/global_hooks.ts b/packages/contract-wrappers/test/global_hooks.ts
index 53b3ef545..fa1dfae38 100644
--- a/packages/contract-wrappers/test/global_hooks.ts
+++ b/packages/contract-wrappers/test/global_hooks.ts
@@ -8,7 +8,8 @@ import { provider } from './utils/web3_wrapper';
before('migrate contracts', async function(): Promise<void> {
// HACK: Since the migrations take longer then our global mocha timeout limit
// we manually increase it for this before hook.
- this.timeout(20000);
+ const mochaTestTimeoutMs = 20000;
+ this.timeout(mochaTestTimeoutMs);
const txDefaults = {
gas: devConstants.GAS_ESTIMATE,
from: devConstants.TESTRPC_FIRST_ADDRESS,
diff --git a/packages/contract-wrappers/test/order_validation_test.ts b/packages/contract-wrappers/test/order_validation_test.ts
index 2acdece3e..a14dc24b6 100644
--- a/packages/contract-wrappers/test/order_validation_test.ts
+++ b/packages/contract-wrappers/test/order_validation_test.ts
@@ -106,6 +106,7 @@ describe('OrderValidation', () => {
});
it('should succeed if the order is asymmetric and fillable', async () => {
const makerFillableAmount = fillableAmount;
+ // tslint:disable-next-line:custom-no-magic-numbers
const takerFillableAmount = fillableAmount.minus(4);
const signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
makerTokenAddress,
@@ -172,6 +173,7 @@ describe('OrderValidation', () => {
fillableAmount,
);
// 27 <--> 28
+ // tslint:disable-next-line:custom-no-magic-numbers
signedOrder.ecSignature.v = 28 - signedOrder.ecSignature.v + 27;
return expect(
contractWrappers.exchange.validateFillOrderThrowIfInvalidAsync(
@@ -206,6 +208,7 @@ describe('OrderValidation', () => {
takerAddress,
fillableAmount,
);
+ // tslint:disable-next-line:custom-no-magic-numbers
const nonTakerAddress = userAddresses[6];
return expect(
contractWrappers.exchange.validateFillOrderThrowIfInvalidAsync(
@@ -353,6 +356,7 @@ describe('OrderValidation', () => {
takerAddress,
zrxTokenAddress,
);
+ // tslint:disable-next-line:custom-no-magic-numbers
expect(transferFromAsync.callCount).to.be.equal(4);
expect(
transferFromAsync
@@ -423,6 +427,7 @@ describe('OrderValidation', () => {
takerAddress,
zrxTokenAddress,
);
+ // tslint:disable-next-line:custom-no-magic-numbers
expect(transferFromAsync.callCount).to.be.equal(4);
expect(
transferFromAsync
@@ -491,6 +496,7 @@ describe('OrderValidation', () => {
takerAddress,
zrxTokenAddress,
);
+ // tslint:disable-next-line:custom-no-magic-numbers
expect(transferFromAsync.callCount).to.be.equal(4);
const makerFillAmount = transferFromAsync.getCall(0).args[3];
expect(makerFillAmount).to.be.bignumber.equal(makerTokenAmount);
@@ -518,6 +524,7 @@ describe('OrderValidation', () => {
);
const makerPartialFee = makerFee.div(2);
const takerPartialFee = takerFee.div(2);
+ // tslint:disable-next-line:custom-no-magic-numbers
expect(transferFromAsync.callCount).to.be.equal(4);
const partialMakerFee = transferFromAsync.getCall(2).args[3];
expect(partialMakerFee).to.be.bignumber.equal(makerPartialFee);
diff --git a/packages/contracts/test/unlimited_allowance_token.ts b/packages/contracts/test/unlimited_allowance_token.ts
index 8851a04ef..5ad9321e8 100644
--- a/packages/contracts/test/unlimited_allowance_token.ts
+++ b/packages/contracts/test/unlimited_allowance_token.ts
@@ -97,8 +97,8 @@ describe('UnlimitedAllowanceToken', () => {
const amountToTransfer = ownerBalance;
const spenderAllowance = await zeroEx.token.getAllowanceAsync(tokenAddress, owner, spender);
- const spenderAllowanceIsInsufficient = spenderAllowance.cmp(amountToTransfer) < 0;
- expect(spenderAllowanceIsInsufficient).to.be.true();
+ const isSpenderAllowanceInsufficient = spenderAllowance.cmp(amountToTransfer) < 0;
+ expect(isSpenderAllowanceInsufficient).to.be.true();
return expect(
token.transferFrom.callAsync(owner, spender, amountToTransfer, {
diff --git a/packages/contracts/test/zrx_token.ts b/packages/contracts/test/zrx_token.ts
index 7a72f85dc..48b8f6e36 100644
--- a/packages/contracts/test/zrx_token.ts
+++ b/packages/contracts/test/zrx_token.ts
@@ -118,8 +118,8 @@ describe('ZRXToken', () => {
const amountToTransfer = ownerBalance;
const spenderAllowance = await zeroEx.token.getAllowanceAsync(zrxAddress, owner, spender);
- const spenderAllowanceIsInsufficient = spenderAllowance.cmp(amountToTransfer) < 0;
- expect(spenderAllowanceIsInsufficient).to.be.true();
+ const isSpenderAllowanceInsufficient = spenderAllowance.cmp(amountToTransfer) < 0;
+ expect(isSpenderAllowanceInsufficient).to.be.true();
const didReturnTrue = await zrxToken.transferFrom.callAsync(owner, spender, amountToTransfer, {
from: spender,
diff --git a/packages/contracts/tslint.json b/packages/contracts/tslint.json
index ffaefe83a..1ab924e47 100644
--- a/packages/contracts/tslint.json
+++ b/packages/contracts/tslint.json
@@ -1,3 +1,6 @@
{
- "extends": ["@0xproject/tslint-config"]
+ "extends": ["@0xproject/tslint-config"],
+ "rules": {
+ "custom-no-magic-numbers": false
+ }
}
diff --git a/packages/json-schemas/test/schema_test.ts b/packages/json-schemas/test/schema_test.ts
index ac6a68b59..b9574a0c9 100644
--- a/packages/json-schemas/test/schema_test.ts
+++ b/packages/json-schemas/test/schema_test.ts
@@ -149,7 +149,8 @@ describe('Schema', () => {
});
describe('#blockParamSchema', () => {
it('should validate valid block param', () => {
- const testCases = [42, 'latest', 'pending', 'earliest'];
+ const blockNumber = 42;
+ const testCases = [blockNumber, 'latest', 'pending', 'earliest'];
validateAgainstSchema(testCases, blockParamSchema);
});
it('should fail for invalid block param', () => {
@@ -182,6 +183,7 @@ describe('Schema', () => {
validateAgainstSchema(testCases, tokenSchema);
});
it('should fail for invalid token', () => {
+ const num = 4;
const testCases = [
{
...token,
@@ -192,7 +194,7 @@ describe('Schema', () => {
decimals: undefined,
},
[],
- 4,
+ num,
];
const shouldFail = true;
validateAgainstSchema(testCases, tokenSchema, shouldFail);
@@ -871,10 +873,12 @@ describe('Schema', () => {
});
describe('#jsNumberSchema', () => {
it('should validate valid js number', () => {
+ // tslint:disable-next-line:custom-no-magic-numbers
const testCases = [1, 42];
validateAgainstSchema(testCases, jsNumber);
});
it('should fail for invalid js number', () => {
+ // tslint:disable-next-line:custom-no-magic-numbers
const testCases = [NaN, -1, new BigNumber(1)];
const shouldFail = true;
validateAgainstSchema(testCases, jsNumber, shouldFail);
@@ -882,13 +886,14 @@ describe('Schema', () => {
});
describe('#txDataSchema', () => {
it('should validate valid txData', () => {
+ const bigNumGasAmount = new BigNumber(42);
const testCases = [
{
from: NULL_ADDRESS,
},
{
from: NULL_ADDRESS,
- gas: new BigNumber(42),
+ gas: bigNumGasAmount,
},
{
from: NULL_ADDRESS,
diff --git a/packages/migrations/package.json b/packages/migrations/package.json
index ab5204d86..d9e68caaf 100644
--- a/packages/migrations/package.json
+++ b/packages/migrations/package.json
@@ -12,7 +12,7 @@
"prebuild": "run-s clean compile copy_artifacts generate_contract_wrappers",
"copy_artifacts": "copyfiles 'artifacts/1.0.0/**/*' ./lib",
"build": "tsc",
- "clean": "shx rm -rf lib",
+ "clean": "shx rm -rf lib src/contract_wrappers",
"lint": "tslint --project .",
"migrate": "run-s build compile script:migrate",
"script:migrate": "node ./lib/migrate.js",
diff --git a/packages/migrations/src/migration.ts b/packages/migrations/src/migration.ts
index 57ac311d7..e29414a57 100644
--- a/packages/migrations/src/migration.ts
+++ b/packages/migrations/src/migration.ts
@@ -80,11 +80,12 @@ export const runMigrationsAsync = async (provider: Provider, artifactsDir: strin
tokenInfo[0].swarmHash,
{ from: owner },
);
+ const decimals = 18;
await tokenReg.addToken.sendTransactionAsync(
zrxToken.address,
'0x Protocol Token',
'ZRX',
- 18,
+ decimals,
NULL_BYTES,
NULL_BYTES,
{
@@ -96,7 +97,7 @@ export const runMigrationsAsync = async (provider: Provider, artifactsDir: strin
etherToken.address,
'Ether Token',
'WETH',
- 18,
+ decimals,
NULL_BYTES,
NULL_BYTES,
{
diff --git a/packages/monorepo-scripts/src/postpublish_utils.ts b/packages/monorepo-scripts/src/postpublish_utils.ts
index 22614f01b..f5785343d 100644
--- a/packages/monorepo-scripts/src/postpublish_utils.ts
+++ b/packages/monorepo-scripts/src/postpublish_utils.ts
@@ -158,6 +158,7 @@ export const postpublishUtils = {
// HACK: tsconfig.json needs wildcard directory endings as `/**/*`
// but TypeDoc needs it as `/**` in order to pick up files at the root
if (_.endsWith(includePath, '/**/*')) {
+ // tslint:disable-next-line:custom-no-magic-numbers
includePath = includePath.slice(0, -2);
}
return includePath;
diff --git a/packages/monorepo-scripts/src/publish.ts b/packages/monorepo-scripts/src/publish.ts
index 5c26475c9..73106821a 100644
--- a/packages/monorepo-scripts/src/publish.ts
+++ b/packages/monorepo-scripts/src/publish.ts
@@ -285,8 +285,8 @@ function shouldAddNewChangelogEntry(currentVersion: string, changelogs: Changelo
return true;
}
const lastEntry = changelogs[0];
- const lastEntryCurrentVersion = lastEntry.version === currentVersion;
- return lastEntryCurrentVersion;
+ const isLastEntryCurrentVersion = lastEntry.version === currentVersion;
+ return isLastEntryCurrentVersion;
}
function generateChangelogMd(changelogs: Changelog[]): string {
diff --git a/packages/order-utils/src/order_hash.ts b/packages/order-utils/src/order_hash.ts
index 1cde72a73..108344a04 100644
--- a/packages/order-utils/src/order_hash.ts
+++ b/packages/order-utils/src/order_hash.ts
@@ -17,7 +17,8 @@ const INVALID_TAKER_FORMAT = 'instance.taker is not of a type(s) string';
* We do not use BN anywhere else in the codebase.
*/
function bigNumberToBN(value: BigNumber): BN {
- return new BN(value.toString(), 10);
+ const base = 10;
+ return new BN(value.toString(), base);
}
/**
diff --git a/packages/order-utils/src/signature_utils.ts b/packages/order-utils/src/signature_utils.ts
index b511573a8..28a8e7241 100644
--- a/packages/order-utils/src/signature_utils.ts
+++ b/packages/order-utils/src/signature_utils.ts
@@ -72,6 +72,7 @@ export async function signOrderHashAsync(
// 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.
+ // tslint:disable-next-line:custom-no-magic-numbers
const validVParamValues = [27, 28];
const ecSignatureVRS = parseSignatureHexAsVRS(signature);
if (_.includes(validVParamValues, ecSignatureVRS.v)) {
@@ -95,11 +96,19 @@ export async function signOrderHashAsync(
function parseSignatureHexAsVRS(signatureHex: string): ECSignature {
const signatureBuffer = ethUtil.toBuffer(signatureHex);
let v = signatureBuffer[0];
- if (v < 27) {
- v += 27;
+ // HACK: Sometimes v is returned as [0, 1] and sometimes as [27, 28]
+ // If it is returned as [0, 1], add 27 to both so it becomes [27, 28]
+ const lowestValidV = 27;
+ const isProperlyFormattedV = v < lowestValidV;
+ if (!isProperlyFormattedV) {
+ v += lowestValidV;
}
- const r = signatureBuffer.slice(1, 33);
- const s = signatureBuffer.slice(33, 65);
+ // signatureBuffer contains vrs
+ const vEndIndex = 1;
+ const rsIndex = 33;
+ const r = signatureBuffer.slice(vEndIndex, rsIndex);
+ const sEndIndex = 65;
+ const s = signatureBuffer.slice(rsIndex, sEndIndex);
const ecSignature: ECSignature = {
v,
r: ethUtil.bufferToHex(r),
diff --git a/packages/order-utils/test/signature_utils_test.ts b/packages/order-utils/test/signature_utils_test.ts
index 4b4de9217..e24fa0ce5 100644
--- a/packages/order-utils/test/signature_utils_test.ts
+++ b/packages/order-utils/test/signature_utils_test.ts
@@ -47,12 +47,13 @@ describe('Signature utils', () => {
});
describe('#generateSalt', () => {
it('generates different salts', () => {
- const equal = generatePseudoRandomSalt().eq(generatePseudoRandomSalt());
- expect(equal).to.be.false();
+ const isEqual = generatePseudoRandomSalt().eq(generatePseudoRandomSalt());
+ expect(isEqual).to.be.false();
});
it('generates salt in range [0..2^256)', () => {
const salt = generatePseudoRandomSalt();
expect(salt.greaterThanOrEqualTo(0)).to.be.true();
+ // tslint:disable-next-line:custom-no-magic-numbers
const twoPow256 = new BigNumber(2).pow(256);
expect(salt.lessThan(twoPow256)).to.be.true();
});
@@ -67,7 +68,8 @@ describe('Signature utils', () => {
expect(isValid).to.be.false();
});
it('returns true if order hash is correct', () => {
- const isValid = isValidOrderHash('0x' + Array(65).join('0'));
+ const orderHashLength = 65;
+ const isValid = isValidOrderHash('0x' + Array(orderHashLength).join('0'));
expect(isValid).to.be.true();
});
});
@@ -111,10 +113,12 @@ describe('Signature utils', () => {
if (payload.method === 'eth_sign') {
const [address, message] = payload.params;
const signature = await web3Wrapper.signMessageAsync(address, message);
+ // tslint:disable-next-line:custom-no-magic-numbers
+ const rsvHex = `0x${signature.substr(130)}${signature.substr(2, 128)}`;
callback(null, {
id: 42,
jsonrpc: '2.0',
- result: `0x${signature.substr(130)}${signature.substr(2, 128)}`,
+ result: rsvHex,
});
} else {
callback(null, { id: 42, jsonrpc: '2.0', result: [makerAddress] });
diff --git a/packages/order-watcher/src/order_watcher/order_watcher.ts b/packages/order-watcher/src/order_watcher/order_watcher.ts
index 3c93d6293..29936a066 100644
--- a/packages/order-watcher/src/order_watcher/order_watcher.ts
+++ b/packages/order-watcher/src/order_watcher/order_watcher.ts
@@ -60,6 +60,7 @@ interface OrderStateByOrderHash {
[orderHash: string]: OrderState;
}
+// tslint:disable-next-line:custom-no-magic-numbers
const DEFAULT_CLEANUP_JOB_INTERVAL_MS = 1000 * 60 * 60; // 1h
/**
@@ -130,7 +131,8 @@ export class OrderWatcher {
assert.isValidSignature(orderHash, signedOrder.ecSignature, signedOrder.maker);
this._orderByOrderHash[orderHash] = signedOrder;
this._addToDependentOrderHashes(signedOrder, orderHash);
- const expirationUnixTimestampMs = signedOrder.expirationUnixTimestampSec.times(1000);
+ const milisecondsInASecond = 1000;
+ const expirationUnixTimestampMs = signedOrder.expirationUnixTimestampSec.times(milisecondsInASecond);
this._expirationWatcher.addOrder(orderHash, expirationUnixTimestampMs);
}
/**
diff --git a/packages/order-watcher/src/utils/utils.ts b/packages/order-watcher/src/utils/utils.ts
index af1125632..d34f6b99f 100644
--- a/packages/order-watcher/src/utils/utils.ts
+++ b/packages/order-watcher/src/utils/utils.ts
@@ -5,7 +5,8 @@ export const utils = {
return new Error(`Unexpected switch value: ${value} encountered for ${name}`);
},
getCurrentUnixTimestampSec(): BigNumber {
- return new BigNumber(Date.now() / 1000).round();
+ const milisecondsInASecond = 1000;
+ return new BigNumber(Date.now() / milisecondsInASecond).round();
},
getCurrentUnixTimestampMs(): BigNumber {
return new BigNumber(Date.now());
diff --git a/packages/order-watcher/test/expiration_watcher_test.ts b/packages/order-watcher/test/expiration_watcher_test.ts
index 8b006f58a..ef15bf006 100644
--- a/packages/order-watcher/test/expiration_watcher_test.ts
+++ b/packages/order-watcher/test/expiration_watcher_test.ts
@@ -22,6 +22,7 @@ import { provider, web3Wrapper } from './utils/web3_wrapper';
chaiSetup.configure();
const expect = chai.expect;
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
+const MILISECONDS_IN_SECOND = 1000;
describe('ExpirationWatcher', () => {
let contractWrappers: ContractWrappers;
@@ -84,13 +85,13 @@ describe('ExpirationWatcher', () => {
expirationUnixTimestampSec,
);
const orderHash = getOrderHashHex(signedOrder);
- expirationWatcher.addOrder(orderHash, signedOrder.expirationUnixTimestampSec.times(1000));
+ expirationWatcher.addOrder(orderHash, signedOrder.expirationUnixTimestampSec.times(MILISECONDS_IN_SECOND));
const callbackAsync = callbackErrorReporter.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);
+ timer.tick(orderLifetimeSec * MILISECONDS_IN_SECOND);
})().catch(done);
});
it("doesn't emit events before order expires", (done: DoneCallback) => {
@@ -106,13 +107,13 @@ describe('ExpirationWatcher', () => {
expirationUnixTimestampSec,
);
const orderHash = getOrderHashHex(signedOrder);
- expirationWatcher.addOrder(orderHash, signedOrder.expirationUnixTimestampSec.times(1000));
+ expirationWatcher.addOrder(orderHash, signedOrder.expirationUnixTimestampSec.times(MILISECONDS_IN_SECOND));
const callbackAsync = callbackErrorReporter.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);
+ timer.tick(notEnoughTime * MILISECONDS_IN_SECOND);
done();
})().catch(done);
});
@@ -140,8 +141,14 @@ describe('ExpirationWatcher', () => {
);
const orderHash1 = getOrderHashHex(signedOrder1);
const orderHash2 = getOrderHashHex(signedOrder2);
- expirationWatcher.addOrder(orderHash2, signedOrder2.expirationUnixTimestampSec.times(1000));
- expirationWatcher.addOrder(orderHash1, signedOrder1.expirationUnixTimestampSec.times(1000));
+ expirationWatcher.addOrder(
+ orderHash2,
+ signedOrder2.expirationUnixTimestampSec.times(MILISECONDS_IN_SECOND),
+ );
+ expirationWatcher.addOrder(
+ orderHash1,
+ signedOrder1.expirationUnixTimestampSec.times(MILISECONDS_IN_SECOND),
+ );
const expirationOrder = [orderHash1, orderHash2];
const expectToBeCalledOnce = false;
const callbackAsync = callbackErrorReporter.reportNoErrorCallbackErrors(done, expectToBeCalledOnce)(
@@ -154,7 +161,7 @@ describe('ExpirationWatcher', () => {
},
);
expirationWatcher.subscribe(callbackAsync);
- timer.tick(order2Lifetime * 1000);
+ timer.tick(order2Lifetime * MILISECONDS_IN_SECOND);
})().catch(done);
});
it('emits events in correct order when expirations are equal', (done: DoneCallback) => {
@@ -181,8 +188,14 @@ describe('ExpirationWatcher', () => {
);
const orderHash1 = getOrderHashHex(signedOrder1);
const orderHash2 = getOrderHashHex(signedOrder2);
- expirationWatcher.addOrder(orderHash1, signedOrder1.expirationUnixTimestampSec.times(1000));
- expirationWatcher.addOrder(orderHash2, signedOrder2.expirationUnixTimestampSec.times(1000));
+ expirationWatcher.addOrder(
+ orderHash1,
+ signedOrder1.expirationUnixTimestampSec.times(MILISECONDS_IN_SECOND),
+ );
+ expirationWatcher.addOrder(
+ orderHash2,
+ signedOrder2.expirationUnixTimestampSec.times(MILISECONDS_IN_SECOND),
+ );
const expirationOrder = orderHash1 < orderHash2 ? [orderHash1, orderHash2] : [orderHash2, orderHash1];
const expectToBeCalledOnce = false;
const callbackAsync = callbackErrorReporter.reportNoErrorCallbackErrors(done, expectToBeCalledOnce)(
@@ -195,7 +208,7 @@ describe('ExpirationWatcher', () => {
},
);
expirationWatcher.subscribe(callbackAsync);
- timer.tick(order2Lifetime * 1000);
+ timer.tick(order2Lifetime * MILISECONDS_IN_SECOND);
})().catch(done);
});
});
diff --git a/packages/order-watcher/test/global_hooks.ts b/packages/order-watcher/test/global_hooks.ts
index 03eab0e13..d4d033dd4 100644
--- a/packages/order-watcher/test/global_hooks.ts
+++ b/packages/order-watcher/test/global_hooks.ts
@@ -9,7 +9,8 @@ import { provider } from './utils/web3_wrapper';
before('migrate contracts', async function(): Promise<void> {
// HACK: Since the migrations take longer then our global mocha timeout limit
// we manually increase it for this before hook.
- this.timeout(20000);
+ const mochaTestTimeoutMs = 20000;
+ this.timeout(mochaTestTimeoutMs);
const txDefaults = {
gas: devConstants.GAS_ESTIMATE,
from: devConstants.TESTRPC_FIRST_ADDRESS,
diff --git a/packages/order-watcher/test/order_watcher_test.ts b/packages/order-watcher/test/order_watcher_test.ts
index dc8e544b1..0d33e7ea2 100644
--- a/packages/order-watcher/test/order_watcher_test.ts
+++ b/packages/order-watcher/test/order_watcher_test.ts
@@ -269,8 +269,8 @@ describe('OrderWatcher', () => {
});
it('should trigger the callback when orders backing ZRX allowance changes', (done: DoneCallback) => {
(async () => {
- const makerFee = Web3Wrapper.toBaseUnitAmount(new BigNumber(2), 18);
- const takerFee = Web3Wrapper.toBaseUnitAmount(new BigNumber(0), 18);
+ const makerFee = Web3Wrapper.toBaseUnitAmount(new BigNumber(2), decimals);
+ const takerFee = Web3Wrapper.toBaseUnitAmount(new BigNumber(0), decimals);
signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
makerToken.address,
takerToken.address,
diff --git a/packages/react-docs/src/docs_info.ts b/packages/react-docs/src/docs_info.ts
index e9c84b7c9..6f4f39f00 100644
--- a/packages/react-docs/src/docs_info.ts
+++ b/packages/react-docs/src/docs_info.ts
@@ -64,8 +64,8 @@ export class DocsInfo {
finalMenu.contracts = _.filter(finalMenu.contracts, (contractName: string) => {
const versionIntroducedIfExists = this._docsInfo.menuSubsectionToVersionWhenIntroduced[contractName];
if (!_.isUndefined(versionIntroducedIfExists)) {
- const existsInSelectedVersion = compareVersions(selectedVersion, versionIntroducedIfExists) >= 0;
- return existsInSelectedVersion;
+ const doesExistInSelectedVersion = compareVersions(selectedVersion, versionIntroducedIfExists) >= 0;
+ return doesExistInSelectedVersion;
} else {
return true;
}
diff --git a/packages/react-docs/tslint.json b/packages/react-docs/tslint.json
index ee918e360..c78434416 100644
--- a/packages/react-docs/tslint.json
+++ b/packages/react-docs/tslint.json
@@ -3,6 +3,7 @@
"rules": {
"no-object-literal-type-assertion": false,
"completed-docs": false,
- "prefer-function-over-method": false
+ "prefer-function-over-method": false,
+ "custom-no-magic-numbers": false
}
}
diff --git a/packages/react-shared/tslint.json b/packages/react-shared/tslint.json
index ee918e360..c78434416 100644
--- a/packages/react-shared/tslint.json
+++ b/packages/react-shared/tslint.json
@@ -3,6 +3,7 @@
"rules": {
"no-object-literal-type-assertion": false,
"completed-docs": false,
- "prefer-function-over-method": false
+ "prefer-function-over-method": false,
+ "custom-no-magic-numbers": false
}
}
diff --git a/packages/sol-compiler/src/compiler.ts b/packages/sol-compiler/src/compiler.ts
index efb30091b..c17616246 100644
--- a/packages/sol-compiler/src/compiler.ts
+++ b/packages/sol-compiler/src/compiler.ts
@@ -152,7 +152,8 @@ export class Compiler {
logUtils.log(`Downloading ${fullSolcVersion}...`);
const url = `${constants.BASE_COMPILER_URL}${fullSolcVersion}`;
const response = await fetch(url);
- if (response.status !== 200) {
+ const SUCCESS_STATUS = 200;
+ if (response.status !== SUCCESS_STATUS) {
throw new Error(`Failed to load ${fullSolcVersion}`);
}
solcjs = await response.text();
diff --git a/packages/sol-compiler/test/compiler_test.ts b/packages/sol-compiler/test/compiler_test.ts
index dc8eb1c4e..991965caa 100644
--- a/packages/sol-compiler/test/compiler_test.ts
+++ b/packages/sol-compiler/test/compiler_test.ts
@@ -39,8 +39,13 @@ describe('#Compiler', function(): void {
const exchangeArtifactString = await fsWrapper.readFileAsync(exchangeArtifactPath, opts);
const exchangeArtifact: ContractArtifact = JSON.parse(exchangeArtifactString);
// The last 43 bytes of the binaries are metadata which may not be equivalent
- const unlinkedBinaryWithoutMetadata = exchangeArtifact.compilerOutput.evm.bytecode.object.slice(2, -86);
- const exchangeBinaryWithoutMetadata = exchange_binary.slice(0, -86);
+ const metadataByteLength = 43;
+ const metadataHexLength = metadataByteLength * 2;
+ const unlinkedBinaryWithoutMetadata = exchangeArtifact.compilerOutput.evm.bytecode.object.slice(
+ 2,
+ -metadataHexLength,
+ );
+ const exchangeBinaryWithoutMetadata = exchange_binary.slice(0, -metadataHexLength);
expect(unlinkedBinaryWithoutMetadata).to.equal(exchangeBinaryWithoutMetadata);
});
});
diff --git a/packages/sol-cov/test/collect_coverage_entries_test.ts b/packages/sol-cov/test/collect_coverage_entries_test.ts
index 82012edfa..a03be19cd 100644
--- a/packages/sol-cov/test/collect_coverage_entries_test.ts
+++ b/packages/sol-cov/test/collect_coverage_entries_test.ts
@@ -40,12 +40,14 @@ describe('Collect coverage entries', () => {
const coverageEntries = collectCoverageEntries(simpleStorageContract);
const fnIds = _.keys(coverageEntries.fnMap);
expect(coverageEntries.fnMap[fnIds[0]].name).to.be.equal('set');
+ // tslint:disable-next-line:custom-no-magic-numbers
expect(coverageEntries.fnMap[fnIds[0]].line).to.be.equal(5);
const setFunction = `function set(uint x) {
storedData = x;
}`;
expect(getRange(simpleStorageContract, coverageEntries.fnMap[fnIds[0]].loc)).to.be.equal(setFunction);
expect(coverageEntries.fnMap[fnIds[1]].name).to.be.equal('get');
+ // tslint:disable-next-line:custom-no-magic-numbers
expect(coverageEntries.fnMap[fnIds[1]].line).to.be.equal(8);
const getFunction = `function get() constant returns (uint retVal) {
return storedData;
@@ -122,6 +124,7 @@ describe('Collect coverage entries', () => {
const branchDescriptions = _.values(coverageEntries.branchMap);
const branchLines = _.map(branchDescriptions, branchDescription => branchDescription.line);
+ // tslint:disable-next-line:custom-no-magic-numbers
expect(branchLines).to.be.deep.equal([94, 115, 119, 130, 151, 187]);
const branchTypes = _.map(branchDescriptions, branchDescription => branchDescription.type);
expect(branchTypes).to.be.deep.equal(['if', 'if', 'if', 'if', 'binary-expr', 'if']);
diff --git a/packages/sol-cov/test/instructions_test.ts b/packages/sol-cov/test/instructions_test.ts
index f66612f5f..8012674f5 100644
--- a/packages/sol-cov/test/instructions_test.ts
+++ b/packages/sol-cov/test/instructions_test.ts
@@ -12,6 +12,7 @@ const expect = chai.expect;
describe('instructions', () => {
describe('#getPcToInstructionIndexMapping', () => {
it('correctly maps pcs to instruction indexed', () => {
+ // tslint:disable-next-line:custom-no-magic-numbers
const bytecode = new Uint8Array([constants.PUSH1, 42, constants.PUSH2, 1, 2, constants.TIMESTAMP]);
const pcToInstruction = getPcToInstructionIndexMapping(bytecode);
const expectedPcToInstruction = { '0': 0, '2': 1, '5': 2 };
diff --git a/packages/sra-report/src/index.ts b/packages/sra-report/src/index.ts
index 9a203b654..3b72ad44e 100644
--- a/packages/sra-report/src/index.ts
+++ b/packages/sra-report/src/index.ts
@@ -13,7 +13,18 @@ import { postmanEnvironmentFactory } from './postman_environment_factory';
import { utils } from './utils';
const DEFAULT_NETWORK_ID = 1;
-const SUPPORTED_NETWORK_IDS = [1, 3, 4, 42];
+const networkNameToId: { [networkName: string]: number } = {
+ mainnet: 1,
+ ropsten: 3,
+ rinkeby: 4,
+ kovan: 42,
+};
+const SUPPORTED_NETWORK_IDS = [
+ networkNameToId.mainnet,
+ networkNameToId.ropsten,
+ networkNameToId.rinkeby,
+ networkNameToId.kovan,
+];
// extract command line arguments
const args = yargs
diff --git a/packages/sra-report/src/postman_environment_factory.ts b/packages/sra-report/src/postman_environment_factory.ts
index 42389aea2..e899aaa79 100644
--- a/packages/sra-report/src/postman_environment_factory.ts
+++ b/packages/sra-report/src/postman_environment_factory.ts
@@ -11,6 +11,12 @@ import { addresses as rinkebyAddresses } from './contract_addresses/rinkeby_addr
import { addresses as ropstenAddresses } from './contract_addresses/ropsten_addresses';
const ENVIRONMENT_NAME = 'SRA Report';
+const networkNameToId: { [networkName: string]: number } = {
+ mainnet: 1,
+ ropsten: 3,
+ rinkeby: 4,
+ kovan: 42,
+};
export interface EnvironmentValue {
key: string;
@@ -107,13 +113,13 @@ async function createOrderEnvironmentValuesAsync(url: string): Promise<Environme
}
function getContractAddresses(networkId: number): Addresses {
switch (networkId) {
- case 1:
+ case networkNameToId.mainnet:
return mainnetAddresses;
- case 3:
+ case networkNameToId.ropsten:
return ropstenAddresses;
- case 4:
+ case networkNameToId.rinkeby:
return rinkebyAddresses;
- case 42:
+ case networkNameToId.kovan:
return kovanAddresses;
default:
throw new Error('Unsupported network id');
diff --git a/packages/sra-report/test/test_runner.ts b/packages/sra-report/test/test_runner.ts
index 5ea3cdc4d..fe238e98a 100644
--- a/packages/sra-report/test/test_runner.ts
+++ b/packages/sra-report/test/test_runner.ts
@@ -24,6 +24,7 @@ const expect = chai.expect;
const CONTENT_TYPE_ASSERTION_NAME = 'Has Content-Type header with value application/json';
const SCHEMA_ASSERTION_NAME = 'Schema is valid';
+const SUCCESS_STATUS = 200;
const baseNewmanRunOptions = {
collection: sraReportCollectionJSON,
environment: postmanEnvironmentJSON,
@@ -46,7 +47,7 @@ export const testRunner = {
};
describe(CONTENT_TYPE_ASSERTION_NAME, () => {
it('fails when there are no headers', async () => {
- nockInterceptor.reply(200, {});
+ nockInterceptor.reply(SUCCESS_STATUS, {});
const summary = await utils.newmanRunAsync(newmanRunOptions);
const error = findAssertionErrorIfExists(
summary,
@@ -61,7 +62,7 @@ export const testRunner = {
const headers = {
'Content-Type': 'text/html',
};
- nockInterceptor.reply(200, {}, headers);
+ nockInterceptor.reply(SUCCESS_STATUS, {}, headers);
const summary = await utils.newmanRunAsync(newmanRunOptions);
const error = findAssertionErrorIfExists(
summary,
@@ -76,7 +77,7 @@ export const testRunner = {
const headers = {
'Content-Type': 'charset=utf-8; application/json',
};
- nockInterceptor.reply(200, {}, headers);
+ nockInterceptor.reply(SUCCESS_STATUS, {}, headers);
const summary = await utils.newmanRunAsync(newmanRunOptions);
const error = findAssertionErrorIfExists(
summary,
@@ -100,7 +101,7 @@ export const testRunner = {
};
describe(SCHEMA_ASSERTION_NAME, () => {
it('fails when schema is invalid', async () => {
- nockInterceptor.reply(200, malformedJson);
+ nockInterceptor.reply(SUCCESS_STATUS, malformedJson);
const summary = await utils.newmanRunAsync(newmanRunOptions);
const error = findAssertionErrorIfExists(summary, postmanCollectionRequestName, SCHEMA_ASSERTION_NAME);
const errorMessage = _.get(error, 'message');
@@ -108,7 +109,7 @@ export const testRunner = {
expect(errorMessage).to.equal('expected false to be true');
});
it('passes when schema is valid', async () => {
- nockInterceptor.reply(200, correctJson);
+ nockInterceptor.reply(SUCCESS_STATUS, correctJson);
const summary = await utils.newmanRunAsync(newmanRunOptions);
const error = findAssertionErrorIfExists(summary, postmanCollectionRequestName, SCHEMA_ASSERTION_NAME);
const errorMessage = _.get(error, 'message');
diff --git a/packages/subproviders/src/subproviders/ledger.ts b/packages/subproviders/src/subproviders/ledger.ts
index 347eda55f..467299db0 100644
--- a/packages/subproviders/src/subproviders/ledger.ts
+++ b/packages/subproviders/src/subproviders/ledger.ts
@@ -113,9 +113,12 @@ export class LedgerSubprovider extends BaseWalletSubprovider {
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
+ const vIndex = 6;
+ tx.raw[vIndex] = Buffer.from([this._networkId]); // v
+ const rIndex = 7;
+ tx.raw[rIndex] = Buffer.from([]); // r
+ const sIndex = 8;
+ tx.raw[sIndex] = Buffer.from([]); // s
const txHex = tx.serialize().toString('hex');
try {
@@ -127,7 +130,8 @@ export class LedgerSubprovider extends BaseWalletSubprovider {
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);
+ const eip55Constant = 35;
+ const signedChainId = Math.floor((tx.v[0] - eip55Constant) / 2);
if (signedChainId !== this._networkId) {
await this._destroyLedgerClientAsync();
const err = new Error(LedgerSubproviderErrors.TooOldLedgerFirmware);
@@ -169,8 +173,10 @@ export class LedgerSubprovider extends BaseWalletSubprovider {
fullDerivationPath,
ethUtil.stripHexPrefix(data),
);
- const v = result.v - 27;
- let vHex = v.toString(16);
+ const lowestValidV = 27;
+ const v = result.v - lowestValidV;
+ const hexBase = 16;
+ let vHex = v.toString(hexBase);
if (vHex.length < 2) {
vHex = `0${v}`;
}
diff --git a/packages/subproviders/src/subproviders/nonce_tracker.ts b/packages/subproviders/src/subproviders/nonce_tracker.ts
index 907330111..345e5e975 100644
--- a/packages/subproviders/src/subproviders/nonce_tracker.ts
+++ b/packages/subproviders/src/subproviders/nonce_tracker.ts
@@ -93,7 +93,8 @@ export class NonceTrackerSubprovider extends Subprovider {
// Increment the nonce from the previous successfully submitted transaction
let nonce = ethUtil.bufferToInt(transaction.nonce);
nonce++;
- let nextHexNonce = nonce.toString(16);
+ const hexBase = 16;
+ let nextHexNonce = nonce.toString(hexBase);
if (nextHexNonce.length % 2) {
nextHexNonce = `0${nextHexNonce}`;
}
diff --git a/packages/subproviders/src/subproviders/subprovider.ts b/packages/subproviders/src/subproviders/subprovider.ts
index 56d2381a0..cb6dffc4a 100644
--- a/packages/subproviders/src/subproviders/subprovider.ts
+++ b/packages/subproviders/src/subproviders/subprovider.ts
@@ -13,10 +13,11 @@ export abstract class Subprovider {
// Ported from: https://github.com/MetaMask/provider-engine/blob/master/util/random-id.js
private static _getRandomId(): number {
const extraDigits = 3;
+ const baseTen = 10;
// 13 time digits
- const datePart = new Date().getTime() * Math.pow(10, extraDigits);
+ const datePart = new Date().getTime() * Math.pow(baseTen, extraDigits);
// 3 random digits
- const extraPart = Math.floor(Math.random() * Math.pow(10, extraDigits));
+ const extraPart = Math.floor(Math.random() * Math.pow(baseTen, extraDigits));
// 16 digits
return datePart + extraPart;
}
diff --git a/packages/subproviders/src/utils/wallet_utils.ts b/packages/subproviders/src/utils/wallet_utils.ts
index cd5cd9ba0..c36fdb9fc 100644
--- a/packages/subproviders/src/utils/wallet_utils.ts
+++ b/packages/subproviders/src/utils/wallet_utils.ts
@@ -30,10 +30,10 @@ class DerivedHDKeyInfoIterator implements IterableIterator<DerivedHDKeyInfo> {
baseDerivationPath,
derivationPath: fullDerivationPath,
};
- const done = this._index === this._searchLimit;
+ const isDone = this._index === this._searchLimit;
this._index++;
return {
- done,
+ done: isDone,
value: derivedKey,
};
}
diff --git a/packages/subproviders/test/integration/ledger_subprovider_test.ts b/packages/subproviders/test/integration/ledger_subprovider_test.ts
index 70fd2cfce..d3e9d0fde 100644
--- a/packages/subproviders/test/integration/ledger_subprovider_test.ts
+++ b/packages/subproviders/test/integration/ledger_subprovider_test.ts
@@ -20,6 +20,8 @@ import { reportCallbackErrors } from '../utils/report_callback_errors';
chaiSetup.configure();
const expect = chai.expect;
+const DEFAULT_NUM_ACCOUNTS = 10;
+const EXPECTED_SIGNATURE_LENGTH = 132;
async function ledgerEthereumNodeJsClientFactoryAsync(): Promise<LedgerEthereumClient> {
const ledgerConnection = await TransportNodeHid.create();
@@ -41,7 +43,7 @@ describe('LedgerSubprovider', () => {
it('returns default number of accounts', async () => {
const accounts = await ledgerSubprovider.getAccountsAsync();
expect(accounts[0]).to.not.be.an('undefined');
- expect(accounts.length).to.be.equal(10);
+ expect(accounts.length).to.be.equal(DEFAULT_NUM_ACCOUNTS);
});
it('returns the expected accounts from a ledger set up with the test mnemonic', async () => {
const accounts = await ledgerSubprovider.getAccountsAsync();
@@ -105,7 +107,7 @@ describe('LedgerSubprovider', () => {
};
const callback = reportCallbackErrors(done)((err: Error, response: JSONRPCResponsePayload) => {
expect(err).to.be.a('null');
- expect(response.result.length).to.be.equal(10);
+ expect(response.result.length).to.be.equal(DEFAULT_NUM_ACCOUNTS);
done();
});
ledgerProvider.sendAsync(payload, callback);
@@ -123,7 +125,7 @@ describe('LedgerSubprovider', () => {
};
const callback = reportCallbackErrors(done)((err: Error, response: JSONRPCResponsePayload) => {
expect(err).to.be.a('null');
- expect(response.result.length).to.be.equal(132);
+ expect(response.result.length).to.be.equal(EXPECTED_SIGNATURE_LENGTH);
expect(response.result.substr(0, 2)).to.be.equal('0x');
done();
});
@@ -143,7 +145,7 @@ describe('LedgerSubprovider', () => {
};
const callback = reportCallbackErrors(done)((err: Error, response: JSONRPCResponsePayload) => {
expect(err).to.be.a('null');
- expect(response.result.length).to.be.equal(132);
+ expect(response.result.length).to.be.equal(EXPECTED_SIGNATURE_LENGTH);
expect(response.result.substr(0, 2)).to.be.equal('0x');
done();
});
@@ -197,7 +199,8 @@ describe('LedgerSubprovider', () => {
const callback = reportCallbackErrors(done)((err: Error, response: JSONRPCResponsePayload) => {
expect(err).to.be.a('null');
const result = response.result;
- expect(result.length).to.be.equal(66);
+ const signedTxLength = 66;
+ expect(result.length).to.be.equal(signedTxLength);
expect(result.substr(0, 2)).to.be.equal('0x');
done();
});
diff --git a/packages/subproviders/test/unit/ledger_subprovider_test.ts b/packages/subproviders/test/unit/ledger_subprovider_test.ts
index 6455454cb..8571f7d11 100644
--- a/packages/subproviders/test/unit/ledger_subprovider_test.ts
+++ b/packages/subproviders/test/unit/ledger_subprovider_test.ts
@@ -21,6 +21,7 @@ import { reportCallbackErrors } from '../utils/report_callback_errors';
chaiSetup.configure();
const expect = chai.expect;
const FAKE_ADDRESS = '0xb088a3bc93f71b4de97b9de773e9647645983688';
+const DEFAULT_NUM_ACCOUNTS = 10;
describe('LedgerSubprovider', () => {
const networkId: number = 42;
@@ -73,7 +74,7 @@ describe('LedgerSubprovider', () => {
it('returns default number of accounts', async () => {
const accounts = await ledgerSubprovider.getAccountsAsync();
expect(accounts[0]).to.be.equal(FAKE_ADDRESS);
- expect(accounts.length).to.be.equal(10);
+ expect(accounts.length).to.be.equal(DEFAULT_NUM_ACCOUNTS);
});
it('returns requested number of accounts', async () => {
const numberOfAccounts = 20;
@@ -119,7 +120,7 @@ describe('LedgerSubprovider', () => {
};
const callback = reportCallbackErrors(done)((err: Error, response: JSONRPCResponsePayload) => {
expect(err).to.be.a('null');
- expect(response.result.length).to.be.equal(10);
+ expect(response.result.length).to.be.equal(DEFAULT_NUM_ACCOUNTS);
expect(response.result[0]).to.be.equal(FAKE_ADDRESS);
done();
});
@@ -176,7 +177,8 @@ describe('LedgerSubprovider', () => {
};
const callback = reportCallbackErrors(done)((err: Error, response: JSONRPCResponsePayload) => {
expect(err).to.be.a('null');
- expect(response.result.raw.length).to.be.equal(192);
+ const rawTxLength = 192;
+ expect(response.result.raw.length).to.be.equal(rawTxLength);
expect(response.result.raw.substr(0, 2)).to.be.equal('0x');
done();
});
diff --git a/packages/subproviders/test/unit/mnemonic_wallet_subprovider_test.ts b/packages/subproviders/test/unit/mnemonic_wallet_subprovider_test.ts
index 52b636ac2..90565181e 100644
--- a/packages/subproviders/test/unit/mnemonic_wallet_subprovider_test.ts
+++ b/packages/subproviders/test/unit/mnemonic_wallet_subprovider_test.ts
@@ -18,6 +18,7 @@ import { reportCallbackErrors } from '../utils/report_callback_errors';
chaiSetup.configure();
const expect = chai.expect;
+const DEFAULT_NUM_ACCOUNTS = 10;
describe('MnemonicWalletSubprovider', () => {
let subprovider: MnemonicWalletSubprovider;
@@ -33,7 +34,7 @@ describe('MnemonicWalletSubprovider', () => {
const accounts = await subprovider.getAccountsAsync();
expect(accounts[0]).to.be.equal(fixtureData.TEST_RPC_ACCOUNT_0);
expect(accounts[1]).to.be.equal(fixtureData.TEST_RPC_ACCOUNT_1);
- expect(accounts.length).to.be.equal(10);
+ expect(accounts.length).to.be.equal(DEFAULT_NUM_ACCOUNTS);
});
it('signs a personal message', async () => {
const data = ethUtils.bufferToHex(ethUtils.toBuffer(fixtureData.PERSONAL_MESSAGE_STRING));
@@ -90,7 +91,7 @@ describe('MnemonicWalletSubprovider', () => {
const callback = reportCallbackErrors(done)((err: Error, response: JSONRPCResponsePayload) => {
expect(err).to.be.a('null');
expect(response.result[0]).to.be.equal(fixtureData.TEST_RPC_ACCOUNT_0);
- expect(response.result.length).to.be.equal(10);
+ expect(response.result.length).to.be.equal(DEFAULT_NUM_ACCOUNTS);
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 f9c47f141..fdbbb332c 100644
--- a/packages/subproviders/test/unit/redundant_rpc_subprovider_test.ts
+++ b/packages/subproviders/test/unit/redundant_rpc_subprovider_test.ts
@@ -14,6 +14,7 @@ import { reportCallbackErrors } from '../utils/report_callback_errors';
const expect = chai.expect;
chaiSetup.configure();
+const DEFAULT_NUM_ACCOUNTS = 10;
describe('RedundantSubprovider', () => {
let provider: Web3ProviderEngine;
@@ -32,7 +33,7 @@ describe('RedundantSubprovider', () => {
};
const callback = reportCallbackErrors(done)((err: Error, response: JSONRPCResponsePayload) => {
expect(err).to.be.a('null');
- expect(response.result.length).to.be.equal(10);
+ expect(response.result.length).to.be.equal(DEFAULT_NUM_ACCOUNTS);
done();
});
provider.sendAsync(payload, callback);
@@ -55,7 +56,7 @@ describe('RedundantSubprovider', () => {
};
const callback = reportCallbackErrors(done)((err: Error, response: JSONRPCResponsePayload) => {
expect(err).to.be.a('null');
- expect(response.result.length).to.be.equal(10);
+ expect(response.result.length).to.be.equal(DEFAULT_NUM_ACCOUNTS);
done();
});
provider.sendAsync(payload, callback);
diff --git a/packages/testnet-faucets/src/ts/constants.ts b/packages/testnet-faucets/src/ts/constants.ts
new file mode 100644
index 000000000..c6370e3f6
--- /dev/null
+++ b/packages/testnet-faucets/src/ts/constants.ts
@@ -0,0 +1,5 @@
+export const constants = {
+ SUCCESS_STATUS: 200,
+ SERVICE_UNAVAILABLE_STATUS: 503,
+ BAD_REQUEST_STATUS: 400,
+};
diff --git a/packages/testnet-faucets/src/ts/handler.ts b/packages/testnet-faucets/src/ts/handler.ts
index 3858b5339..d5f0dc2f9 100644
--- a/packages/testnet-faucets/src/ts/handler.ts
+++ b/packages/testnet-faucets/src/ts/handler.ts
@@ -15,6 +15,7 @@ import ProviderEngine = require('web3-provider-engine');
import RpcSubprovider = require('web3-provider-engine/subproviders/rpc');
import { configs } from './configs';
+import { constants } from './constants';
import { DispatchQueue } from './dispatch_queue';
import { dispenseAssetTasks } from './dispense_asset_tasks';
import { rpcUrls } from './rpc_urls';
@@ -80,7 +81,7 @@ export class Handler {
};
});
const payload = JSON.stringify(queueInfo);
- res.status(200).send(payload);
+ res.status(constants.SUCCESS_STATUS).send(payload);
}
public dispenseEther(req: express.Request, res: express.Response): void {
this._dispenseAsset(req, res, RequestedAssetType.ETH);
@@ -120,11 +121,11 @@ export class Handler {
}
const didAddToQueue = networkConfig.dispatchQueue.add(dispenserTask);
if (!didAddToQueue) {
- res.status(503).send('QUEUE_IS_FULL');
+ res.status(constants.SERVICE_UNAVAILABLE_STATUS).send('QUEUE_IS_FULL');
return;
}
logUtils.log(`Added ${recipient} to queue: ${requestedAssetType} networkId: ${networkId}`);
- res.status(200).end();
+ res.status(constants.SUCCESS_STATUS).end();
}
private async _dispenseOrderAsync(
req: express.Request,
@@ -133,7 +134,7 @@ export class Handler {
): Promise<void> {
const networkConfig = _.get(this._networkConfigByNetworkId, req.params.networkId);
if (_.isUndefined(networkConfig)) {
- res.status(400).send('UNSUPPORTED_NETWORK_ID');
+ res.status(constants.BAD_REQUEST_STATUS).send('UNSUPPORTED_NETWORK_ID');
return;
}
const zeroEx = networkConfig.zeroEx;
@@ -173,6 +174,6 @@ export class Handler {
const signedOrderHash = ZeroEx.getOrderHashHex(signedOrder);
const payload = JSON.stringify(signedOrder);
logUtils.log(`Dispensed signed order: ${payload}`);
- res.status(200).send(payload);
+ res.status(constants.SUCCESS_STATUS).send(payload);
}
}
diff --git a/packages/testnet-faucets/src/ts/parameter_transformer.ts b/packages/testnet-faucets/src/ts/parameter_transformer.ts
index 58bf154dc..b9929a0d9 100644
--- a/packages/testnet-faucets/src/ts/parameter_transformer.ts
+++ b/packages/testnet-faucets/src/ts/parameter_transformer.ts
@@ -3,6 +3,7 @@ import { NextFunction, Request, Response } from 'express';
import * as _ from 'lodash';
import { configs } from './configs';
+import { constants } from './constants';
import { rpcUrls } from './rpc_urls';
const DEFAULT_NETWORK_ID = 42; // kovan
@@ -11,7 +12,7 @@ export const parameterTransformer = {
transform(req: Request, res: Response, next: NextFunction): void {
const recipientAddress = req.params.recipient;
if (_.isUndefined(recipientAddress) || !addressUtils.isAddress(recipientAddress)) {
- res.status(400).send('INVALID_RECIPIENT_ADDRESS');
+ res.status(constants.BAD_REQUEST_STATUS).send('INVALID_RECIPIENT_ADDRESS');
return;
}
const lowerCaseRecipientAddress = recipientAddress.toLowerCase();
@@ -19,7 +20,7 @@ export const parameterTransformer = {
const networkId = _.get(req.query, 'networkId', DEFAULT_NETWORK_ID);
const rpcUrlIfExists = _.get(rpcUrls, networkId);
if (_.isUndefined(rpcUrlIfExists)) {
- res.status(400).send('UNSUPPORTED_NETWORK_ID');
+ res.status(constants.BAD_REQUEST_STATUS).send('UNSUPPORTED_NETWORK_ID');
return;
}
req.params.networkId = networkId;
diff --git a/packages/testnet-faucets/src/ts/server.ts b/packages/testnet-faucets/src/ts/server.ts
index 198a5fdc9..55c1d55d8 100644
--- a/packages/testnet-faucets/src/ts/server.ts
+++ b/packages/testnet-faucets/src/ts/server.ts
@@ -1,6 +1,7 @@
import * as bodyParser from 'body-parser';
import * as express from 'express';
+import { constants } from './constants';
import { errorReporter } from './error_reporter';
import { Handler } from './handler';
import { parameterTransformer } from './parameter_transformer';
@@ -18,7 +19,7 @@ app.use((req, res, next) => {
const handler = new Handler();
app.get('/ping', (req: express.Request, res: express.Response) => {
- res.status(200).send('pong');
+ res.status(constants.SUCCESS_STATUS).send('pong');
});
app.get('/info', handler.getQueueInfo.bind(handler));
app.get('/ether/:recipient', parameterTransformer.transform, handler.dispenseEther.bind(handler));
@@ -28,5 +29,6 @@ app.get('/order/zrx/:recipient', parameterTransformer.transform, handler.dispens
// Log to rollbar any errors unhandled by handlers
app.use(errorReporter.errorHandler());
-const port = process.env.PORT || 3000;
+const DEFAULT_PORT = 3000;
+const port = process.env.PORT || DEFAULT_PORT;
app.listen(port);
diff --git a/packages/tslint-config/package.json b/packages/tslint-config/package.json
index 317ae4591..75cf03b05 100644
--- a/packages/tslint-config/package.json
+++ b/packages/tslint-config/package.json
@@ -45,7 +45,8 @@
"lodash": "^4.17.4",
"tslint": "5.8.0",
"tslint-eslint-rules": "^4.1.1",
- "tslint-react": "^3.2.0"
+ "tslint-react": "^3.2.0",
+ "tsutils": "^2.12.1"
},
"publishConfig": {
"access": "public"
diff --git a/packages/tslint-config/rules/booleanNamingRule.ts b/packages/tslint-config/rules/booleanNamingRule.ts
new file mode 100644
index 000000000..f673afc6a
--- /dev/null
+++ b/packages/tslint-config/rules/booleanNamingRule.ts
@@ -0,0 +1,68 @@
+import * as _ from 'lodash';
+import * as Lint from 'tslint';
+import * as ts from 'typescript';
+
+const VALID_BOOLEAN_PREFIXES = ['is', 'does', 'should', 'was', 'has', 'can', 'did', 'would'];
+
+export class Rule extends Lint.Rules.TypedRule {
+ public static FAILURE_STRING = `Boolean variable names should begin with: ${VALID_BOOLEAN_PREFIXES.join(', ')}`;
+
+ public applyWithProgram(sourceFile: ts.SourceFile, program: ts.Program): Lint.RuleFailure[] {
+ return this.applyWithFunction(sourceFile, walk, undefined, program.getTypeChecker());
+ }
+}
+
+function walk(ctx: Lint.WalkContext<void>, tc: ts.TypeChecker): void {
+ traverse(ctx.sourceFile);
+
+ function traverse(node: ts.Node): void {
+ checkNodeForViolations(ctx, node, tc);
+ return ts.forEachChild(node, traverse);
+ }
+}
+
+function checkNodeForViolations(ctx: Lint.WalkContext<void>, node: ts.Node, tc: ts.TypeChecker): void {
+ switch (node.kind) {
+ // Handle: const { timestamp } = ...
+ case ts.SyntaxKind.BindingElement: {
+ const bindingElementNode = node as ts.BindingElement;
+ if (bindingElementNode.name.kind === ts.SyntaxKind.Identifier) {
+ handleBooleanNaming(bindingElementNode, tc, ctx);
+ }
+ break;
+ }
+
+ // Handle regular assignments: const block = ...
+ case ts.SyntaxKind.VariableDeclaration:
+ const variableDeclarationNode = node as ts.VariableDeclaration;
+ if (variableDeclarationNode.name.kind === ts.SyntaxKind.Identifier) {
+ handleBooleanNaming(node as ts.VariableDeclaration, tc, ctx);
+ }
+ break;
+
+ default:
+ _.noop();
+ }
+}
+
+function handleBooleanNaming(
+ node: ts.VariableDeclaration | ts.BindingElement,
+ tc: ts.TypeChecker,
+ ctx: Lint.WalkContext<void>,
+): void {
+ const nodeName = node.name;
+ const variableName = nodeName.getText();
+ const lowercasedName = _.toLower(variableName);
+ const typeNode = tc.getTypeAtLocation(node);
+ const typeName = (typeNode as any).intrinsicName;
+ if (typeName === 'boolean') {
+ const hasProperName = !_.isUndefined(
+ _.find(VALID_BOOLEAN_PREFIXES, prefix => {
+ return _.startsWith(lowercasedName, prefix);
+ }),
+ );
+ if (!hasProperName) {
+ ctx.addFailureAtNode(node, Rule.FAILURE_STRING);
+ }
+ }
+}
diff --git a/packages/tslint-config/rules/customNoMagicNumbersRule.ts b/packages/tslint-config/rules/customNoMagicNumbersRule.ts
new file mode 100644
index 000000000..e358221eb
--- /dev/null
+++ b/packages/tslint-config/rules/customNoMagicNumbersRule.ts
@@ -0,0 +1,76 @@
+import * as Lint from 'tslint';
+import { isPrefixUnaryExpression } from 'tsutils';
+import * as ts from 'typescript';
+
+/**
+ * A modified version of the no-magic-numbers rule that allows for magic numbers
+ * when instantiating a BigNumber instance.
+ * E.g We want to be able to write:
+ * const amount = new BigNumber(5);
+ * Original source: https://github.com/palantir/tslint/blob/42b058a6baa688f8be8558b277eb056c3ff79818/src/rules/noMagicNumbersRule.ts
+ */
+export class Rule extends Lint.Rules.AbstractRule {
+ public static ALLOWED_NODES = new Set<ts.SyntaxKind>([
+ ts.SyntaxKind.ExportAssignment,
+ ts.SyntaxKind.FirstAssignment,
+ ts.SyntaxKind.LastAssignment,
+ ts.SyntaxKind.PropertyAssignment,
+ ts.SyntaxKind.ShorthandPropertyAssignment,
+ ts.SyntaxKind.VariableDeclaration,
+ ts.SyntaxKind.VariableDeclarationList,
+ ts.SyntaxKind.EnumMember,
+ ts.SyntaxKind.PropertyDeclaration,
+ ts.SyntaxKind.Parameter,
+ ]);
+
+ public static DEFAULT_ALLOWED = [-1, 0, 1];
+
+ public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
+ const allowedNumbers = this.ruleArguments.length > 0 ? this.ruleArguments : Rule.DEFAULT_ALLOWED;
+ return this.applyWithWalker(
+ new CustomNoMagicNumbersWalker(sourceFile, this.ruleName, new Set(allowedNumbers.map(String))),
+ );
+ }
+}
+
+// tslint:disable-next-line:max-classes-per-file
+class CustomNoMagicNumbersWalker extends Lint.AbstractWalker<Set<string>> {
+ public static FAILURE_STRING = "'magic numbers' are not allowed";
+ private static _isNegativeNumberLiteral(
+ node: ts.Node,
+ ): node is ts.PrefixUnaryExpression & { operand: ts.NumericLiteral } {
+ return (
+ isPrefixUnaryExpression(node) &&
+ node.operator === ts.SyntaxKind.MinusToken &&
+ node.operand.kind === ts.SyntaxKind.NumericLiteral
+ );
+ }
+ public walk(sourceFile: ts.SourceFile): void {
+ const cb = (node: ts.Node): void => {
+ if (node.kind === ts.SyntaxKind.NumericLiteral) {
+ return this.checkNumericLiteral(node, (node as ts.NumericLiteral).text);
+ }
+ if (CustomNoMagicNumbersWalker._isNegativeNumberLiteral(node)) {
+ return this.checkNumericLiteral(node, `-${(node.operand as ts.NumericLiteral).text}`);
+ }
+ return ts.forEachChild(node, cb);
+ };
+ return ts.forEachChild(sourceFile, cb);
+ }
+
+ // tslint:disable:no-non-null-assertion
+ // tslint:disable-next-line:underscore-private-and-protected
+ private checkNumericLiteral(node: ts.Node, num: string): void {
+ if (!Rule.ALLOWED_NODES.has(node.parent!.kind) && !this.options.has(num)) {
+ if (node.parent!.kind === ts.SyntaxKind.NewExpression) {
+ const className = (node.parent! as any).expression.escapedText;
+ const BIG_NUMBER_NEW_EXPRESSION = 'BigNumber';
+ if (className === BIG_NUMBER_NEW_EXPRESSION) {
+ return; // noop
+ }
+ }
+ this.addFailureAtNode(node, CustomNoMagicNumbersWalker.FAILURE_STRING);
+ }
+ }
+ // tslint:enable:no-non-null-assertion
+}
diff --git a/packages/tslint-config/tslint.json b/packages/tslint-config/tslint.json
index 1d717430d..77a1f41cc 100644
--- a/packages/tslint-config/tslint.json
+++ b/packages/tslint-config/tslint.json
@@ -5,7 +5,10 @@
"arrow-parens": [true, "ban-single-arg-parens"],
"arrow-return-shorthand": true,
"async-suffix": true,
+ "boolean-naming": true,
+ "no-switch-case-fall-through": true,
"await-promise": true,
+ "custom-no-magic-numbers": [true, 0, 1, 2, 3, -1],
"binary-expression-operand-order": true,
"callable-types": true,
"class-name": true,
diff --git a/packages/utils/src/abi_decoder.ts b/packages/utils/src/abi_decoder.ts
index d329f917a..c78bfa343 100644
--- a/packages/utils/src/abi_decoder.ts
+++ b/packages/utils/src/abi_decoder.ts
@@ -23,7 +23,8 @@ export class AbiDecoder {
formatted = formatted.slice(2);
}
- formatted = _.padStart(formatted, 40, '0');
+ const addressLength = 40;
+ formatted = _.padStart(formatted, addressLength, '0');
return `0x${formatted}`;
}
constructor(abiArrays: AbiDefinition[][]) {
@@ -45,16 +46,17 @@ export class AbiDecoder {
const dataTypes = _.map(nonIndexedInputs, input => input.type);
const decodedData = ethersInterface.events[event.name].parse(log.data);
- let failedToDecode = false;
+ let didFailToDecode = false;
_.forEach(event.inputs, (param: EventParameter, i: number) => {
// Indexed parameters are stored in topics. Non-indexed ones in decodedData
let value: BigNumber | string | number = param.indexed ? log.topics[topicsIndex++] : decodedData[i];
if (_.isUndefined(value)) {
- failedToDecode = true;
+ didFailToDecode = true;
return;
}
if (param.type === SolidityTypes.Address) {
- value = AbiDecoder._padZeros(new BigNumber(value).toString(16));
+ const baseHex = 16;
+ value = AbiDecoder._padZeros(new BigNumber(value).toString(baseHex));
} else if (param.type === SolidityTypes.Uint256 || param.type === SolidityTypes.Uint) {
value = new BigNumber(value);
} else if (param.type === SolidityTypes.Uint8) {
@@ -63,7 +65,7 @@ export class AbiDecoder {
decodedParams[param.name] = value;
});
- if (failedToDecode) {
+ if (didFailToDecode) {
return log;
} else {
return {
diff --git a/packages/utils/src/address_utils.ts b/packages/utils/src/address_utils.ts
index f94985441..e25bde249 100644
--- a/packages/utils/src/address_utils.ts
+++ b/packages/utils/src/address_utils.ts
@@ -9,11 +9,16 @@ export const addressUtils = {
const unprefixedAddress = address.replace('0x', '');
const addressHash = jsSHA3.keccak256(unprefixedAddress.toLowerCase());
- for (let i = 0; i < 40; i++) {
+ const addressLength = 40;
+ for (let i = 0; i < addressLength; i++) {
// The nth letter should be uppercase if the nth digit of casemap is 1
+ const hexBase = 16;
+ const lowercaseRange = 7;
if (
- (parseInt(addressHash[i], 16) > 7 && unprefixedAddress[i].toUpperCase() !== unprefixedAddress[i]) ||
- (parseInt(addressHash[i], 16) <= 7 && unprefixedAddress[i].toLowerCase() !== unprefixedAddress[i])
+ (parseInt(addressHash[i], hexBase) > lowercaseRange &&
+ unprefixedAddress[i].toUpperCase() !== unprefixedAddress[i]) ||
+ (parseInt(addressHash[i], hexBase) <= lowercaseRange &&
+ unprefixedAddress[i].toLowerCase() !== unprefixedAddress[i])
) {
return false;
}
diff --git a/packages/utils/src/interval_utils.ts b/packages/utils/src/interval_utils.ts
index 6984bf42d..6784d5b35 100644
--- a/packages/utils/src/interval_utils.ts
+++ b/packages/utils/src/interval_utils.ts
@@ -6,18 +6,18 @@ export const intervalUtils = {
intervalMs: number,
onError: (err: Error) => void,
): NodeJS.Timer {
- let locked = false;
+ let isLocked = false;
const intervalId = setInterval(async () => {
- if (locked) {
+ if (isLocked) {
return;
} else {
- locked = true;
+ isLocked = true;
try {
await fn();
} catch (err) {
onError(err);
}
- locked = false;
+ isLocked = false;
}
}, intervalMs);
return intervalId;
diff --git a/packages/web3-wrapper/src/web3_wrapper.ts b/packages/web3-wrapper/src/web3_wrapper.ts
index c60d5fe33..91a1af870 100644
--- a/packages/web3-wrapper/src/web3_wrapper.ts
+++ b/packages/web3-wrapper/src/web3_wrapper.ts
@@ -19,6 +19,8 @@ import * as Web3 from 'web3';
import { Web3WrapperErrors } from './types';
+const BASE_TEN = 10;
+
/**
* A wrapper around the Web3.js 0.x library that provides a consistent, clean promise-based interface.
*/
@@ -48,7 +50,7 @@ export class Web3Wrapper {
* @return The amount in units.
*/
public static toUnitAmount(amount: BigNumber, decimals: number): BigNumber {
- const aUnit = new BigNumber(10).pow(decimals);
+ const aUnit = new BigNumber(BASE_TEN).pow(decimals);
const unit = amount.div(aUnit);
return unit;
}
@@ -61,7 +63,7 @@ export class Web3Wrapper {
* @return The amount in baseUnits.
*/
public static toBaseUnitAmount(amount: BigNumber, decimals: number): BigNumber {
- const unit = new BigNumber(10).pow(decimals);
+ const unit = new BigNumber(BASE_TEN).pow(decimals);
const baseUnitAmount = amount.times(unit);
const hasDecimals = baseUnitAmount.decimalPlaces() !== 0;
if (hasDecimals) {
@@ -180,8 +182,8 @@ export class Web3Wrapper {
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;
+ const isCodeEmpty = /^0x0{0,40}$/i.test(code);
+ return !isCodeEmpty;
}
/**
* Sign a message with a specific address's private key (`eth_sign`)
@@ -336,16 +338,16 @@ export class Web3Wrapper {
pollingIntervalMs: number = 1000,
timeoutMs?: number,
): Promise<TransactionReceiptWithDecodedLogs> {
- let timeoutExceeded = false;
+ let wasTimeoutExceeded = false;
if (timeoutMs) {
- setTimeout(() => (timeoutExceeded = true), timeoutMs);
+ setTimeout(() => (wasTimeoutExceeded = true), timeoutMs);
}
const txReceiptPromise = new Promise(
(resolve: (receipt: TransactionReceiptWithDecodedLogs) => void, reject) => {
const intervalId = intervalUtils.setAsyncExcludingInterval(
async () => {
- if (timeoutExceeded) {
+ if (wasTimeoutExceeded) {
intervalUtils.clearAsyncExcludingInterval(intervalId);
return reject(Web3WrapperErrors.TransactionMiningTimeout);
}
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 10f71b430..a9b8e9589 100644
--- a/packages/website/ts/components/generate_order/new_token_form.tsx
+++ b/packages/website/ts/components/generate_order/new_token_form.tsx
@@ -157,14 +157,14 @@ export class NewTokenForm extends React.Component<NewTokenFormProps, NewTokenFor
const maxLength = 30;
const tokens = _.values(this.props.tokenByAddress);
const tokenWithNameIfExists = _.find(tokens, { name });
- const tokenWithNameExists = !_.isUndefined(tokenWithNameIfExists);
+ const doesTokenWithNameExists = !_.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) {
+ } else if (doesTokenWithNameExists) {
nameErrText = 'Token with this name already exists';
}
@@ -177,14 +177,14 @@ export class NewTokenForm extends React.Component<NewTokenFormProps, NewTokenFor
let symbolErrText = '';
const maxLength = 5;
const tokens = _.values(this.props.tokenByAddress);
- const tokenWithSymbolExists = !_.isUndefined(_.find(tokens, { symbol }));
+ const doesTokenWithSymbolExists = !_.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) {
+ } else if (doesTokenWithSymbolExists) {
symbolErrText = 'Token with symbol already exists';
}
diff --git a/packages/website/ts/components/relayer_index/relayer_index.tsx b/packages/website/ts/components/relayer_index/relayer_index.tsx
index 8da4e0e10..9ef6eaf59 100644
--- a/packages/website/ts/components/relayer_index/relayer_index.tsx
+++ b/packages/website/ts/components/relayer_index/relayer_index.tsx
@@ -60,8 +60,8 @@ export class RelayerIndex extends React.Component<RelayerIndexProps, RelayerInde
this._isUnmounted = true;
}
public render(): React.ReactNode {
- const readyToRender = _.isUndefined(this.state.error) && !_.isUndefined(this.state.relayerInfos);
- if (!readyToRender) {
+ const isReadyToRender = _.isUndefined(this.state.error) && !_.isUndefined(this.state.relayerInfos);
+ if (!isReadyToRender) {
return (
// TODO: consolidate this loading component with the one in portal
<div className="center">
diff --git a/packages/website/tslint.json b/packages/website/tslint.json
index d6a5f5031..b55ffe90f 100644
--- a/packages/website/tslint.json
+++ b/packages/website/tslint.json
@@ -4,6 +4,7 @@
"no-implicit-dependencies": false,
"no-object-literal-type-assertion": false,
"completed-docs": false,
- "prefer-function-over-method": false
+ "prefer-function-over-method": false,
+ "custom-no-magic-numbers": false
}
}