From ad4ba658d83718a964dffa8a21db1a419823fe53 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Fri, 15 May 2020 18:59:40 +0530 Subject: [PATCH] added location in warning --- .../src/solidity-analyzer/modules/gasCosts.ts | 41 +++++++++++-------- remix-analyzer/src/types.ts | 9 ++-- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/remix-analyzer/src/solidity-analyzer/modules/gasCosts.ts b/remix-analyzer/src/solidity-analyzer/modules/gasCosts.ts index d01e01d43d..6bedd59a69 100644 --- a/remix-analyzer/src/solidity-analyzer/modules/gasCosts.ts +++ b/remix-analyzer/src/solidity-analyzer/modules/gasCosts.ts @@ -1,13 +1,8 @@ import { default as category } from './categories' import { default as algorithm } from './algorithmCategories' -import { getFunctionDefinitionName, helpers, getType } from './staticAnalysisCommon' -import { ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, CompiledContractObj, CompiledContract, VisitFunction, AnalyzerModule, FunctionDefinitionAstNode, YulVariableDeclarationAstNode, VariableDeclarationAstNode} from './../../types' - -interface VisitedContract { - name: string - object: CompiledContract - file: string -} +import { getFunctionDefinitionName, helpers } from './staticAnalysisCommon' +import { ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, CompiledContract, AnalyzerModule, + FunctionDefinitionAstNode, VariableDeclarationAstNode } from './../../types' export default class gasCosts implements AnalyzerModule { name: string = `Gas costs: ` @@ -24,11 +19,12 @@ export default class gasCosts implements AnalyzerModule { report (compilationResults: CompilationResult): ReportObj[] { const report: ReportObj[] = [] - const filename = Object.keys(compilationResults.contracts)[0] - const methodsWithSignature = this.warningNodes.map(node => { - let signature; - if(node.nodeType === 'FunctionDefinition') - signature = helpers.buildAbiSignature(getFunctionDefinitionName(node), node.parameters.parameters.map(node => node.typeDescriptions.typeString.split(' ')[0])) + const methodsWithSignature: Record[] = this.warningNodes.map(node => { + let signature: string; + if(node.nodeType === 'FunctionDefinition'){ + const functionName: string = getFunctionDefinitionName(node) + signature = helpers.buildAbiSignature(functionName, node.parameters.parameters.map(this.getSplittedTypeDesc)) + } else signature = node.name + '()' @@ -41,20 +37,22 @@ export default class gasCosts implements AnalyzerModule { for (const method of methodsWithSignature) { for (const filename in compilationResults.contracts) { for (const contractName in compilationResults.contracts[filename]) { - const contract = compilationResults.contracts[filename][contractName] - const methodGas: any = this.checkMethodGas(contract, method.signature) + const contract: CompiledContract = compilationResults.contracts[filename][contractName] + const methodGas: Record | undefined = this.checkMethodGas(contract, method.signature) if(methodGas && methodGas.isInfinite) { if(methodGas.isFallback) { report.push({ warning: `Fallback function of contract ${contractName} requires too much gas (${methodGas.msg}). - If the fallback function requires more than 2300 gas, the contract cannot receive Ether.` + If the fallback function requires more than 2300 gas, the contract cannot receive Ether.`, + location: method.src }) } else { report.push({ warning: `Gas requirement of function ${contractName}.${method.name} ${methodGas.msg}. If the gas requirement of a function is higher than the block gas limit, it cannot be executed. Please avoid loops in your functions or actions that modify large areas of storage - (this includes clearing or copying arrays in storage)` + (this includes clearing or copying arrays in storage)`, + location: method.src }) } } else continue @@ -64,7 +62,14 @@ export default class gasCosts implements AnalyzerModule { return report } - private checkMethodGas(contract: any, methodSignature: string) { + // To create the method signature similar to contract.evm.gasEstimates.external object + // For address payable, return address + private getSplittedTypeDesc(node: VariableDeclarationAstNode): string { + return node.typeDescriptions.typeString.split(' ')[0] + } + + + private checkMethodGas(contract: CompiledContract, methodSignature: string): Record | undefined { if(contract.evm && contract.evm.gasEstimates && contract.evm.gasEstimates.external) { if(methodSignature === '()') { const fallback: string = contract.evm.gasEstimates.external[''] diff --git a/remix-analyzer/src/types.ts b/remix-analyzer/src/types.ts index 0646267064..e010b0d27b 100644 --- a/remix-analyzer/src/types.ts +++ b/remix-analyzer/src/types.ts @@ -20,11 +20,11 @@ export interface ModuleCategory { export interface ReportObj { warning: string, - location?: string | null, + location: string, more?: string } -// Regarding location, she source mappings inside the AST use the following notation: +// Regarding location, the source mappings inside the AST use the following notation: // s:l:f @@ -33,7 +33,10 @@ export interface ReportObj { // l is the length of the source range in bytes and // f is the source index mentioned above. -export interface AnalysisReportObj extends ReportObj { +export interface AnalysisReportObj { + warning: string, + location?: string, + more?: string error? : string }