Esempio n. 1
0
        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);
            }
        }
Esempio n. 2
0
        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));
        }
Esempio n. 3
0
        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)));
        }
Esempio n. 4
0
        //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)));
        }
Esempio n. 5
0
        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)));
                        }
                    }
                }
            }
        }
Esempio n. 7
0
        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
            }));
        }
Esempio n. 8
0
        //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);
            }
        }
Esempio n. 9
0
        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)));
            }
        }
Esempio n. 11
0
        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);
        }
Esempio n. 13
0
        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);
        }