Commit b6b07a0c authored by aniket-engg's avatar aniket-engg Committed by Aniket

commons updated according to latest AST

parent dd3edce0
import { default as category } from './categories'
import { isSubScopeWithTopLevelUnAssignedBinOp, getUnAssignedTopLevelBinOps } from './staticAnalysisCommon'
import { default as algorithm } from './algorithmCategories'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, AstNodeLegacy, CompilationResult} from './../../types'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, BlockAstNode, IfStatementAstNode, WhileStatementAstNode, ForStatementAstNode, CompilationResult, ExpressionStatementAstNode} from './../../types'
export default class assignAndCompare implements AnalyzerModule {
warningNodes: AstNodeLegacy[] = []
warningNodes: ExpressionStatementAstNode[] = []
name: string = 'Result not used: '
description: string = 'The result of an operation was not used.'
category: ModuleCategory = category.MISC
algorithm: ModuleAlgorithm = algorithm.EXACT
visit (node: AstNodeLegacy): void {
visit (node: BlockAstNode | IfStatementAstNode | WhileStatementAstNode | ForStatementAstNode): void {
if (isSubScopeWithTopLevelUnAssignedBinOp(node)) getUnAssignedTopLevelBinOps(node).forEach((n) => this.warningNodes.push(n))
}
......
import { default as category } from './categories'
import { isBlockBlockHashAccess } from './staticAnalysisCommon'
import { default as algorithm } from './algorithmCategories'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, AstNodeLegacy, CompilationResult} from './../../types'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, FunctionCallAstNode} from './../../types'
export default class blockBlockhash implements AnalyzerModule {
warningNodes: AstNodeLegacy[] = []
warningNodes: FunctionCallAstNode[] = []
name: string = 'Block.blockhash usage: '
description: string = 'Semantics maybe unclear'
category: ModuleCategory = category.SECURITY
algorithm: ModuleAlgorithm = algorithm.EXACT
visit (node: AstNodeLegacy): void {
visit (node: FunctionCallAstNode): void {
if (isBlockBlockHashAccess(node)) this.warningNodes.push(node)
}
......
import { default as category } from './categories'
import { isNowAccess, isBlockTimestampAccess } from './staticAnalysisCommon'
import { default as algorithm } from './algorithmCategories'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, AstNodeLegacy, CompilationResult, IdentifierAstNode, MemberAccessAstNode} from './../../types'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, IdentifierAstNode, MemberAccessAstNode} from './../../types'
export default class blockTimestamp implements AnalyzerModule {
warningNowNodes: IdentifierAstNode[] = []
......
import { default as category } from './categories'
import { default as algorithm } from './algorithmCategories'
import { isTransfer } from './staticAnalysisCommon'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, AstNodeLegacy, CompilationResult, ForStatementAstNode, WhileStatementAstNode, CommonAstNode, ExpressionStatementAstNode} from './../../types'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, ForStatementAstNode, WhileStatementAstNode, CommonAstNode, ExpressionStatementAstNode} from './../../types'
export default class etherTransferInLoop implements AnalyzerModule {
relevantNodes: CommonAstNode[] = []
......@@ -11,13 +11,13 @@ export default class etherTransferInLoop implements AnalyzerModule {
algorithm: ModuleAlgorithm = algorithm.EXACT
visit (node: ForStatementAstNode | WhileStatementAstNode): void {
let transferNodes: CommonAstNode[] = []
transferNodes = node.body.statements.filter(child => (
child.nodeType === 'ExpressionStatement' &&
child.expression.nodeType === 'FunctionCall' &&
isTransfer(child.expression.expression)
)
)
let transferNodes: ExpressionStatementAstNode[] = []
if(node.body.nodeType === 'Block')
transferNodes = node.body.statements.filter(child => ( child.nodeType === 'ExpressionStatement' &&
child.expression.nodeType === 'FunctionCall' && isTransfer(child.expression.expression)))
// When loop body is described without braces
else if(node.body.nodeType === 'ExpressionStatement' && node.body.expression.nodeType === 'FunctionCall' && isTransfer(node.body.expression.expression))
transferNodes.push(node.body)
if (transferNodes.length > 0) {
this.relevantNodes.push(...transferNodes)
}
......
import { default as category } from './categories'
import { default as algorithm } from './algorithmCategories'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, AstNodeLegacy, CompilationResult, InlineAssemblyAstNode} from './../../types'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, InlineAssemblyAstNode} from './../../types'
export default class inlineAssembly implements AnalyzerModule {
inlineAssNodes: InlineAssemblyAstNode[] = []
......
import { default as category } from './categories'
import { default as algorithm } from './algorithmCategories'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, AstNodeLegacy, CompilationResult} from './../../types'
import { isTxOriginAccess } from './staticAnalysisCommon'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, MemberAccessAstNode} from './../../types'
export default class txOrigin implements AnalyzerModule {
txOriginNodes: AstNodeLegacy[] = []
txOriginNodes: MemberAccessAstNode[] = []
name: string = 'Transaction origin: '
description: string = 'Warn if tx.origin is used'
category: ModuleCategory = category.SECURITY
algorithm: ModuleAlgorithm = algorithm.EXACT
visit (node: AstNodeLegacy): void {
if (node.name === 'MemberAccess' && node.attributes &&
node.attributes.member_name === 'origin' &&
(node.attributes.type === 'address' || node.attributes.type === 'address payable') &&
node.children && node.children.length && node.children[0].attributes &&
node.children[0].attributes.type === 'tx' &&
node.children[0].attributes.value === 'tx') {
visit (node: MemberAccessAstNode): void {
if (isTxOriginAccess(node)) {
this.txOriginNodes.push(node)
}
}
......
......@@ -312,8 +312,8 @@ export interface IfStatementAstNode {
nodeType: 'IfStatement'
src: string
condition: object
trueBody: object
falseBody: object
trueBody: BlockAstNode | ExpressionStatementAstNode
falseBody: BlockAstNode | ExpressionStatementAstNode
}
export interface TryCatchClauseAstNode {
......@@ -338,7 +338,7 @@ export interface WhileStatementAstNode {
nodeType: 'WhileStatement' | 'DoWhileStatement'
src: string
condition: any
body: BlockAstNode
body: BlockAstNode | ExpressionStatementAstNode
}
export interface ForStatementAstNode {
......@@ -348,7 +348,7 @@ export interface ForStatementAstNode {
initializationExpression: VariableDeclarationStatementAstNode
condition: any
loopExpression: ExpressionStatementAstNode
body: BlockAstNode
body: BlockAstNode | ExpressionStatementAstNode
}
export interface ContinueAstNode {
......@@ -423,7 +423,7 @@ export interface AssignmentAstNode extends ExpressionAttributes {
nodeType: 'Assignment'
src: string
operator: string
leftHandSide: object
leftHandSide: any
rightHandSide: object
}
......
pragma solidity >=0.4.9 <0.7.0;
library Set {
contract Set {
// We define a new struct datatype that will be used to
// hold its data in the calling contract.
struct Data { mapping(uint => bool) flags; }
// struct Data { uint flags; }
// Note that the first parameter is of type "storage
// reference" and thus only its storage address and not
......@@ -11,35 +11,35 @@ library Set {
// special feature of library functions. It is idiomatic
// to call the first parameter 'self', if the function can
// be seen as a method of that object.
function insert(Data storage self, uint value) public
returns (bool)
{
if (self.flags[value])
return false; // already there
self.flags[value] = true;
//function insert(Data memory self, uint value) public
// returns (bool)
//{
// if (self.flags[value])
// return false; // already there
// self.flags[value] = true;
return true;
}
// return true;
// }
function remove(Data storage self, uint value) public
returns (bool)
{
if (!self.flags[value])
return false; // not there
self.flags[value] = false;
return true;
}
// function remove(Data memory self, uint value) public
// returns (bool)
// {
// if (!self.flags[value])
// return false; // not there
// self.flags[value] = false;
// return true;
// }
function contains(Data storage self, uint value) public
returns (bool)
function contains(uint value) public pure
returns (uint)
{
return self.flags[value];
return value;
}
}
contract C {
Set.Data knownValues;
Set x;
function register(uint value) public {
// The library functions can be called without a
......@@ -47,12 +47,18 @@ contract C {
// "instance" will be the current contract.
address payable a;
a.send(10 wei);
if (!Set.insert(knownValues, value))
revert();
//if (!Set.insert(knownValues, value))
// revert();
}
function tests2() public {
this.register(10);
x = Set(0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c);
uint y = x.contains(103);
if(y == 103){
y++;
} else {
y--;
}
}
// In this contract, we can also directly access knownValues.flags, if we want.
}
\ No newline at end of file
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