private void GenerateGlobalVariables() { BoogieTypedIdent dtypeId = new BoogieTypedIdent("DType", new BoogieMapType(BoogieType.Ref, contractType)); BoogieGlobalVariable dtype = new BoogieGlobalVariable(dtypeId); context.Program.AddDeclaration(dtype); BoogieTypedIdent allocId = new BoogieTypedIdent("Alloc", new BoogieMapType(BoogieType.Ref, BoogieType.Bool)); BoogieGlobalVariable alloc = new BoogieGlobalVariable(allocId); context.Program.AddDeclaration(alloc); BoogieTypedIdent addrBalanceId = new BoogieTypedIdent("balance_ADDR", new BoogieMapType(BoogieType.Ref, BoogieType.Int)); BoogieGlobalVariable addrBalance = new BoogieGlobalVariable(addrBalanceId); context.Program.AddDeclaration(addrBalance); // generate global variables for each array/mapping type to model memory GenerateMemoryVariables(); BoogieMapType type = new BoogieMapType(BoogieType.Ref, BoogieType.Int); BoogieTypedIdent arrayLengthId = new BoogieTypedIdent("Length", type); BoogieGlobalVariable arrayLength = new BoogieGlobalVariable(arrayLengthId); context.Program.AddDeclaration(arrayLength); if (context.TranslateFlags.ModelReverts) { BoogieTypedIdent revertId = new BoogieTypedIdent("revert", BoogieType.Bool); BoogieGlobalVariable revert = new BoogieGlobalVariable(revertId); context.Program.AddDeclaration(revert); } }
private void GenerateGlobalVariables() { BoogieTypedIdent balanceId = new BoogieTypedIdent("Balance", new BoogieMapType(BoogieType.Ref, BoogieType.Int)); BoogieGlobalVariable balanceVar = new BoogieGlobalVariable(balanceId); context.Program.AddDeclaration(balanceVar); BoogieTypedIdent dtypeId = new BoogieTypedIdent("DType", new BoogieMapType(BoogieType.Ref, contractType)); BoogieGlobalVariable dtype = new BoogieGlobalVariable(dtypeId); context.Program.AddDeclaration(dtype); BoogieTypedIdent allocId = new BoogieTypedIdent("Alloc", new BoogieMapType(BoogieType.Ref, BoogieType.Bool)); BoogieGlobalVariable alloc = new BoogieGlobalVariable(allocId); context.Program.AddDeclaration(alloc); BoogieTypedIdent addrBalanceId = new BoogieTypedIdent("balance_ADDR", new BoogieMapType(BoogieType.Ref, BoogieType.Int)); BoogieGlobalVariable addrBalance = new BoogieGlobalVariable(addrBalanceId); context.Program.AddDeclaration(addrBalance); // generate global variables for each array/mapping type to model memory GenerateMemoryVariables(); BoogieMapType type = new BoogieMapType(BoogieType.Ref, BoogieType.Int); BoogieTypedIdent arrayLengthId = new BoogieTypedIdent("Length", type); BoogieGlobalVariable arrayLength = new BoogieGlobalVariable(arrayLengthId); context.Program.AddDeclaration(arrayLength); if (context.TranslateFlags.ModelReverts) { BoogieTypedIdent revertId = new BoogieTypedIdent("revert", BoogieType.Bool); BoogieGlobalVariable revert = new BoogieGlobalVariable(revertId); context.Program.AddDeclaration(revert); } if (context.TranslateFlags.InstrumentGas) { BoogieTypedIdent gasId = new BoogieTypedIdent("gas", BoogieType.Int); BoogieGlobalVariable gas = new BoogieGlobalVariable(gasId); context.Program.AddDeclaration(gas); } if (context.TranslateFlags.InstrumentSums) { BoogieTypedIdent sumId = new BoogieTypedIdent("sum", new BoogieMapType(BoogieType.Ref, BoogieType.Int)); BoogieGlobalVariable sum = new BoogieGlobalVariable(sumId); context.Program.AddDeclaration(sum); } // Solidity-specific vars BoogieTypedIdent nowVar = new BoogieTypedIdent("now", BoogieType.Int); context.Program.AddDeclaration(new BoogieGlobalVariable(nowVar)); }
private void GenerateSingleMemoryVariable(BoogieType keyType, BoogieType valType) { BoogieMapType map = new BoogieMapType(keyType, valType); map = new BoogieMapType(BoogieType.Ref, map); string name = MapArrayHelper.GetMemoryMapName(keyType, valType); context.Program.AddDeclaration(new BoogieGlobalVariable(new BoogieTypedIdent(name, map))); }
//Build Single Memory Map using key and value types private void BuildSingleMapMemoryName(BoogieType keyTypes, BoogieType valueTypes) { BoogieMapType map = new BoogieMapType(keyTypes, valueTypes); map = new BoogieMapType(BoogieType.Ref, map); string name = Flags_HelperClass.generateMemoryMapName(keyTypes, valueTypes); context.getProgram.AddBoogieDeclaration(new BoogieGlobalVariable(new BoogieTypedIdent(name, map))); }
public List <BoogieDeclaration> GetMultiDimArrayLens(VariableDeclaration decl) { List <BoogieDeclaration> lenVars = new List <BoogieDeclaration>(); TypeName curType = decl.TypeName; List <BoogieType> indTypes = new List <BoogieType>() { BoogieType.Ref }; int lvl = 0; while (curType is Mapping || curType is ArrayTypeName) { if (curType is Mapping map) { curType = map.ValueType; indTypes.Add(TransUtils.GetBoogieTypeFromSolidityTypeName(map.KeyType)); } else if (curType is ArrayTypeName arr) { BoogieType mapType = BoogieType.Int; BoogieType initType = BoogieType.Int; for (int i = indTypes.Count - 1; i >= 0; i--) { initType = mapType; mapType = new BoogieMapType(indTypes[i], mapType); } if (arr.Length != null && initType is BoogieMapType lenMap) { BoogieFunction initFn = GenerateMultiDimInitFunction(lenMap); lenVars.Add(initFn); } BoogieGlobalVariable lenVar = new BoogieGlobalVariable(new BoogieTypedIdent(GetMultiDimLengthName(decl, lvl), mapType)); lenVars.Add(lenVar); curType = arr.BaseType; indTypes.Add(BoogieType.Int); } lvl++; } return(lenVars); }
private void GenerateMemoryVariables() { HashSet <String> generatedMaps = new HashSet <String>(); // mappings foreach (ContractDefinition contract in context.ContractToMappingsMap.Keys) { foreach (VariableDeclaration varDecl in context.ContractToMappingsMap[contract]) { Debug.Assert(varDecl.TypeName is Mapping); Mapping mapping = varDecl.TypeName as Mapping; GenerateMemoryVariablesForMapping(varDecl, mapping, generatedMaps, 0); if (context.TranslateFlags.InstrumentSums) { String sumName = mapHelper.GetSumName(varDecl); if (!generatedMaps.Contains(sumName)) { generatedMaps.Add(sumName); BoogieType sumType = new BoogieMapType(BoogieType.Ref, BoogieType.Int); context.Program.AddDeclaration(new BoogieGlobalVariable(new BoogieTypedIdent(sumName, sumType))); } } } } // arrays foreach (ContractDefinition contract in context.ContractToArraysMap.Keys) { foreach (VariableDeclaration varDecl in context.ContractToArraysMap[contract]) { Debug.Assert(varDecl.TypeName is ArrayTypeName); ArrayTypeName array = varDecl.TypeName as ArrayTypeName; GenerateMemoryVariablesForArray(varDecl, array, generatedMaps, 0); if (context.TranslateFlags.InstrumentSums) { String sumName = mapHelper.GetSumName(varDecl); if (!generatedMaps.Contains(sumName)) { generatedMaps.Add(sumName); BoogieType sumType = new BoogieMapType(BoogieType.Ref, BoogieType.Int); context.Program.AddDeclaration(new BoogieGlobalVariable(new BoogieTypedIdent(sumName, sumType))); } } } } }
public static BoogieFunction GenerateMultiDimZeroFunction(VariableDeclaration decl) { TypeName curType = decl.TypeName; List <BoogieType> boogieType = new List <BoogieType>(); while (curType is Mapping || curType is ArrayTypeName) { if (curType is Mapping map) { boogieType.Insert(0, TransUtils.GetBoogieTypeFromSolidityTypeName(map.KeyType)); curType = map.ValueType; } else if (curType is ArrayTypeName arr) { boogieType.Insert(0, BoogieType.Int); curType = arr.BaseType; } } BoogieType valType = TransUtils.GetBoogieTypeFromSolidityTypeName(curType); BoogieExpr boogieInit = TransUtils.GetDefaultVal(valType); string smtType = GetSmtType(valType); string smtInit = boogieInit.ToString().Equals("null") ? "0" : boogieInit.ToString(); BoogieType mapType = valType; string fnName = $"{valType.ToString()}Arr"; foreach (BoogieType type in boogieType) { smtType = $"(Array {GetSmtType(type)} {smtType})"; mapType = new BoogieMapType(type, mapType); smtInit = $"((as const {smtType}) {smtInit})"; fnName = $"{type.ToString()}{fnName}"; } var outVar = new BoogieFormalParam(new BoogieTypedIdent("ret", mapType)); var smtDefinedAttr = new BoogieAttribute("smtdefined", $"\"{smtInit}\""); return(new BoogieFunction($"zero{fnName}", new List <BoogieVariable>(), new List <BoogieVariable>() { outVar }, new List <BoogieAttribute>() { smtDefinedAttr })); }
//Function to build standard global variables for Boogie expressions set. private void buildGlobalVariables() { BoogieTypedIdent balanceId = new BoogieTypedIdent("Balance", new BoogieMapType(BoogieType.Ref, BoogieType.Int)); BoogieGlobalVariable balanceVar = new BoogieGlobalVariable(balanceId); context.getProgram.AddBoogieDeclaration(balanceVar); BoogieTypedIdent dtypeId = new BoogieTypedIdent("DType", new BoogieMapType(BoogieType.Ref, new BoogieCtorType("ContractName"))); BoogieGlobalVariable dtype = new BoogieGlobalVariable(dtypeId); context.getProgram.AddBoogieDeclaration(dtype); BoogieTypedIdent addrBalanceId = new BoogieTypedIdent("balance_ADDR", new BoogieMapType(BoogieType.Ref, BoogieType.Int)); BoogieGlobalVariable addrBalance = new BoogieGlobalVariable(addrBalanceId); context.getProgram.AddBoogieDeclaration(addrBalance); BoogieTypedIdent allocId = new BoogieTypedIdent("Alloc", new BoogieMapType(BoogieType.Ref, BoogieType.Bool)); BoogieGlobalVariable alloc = new BoogieGlobalVariable(allocId); context.getProgram.AddBoogieDeclaration(alloc); // generate global variables for each array/mapping type to model memory ConstructMemoryVariables(); BoogieMapType type = new BoogieMapType(BoogieType.Ref, BoogieType.Int); BoogieTypedIdent arrayLengthId = new BoogieTypedIdent("Length", type); BoogieGlobalVariable arrayLength = new BoogieGlobalVariable(arrayLengthId); context.getProgram.AddBoogieDeclaration(arrayLength); if (context.TranslateFlags.ModelReverts == true) { BoogieTypedIdent revertId = new BoogieTypedIdent("revert", BoogieType.Bool); BoogieGlobalVariable revert = new BoogieGlobalVariable(revertId); context.getProgram.AddBoogieDeclaration(revert);// } if (Flags_HelperClass.InstrumentGas == true) { BoogieTypedIdent gasId = new BoogieTypedIdent("gas", BoogieType.Int); BoogieGlobalVariable gas = new BoogieGlobalVariable(gasId); context.getProgram.AddBoogieDeclaration(gas); } }
public static BoogieFunction GenerateMultiDimInitFunction(BoogieMapType type) { BoogieType curType = type; List <BoogieType> boogieType = new List <BoogieType>(); while (curType is BoogieMapType map) { if (map.Arguments.Count != 1) { throw new Exception("Boogie map must have one argument"); } boogieType.Insert(0, map.Arguments[0]); curType = map.Result; } BoogieVariable arg = new BoogieFormalParam(new BoogieTypedIdent("n", curType)); string smtInit = "n"; string smtType = GetSmtType(curType); string fnName = $"{curType.ToString()}Arr"; foreach (BoogieType dimType in boogieType) { smtType = $"(Array {GetSmtType(dimType)} {smtType})"; smtInit = $"((as const {smtType}) {smtInit})"; fnName = $"{dimType.ToString()}{fnName}"; } var outVar = new BoogieFormalParam(new BoogieTypedIdent("ret", type)); var smtDefinedAttr = new BoogieAttribute("smtdefined", $"\"{smtInit}\""); return(new BoogieFunction($"init{fnName}", new List <BoogieVariable>() { arg }, new List <BoogieVariable>() { outVar }, new List <BoogieAttribute>() { smtDefinedAttr })); }
private void GenerateSingleMemoryVariable(VariableDeclaration decl, BoogieType keyType, BoogieType valType, HashSet <String> generatedMaps) { BoogieMapType map = new BoogieMapType(keyType, valType); map = new BoogieMapType(BoogieType.Ref, map); string name = mapHelper.GetMemoryMapName(decl, keyType, valType); if (!generatedMaps.Contains(name)) { BoogieFunction initFn = MapArrayHelper.GenerateMultiDimZeroFunction(keyType, valType); if (!context.initFns.Contains(initFn.Name)) { context.initFns.Add(initFn.Name); context.Program.AddDeclaration(initFn); } generatedMaps.Add(name); context.Program.AddDeclaration(new BoogieGlobalVariable(new BoogieTypedIdent(name, map))); } }
public static BoogieFunction GenerateMultiDimZeroFunction(BoogieType keyType, BoogieType valType) { BoogieExpr boogieInit = TransUtils.GetDefaultVal(valType); string smtType = GetSmtType(valType); BoogieType mapType = new BoogieMapType(keyType, valType); string fnName = $"zero{keyType.ToString()}{valType.ToString()}Arr"; string smtInit = boogieInit.ToString().Equals("null") ? "0" : boogieInit.ToString(); smtInit = $"((as const (Array {GetSmtType(keyType)} {smtType})) {smtInit})"; var outVar = new BoogieFormalParam(new BoogieTypedIdent("ret", mapType)); var smtDefinedAttr = new BoogieAttribute("smtdefined", $"\"{smtInit}\""); return(new BoogieFunction(fnName, new List <BoogieVariable>(), new List <BoogieVariable>() { outVar }, new List <BoogieAttribute>() { smtDefinedAttr })); }
private void GenerateMemoryVariablesForArray(VariableDeclaration decl, ArrayTypeName array, HashSet <String> generatedMaps, int lvl) { BoogieType boogieKeyType = BoogieType.Int; BoogieType boogieValType = null; if (array.BaseType is ArrayTypeName subarray) { boogieValType = BoogieType.Ref; GenerateMemoryVariablesForArray(decl, subarray, generatedMaps, lvl + 1); // The last level gets initialized all at once if (context.TranslateFlags.LazyAllocNoMod) { BoogieMapType mapType = new BoogieMapType(BoogieType.Ref, new BoogieMapType(boogieKeyType, BoogieType.Bool)); context.Program.AddDeclaration(new BoogieGlobalVariable(new BoogieTypedIdent(mapHelper.GetNestedAllocName(decl, lvl), mapType))); } } else if (array.BaseType is Mapping mapping) { boogieValType = BoogieType.Ref; GenerateMemoryVariablesForMapping(decl, mapping, generatedMaps, lvl + 1); if (context.TranslateFlags.LazyAllocNoMod) { BoogieMapType mapType = new BoogieMapType(BoogieType.Ref, new BoogieMapType(boogieKeyType, BoogieType.Bool)); context.Program.AddDeclaration(new BoogieGlobalVariable(new BoogieTypedIdent(mapHelper.GetNestedAllocName(decl, lvl), mapType))); } } else { boogieValType = TransUtils.GetBoogieTypeFromSolidityTypeName(array.BaseType); } KeyValuePair <BoogieType, BoogieType> pair = new KeyValuePair <BoogieType, BoogieType>(boogieKeyType, boogieValType); GenerateSingleMemoryVariable(decl, boogieKeyType, boogieValType, generatedMaps); }
public static BoogieType GetMultiDimBoogieType(TypeName varType) { if (!(varType is Mapping || varType is ArrayTypeName)) { return(TransUtils.GetBoogieTypeFromSolidityTypeName(varType)); } BoogieType resultType = null; if (varType is Mapping map) { BoogieType valType = GetMultiDimBoogieType(map.ValueType); BoogieType keyType = GetMultiDimBoogieType(map.KeyType); resultType = new BoogieMapType(keyType, valType); } else if (varType is ArrayTypeName arr) { BoogieType baseType = GetMultiDimBoogieType(arr.BaseType); resultType = new BoogieMapType(BoogieType.Int, baseType); } return(resultType); }