Merge pull request #10 from ethereum/libs-update

Libs updated to release v0.2.3
pull/12/head
Aniket 4 years ago committed by GitHub
commit 287fd53262
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 5634
      libs/package-lock.json
  2. 53
      libs/package.json
  3. 6145
      libs/remix-analyzer/package-lock.json
  4. 2
      libs/remix-analyzer/package.json
  5. 8
      libs/remix-analyzer/src/solidity-analyzer/modules/abstractAstView.ts
  6. 9
      libs/remix-analyzer/src/solidity-analyzer/modules/blockTimestamp.ts
  7. 6
      libs/remix-analyzer/src/solidity-analyzer/modules/checksEffectsInteraction.ts
  8. 6
      libs/remix-analyzer/src/solidity-analyzer/modules/constantFunctions.ts
  9. 5
      libs/remix-analyzer/src/solidity-analyzer/modules/deleteDynamicArrays.ts
  10. 5
      libs/remix-analyzer/src/solidity-analyzer/modules/etherTransferInLoop.ts
  11. 5
      libs/remix-analyzer/src/solidity-analyzer/modules/forLoopIteratesOverDynamicArray.ts
  12. 5
      libs/remix-analyzer/src/solidity-analyzer/modules/guardConditions.ts
  13. 4
      libs/remix-analyzer/src/solidity-analyzer/modules/inlineAssembly.ts
  14. 17
      libs/remix-analyzer/src/solidity-analyzer/modules/lowLevelCalls.ts
  15. 4
      libs/remix-analyzer/src/solidity-analyzer/modules/noReturn.ts
  16. 4
      libs/remix-analyzer/src/solidity-analyzer/modules/selfdestruct.ts
  17. 4
      libs/remix-analyzer/src/solidity-analyzer/modules/similarVariableNames.ts
  18. 26
      libs/remix-analyzer/src/solidity-analyzer/modules/staticAnalysisCommon.ts
  19. 5
      libs/remix-analyzer/src/solidity-analyzer/modules/stringBytesLength.ts
  20. 7
      libs/remix-analyzer/src/solidity-analyzer/modules/thisLocal.ts
  21. 7
      libs/remix-analyzer/src/solidity-analyzer/modules/txOrigin.ts
  22. 5
      libs/remix-analyzer/src/types.ts
  23. 36
      libs/remix-analyzer/test/analysis/staticAnalysisIntegration-test-0.5.0.ts
  24. 2
      libs/remix-analyzer/tsconfig.json
  25. 384
      libs/remix-astwalker/package-lock.json
  26. 2
      libs/remix-astwalker/package.json
  27. 2
      libs/remix-astwalker/tsconfig.json
  28. 2
      libs/remix-debug/package.json
  29. 2
      libs/remix-debug/src/debugger/VmDebugger.js
  30. 54
      libs/remix-debug/src/solidity-decoder/internalCallTree.js
  31. 16
      libs/remix-debug/test/decoder/contracts/intLocal.js
  32. 37
      libs/remix-debug/test/decoder/localsTests/int.js
  33. 50
      libs/remix-lib/src/execution/txListener.js
  34. 3
      libs/remix-lib/src/sourceMappingDecoder.js
  35. 14
      libs/remix-lib/test/resources/sourceMapping.js
  36. 17
      libs/remix-lib/test/resources/testWeb3.json~merged
  37. 12
      libs/remix-lib/test/sourceMappingDecoder.js
  38. 2
      libs/remix-simulator/package.json
  39. 2
      libs/remix-simulator/src/methods/accounts.js
  40. 3
      libs/remix-simulator/src/methods/blocks.js
  41. 3
      libs/remix-simulator/src/methods/filters.js
  42. 2
      libs/remix-simulator/src/methods/transactions.js
  43. 2
      libs/remix-simulator/src/provider.js
  44. 2
      libs/remix-solidity/tsconfig.json
  45. 2
      libs/remix-tests/tsconfig.json
  46. 1065
      libs/remix-url-resolver/package-lock.json
  47. 2
      libs/remix-url-resolver/tsconfig.json
  48. 42120
      package-lock.json

5634
libs/package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -1,27 +1,28 @@
{
"version": "0.2.2",
"devDependencies": {
"gulp": "^4.0.2",
"lerna": "^2.10.2"
},
"scripts": {
"diff": "lerna diff",
"updated": "lerna updated",
"bootstrap": "npm run build-ts-packages; lerna bootstrap",
"build-ts-packages": "lerna run --scope 'remix-analyzer' --scope 'remix-astwalker' --scope 'remix-solidity' --scope 'remix-tests' --scope 'remix-url-resolver' build",
"publish": "npm run build-ts-packages; lerna publish",
"release": "lerna bootstrap; lerna publish;",
"tag": "gulp; gulp publishTag;",
"updateChangelog": "gulp; gulp updateChangelog --prev $previousVersion;",
"remove-all-install": "npm run remove-install; npm run remove-install-analyzer; npm run remove-install-astwalker; npm run remove-install-debug; npm run remove-install-lib; npm run remove-install-simulator; npm run remove-install-tests; npm run remove-install-url-resolver; npm run remove-install-solidity;",
"remove-install": "rm package-lock.json; rm -rf node_modules",
"remove-install-analyzer": "rm remix-analyzer/package-lock.json; rm -rf remix-analyzer/node_modules; rm -rf remix-analyzer/dist",
"remove-install-astwalker": "rm remix-astwalker/package-lock.json; rm -rf remix-astwalker/node_modules; rm -rf remix-astwalker/dist",
"remove-install-debug": "rm remix-debug/package-lock.json; rm -rf remix-debug/node_modules",
"remove-install-lib": "rm remix-lib/package-lock.json; rm -rf remix-lib/node_modules",
"remove-install-simulator": "rm remix-simulator/package-lock.json; rm -rf remix-simulator/node_modules",
"remove-install-solidity": "rm remix-solidity/package-lock.json; rm -rf remix-solidity/node_modules; rm -rf remix-solidity/dist",
"remove-install-tests": "rm remix-tests/package-lock.json; rm -rf remix-tests/node_modules; rm -rf remix-tests/dist",
"remove-install-url-resolver": "rm remix-url-resolver/package-lock.json; rm -rf remix-url-resolver/node_modules; rm -rf remix-url-resolver/dist"
}
}
"version": "0.2.3",
"devDependencies": {
"gulp": "^4.0.2",
"lerna": "^2.10.2"
},
"scripts": {
"diff": "lerna diff",
"updated": "lerna updated",
"bootstrap": "lerna bootstrap; npm run build-ts-packages",
"build-ts-packages": "lerna run --scope 'remix-analyzer' --scope 'remix-astwalker' --scope 'remix-solidity' --scope 'remix-tests' --scope 'remix-url-resolver' build",
"publish": "npm run build-ts-packages; lerna publish",
"release": "lerna bootstrap; lerna publish;",
"tag": "gulp; gulp publishTag;",
"updateChangelog": "gulp; gulp updateChangelog --prev $previousVersion;",
"remove-all-install": "npm run remove-install; npm run remove-install-analyzer; npm run remove-install-astwalker; npm run remove-install-debug; npm run remove-install-lib; npm run remove-install-simulator; npm run remove-install-tests; npm run remove-install-url-resolver; npm run remove-install-solidity;",
"remove-install": "rm package-lock.json; rm -rf node_modules",
"remove-install-analyzer": "rm remix-analyzer/package-lock.json; rm -rf remix-analyzer/node_modules; rm -rf remix-analyzer/dist",
"remove-install-astwalker": "rm remix-astwalker/package-lock.json; rm -rf remix-astwalker/node_modules; rm -rf remix-astwalker/dist",
"remove-install-debug": "rm remix-debug/package-lock.json; rm -rf remix-debug/node_modules",
"remove-install-lib": "rm remix-lib/package-lock.json; rm -rf remix-lib/node_modules",
"remove-install-simulator": "rm remix-simulator/package-lock.json; rm -rf remix-simulator/node_modules",
"remove-install-solidity": "rm remix-solidity/package-lock.json; rm -rf remix-solidity/node_modules; rm -rf remix-solidity/dist",
"remove-install-tests": "rm remix-tests/package-lock.json; rm -rf remix-tests/node_modules; rm -rf remix-tests/dist",
"remove-install-url-resolver": "rm remix-url-resolver/package-lock.json; rm -rf remix-url-resolver/node_modules; rm -rf remix-url-resolver/dist"
}
}

File diff suppressed because it is too large Load Diff

@ -1,6 +1,6 @@
{
"name": "remix-analyzer",
"version": "0.5.2",
"version": "0.5.3",
"description": "Tool to perform static analysis on Solidity smart contracts",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",

@ -1,10 +1,11 @@
import { getStateVariableDeclarationsFromContractNode, getInheritsFromName, getContractName,
getFunctionOrModifierDefinitionParameterPart, getType, getDeclaredVariableName, getFunctionDefinitionReturnParameterPart } from './staticAnalysisCommon'
getFunctionOrModifierDefinitionParameterPart, getType, getDeclaredVariableName,
getFunctionDefinitionReturnParameterPart, getCompilerVersion } from './staticAnalysisCommon'
import { AstWalker } from '@remix-project/remix-astwalker'
import { FunctionDefinitionAstNode, ParameterListAstNode, ModifierDefinitionAstNode, ContractHLAst, VariableDeclarationAstNode,
FunctionHLAst, ReportObj, ReportFunction, VisitFunction, ModifierHLAst, CompilationResult } from '../../types'
type WrapFunction = ((contracts: ContractHLAst[], isSameName: boolean) => ReportObj[])
type WrapFunction = ((contracts: ContractHLAst[], isSameName: boolean, version: string) => ReportObj[])
export default class abstractAstView {
contracts: ContractHLAst[] = []
@ -104,8 +105,9 @@ export default class abstractAstView {
build_report (wrap: WrapFunction): ReportFunction {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
return (compilationResult: CompilationResult) => {
const solVersion = getCompilerVersion(compilationResult.contracts)
this.resolveStateVariablesInHierarchy(this.contracts)
return wrap(this.contracts, this.multipleContractsWithSameName)
return wrap(this.contracts, this.multipleContractsWithSameName, solVersion)
}
}

@ -1,5 +1,5 @@
import { default as category } from './categories'
import { isNowAccess, isBlockTimestampAccess } from './staticAnalysisCommon'
import { isNowAccess, isBlockTimestampAccess, getCompilerVersion } from './staticAnalysisCommon'
import { default as algorithm } from './algorithmCategories'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, IdentifierAstNode,
MemberAccessAstNode, SupportedVersion} from './../../types'
@ -22,19 +22,20 @@ export default class blockTimestamp implements AnalyzerModule {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
report (compilationResults: CompilationResult): ReportObj[] {
return this.warningNowNodes.map((item) => {
const version = getCompilerVersion(compilationResults.contracts)
return this.warningNowNodes.map((item, i) => {
return {
warning: `Use of "now": "now" does not mean current time. "now" is an alias for "block.timestamp".
"block.timestamp" can be influenced by miners to a certain degree, be careful.`,
location: item.src,
more: 'https://solidity.readthedocs.io/en/develop/units-and-global-variables.html?highlight=block.timestamp#block-and-transaction-properties'
more: `https://solidity.readthedocs.io/en/${version}/units-and-global-variables.html?highlight=block.timestamp#block-and-transaction-properties`
}
}).concat(this.warningblockTimestampNodes.map((item) => {
return {
warning: `Use of "block.timestamp": "block.timestamp" can be influenced by miners to a certain degree.
That means that a miner can "choose" the block.timestamp, to a certain degree, to change the outcome of a transaction in the mined block.`,
location: item.src,
more: 'https://solidity.readthedocs.io/en/develop/units-and-global-variables.html?highlight=block.timestamp#block-and-transaction-properties'
more: `https://solidity.readthedocs.io/en/${version}/units-and-global-variables.html?highlight=block.timestamp#block-and-transaction-properties`
}
}))
}

@ -1,6 +1,6 @@
import { default as category } from './categories'
import { isInteraction, isEffect, isLocalCallGraphRelevantNode, getFullQuallyfiedFuncDefinitionIdent,
isWriteOnStateVariable, isStorageVariableDeclaration, getFullQualifiedFunctionCallIdent } from './staticAnalysisCommon'
isWriteOnStateVariable, isStorageVariableDeclaration, getFullQualifiedFunctionCallIdent, getCompilerVersion } from './staticAnalysisCommon'
import { default as algorithm } from './algorithmCategories'
import { buildGlobalFuncCallGraph, resolveCallGraphSymbol, analyseCallGraph } from './functionCallGraph'
import AbstractAst from './abstractAstView'
@ -25,7 +25,7 @@ export default class checksEffectsInteraction implements AnalyzerModule {
report: ReportFunction = this.abstractAst.build_report(this._report.bind(this))
private _report (contracts: ContractHLAst[], multipleContractsWithSameName: boolean): ReportObj[] {
private _report (contracts: ContractHLAst[], multipleContractsWithSameName: boolean, version: string): ReportObj[] {
const warnings: ReportObj[] = []
const hasModifiers: boolean = contracts.some((item) => item.modifiers.length > 0)
const callGraph: Record<string, ContractCallGraph> = buildGlobalFuncCallGraph(contracts)
@ -51,7 +51,7 @@ export default class checksEffectsInteraction implements AnalyzerModule {
warnings.push({
warning: `Potential violation of Checks-Effects-Interaction pattern in ${funcName}: Could potentially lead to re-entrancy vulnerability. ${comments}`,
location: func.node['src'],
more: 'http://solidity.readthedocs.io/en/develop/security-considerations.html#re-entrancy'
more: `https://solidity.readthedocs.io/en/${version}/security-considerations.html#re-entrancy`
})
}
})

@ -34,7 +34,7 @@ export default class constantFunctions implements AnalyzerModule {
report: ReportFunction = this.abstractAst.build_report(this._report.bind(this))
private _report (contracts: ContractHLAst[], multipleContractsWithSameName: boolean): ReportObj[] {
private _report (contracts: ContractHLAst[], multipleContractsWithSameName: boolean, version: string): ReportObj[] {
const warnings: ReportObj[] = []
const hasModifiers: boolean = contracts.some((item) => item.modifiers.length > 0)
@ -68,13 +68,13 @@ export default class constantFunctions implements AnalyzerModule {
warnings.push({
warning: `${funcName} : Potentially should be constant/view/pure but is not. ${comments}`,
location: func.node['src'],
more: 'https://solidity.readthedocs.io/en/develop/contracts.html#view-functions'
more: `https://solidity.readthedocs.io/en/${version}/contracts.html#view-functions`
})
} else {
warnings.push({
warning: `${funcName} : Is constant but potentially should not be. ${comments}`,
location: func.node['src'],
more: 'https://solidity.readthedocs.io/en/develop/contracts.html#view-functions'
more: `https://solidity.readthedocs.io/en/${version}/contracts.html#view-functions`
})
}
}

@ -1,5 +1,5 @@
import { default as category } from './categories'
import { isDeleteOfDynamicArray } from './staticAnalysisCommon'
import { isDeleteOfDynamicArray, getCompilerVersion } from './staticAnalysisCommon'
import { default as algorithm } from './algorithmCategories'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, UnaryOperationAstNode, SupportedVersion} from './../../types'
@ -19,11 +19,12 @@ export default class deleteDynamicArrays implements AnalyzerModule {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
report (compilationResults: CompilationResult): ReportObj[] {
const version = getCompilerVersion(compilationResults.contracts)
return this.rel.map((node) => {
return {
warning: `The "delete" operation when applied to a dynamically sized array in Solidity generates code to delete each of the elements contained. If the array is large, this operation can surpass the block gas limit and raise an OOG exception. Also nested dynamically sized objects can produce the same results.`,
location: node.src,
more: 'https://solidity.readthedocs.io/en/latest/types.html#delete'
more: `https://solidity.readthedocs.io/en/${version}/types.html#delete`
}
})
}

@ -1,6 +1,6 @@
import { default as category } from './categories'
import { default as algorithm } from './algorithmCategories'
import { isLoop, isTransfer } from './staticAnalysisCommon'
import { isLoop, isTransfer, getCompilerVersion } from './staticAnalysisCommon'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, ForStatementAstNode,
WhileStatementAstNode, ExpressionStatementAstNode, SupportedVersion} from './../../types'
@ -31,11 +31,12 @@ export default class etherTransferInLoop implements AnalyzerModule {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
report (compilationResults: CompilationResult): ReportObj[] {
const version = getCompilerVersion(compilationResults.contracts)
return this.relevantNodes.map((node) => {
return {
warning: `Ether payout should not be done in a loop: Due to the block gas limit, transactions can only consume a certain amount of gas. The number of iterations in a loop can grow beyond the block gas limit which can cause the complete contract to be stalled at a certain point. If required then make sure that number of iterations are low and you trust each address involved.`,
location: node.src,
more: 'https://solidity.readthedocs.io/en/latest/security-considerations.html#gas-limit-and-loops'
more: `https://solidity.readthedocs.io/en/${version}/security-considerations.html#gas-limit-and-loops`
}
})
}

@ -1,6 +1,6 @@
import { default as category } from './categories'
import { default as algorithm } from './algorithmCategories'
import { isDynamicArrayLengthAccess } from './staticAnalysisCommon'
import { isDynamicArrayLengthAccess, getCompilerVersion } from './staticAnalysisCommon'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, ForStatementAstNode, SupportedVersion} from './../../types'
export default class forLoopIteratesOverDynamicArray implements AnalyzerModule {
@ -25,11 +25,12 @@ export default class forLoopIteratesOverDynamicArray implements AnalyzerModule {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
report (compilationResults: CompilationResult): ReportObj[] {
const version = getCompilerVersion(compilationResults.contracts)
return this.relevantNodes.map((node) => {
return {
warning: `Loops that do not have a fixed number of iterations, for example, loops that depend on storage values, have to be used carefully. Due to the block gas limit, transactions can only consume a certain amount of gas. The number of iterations in a loop can grow beyond the block gas limit which can cause the complete contract to be stalled at a certain point. \n Additionally, using unbounded loops incurs in a lot of avoidable gas costs. Carefully test how many items at maximum you can pass to such functions to make it successful.`,
location: node.src,
more: 'http://solidity.readthedocs.io/en/latest/security-considerations.html#gas-limit-and-loops'
more: `https://solidity.readthedocs.io/en/${version}/security-considerations.html#gas-limit-and-loops`
}
})
}

@ -1,5 +1,5 @@
import { default as category } from './categories'
import { isRequireCall, isAssertCall } from './staticAnalysisCommon'
import { isRequireCall, isAssertCall, getCompilerVersion } from './staticAnalysisCommon'
import { default as algorithm } from './algorithmCategories'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, FunctionCallAstNode, SupportedVersion} from './../../types'
@ -19,11 +19,12 @@ export default class guardConditions implements AnalyzerModule {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
report (compilationResults: CompilationResult): ReportObj[] {
const version = getCompilerVersion(compilationResults.contracts)
return this.guards.map((node) => {
return {
warning: `Use "assert(x)" if you never ever want x to be false, not in any circumstance (apart from a bug in your code). Use "require(x)" if x can be false, due to e.g. invalid input or a failing external component.`,
location: node.src,
more: 'http://solidity.readthedocs.io/en/develop/control-structures.html#error-handling-assert-require-revert-and-exceptions'
more: `https://solidity.readthedocs.io/en/${version}/control-structures.html#error-handling-assert-require-revert-and-exceptions`
}
})
}

@ -1,6 +1,7 @@
import { default as category } from './categories'
import { default as algorithm } from './algorithmCategories'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, InlineAssemblyAstNode, SupportedVersion} from './../../types'
import { getCompilerVersion } from './staticAnalysisCommon'
export default class inlineAssembly implements AnalyzerModule {
inlineAssNodes: InlineAssemblyAstNode[] = []
@ -18,12 +19,13 @@ export default class inlineAssembly implements AnalyzerModule {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
report (compilationResults: CompilationResult): ReportObj[] {
const version = getCompilerVersion(compilationResults.contracts)
return this.inlineAssNodes.map((node) => {
return {
warning: `The Contract uses inline assembly, this is only advised in rare cases.
Additionally static analysis modules do not parse inline Assembly, this can lead to wrong analysis results.`,
location: node.src,
more: 'http://solidity.readthedocs.io/en/develop/assembly.html'
more: `https://solidity.readthedocs.io/en/${version}/assembly.html`
}
})
}

@ -1,5 +1,5 @@
import { default as category } from './categories'
import { isLLCall, isLLDelegatecall, isLLCallcode, isLLCall04, isLLDelegatecall04, isLLSend04, isLLSend, lowLevelCallTypes } from './staticAnalysisCommon'
import { isLLCall, isLLDelegatecall, isLLCallcode, isLLCall04, isLLDelegatecall04, isLLSend04, isLLSend, lowLevelCallTypes, getCompilerVersion } from './staticAnalysisCommon'
import { default as algorithm } from './algorithmCategories'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, MemberAccessAstNode, SupportedVersion} from './../../types'
@ -38,34 +38,35 @@ export default class lowLevelCalls implements AnalyzerModule {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
report (compilationResults: CompilationResult): ReportObj[] {
return this.llcNodes.map((item) => {
let text = ''
let morehref = ''
const version = getCompilerVersion(compilationResults.contracts)
return this.llcNodes.map((item, i) => {
let text: string = ''
let morehref: string = ''
switch (item.type) {
case lowLevelCallTypes.CALL:
text = `Use of "call": should be avoided whenever possible.
It can lead to unexpected behavior if return value is not handled properly.
Please use Direct Calls via specifying the called contract's interface.`
morehref = 'http://solidity.readthedocs.io/en/develop/control-structures.html?#external-function-calls'
morehref = `https://solidity.readthedocs.io/en/${version}/control-structures.html?#external-function-calls`
break
case lowLevelCallTypes.CALLCODE:
text = `Use of "callcode": should be avoided whenever possible.
External code, that is called can change the state of the calling contract and send ether from the caller's balance.
If this is wanted behaviour, use the Solidity library feature if possible.`
morehref = 'http://solidity.readthedocs.io/en/develop/contracts.html#libraries'
morehref = `https://solidity.readthedocs.io/en/${version}/contracts.html#libraries`
break
case lowLevelCallTypes.DELEGATECALL:
text = `Use of "delegatecall": should be avoided whenever possible.
External code, that is called can change the state of the calling contract and send ether from the caller's balance.
If this is wanted behaviour, use the Solidity library feature if possible.`
morehref = 'http://solidity.readthedocs.io/en/develop/contracts.html#libraries'
morehref = `https://solidity.readthedocs.io/en/${version}/contracts.html#libraries`
break
case lowLevelCallTypes.SEND:
text = `Use of "send": "send" does not throw an exception when not successful, make sure you deal with the failure case accordingly.
Use "transfer" whenever failure of the ether transfer should rollback the whole transaction.
Note: if you "send/transfer" ether to a contract the fallback function is called, the callees fallback function is very limited due to the limited amount of gas provided by "send/transfer".
No state changes are possible but the callee can log the event or revert the transfer. "send/transfer" is syntactic sugar for a "call" to the fallback function with 2300 gas and a specified ether value.`
morehref = 'http://solidity.readthedocs.io/en/develop/security-considerations.html#sending-and-receiving-ether'
morehref = `https://solidity.readthedocs.io/en/${version}/security-considerations.html#sending-and-receiving-ether`
break
}
return { warning: text, more: morehref, location: item.node.src }

@ -21,9 +21,7 @@ export default class noReturn implements AnalyzerModule {
)
report: ReportFunction = this.abstractAst.build_report(this._report.bind(this))
// eslint-disable-next-line @typescript-eslint/no-unused-vars
private _report (contracts: ContractHLAst[], multipleContractsWithSameName: boolean): ReportObj[] {
private _report (contracts: ContractHLAst[], multipleContractsWithSameName: boolean, version: string): ReportObj[] {
const warnings: ReportObj[] = []
contracts.forEach((contract: ContractHLAst) => {

@ -21,7 +21,7 @@ export default class selfdestruct implements AnalyzerModule {
report: ReportFunction = this.abstractAst.build_report(this._report.bind(this))
// eslint-disable-next-line @typescript-eslint/no-unused-vars
private _report (contracts: ContractHLAst[], multipleContractsWithSameName: boolean): ReportObj[] {
private _report (contracts: ContractHLAst[], multipleContractsWithSameName: boolean, version: string): ReportObj[] {
const warnings: ReportObj[] = []
contracts.forEach((contract) => {
@ -40,7 +40,7 @@ export default class selfdestruct implements AnalyzerModule {
warnings.push({
warning: `Use of selfdestruct: No code after selfdestruct is executed. Selfdestruct is a terminal.`,
location: node.src,
more: 'https://solidity.readthedocs.io/en/develop/introduction-to-smart-contracts.html#deactivate-and-self-destruct'
more: `https://solidity.readthedocs.io/en/${version}/introduction-to-smart-contracts.html#deactivate-and-self-destruct`
})
hasSelf = false
}

@ -28,7 +28,7 @@ export default class similarVariableNames implements AnalyzerModule {
report: ReportFunction = this.abstractAst.build_report(this._report.bind(this))
private _report (contracts: ContractHLAst[], multipleContractsWithSameName: boolean): ReportObj[] {
private _report (contracts: ContractHLAst[], multipleContractsWithSameName: boolean, version: string): ReportObj[] {
const warnings: ReportObj[] = []
const hasModifiers: boolean = contracts.some((item) => item.modifiers.length > 0)
@ -47,7 +47,7 @@ export default class similarVariableNames implements AnalyzerModule {
const vars: string[] = this.getFunctionVariables(contract, func).map(getDeclaredVariableName)
this.findSimilarVarNames(vars).map((sim) => {
warnings.push({
warning: `${funcName} : Variables have very similar names ${sim.var1} and ${sim.var2}. ${hasModifiersComments} ${multipleContractsWithSameNameComments}`,
warning: `${funcName} : Variables have very similar names "${sim.var1}" and "${sim.var2}". ${hasModifiersComments} ${multipleContractsWithSameNameComments}`,
location: func.node['src']
})
})

@ -3,7 +3,7 @@
import { FunctionDefinitionAstNode, ModifierDefinitionAstNode, ParameterListAstNode, ForStatementAstNode,
WhileStatementAstNode, VariableDeclarationAstNode, ContractDefinitionAstNode, InheritanceSpecifierAstNode,
MemberAccessAstNode, BinaryOperationAstNode, FunctionCallAstNode, ExpressionStatementAstNode, UnaryOperationAstNode,
IdentifierAstNode, IndexAccessAstNode, BlockAstNode, AssignmentAstNode, InlineAssemblyAstNode, IfStatementAstNode, CompiledContractObj, ABIParameter } from "../../types"
IdentifierAstNode, IndexAccessAstNode, BlockAstNode, AssignmentAstNode, InlineAssemblyAstNode, IfStatementAstNode, CompiledContractObj, ABIParameter, CompiledContract } from "../../types"
import { util } from '@remix-project/remix-lib'
type SpecialObjDetail = {
@ -1131,6 +1131,29 @@ function getTypeStringFromComponents(components: ABIParameter[]) {
return typeString
}
/**
* Get compiler version from compiler contract object
* This is used to redirect the user to specific version of Solidity documentation
* @param contractFiles compiled contract object
*/
function getCompilerVersion(contractFiles: CompiledContractObj): string {
// Solidity documentation is not available for these versions
const noDocVersions = ['0.4.26', '0.5.16', '0.5.17']
let version = 'develop'
const fileNames: string[] = Object.keys(contractFiles)
const contracts = contractFiles[fileNames[0]]
const contractNames: string[] = Object.keys(contracts)
const contract: CompiledContract = contracts[contractNames[0]]
const metadata = JSON.parse(contract.metadata)
const compilerVersion: string = metadata.compiler.version
if(!compilerVersion.includes('nightly')) {
const solVersion = compilerVersion.split('+commit')[0]
if(!noDocVersions.includes(solVersion))
version = 'v' + solVersion
}
return version
}
const helpers = {
expressionTypeDescription,
nodeType,
@ -1167,6 +1190,7 @@ export {
getFunctionDefinitionReturnParameterPart,
getUnAssignedTopLevelBinOps,
getMethodParamsSplittedTypeDesc,
getCompilerVersion,
// #################### Complex Node Identification
isDeleteOfDynamicArray,

@ -1,6 +1,6 @@
import { default as category } from './categories'
import { default as algorithm } from './algorithmCategories'
import { isStringToBytesConversion, isBytesLengthCheck } from './staticAnalysisCommon'
import { isStringToBytesConversion, isBytesLengthCheck, getCompilerVersion } from './staticAnalysisCommon'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, MemberAccessAstNode, FunctionCallAstNode, SupportedVersion} from './../../types'
export default class stringBytesLength implements AnalyzerModule {
@ -22,11 +22,12 @@ export default class stringBytesLength implements AnalyzerModule {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
report (compilationResults: CompilationResult): ReportObj[] {
const version = getCompilerVersion(compilationResults.contracts)
if (this.stringToBytesConversions.length > 0 && this.bytesLengthChecks.length > 0) {
return [{
warning: `"bytes" and "string" lengths are not the same since strings are assumed to be UTF-8 encoded (according to the ABI defintion) therefore one character is not nessesarily encoded in one byte of data.`,
location: this.bytesLengthChecks[0].src,
more: 'https://solidity.readthedocs.io/en/develop/abi-spec.html#argument-encoding'
more: `https://solidity.readthedocs.io/en/${version}/abi-spec.html#argument-encoding`
}]
} else {
return []

@ -1,5 +1,5 @@
import { default as category } from './categories'
import { isThisLocalCall } from './staticAnalysisCommon'
import { isThisLocalCall, getCompilerVersion } from './staticAnalysisCommon'
import { default as algorithm } from './algorithmCategories'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, MemberAccessAstNode, SupportedVersion} from './../../types'
@ -19,11 +19,12 @@ export default class thisLocal implements AnalyzerModule {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
report (compilationResults: CompilationResult): ReportObj[] {
return this.warningNodes.map(function (item) {
const version = getCompilerVersion(compilationResults.contracts)
return this.warningNodes.map(function (item, i) {
return {
warning: `Use of "this" for local functions: Never use "this" to call functions in the same contract, it only consumes more gas than normal local calls.`,
location: item.src,
more: 'http://solidity.readthedocs.io/en/develop/control-structures.html#external-function-calls'
more: `https://solidity.readthedocs.io/en/${version}/control-structures.html#external-function-calls`
}
})
}

@ -1,6 +1,6 @@
import { default as category } from './categories'
import { default as algorithm } from './algorithmCategories'
import { isTxOriginAccess } from './staticAnalysisCommon'
import { isTxOriginAccess, getCompilerVersion } from './staticAnalysisCommon'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, MemberAccessAstNode, SupportedVersion} from './../../types'
export default class txOrigin implements AnalyzerModule {
@ -20,12 +20,13 @@ export default class txOrigin implements AnalyzerModule {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
report (compilationResults: CompilationResult): ReportObj[] {
return this.txOriginNodes.map((item) => {
const version = getCompilerVersion(compilationResults.contracts)
return this.txOriginNodes.map((item, i) => {
return {
warning: `Use of tx.origin: "tx.origin" is useful only in very exceptional cases.
If you use it for authentication, you usually want to replace it by "msg.sender", because otherwise any contract you call can act on your behalf.`,
location: item.src,
more: 'https://solidity.readthedocs.io/en/develop/security-considerations.html#tx-origin'
more: `https://solidity.readthedocs.io/en/${version}/security-considerations.html#tx-origin`
}
})
}

@ -8,6 +8,11 @@ export interface AnalyzerModule {
report: ReportFunction
}
// This version signifies the module support for Solidity version.
// start will be minimum at 0.4.12 as since that version Solidity exports latest AST
// end should be a version in which analysis feature got deprecated.
// This will be helpful in version based analysis in future.
export interface SupportedVersion {
start: string
end?: string

@ -416,6 +416,42 @@ test('Integration test blockBlockhash module', function (t: test.Test) {
})
})
test('Integration test noReturn module', function (t: test.Test) {
t.plan(testFiles.length)
const module = modules.noReturn
const lengthCheck = {
'KingOfTheEtherThrone.sol': 0,
'assembly.sol': 1,
'ballot.sol': 0,
'ballot_reentrant.sol': 0,
'ballot_withoutWarnings.sol': 0,
'cross_contract.sol': 0,
'inheritance.sol': 0,
'modifier1.sol': 0,
'modifier2.sol': 0,
'notReentrant.sol': 0,
'structReentrant.sol': 0,
'thisLocal.sol': 1,
'globals.sol': 0,
'library.sol': 0,
'transfer.sol': 0,
'ctor.sol': 0,
'forgottenReturn.sol': 1,
'selfdestruct.sol': 0,
'deleteDynamicArray.sol': 0,
'deleteFromDynamicArray.sol': 0,
'blockLevelCompare.sol': 0,
'intDivisionTruncate.sol': 0,
'ERC20.sol': 0,
'stringBytesLength.sol': 0,
'etherTransferInLoop.sol': 0,
'forLoopIteratesOverDynamicArray.sol': 0
}
runModuleOnFiles(module, t, (file: string, report: AnalysisReportObj[]) => {
t.equal(report.length, lengthCheck[file], `${file} has right amount of noReturn warnings`)
})
})
test('Integration test selfdestruct module', function (t: test.Test) {
t.plan(testFiles.length)
const module: any = modules.selfdestruct

@ -7,4 +7,4 @@
"outDir": "./dist",
},
"include": ["**/*.ts"]
}
}

@ -3,110 +3,115 @@
"lockfileVersion": 1,
"dependencies": {
"@babel/code-frame": {
"version": "7.5.5",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz",
"integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==",
"version": "7.10.3",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.3.tgz",
"integrity": "sha512-fDx9eNW0qz0WkUeqL6tXEXzVlPh6Y5aCDEZesl0xBGA8ndRukX91Uk44ZqnkECp01NAZUdCAl+aiQNGi0k88Eg==",
"requires": {
"@babel/highlight": "^7.0.0"
"@babel/highlight": "^7.10.3"
}
},
"@babel/generator": {
"version": "7.7.0",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.0.tgz",
"integrity": "sha512-1wdJ6UxHyL1XoJQ119JmvuRX27LRih7iYStMPZOWAjQqeAabFg3dYXKMpgihma+to+0ADsTVVt6oRyUxWZw6Mw==",
"version": "7.10.3",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.3.tgz",
"integrity": "sha512-drt8MUHbEqRzNR0xnF8nMehbY11b1SDkRw03PSNH/3Rb2Z35oxkddVSi3rcaak0YJQ86PCuE7Qx1jSFhbLNBMA==",
"requires": {
"@babel/types": "^7.7.0",
"@babel/types": "^7.10.3",
"jsesc": "^2.5.1",
"lodash": "^4.17.13",
"source-map": "^0.5.0"
}
},
"@babel/helper-function-name": {
"version": "7.7.0",
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.0.tgz",
"integrity": "sha512-tDsJgMUAP00Ugv8O2aGEua5I2apkaQO7lBGUq1ocwN3G23JE5Dcq0uh3GvFTChPa4b40AWiAsLvCZOA2rdnQ7Q==",
"version": "7.10.3",
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.3.tgz",
"integrity": "sha512-FvSj2aiOd8zbeqijjgqdMDSyxsGHaMt5Tr0XjQsGKHD3/1FP3wksjnLAWzxw7lvXiej8W1Jt47SKTZ6upQNiRw==",
"requires": {
"@babel/helper-get-function-arity": "^7.7.0",
"@babel/template": "^7.7.0",
"@babel/types": "^7.7.0"
"@babel/helper-get-function-arity": "^7.10.3",
"@babel/template": "^7.10.3",
"@babel/types": "^7.10.3"
}
},
"@babel/helper-get-function-arity": {
"version": "7.7.0",
"resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.0.tgz",
"integrity": "sha512-tLdojOTz4vWcEnHWHCuPN5P85JLZWbm5Fx5ZsMEMPhF3Uoe3O7awrbM2nQ04bDOUToH/2tH/ezKEOR8zEYzqyw==",
"version": "7.10.3",
"resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.3.tgz",
"integrity": "sha512-iUD/gFsR+M6uiy69JA6fzM5seno8oE85IYZdbVVEuQaZlEzMO2MXblh+KSPJgsZAUx0EEbWXU0yJaW7C9CdAVg==",
"requires": {
"@babel/types": "^7.7.0"
"@babel/types": "^7.10.3"
}
},
"@babel/helper-split-export-declaration": {
"version": "7.7.0",
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.0.tgz",
"integrity": "sha512-HgYSI8rH08neWlAH3CcdkFg9qX9YsZysZI5GD8LjhQib/mM0jGOZOVkoUiiV2Hu978fRtjtsGsW6w0pKHUWtqA==",
"version": "7.10.1",
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.1.tgz",
"integrity": "sha512-UQ1LVBPrYdbchNhLwj6fetj46BcFwfS4NllJo/1aJsT+1dLTEnXJL0qHqtY7gPzF8S2fXBJamf1biAXV3X077g==",
"requires": {
"@babel/types": "^7.7.0"
"@babel/types": "^7.10.1"
}
},
"@babel/helper-validator-identifier": {
"version": "7.10.3",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.3.tgz",
"integrity": "sha512-bU8JvtlYpJSBPuj1VUmKpFGaDZuLxASky3LhaKj3bmpSTY6VWooSM8msk+Z0CZoErFye2tlABF6yDkT3FOPAXw=="
},
"@babel/highlight": {
"version": "7.5.0",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz",
"integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==",
"version": "7.10.3",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.3.tgz",
"integrity": "sha512-Ih9B/u7AtgEnySE2L2F0Xm0GaM729XqqLfHkalTsbjXGyqmf/6M0Cu0WpvqueUlW+xk88BHw9Nkpj49naU+vWw==",
"requires": {
"@babel/helper-validator-identifier": "^7.10.3",
"chalk": "^2.0.0",
"esutils": "^2.0.2",
"js-tokens": "^4.0.0"
}
},
"@babel/parser": {
"version": "7.7.0",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.0.tgz",
"integrity": "sha512-GqL+Z0d7B7ADlQBMXlJgvXEbtt5qlqd1YQ5fr12hTSfh7O/vgrEIvJxU2e7aSVrEUn75zTZ6Nd0s8tthrlZnrQ=="
"version": "7.10.3",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.3.tgz",
"integrity": "sha512-oJtNJCMFdIMwXGmx+KxuaD7i3b8uS7TTFYW/FNG2BT8m+fmGHoiPYoH0Pe3gya07WuFmM5FCDIr1x0irkD/hyA=="
},
"@babel/template": {
"version": "7.7.0",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.0.tgz",
"integrity": "sha512-OKcwSYOW1mhWbnTBgQY5lvg1Fxg+VyfQGjcBduZFljfc044J5iDlnDSfhQ867O17XHiSCxYHUxHg2b7ryitbUQ==",
"version": "7.10.3",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.3.tgz",
"integrity": "sha512-5BjI4gdtD+9fHZUsaxPHPNpwa+xRkDO7c7JbhYn2afvrkDu5SfAAbi9AIMXw2xEhO/BR35TqiW97IqNvCo/GqA==",
"requires": {
"@babel/code-frame": "^7.0.0",
"@babel/parser": "^7.7.0",
"@babel/types": "^7.7.0"
"@babel/code-frame": "^7.10.3",
"@babel/parser": "^7.10.3",
"@babel/types": "^7.10.3"
}
},
"@babel/traverse": {
"version": "7.7.0",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.7.0.tgz",
"integrity": "sha512-ea/3wRZc//e/uwCpuBX2itrhI0U9l7+FsrKWyKGNyvWbuMcCG7ATKY2VI4wlg2b2TA39HHwIxnvmXvtiKsyn7w==",
"version": "7.10.3",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.3.tgz",
"integrity": "sha512-qO6623eBFhuPm0TmmrUFMT1FulCmsSeJuVGhiLodk2raUDFhhTECLd9E9jC4LBIWziqt4wgF6KuXE4d+Jz9yug==",
"requires": {
"@babel/code-frame": "^7.5.5",
"@babel/generator": "^7.7.0",
"@babel/helper-function-name": "^7.7.0",
"@babel/helper-split-export-declaration": "^7.7.0",
"@babel/parser": "^7.7.0",
"@babel/types": "^7.7.0",
"@babel/code-frame": "^7.10.3",
"@babel/generator": "^7.10.3",
"@babel/helper-function-name": "^7.10.3",
"@babel/helper-split-export-declaration": "^7.10.1",
"@babel/parser": "^7.10.3",
"@babel/types": "^7.10.3",
"debug": "^4.1.0",
"globals": "^11.1.0",
"lodash": "^4.17.13"
}
},
"@babel/types": {
"version": "7.7.1",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.1.tgz",
"integrity": "sha512-kN/XdANDab9x1z5gcjDc9ePpxexkt+1EQ2MQUiM4XnMvQfvp87/+6kY4Ko2maLXH+tei/DgJ/ybFITeqqRwDiA==",
"version": "7.10.3",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.3.tgz",
"integrity": "sha512-nZxaJhBXBQ8HVoIcGsf9qWep3Oh3jCENK54V4mRF7qaJabVsAYdbTtmSD8WmAp1R6ytPiu5apMwSXyxB1WlaBA==",
"requires": {
"esutils": "^2.0.2",
"@babel/helper-validator-identifier": "^7.10.3",
"lodash": "^4.17.13",
"to-fast-properties": "^2.0.0"
}
},
"@types/node": {
"version": "12.12.6",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.6.tgz",
"integrity": "sha512-FjsYUPzEJdGXjwKqSpE0/9QEh6kzhTAeObA54rn6j3rR4C/mzpI9L0KNfoeASSPMMdxIsoJuCLDWcM/rVjIsSA=="
"version": "14.0.14",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.14.tgz",
"integrity": "sha512-syUgf67ZQpaJj01/tRTknkMNoBBLWJOBODF0Zm4NrXmiSuxjymFrxnTu1QVYRubhVkRcZLYZG8STTwJRdVm/WQ=="
},
"@types/tape": {
"version": "4.2.33",
"resolved": "https://registry.npmjs.org/@types/tape/-/tape-4.2.33.tgz",
"integrity": "sha512-ltfyuY5BIkYlGuQfwqzTDT8f0q8Z5DGppvUnWGs39oqDmMd6/UWhNpX3ZMh/VYvfxs3rFGHMrLC/eGRdLiDGuw==",
"version": "4.13.0",
"resolved": "https://registry.npmjs.org/@types/tape/-/tape-4.13.0.tgz",
"integrity": "sha512-0V8cKowBdsiA9nbxAg7531sF2cdPZNiUogcfIUeUGm+bejUBE/bvibz3rH36iQP9bQjO/sOzFwU97/uC5mCyoA==",
"requires": {
"@types/node": "*"
}
@ -125,9 +130,9 @@
}
},
"arg": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.1.tgz",
"integrity": "sha512-SlmP3fEA88MBv0PypnXZ8ZfJhwmDeIE3SP71j37AiXQBXYosPV0x6uISAaHYSlSVhmHOVkomen0tbGk6Anlebw=="
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA=="
},
"balanced-match": {
"version": "1.0.0",
@ -195,9 +200,17 @@
}
},
"deep-equal": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz",
"integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU="
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz",
"integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==",
"requires": {
"is-arguments": "^1.0.4",
"is-date-object": "^1.0.1",
"is-regex": "^1.0.4",
"object-is": "^1.0.1",
"object-keys": "^1.1.1",
"regexp.prototype.flags": "^1.2.0"
}
},
"define-properties": {
"version": "1.1.3",
@ -213,9 +226,17 @@
"integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM="
},
"diff": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz",
"integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q=="
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A=="
},
"dotignore": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/dotignore/-/dotignore-0.1.2.tgz",
"integrity": "sha512-UGGGWfSauusaVJC+8fgV+NVvBXkCTmVv7sk6nojDZZvuOUNGUy0Zk4UpHQD6EDjS0jpBwcACvH4eofvyzBcRDw==",
"requires": {
"minimatch": "^3.0.4"
}
},
"duplexer": {
"version": "0.1.1",
@ -223,26 +244,37 @@
"integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E="
},
"es-abstract": {
"version": "1.16.0",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.16.0.tgz",
"integrity": "sha512-xdQnfykZ9JMEiasTAJZJdMWCQ1Vm00NBw79/AWi7ELfZuuPCSOMDZbT9mkOfSctVtfhb+sAAzrm+j//GjjLHLg==",
"version": "1.17.6",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz",
"integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==",
"requires": {
"es-to-primitive": "^1.2.0",
"es-to-primitive": "^1.2.1",
"function-bind": "^1.1.1",
"has": "^1.0.3",
"has-symbols": "^1.0.0",
"is-callable": "^1.1.4",
"is-regex": "^1.0.4",
"object-inspect": "^1.6.0",
"has-symbols": "^1.0.1",
"is-callable": "^1.2.0",
"is-regex": "^1.1.0",
"object-inspect": "^1.7.0",
"object-keys": "^1.1.1",
"string.prototype.trimleft": "^2.1.0",
"string.prototype.trimright": "^2.1.0"
"object.assign": "^4.1.0",
"string.prototype.trimend": "^1.0.1",
"string.prototype.trimstart": "^1.0.1"
},
"dependencies": {
"is-regex": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz",
"integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==",
"requires": {
"has-symbols": "^1.0.1"
}
}
}
},
"es-to-primitive": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz",
"integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==",
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
"integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
"requires": {
"is-callable": "^1.1.4",
"is-date-object": "^1.0.1",
@ -254,11 +286,6 @@
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
},
"esutils": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="
},
"figures": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
@ -287,9 +314,9 @@
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
},
"glob": {
"version": "7.1.5",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.5.tgz",
"integrity": "sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==",
"version": "7.1.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
"integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
@ -326,9 +353,9 @@
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
},
"has-symbols": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz",
"integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q="
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
"integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg=="
},
"inflight": {
"version": "1.0.6",
@ -344,38 +371,40 @@
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"is-arguments": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz",
"integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA=="
},
"is-callable": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz",
"integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA=="
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz",
"integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw=="
},
"is-date-object": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz",
"integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY="
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz",
"integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g=="
},
"is-finite": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
"integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
"requires": {
"number-is-nan": "^1.0.0"
}
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz",
"integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w=="
},
"is-regex": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
"integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz",
"integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==",
"requires": {
"has": "^1.0.1"
"has": "^1.0.3"
}
},
"is-symbol": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz",
"integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==",
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz",
"integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==",
"requires": {
"has-symbols": "^1.0.0"
"has-symbols": "^1.0.1"
}
},
"isarray": {
@ -418,9 +447,9 @@
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
},
"make-error": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz",
"integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g=="
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw=="
},
"minimatch": {
"version": "3.0.4",
@ -431,20 +460,15 @@
}
},
"minimist": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"number-is-nan": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
},
"nyc": {
"version": "13.3.0",
"resolved": "https://registry.npmjs.org/nyc/-/nyc-13.3.0.tgz",
@ -1347,15 +1371,35 @@
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
},
"object-inspect": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz",
"integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ=="
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz",
"integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw=="
},
"object-is": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.2.tgz",
"integrity": "sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ==",
"requires": {
"define-properties": "^1.1.3",
"es-abstract": "^1.17.5"
}
},
"object-keys": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="
},
"object.assign": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
"integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
"requires": {
"define-properties": "^1.1.2",
"function-bind": "^1.1.1",
"has-symbols": "^1.0.0",
"object-keys": "^1.0.11"
}
},
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
@ -1418,15 +1462,24 @@
"util-deprecate": "~1.0.1"
}
},
"regexp.prototype.flags": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz",
"integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==",
"requires": {
"define-properties": "^1.1.3",
"es-abstract": "^1.17.0-next.1"
}
},
"repeat-string": {
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
"integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc="
},
"resolve": {
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.1.tgz",
"integrity": "sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw==",
"version": "1.17.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz",
"integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==",
"requires": {
"path-parse": "^1.0.6"
}
@ -1455,9 +1508,9 @@
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
},
"source-map-support": {
"version": "0.5.16",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz",
"integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==",
"version": "0.5.19",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
"integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
"requires": {
"buffer-from": "^1.0.0",
"source-map": "^0.6.0"
@ -1479,31 +1532,31 @@
}
},
"string.prototype.trim": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz",
"integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=",
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.1.tgz",
"integrity": "sha512-MjGFEeqixw47dAMFMtgUro/I0+wNqZB5GKXGt1fFr24u3TzDXCPu7J9Buppzoe3r/LqkSDLDDJzE15RGWDGAVw==",
"requires": {
"define-properties": "^1.1.2",
"es-abstract": "^1.5.0",
"function-bind": "^1.0.2"
"define-properties": "^1.1.3",
"es-abstract": "^1.17.0-next.1",
"function-bind": "^1.1.1"
}
},
"string.prototype.trimleft": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz",
"integrity": "sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==",
"string.prototype.trimend": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz",
"integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==",
"requires": {
"define-properties": "^1.1.3",
"function-bind": "^1.1.1"
"es-abstract": "^1.17.5"
}
},
"string.prototype.trimright": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz",
"integrity": "sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==",
"string.prototype.trimstart": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz",
"integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==",
"requires": {
"define-properties": "^1.1.3",
"function-bind": "^1.1.1"
"es-abstract": "^1.17.5"
}
},
"string_decoder": {
@ -1581,22 +1634,24 @@
}
},
"tape": {
"version": "4.11.0",
"resolved": "https://registry.npmjs.org/tape/-/tape-4.11.0.tgz",
"integrity": "sha512-yixvDMX7q7JIs/omJSzSZrqulOV51EC9dK8dM0TzImTIkHWfe2/kFyL5v+d9C+SrCMaICk59ujsqFAVidDqDaA==",
"version": "4.13.3",
"resolved": "https://registry.npmjs.org/tape/-/tape-4.13.3.tgz",
"integrity": "sha512-0/Y20PwRIUkQcTCSi4AASs+OANZZwqPKaipGCEwp10dQMipVvSZwUUCi01Y/OklIGyHKFhIcjock+DKnBfLAFw==",
"requires": {
"deep-equal": "~1.0.1",
"deep-equal": "~1.1.1",
"defined": "~1.0.0",
"dotignore": "~0.1.2",
"for-each": "~0.3.3",
"function-bind": "~1.1.1",
"glob": "~7.1.4",
"glob": "~7.1.6",
"has": "~1.0.3",
"inherits": "~2.0.4",
"minimist": "~1.2.0",
"object-inspect": "~1.6.0",
"resolve": "~1.11.1",
"is-regex": "~1.0.5",
"minimist": "~1.2.5",
"object-inspect": "~1.7.0",
"resolve": "~1.17.0",
"resumer": "~0.0.0",
"string.prototype.trim": "~1.1.2",
"string.prototype.trim": "~1.2.1",
"through": "~2.3.8"
}
},
@ -1620,9 +1675,9 @@
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
},
"readable-stream": {
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
"requires": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
@ -1654,21 +1709,21 @@
"integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0="
},
"ts-node": {
"version": "8.4.1",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.4.1.tgz",
"integrity": "sha512-5LpRN+mTiCs7lI5EtbXmF/HfMeCjzt7DH9CZwtkr6SywStrNQC723wG+aOWFiLNn7zT3kD/RnFqi3ZUfr4l5Qw==",
"version": "8.10.2",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz",
"integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==",
"requires": {
"arg": "^4.1.0",
"diff": "^4.0.1",
"make-error": "^1.1.1",
"source-map-support": "^0.5.6",
"yn": "^3.0.0"
"source-map-support": "^0.5.17",
"yn": "3.1.1"
}
},
"typescript": {
"version": "3.7.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.2.tgz",
"integrity": "sha512-ml7V7JfiN2Xwvcer+XAf2csGO1bPBdRbFCkYBczNZggrBZ9c7G3riSUeJmqEU5uOtXNPMhE3n+R4FA/3YOAWOQ=="
"version": "3.9.5",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.5.tgz",
"integrity": "sha512-hSAifV3k+i6lEoCJ2k6R2Z/rp/H3+8sdmcn5NrS3/3kE7+RyZXm9aqvxWqjEXHAd8b0pShatpcdMTvEdvAJltQ=="
},
"util-deprecate": {
"version": "1.0.2",
@ -1690,6 +1745,5 @@
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q=="
}
},
"version": "0.0.15"
}
}

@ -34,7 +34,7 @@
"dependencies": {
"@types/tape": "^4.2.33",
"nyc": "^13.3.0",
"remix-lib": "0.4.29",
"remix-lib": "0.4.30",
"tape": "^4.10.1",
"ts-node": "^8.0.3",
"typescript": "^3.4.3"

@ -6,4 +6,4 @@
"esModuleInterop": true
},
"include": ["**/*.ts"]
}
}

@ -1,6 +1,6 @@
{
"name": "remix-debug",
"version": "0.4.4",
"version": "0.4.5",
"description": "Tool to debug Ethereum transactions",
"contributors": [
{

@ -58,6 +58,8 @@ class VmDebuggerLogic {
this.event.trigger('indexUpdate', [index])
this.event.trigger('functionsStackUpdate', [this._callTree.retrieveFunctionsStack(index)])
this._traceManager.getCallDataAt(index, (error, calldata) => {
if (error) {
// console.log(error)

@ -66,6 +66,7 @@ class InternalCallTree {
*/
this.sourceLocationTracker.clearCache()
this.functionCallStack = []
this.functionDefinitionsByScope = {}
this.scopeStarts = {}
this.variableDeclarationByFile = {}
this.functionDefinitionByFile = {}
@ -79,21 +80,49 @@ class InternalCallTree {
* @param {Int} vmtraceIndex - index on the vm trace
*/
findScope (vmtraceIndex) {
const scopes = Object.keys(this.scopeStarts)
if (!scopes.length) {
return null
}
let scopeId = util.findLowerBoundValue(vmtraceIndex, scopes)
scopeId = this.scopeStarts[scopeId]
let scopeId = this.findScopeId(vmtraceIndex)
if (scopeId !== '' && !scopeId) return null
let scope = this.scopes[scopeId]
while (scope.lastStep && scope.lastStep < vmtraceIndex && scope.firstStep > 0) {
const matched = scopeId.match(/(.\d|\d)$/)
scopeId = scopeId.replace(matched[1], '')
scopeId = this.parentScope(scopeId)
scope = this.scopes[scopeId]
}
return scope
}
parentScope (scopeId) {
const matched = scopeId.match(/(.\d|\d)$/)
return scopeId.replace(matched[1], '')
}
findScopeId (vmtraceIndex) {
const scopes = Object.keys(this.scopeStarts)
if (!scopes.length) return null
const scopeStart = util.findLowerBoundValue(vmtraceIndex, scopes)
return this.scopeStarts[scopeStart]
}
retrieveFunctionsStack (vmtraceIndex) {
let scope = this.findScope(vmtraceIndex)
if (!scope) return []
let scopeId = this.scopeStarts[scope.firstStep]
let functions = []
if (!scopeId) return functions
let i = 0
while (true) {
i += 1
if (i > 1000) throw new Error('retrieFunctionStack: recursion too deep')
let functionDefinition = this.functionDefinitionsByScope[scopeId]
if (functionDefinition !== undefined) {
functions.push(functionDefinition)
}
let parent = this.parentScope(scopeId)
if (!parent) break
else scopeId = parent
}
return functions
}
extractSourceLocation (step) {
return new Promise((resolve, reject) => {
this.traceManager.getCurrentCalledAddressAt(step, (error, address) => {
@ -220,6 +249,7 @@ function includeVariableDeclaration (tree, step, sourceLocation, scopeId, newLoc
const functionDefinition = resolveFunctionDefinition(tree, step, previousSourceLocation)
if (functionDefinition && (newLocation && traceHelper.isJumpDestInstruction(tree.traceManager.trace[step - 1]) || functionDefinition.attributes.isConstructor)) {
tree.functionCallStack.push(step)
const functionDefinitionAndInputs = {functionDefinition, inputs: []}
// means: the previous location was a function definition && JUMPDEST
// => we are at the beginning of the function and input/output are setup
tree.solidityProxy.contractNameAt(step, (error, contractName) => { // cached
@ -240,7 +270,9 @@ function includeVariableDeclaration (tree, step, sourceLocation, scopeId, newLoc
}
}
// input params
if (inputs) addParams(inputs, tree, scopeId, states, contractName, previousSourceLocation, stack.length, inputs.children.length, -1)
if (inputs) {
functionDefinitionAndInputs.inputs = addParams(inputs, tree, scopeId, states, contractName, previousSourceLocation, stack.length, inputs.children.length, -1)
}
// output params
if (outputs) addParams(outputs, tree, scopeId, states, contractName, previousSourceLocation, stack.length, 0, 1)
}
@ -248,6 +280,7 @@ function includeVariableDeclaration (tree, step, sourceLocation, scopeId, newLoc
})
}
})
tree.functionDefinitionsByScope[scopeId] = functionDefinitionAndInputs
}
}
@ -304,6 +337,7 @@ function extractFunctionDefinitions (ast, astWalker) {
}
function addParams (parameterList, tree, scopeId, states, contractName, sourceLocation, stackLength, stackPosition, dir) {
let params = []
for (let inputParam in parameterList.children) {
const param = parameterList.children[inputParam]
const stackDepth = stackLength + (dir * stackPosition)
@ -317,9 +351,11 @@ function addParams (parameterList, tree, scopeId, states, contractName, sourceLo
stackDepth: stackDepth,
sourceLocation: sourceLocation
}
params.push(attributesName)
}
stackPosition += dir
}
return params
}
module.exports = InternalCallTree

@ -26,17 +26,17 @@ contract intLocal {
int256 i256 = 3434343;
int i = -32432423423;
int32 ishrink = 2;
level11();
level12();
level11();
level11(123);
level12(12);
level11(123);
}
function level11() public {
uint8 ui8 = 123;
level12();
function level11(uint8 foo) public {
uint8 ui8 = foo;
level12(12);
}
function level12() public {
uint8 ui81 = 12;
function level12(uint8 asd) public {
uint8 ui81 = asd;
}
}
`}

@ -37,14 +37,35 @@ module.exports = function (st, vm, privateKey, contractBytecode, compilationResu
})
callTree.event.register('callTreeReady', (scopes, scopeStarts) => {
try {
console.log(scopeStarts)
let functions1 = callTree.retrieveFunctionsStack(102)
let functions2 = callTree.retrieveFunctionsStack(115)
let functions3 = callTree.retrieveFunctionsStack(13)
st.equals(functions1.length, 1)
st.equals(functions2.length, 2)
st.equals(functions3.length, 0)
st.equals(Object.keys(functions1[0])[0], 'functionDefinition')
st.equals(Object.keys(functions1[0])[1], 'inputs')
st.equals(functions1[0].inputs[0], 'foo')
st.equals(Object.keys(functions2[0])[0], 'functionDefinition')
st.equals(Object.keys(functions2[0])[1], 'inputs')
st.equals(Object.keys(functions2[1])[0], 'functionDefinition')
st.equals(Object.keys(functions2[1])[1], 'inputs')
st.equals(functions2[0].inputs[0], 'asd')
st.equals(functions2[1].inputs[0], 'foo')
st.equals(functions1[0].functionDefinition.attributes.name, 'level11')
st.equals(functions2[0].functionDefinition.attributes.name, 'level12')
st.equals(functions2[1].functionDefinition.attributes.name, 'level11')
st.equals(scopeStarts[0], '')
st.equals(scopeStarts[13], '1')
st.equals(scopeStarts[101], '2')
st.equals(scopeStarts[113], '2.1')
st.equals(scopeStarts[131], '3')
st.equals(scopeStarts[146], '4')
st.equals(scopeStarts[158], '4.1')
st.equals(scopeStarts[102], '2')
st.equals(scopeStarts[115], '2.1')
st.equals(scopeStarts[136], '3')
st.equals(scopeStarts[153], '4')
st.equals(scopeStarts[166], '4.1')
st.equals(scopes[''].locals['ui8'].type.typeName, 'uint8')
st.equals(scopes[''].locals['ui16'].type.typeName, 'uint16')
st.equals(scopes[''].locals['ui32'].type.typeName, 'uint32')
@ -88,10 +109,10 @@ module.exports = function (st, vm, privateKey, contractBytecode, compilationResu
st.equals(locals['ishrink'].value, '2')
})
helper.decodeLocals(st, 105, traceManager, callTree, function (locals) {
helper.decodeLocals(st, 106, traceManager, callTree, function (locals) {
try {
st.equals(locals['ui8'].value, '123')
st.equals(Object.keys(locals).length, 1)
st.equals(Object.keys(locals).length, 2)
} catch (e) {
st.fail(e.message)
}

@ -181,7 +181,8 @@ class TxListener {
* @return {String} - contract name
*/
resolvedContract (address) {
return this._resolvedContracts[address]
if (this._resolvedContracts[address]) return this._resolvedContracts[address].name
return null
}
/**
@ -222,54 +223,53 @@ class TxListener {
_resolveTx (tx, receipt, cb) {
const contracts = this._api.contracts()
if (!contracts) return cb()
let contractName
let fun
let contract
if (!tx.to || tx.to === '0x0') { // testrpc returns 0x0 in that case
// contract creation / resolve using the creation bytes code
// if web3: we have to call getTransactionReceipt to get the created address
// if VM: created address already included
const code = tx.input
contractName = this._tryResolveContract(code, contracts, true)
if (contractName) {
contract = this._tryResolveContract(code, contracts, true)
if (contract) {
let address = receipt.contractAddress
this._resolvedContracts[address] = contractName
fun = this._resolveFunction(contractName, contracts, tx, true)
this._resolvedContracts[address] = contract
fun = this._resolveFunction(contract, tx, true)
if (this._resolvedTransactions[tx.hash]) {
this._resolvedTransactions[tx.hash].contractAddress = address
}
return cb(null, {to: null, contractName: contractName, function: fun, creationAddress: address})
return cb(null, {to: null, contractName: contract.name, function: fun, creationAddress: address})
}
return cb()
} else {
// first check known contract, resolve against the `runtimeBytecode` if not known
contractName = this._resolvedContracts[tx.to]
if (!contractName) {
contract = this._resolvedContracts[tx.to]
if (!contract) {
this.executionContext.web3().eth.getCode(tx.to, (error, code) => {
if (error) return cb(error)
if (code) {
const contractName = this._tryResolveContract(code, contracts, false)
if (contractName) {
this._resolvedContracts[tx.to] = contractName
const fun = this._resolveFunction(contractName, contracts, tx, false)
return cb(null, {to: tx.to, contractName: contractName, function: fun})
const contract = this._tryResolveContract(code, contracts, false)
if (contract) {
this._resolvedContracts[tx.to] = contract
const fun = this._resolveFunction(contract, tx, false)
return cb(null, {to: tx.to, contractName: contract.name, function: fun})
}
}
return cb()
})
return
}
if (contractName) {
fun = this._resolveFunction(contractName, contracts, tx, false)
return cb(null, {to: tx.to, contractName: contractName, function: fun})
if (contract) {
fun = this._resolveFunction(contract, tx, false)
return cb(null, {to: tx.to, contractName: contract.name, function: fun})
}
return cb()
}
}
_resolveFunction (contractName, compiledContracts, tx, isCtor) {
const contract = txHelper.getContract(contractName, compiledContracts)
_resolveFunction (contract, tx, isCtor) {
if (!contract) {
console.log('txListener: cannot resolve ' + contractName)
console.log('txListener: cannot resolve contract - contract is null')
return
}
const abi = contract.object.abi
@ -280,7 +280,7 @@ class TxListener {
if (methodIdentifiers[fn] === inputData.substring(0, 8)) {
const fnabi = txHelper.getFunction(abi, fn)
this._resolvedTransactions[tx.hash] = {
contractName: contractName,
contractName: contract.name,
to: tx.to,
fn: fn,
params: this._decodeInputParams(inputData.substring(8), fnabi)
@ -294,7 +294,7 @@ class TxListener {
// receive function
if (!inputData && txHelper.getReceiveInterface(abi)) {
this._resolvedTransactions[tx.hash] = {
contractName: contractName,
contractName: contract.name,
to: tx.to,
fn: '(receive)',
params: null
@ -302,7 +302,7 @@ class TxListener {
} else {
// fallback function
this._resolvedTransactions[tx.hash] = {
contractName: contractName,
contractName: contract.name,
to: tx.to,
fn: '(fallback)',
params: null
@ -315,7 +315,7 @@ class TxListener {
params = this._decodeInputParams(inputData.substring(bytecode.length), txHelper.getConstructorInterface(abi))
}
this._resolvedTransactions[tx.hash] = {
contractName: contractName,
contractName: contract.name,
to: null,
fn: '(constructor)',
params: params
@ -329,7 +329,7 @@ class TxListener {
txHelper.visitContracts(compiledContracts, (contract) => {
const bytes = isCreation ? contract.object.evm.bytecode.object : contract.object.evm.deployedBytecode.object
if (codeUtil.compareByteCode(codeToResolve, '0x' + bytes)) {
found = contract.name
found = contract
return true
}
})

@ -216,6 +216,9 @@ function atIndex (index, mapping) {
}
current = current.split(':')
if (current[2] === '-1') { // if the current step has -1 for the file attribute, we discard it
// case: 'file' is not yet assigned, while processing the srcmap (reverse looping) to find 'start', 'length' (etc..), we tumble on -1 for the file.
// in that case the step has to be discarded
if (ret.file === undefined) ret = {}
continue
}
if (ret.start === undefined && current[0] && current[0] !== '-1' && current[0].length) {

@ -17,6 +17,20 @@ sourceRuntimeMapping.source = `contract test {
}
}`
sourceRuntimeMapping.tokenSaleChallengeSourceMap = '0:286:0:-:0;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;0:286:0;;;;;;;;;;;;;;;;;;;;;12:1:-1;9;2:12;34:44:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;34:44:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;161:123;;;:::i;:::-;;;;;;;;;;;;;;;;;;;34:44;;;;;;;;;;;;;;;;;:::o;161:123::-;192:7;211:10;:19;;:48;119:7;231:9;;:27;211:48;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;211:48:0;276:1;269:8;;161:123;:::o'
sourceRuntimeMapping.tokenSaleChallengeSource = `
contract TokenSaleChallenge {
mapping(address => uint256) public balanceOf;
uint256 constant PRICE_PER_TOKEN = 1 ether;
uint256 numTokens = 30;
function test() public returns(uint256) {
msg.sender.transfer(numTokens * PRICE_PER_TOKEN);
return 2;
}
}
`
sourceRuntimeMapping.ballotSourceMap = '33:1970:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;33:1970:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;712:577;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;712:577:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;1641:360;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;495:164;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;495:164:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;1349:286;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;1349:286:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;712:577;759:20;782:6;:18;789:10;782:18;;;;;;;;;;;;;;;759:41;;835:6;:12;;;;;;;;;;;;831:25;;;849:7;;;831:25;865:115;903:1;872:33;;:6;:10;879:2;872:10;;;;;;;;;;;;;;;:19;;;;;;;;;;;;:33;;;;:70;;;;;932:10;909:33;;:6;:10;916:2;909:10;;;;;;;;;;;;;;;:19;;;;;;;;;;;;:33;;;;872:70;865:115;;;961:6;:10;968:2;961:10;;;;;;;;;;;;;;;:19;;;;;;;;;;;;956:24;;865:115;;;1000:10;994:16;;:2;:16;;;990:29;;;1012:7;;;990:29;1043:4;1028:6;:12;;;:19;;;;;;;;;;;;;;;;;;1075:2;1057:6;:15;;;:20;;;;;;;;;;;;;;;;;;1087:24;1114:6;:10;1121:2;1114:10;;;;;;;;;;;;;;;1087:37;;1138:10;:16;;;;;;;;;;;;1134:148;;;1208:6;:13;;;1168:9;1178:10;:15;;;;;;;;;;;;1168:26;;;;;;;;;;;;;;;;;:36;;;:53;;;;;;;;;;;1134:148;;;1269:6;:13;;;1248:10;:17;;;:34;;;;;;;;;;;1134:148;712:577;;;;:::o;1641:360::-;1689:22;1723:24;1750:1;1723:28;;1766:10;1779:1;1766:14;;1761:234;1789:9;:16;;;;1782:4;:23;;;1761:234;;;1859:16;1831:9;1841:4;1831:15;;;;;;;;;;;;;;;;;:25;;;:44;1827:168;;;1914:9;1924:4;1914:15;;;;;;;;;;;;;;;;;:25;;;1895:44;;1976:4;1957:23;;1827:168;1807:6;;;;;;;1761:234;;;;1641:360;;:::o;495:164::-;572:11;;;;;;;;;;;558:25;;:10;:25;;;;:50;;;;587:6;:15;594:7;587:15;;;;;;;;;;;;;;;:21;;;;;;;;;;;;558:50;554:63;;;610:7;;554:63;651:1;626:6;:15;633:7;626:15;;;;;;;;;;;;;;;:22;;:26;;;;495:164;;:::o;1349:286::-;1398:20;1421:6;:18;1428:10;1421:18;;;;;;;;;;;;;;;1398:41;;1453:6;:12;;;;;;;;;;;;:46;;;;1483:9;:16;;;;1469:10;:30;;;;1453:46;1449:59;;;1501:7;;;1449:59;1532:4;1517:6;:12;;;:19;;;;;;;;;;;;;;;;;;1560:10;1546:6;:11;;;:24;;;;;;;;;;;;;;;;;;1615:6;:13;;;1580:9;1590:10;1580:21;;;;;;;;;;;;;;;;;:31;;;:48;;;;;;;;;;;1349:286;;;:::o'
sourceRuntimeMapping.ballotSource = `
pragma solidity >=0.4.22 <0.6.0;

File diff suppressed because one or more lines are too long

@ -22,7 +22,7 @@ tape('SourceMappingDecoder', function (t) {
const testSourceMapping = {}
t.test('sourceMappingDecoder', function (st) {
st.plan(32)
st.plan(36)
const sourceMappingDecoder = new SourceMappingDecoder()
console.log('test decompressAll')
let result = sourceMappingDecoder.decompressAll(sourceMapping.mapping)
@ -81,6 +81,14 @@ tape('SourceMappingDecoder', function (t) {
st.equal(delegateSrcMap.length, 577)
st.equal(delegateSrcMap.file, 0)
st.equal(delegateSrcMap.jump, '-')
// TokenSaleChallenge - function test(uint256)
const tokenSaleChallengeMap = sourceMappingDecoder.atIndex(170, sourceMapping.tokenSaleChallengeSourceMap)
console.log(tokenSaleChallengeMap)
st.equal(tokenSaleChallengeMap.start, 211)
st.equal(tokenSaleChallengeMap.length, 48)
st.equal(tokenSaleChallengeMap.file, 0)
st.equal(tokenSaleChallengeMap.jump, '-')
})
t.test('sourceMappingLineColumnConverter', function (st) {
@ -106,6 +114,8 @@ tape('SourceMappingDecoder', function (t) {
file: 4,
jump: '-'
}
// case: 'file' is not yet assigned, while processing the srcmap (reverse looping) to find 'start', 'length' (etc..), we tumble on -1 for the file.
// in that case the step has to be discarded
result = sourceMappingDecoder.convertOffsetToLineColumn(res, linesbreak)
st.equal(result.start.line, 7)
st.equal(result.start.column, 12)

@ -1,6 +1,6 @@
{
"name": "remix-simulator",
"version": "0.1.9-beta.5",
"version": "0.1.9-beta.6",
"description": "Ethereum IDE and tools for the web",
"contributors": [
{

@ -127,4 +127,4 @@ class Accounts{
}
}
module.exports = Accounts
module.exports = Accounts

@ -1,4 +1,3 @@
class Blocks {
constructor (executionContext, _options) {
this.executionContext = executionContext
@ -137,4 +136,4 @@ class Blocks {
}
}
module.exports = Blocks
module.exports = Blocks

@ -1,4 +1,3 @@
class Filters {
constructor(executionContext) {
this.executionContext = executionContext
@ -60,4 +59,4 @@ class Filters {
}
}
module.exports = Filters
module.exports = Filters

@ -235,4 +235,4 @@ class Transactions{
}
}
module.exports = Transactions
module.exports = Transactions

@ -74,4 +74,4 @@ class Provider {
}
}
module.exports = Provider
module.exports = Provider

@ -4,4 +4,4 @@
"types": ["node"]
},
"include": ["**/*.ts"]
}
}

@ -6,4 +6,4 @@
"esModuleInterop": true
},
"include": ["**/*.ts"]
}
}

File diff suppressed because it is too large Load Diff

@ -6,4 +6,4 @@
"esModuleInterop": true
},
"include": ["**/*.ts"]
}
}

42120
package-lock.json generated

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save