Exemple #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);
            }
        }
Exemple #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));
        }
Exemple #3
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);
            }
        }
Exemple #4
0
        private void GenerateConstants()
        {
            BoogieConstant nullConstant = new BoogieConstant(new BoogieTypedIdent("null", BoogieType.Ref), true);

            context.Program.AddDeclaration(nullConstant);

            // constants for contract names
            BoogieCtorType tnameType = new BoogieCtorType("ContractName");

            foreach (ContractDefinition contract in context.ContractDefinitions)
            {
                BoogieTypedIdent typedIdent           = new BoogieTypedIdent(contract.Name, tnameType);
                BoogieConstant   contractNameConstant = new BoogieConstant(typedIdent, true);
                context.Program.AddDeclaration(contractNameConstant);
                foreach (var node in contract.Nodes)
                {
                    if (node is StructDefinition structDefn)
                    {
                        var structTypedIdent = new BoogieTypedIdent(structDefn.CanonicalName, tnameType);
                        context.Program.AddDeclaration(new BoogieConstant(structTypedIdent, true));
                    }
                }
            }
        }
Exemple #5
0
        public void Generate()
        {
            // Collect Global Variables.
            HashSet <BoogieGlobalVariable> globals = new HashSet <BoogieGlobalVariable>();

            foreach (var decl in context.Program.Declarations)
            {
                if (decl is BoogieGlobalVariable)
                {
                    var g = (BoogieGlobalVariable)decl;

                    if (mustHaveShadow(g.Name))
                    {
                        globals.Add(g);
                    }
                }
            }

            // Generate shadow state.
            foreach (var g in globals)
            {
                var varName = g.TypedIdent.Name;
                BoogieTypedIdent     shadowGlobal     = new BoogieTypedIdent("__tmp__" + varName, g.TypedIdent.Type);
                BoogieGlobalVariable shadowGlobalDecl = new BoogieGlobalVariable(shadowGlobal);

                context.Program.AddDeclaration(shadowGlobalDecl);
                shadowGlobals.Add(varName, shadowGlobalDecl);
            }

            // Duplicate and rename methods.
            Dictionary <string, BoogieImplementation> proceduresWithImpl = new Dictionary <string, BoogieImplementation>();

            procsWiltImplNames = proceduresWithImpl.Keys;
            foreach (var decl in context.Program.Declarations)
            {
                if (decl is BoogieImplementation)
                {
                    var boogieImpl = ((BoogieImplementation)decl);
                    if (proceduresInProgram.ContainsKey(boogieImpl.Name))
                    {
                        proceduresWithImpl.Add(boogieImpl.Name, boogieImpl);
                    }
                }
            }

            Dictionary <string, BoogieProcedure> failProcedures = new Dictionary <string, BoogieProcedure>();

            foreach (var implPair in proceduresWithImpl)
            {
                BoogieProcedure proc = proceduresInProgram[implPair.Key];

                if (isPublic(proc) || isConstructor(proc.Name))
                {
                    // If public maintain original definition as the wrapper.
                    BoogieProcedure successVersion = duplicateProcedure(proc, "success", true);
                    //BoogieImplementation successImpl = duplicateImplementation(implPair.Value, "success");

                    context.Program.AddDeclaration(successVersion);
                    //context.Program.AddDeclaration(successImpl);

                    BoogieProcedure failVersion = duplicateProcedure(proc, "fail", true);

                    context.Program.AddDeclaration(failVersion);

                    // Use original name of the procedure.
                    failProcedures.Add(implPair.Key, failVersion);
                }
                else if (!isHarnessProcudure(proc.Name))
                {
                    // Otherwise reuse original definition/impl as the "successful" method.
                    BoogieProcedure failVersion = duplicateProcedure(proc, "fail");

                    context.Program.AddDeclaration(failVersion);

                    // Use original name of the procedure.
                    failProcedures.Add(implPair.Key, failVersion);

                    // Reuse original node
                    proc.Name           = proc.Name + "__success";
                    implPair.Value.Name = implPair.Value.Name + "__success";
                }
            }

            // Create implementations for failing methods.
            foreach (var failProcedurePair in failProcedures)
            {
                string          originalProcName = failProcedurePair.Key;
                BoogieProcedure proc             = failProcedurePair.Value;

                var originalImpl = proceduresWithImpl[originalProcName];
                context.Program.AddDeclaration(createFailImplementation(proc.Name, originalImpl));
                context.Program.AddDeclaration(createSuccessImplementation(originalProcName + "__success", originalImpl));

                // Remove original implementation for non-public methods
                if (!isPublic(proceduresInProgram[originalProcName]) && !isConstructor(originalProcName))
                {
                    context.Program.Declarations.Remove(originalImpl);
                }
            }

            foreach (var implPair in proceduresWithImpl)
            {
                // Update non-public methods in harness methods
                if (isHarnessProcudure(implPair.Key))
                {
                    context.Program.AddDeclaration(createSuccessImplementation(implPair.Key, implPair.Value));

                    context.Program.Declarations.Remove(implPair.Value);
                }
            }

            // Create wrappers for public methods.

            foreach (var proc in proceduresInProgram.Values)
            {
                if (proceduresWithImpl.ContainsKey(proc.Name) && (isPublic(proc) || isConstructor(proc.Name)))
                {
                    BoogieImplementation impl = proceduresWithImpl[proc.Name];
                    impl.StructuredStmts = new BoogieStmtList();
                    impl.LocalVars       = new List <BoogieVariable>();

                    var exceptionVarName = "__exception";
                    var revertGlobalName = "revert";
                    impl.LocalVars.Add(new BoogieLocalVariable(new BoogieTypedIdent(exceptionVarName, BoogieType.Bool)));

                    var stmtList = impl.StructuredStmts;
                    stmtList.AddStatement(new BoogieHavocCmd(new BoogieIdentifierExpr(exceptionVarName)));
                    stmtList.AddStatement(new BoogieAssignCmd(new BoogieIdentifierExpr(revertGlobalName), new BoogieLiteralExpr(false)));

                    // Call Successful version.
                    BoogieStmtList successCallStmtList = new BoogieStmtList();
                    successCallStmtList.AddStatement(new BoogieCallCmd(impl.Name + "__success",
                                                                       impl.InParams.Select(inParam => (BoogieExpr) new BoogieIdentifierExpr(inParam.Name)).ToList(),
                                                                       impl.OutParams.Select(outParam => new BoogieIdentifierExpr(outParam.Name)).ToList()));
                    successCallStmtList.AddStatement(new BoogieAssumeCmd(new BoogieUnaryOperation(BoogieUnaryOperation.Opcode.NOT, new BoogieIdentifierExpr(revertGlobalName))));

                    // Call fail version.
                    BoogieStmtList failCallStmtList = new BoogieStmtList();
                    // Write global variables to temps
                    foreach (var shadowGlobalPair in shadowGlobals)
                    {
                        string origVarName = shadowGlobalPair.Key;
                        string shadowName  = shadowGlobalPair.Value.Name;
                        failCallStmtList.AddStatement(new BoogieAssignCmd(new BoogieIdentifierExpr(shadowName), new BoogieIdentifierExpr(origVarName)));
                    }
                    failCallStmtList.AddStatement(new BoogieCallCmd(impl.Name + "__fail",
                                                                    impl.InParams.Select(inParam => (BoogieExpr) new BoogieIdentifierExpr(inParam.Name)).ToList(),
                                                                    impl.OutParams.Select(outParam => new BoogieIdentifierExpr(outParam.Name)).ToList()));
                    failCallStmtList.AddStatement(new BoogieAssumeCmd(new BoogieIdentifierExpr(revertGlobalName)));

                    stmtList.AddStatement(new BoogieIfCmd(new BoogieIdentifierExpr(exceptionVarName), failCallStmtList, successCallStmtList));
                }
            }
        }