Commit ad4ba658 authored by aniket-engg's avatar aniket-engg

added location in warning

parent c0331038
import { default as category } from './categories' import { default as category } from './categories'
import { default as algorithm } from './algorithmCategories' import { default as algorithm } from './algorithmCategories'
import { getFunctionDefinitionName, helpers, getType } from './staticAnalysisCommon' import { getFunctionDefinitionName, helpers } from './staticAnalysisCommon'
import { ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, CompiledContractObj, CompiledContract, VisitFunction, AnalyzerModule, FunctionDefinitionAstNode, YulVariableDeclarationAstNode, VariableDeclarationAstNode} from './../../types' import { ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, CompiledContract, AnalyzerModule,
FunctionDefinitionAstNode, VariableDeclarationAstNode } from './../../types'
interface VisitedContract {
name: string
object: CompiledContract
file: string
}
export default class gasCosts implements AnalyzerModule { export default class gasCosts implements AnalyzerModule {
name: string = `Gas costs: ` name: string = `Gas costs: `
...@@ -24,11 +19,12 @@ export default class gasCosts implements AnalyzerModule { ...@@ -24,11 +19,12 @@ export default class gasCosts implements AnalyzerModule {
report (compilationResults: CompilationResult): ReportObj[] { report (compilationResults: CompilationResult): ReportObj[] {
const report: ReportObj[] = [] const report: ReportObj[] = []
const filename = Object.keys(compilationResults.contracts)[0] const methodsWithSignature: Record<string, string>[] = this.warningNodes.map(node => {
const methodsWithSignature = this.warningNodes.map(node => { let signature: string;
let signature; if(node.nodeType === 'FunctionDefinition'){
if(node.nodeType === 'FunctionDefinition') const functionName: string = getFunctionDefinitionName(node)
signature = helpers.buildAbiSignature(getFunctionDefinitionName(node), node.parameters.parameters.map(node => node.typeDescriptions.typeString.split(' ')[0])) signature = helpers.buildAbiSignature(functionName, node.parameters.parameters.map(this.getSplittedTypeDesc))
}
else else
signature = node.name + '()' signature = node.name + '()'
...@@ -41,20 +37,22 @@ export default class gasCosts implements AnalyzerModule { ...@@ -41,20 +37,22 @@ export default class gasCosts implements AnalyzerModule {
for (const method of methodsWithSignature) { for (const method of methodsWithSignature) {
for (const filename in compilationResults.contracts) { for (const filename in compilationResults.contracts) {
for (const contractName in compilationResults.contracts[filename]) { for (const contractName in compilationResults.contracts[filename]) {
const contract = compilationResults.contracts[filename][contractName] const contract: CompiledContract = compilationResults.contracts[filename][contractName]
const methodGas: any = this.checkMethodGas(contract, method.signature) const methodGas: Record<string, any> | undefined = this.checkMethodGas(contract, method.signature)
if(methodGas && methodGas.isInfinite) { if(methodGas && methodGas.isInfinite) {
if(methodGas.isFallback) { if(methodGas.isFallback) {
report.push({ report.push({
warning: `Fallback function of contract ${contractName} requires too much gas (${methodGas.msg}). 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 { } else {
report.push({ report.push({
warning: `Gas requirement of function ${contractName}.${method.name} ${methodGas.msg}. 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. 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 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 } else continue
...@@ -64,7 +62,14 @@ export default class gasCosts implements AnalyzerModule { ...@@ -64,7 +62,14 @@ export default class gasCosts implements AnalyzerModule {
return report 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<string, any> | undefined {
if(contract.evm && contract.evm.gasEstimates && contract.evm.gasEstimates.external) { if(contract.evm && contract.evm.gasEstimates && contract.evm.gasEstimates.external) {
if(methodSignature === '()') { if(methodSignature === '()') {
const fallback: string = contract.evm.gasEstimates.external[''] const fallback: string = contract.evm.gasEstimates.external['']
......
...@@ -20,11 +20,11 @@ export interface ModuleCategory { ...@@ -20,11 +20,11 @@ export interface ModuleCategory {
export interface ReportObj { export interface ReportObj {
warning: string, warning: string,
location?: string | null, location: string,
more?: 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 // s:l:f
...@@ -33,7 +33,10 @@ export interface ReportObj { ...@@ -33,7 +33,10 @@ export interface ReportObj {
// l is the length of the source range in bytes and // l is the length of the source range in bytes and
// f is the source index mentioned above. // f is the source index mentioned above.
export interface AnalysisReportObj extends ReportObj { export interface AnalysisReportObj {
warning: string,
location?: string,
more?: string
error? : string error? : string
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment