//returns a boogieAST reference, containing all captured elements of the sol file in question public BoogieAST Translate(AST solidityAST, HashSet <Tuple <string, string> > ignoredMethods, Flags_HelperClass _translatorFlags = null) { //ignored methods and translator flags need to be remove as not enough time to implement these. sourceUnits = solidityAST.GetSourceUnits(); //create an empty AST_Handler Instance with no ignored method, generate InlineAttributes and no translator flags. AST_Handler context = new AST_Handler(ignoredMethods, true, _translatorFlags); context.IdToNodeMap = solidityAST.GetIdToNodeMap(); context.SourceDirectory = solidityAST.SourceDirectory; //assign class instance to temporary instance and use it throughout the rest of the //process to populate it. classTranslatorContext = context; //Execute Collection process from given sol contract. //Will enable boogie conversion to occur once specific states/functions/variables have been retrieved from the contract. executeSourceInfoCollector(); executeContractCollection(); executeInheritanceCollector(); executeStateVariableCollector(); executeMapArrayCollector(); executeConstructorCollector(); executeFunctionEventCollector(); executeFunctionEventResolver(); executeBoogieGenerator(); executeDefinitionsCollector(); executeProcessHandler(); // generate harness for contract // non specifiable property, harness is always created and cannot be altered in this code OverSight_Harness_Generator harnessGenerator = new OverSight_Harness_Generator(); harnessGenerator.setTranslatorContext(classTranslatorContext); harnessGenerator.createHarness(); BoogieAST completeAST = new BoogieAST(classTranslatorContext.getProgram); Debug.Assert(completeAST != null); //returns the BoogieAST containing the root property, where the declarations of the contract are present. return(completeAST); }
public void setContext(AST_Handler context) { this.classTranslationContext = context; }
public OverSight_Boogie_Generate_Properties(AST_Handler context) { this.context = context; }
public void setContext(AST_Handler context) { //assigned updated context to local context this.classTranslatorContext = context; }
//provides base context, called after instantiation public void setContext(AST_Handler tempContext) { this.classTranslatorContext = tempContext; }
/** * Set the given handler contex to a temporary instance. */ public void setTranslatorContext(AST_Handler givenContext) { this.classTranslatorContext = givenContext; }
public void setContext(AST_Handler context) { //pass the updated AST_Handler instance to the class translative context //Reassignment is not neccessary as any additons or modifications to the codw is handled back within the AST_Handler this.classTransContext = context; }
public void setContext(AST_Handler context) { this.classContext = context; }
public static List <BoogieVariable> CollectLocalVars(List <ContractDefinition> contracts, AST_Handler context) { Debug.Assert(contracts.Count > 0, "Internal exception: expecting at least one contract here"); List <BoogieVariable> localVars = new List <BoogieVariable>() { new BoogieLocalVariable(new BoogieTypedIdent("this", BoogieType.Ref)), new BoogieLocalVariable(new BoogieTypedIdent("msgsender_MSG", BoogieType.Ref)), new BoogieLocalVariable(new BoogieTypedIdent("msgvalue_MSG", BoogieType.Int)), new BoogieLocalVariable(new BoogieTypedIdent("choice", BoogieType.Int)), }; // use to remove duplicated variables by name HashSet <string> uniqueVarNames = new HashSet <string>() { "this", "msgsender_MSG", "msgvalue_MSG", "choice" }; foreach (var contract in contracts) { if (contract.ContractKind != EnumContractKind.CONTRACT) { continue; } // Consider all visible functions HashSet <FunctionDefinition> funcDefs = context.RetrieveVisibleFunctions(contract); foreach (FunctionDefinition funcDef in funcDefs) { if (funcDef.Visibility == EnumVisibility.PUBLIC || funcDef.Visibility == EnumVisibility.EXTERNAL) { var inpParamCount = 0; foreach (VariableDeclaration param in funcDef.Parameters.Parameters) { string name = $"__arg_{inpParamCount++}_" + funcDef.Name; if (!string.IsNullOrEmpty(param.Name)) { name = Conversion_Utility_Tool.GetCanonicalLocalVariableName(param, context); } if (!uniqueVarNames.Contains(name)) { BoogieType type = Conversion_Utility_Tool.GetBoogieTypeFromSolidityTypeName(param.TypeName); BoogieVariable localVar = new BoogieLocalVariable(new BoogieTypedIdent(name, type)); localVars.Add(localVar); uniqueVarNames.Add(name); } } var retParamCount = 0; foreach (VariableDeclaration param in funcDef.ReturnParameters.Parameters) { string name = $"__ret_{retParamCount++}_" + funcDef.Name; if (!string.IsNullOrEmpty(param.Name)) { name = Conversion_Utility_Tool.GetCanonicalLocalVariableName(param, context); } if (!uniqueVarNames.Contains(name)) { BoogieType type = Conversion_Utility_Tool.GetBoogieTypeFromSolidityTypeName(param.TypeName); BoogieVariable localVar = new BoogieLocalVariable(new BoogieTypedIdent(name, type)); localVars.Add(localVar); uniqueVarNames.Add(name); } } } } } return(localVars); }
/// <summary> /// generate a non-deterministic choice block to call every public visible functions except constructors /// /// </summary> /// <param name="contracts"></param> /// <param name="context"></param> /// <param name="callBackTarget">If non-null, this will be the msg.sender for calling back into the contracts</param> /// <returns></returns> public static BoogieIfCmd GenerateChoiceBlock(List <ContractDefinition> contracts, AST_Handler context, Tuple <string, string> callBackTarget = null) { BoogieIfCmd ifCmd = null; int j = 0; foreach (var contract in contracts) { if (contract.ContractKind != EnumContractKind.CONTRACT) { continue; } HashSet <FunctionDefinition> funcDefs = context.RetrieveVisibleFunctions(contract); List <FunctionDefinition> publicFuncDefs = new List <FunctionDefinition>(); foreach (FunctionDefinition funcDef in funcDefs) { if (funcDef.ofConstructorType) { continue; } if (funcDef.ofFallBackType) { continue; //let us not call fallback directly in harness } if (funcDef.Visibility == EnumVisibility.PUBLIC || funcDef.Visibility == EnumVisibility.EXTERNAL) { publicFuncDefs.Add(funcDef); } } for (int i = publicFuncDefs.Count - 1; i >= 0; --i) { j++; BoogieExpr guard = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.EQ, new BoogieIdentifierExpr("choice"), new BoogieLiteralExpr(j)); BoogieStmtList thenBody = new BoogieStmtList(); FunctionDefinition funcDef = publicFuncDefs[i]; string callee = Conversion_Utility_Tool.GetCanonicalFunctionName(funcDef, context); List <BoogieExpr> inputs = new List <BoogieExpr>() { // let us just call back into the calling contract callBackTarget != null ? new BoogieIdentifierExpr(callBackTarget.Item1) : new BoogieIdentifierExpr("this"), callBackTarget != null ? new BoogieIdentifierExpr(callBackTarget.Item2) : new BoogieIdentifierExpr("msgsender_MSG"), new BoogieIdentifierExpr("msgvalue_MSG"), }; var inpParamCount = 0; foreach (VariableDeclaration param in funcDef.Parameters.Parameters) { string name = $"__arg_{inpParamCount++}_" + funcDef.Name; if (!string.IsNullOrEmpty(param.Name)) { name = Conversion_Utility_Tool.GetCanonicalLocalVariableName(param, context); } inputs.Add(new BoogieIdentifierExpr(name)); if (param.TypeName is ArrayTypeName array) { thenBody.AddStatement(new BoogieCallCmd( "FreshRefGenerator", new List <BoogieExpr>(), new List <BoogieIdentifierExpr>() { new BoogieIdentifierExpr(name) })); } } List <BoogieIdentifierExpr> outputs = new List <BoogieIdentifierExpr>(); var retParamCount = 0; foreach (VariableDeclaration param in funcDef.ReturnParameters.Parameters) { string name = $"__ret_{retParamCount++}_" + funcDef.Name; if (!string.IsNullOrEmpty(param.Name)) { name = Conversion_Utility_Tool.GetCanonicalLocalVariableName(param, context); } outputs.Add(new BoogieIdentifierExpr(name)); } if (Flags_HelperClass.InstrumentGas) { havocGas(thenBody); } BoogieCallCmd callCmd = new BoogieCallCmd(callee, inputs, outputs); thenBody.AddStatement(callCmd); BoogieStmtList elseBody = ifCmd == null ? null : BoogieStmtList.MakeSingletonStmtList(ifCmd); ifCmd = new BoogieIfCmd(guard, thenBody, elseBody); } } return(ifCmd); }
public static Tuple <string, int> GenerateSourceInfoAnnotation(ASTNode node, AST_Handler context) { return(Tuple.Create <string, int>(context.GetAbsoluteSourcePathOfASTNode(node), context.GetLineNumberOfASTNode(node))); }
public static string InferFunctionSignature(AST_Handler context, FunctionCall node) { Debug.Assert(node.Arguments != null); if (node.Expression is MemberAccess memberAccess) { Debug.Assert(memberAccess.ReferencedDeclaration != null); FunctionDefinition function = context.retrieveASTNodethroughID(memberAccess.ReferencedDeclaration.Value) as FunctionDefinition; Debug.Assert(function != null, $"Could not find function {node.ToString()}"); StringBuilder builder = new StringBuilder(); builder.Append(function.Name).Append("("); if (function.Parameters.Parameters != null && function.Parameters.Parameters.Count > 0) { foreach (VariableDeclaration varDecl in function.Parameters.Parameters) { builder.Append(varDecl.TypeDescriptions.TypeString).Append(", "); } builder.Length -= 2; } builder.Append(")"); return(builder.ToString()); } else { string functionName = GetFuncNameFromFuncCall(node); StringBuilder builder = new StringBuilder(); builder.Append(functionName).Append("("); if (node.Arguments.Count > 0) { foreach (Expression argument in node.Arguments) { string typeString = argument.TypeDescriptions.TypeString; if (typeString.StartsWith("int_const")) { typeString = "int256"; } if (typeString.StartsWith("uint_const")) { typeString = "int256"; } if (typeString.StartsWith("string") || typeString.StartsWith("literal_string")) { typeString = "string"; } if (typeString.StartsWith("bytes ")) { typeString = "bytes"; //"bytes storage ref" } if (typeString.Contains(" memory")) //"struct Foo memory" { typeString = typeString.Substring(0, typeString.IndexOf(" memory")); } if (typeString.Contains(" storage")) { typeString = typeString.Substring(0, typeString.IndexOf(" storage")); } if (typeString.Contains(" payable")) { typeString = typeString.Substring(0, typeString.IndexOf(" payable")); //address payable } builder.Append(typeString).Append(", "); } builder.Length -= 2; } builder.Append(")"); return(builder.ToString()); } }
public static string GetCanonicalFunctionName(FunctionDefinition funcDef, AST_Handler context) { ContractDefinition contract = context.GetContractByFunction(funcDef); return(funcDef.Name + "_" + contract.Name); }
public static string GetCanonicalStateVariableName(VariableDeclaration varDecl, AST_Handler context) { Debug.Assert(varDecl.StateVariable, $"{varDecl.Name} is not a state variable"); Dictionary <VariableDeclaration, ContractDefinition> varToContractMap = context.StateVarToContractMap; Debug.Assert(varToContractMap.ContainsKey(varDecl), $"Cannot find state variable: {varDecl.Name}"); return(varDecl.Name + "_" + varToContractMap[varDecl].Name); }
public static string GetCanonicalLocalVariableName(VariableDeclaration varDecl, AST_Handler context) { if (Flags_HelperClass.RemoveScopeInVarName) { return(varDecl.Name); // not recommended } return(varDecl.Name + "_s" + varDecl.Scope.ToString()); }