Esempio n. 1
0
        private BoogieStmtList CreateBodyOfUnknownFallback(List <BoogieVariable> fbLocalVars, List <BoogieVariable> inParams)
        {
            Debug.Assert(context.TranslateFlags.ModelStubsAsSkips() || context.TranslateFlags.ModelStubsAsCallbacks(),
                         "CreateBodyOfUnknownFallback called in unexpected context");
            var procBody = new BoogieStmtList();

            procBody.AddStatement(new BoogieCommentCmd("---- Logic for payable function START "));
            var balnSender = new BoogieMapSelect(new BoogieIdentifierExpr("Balance"), new BoogieIdentifierExpr(inParams[0].Name));
            var balnThis   = new BoogieMapSelect(new BoogieIdentifierExpr("Balance"), new BoogieIdentifierExpr(inParams[1].Name));
            var msgVal     = new BoogieIdentifierExpr("amount");

            //assume Balance[msg.sender] >= msg.value
            procBody.AddStatement(new BoogieAssumeCmd(new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.GE, balnSender, msgVal)));
            //balance[from] = balance[from] - msg.value
            procBody.AddStatement(new BoogieAssignCmd(balnSender, new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.SUB, balnSender, msgVal)));
            //balance[to] = balance[to] + msg.value
            procBody.AddStatement(new BoogieAssignCmd(balnThis, new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.ADD, balnThis, msgVal)));
            procBody.AddStatement(new BoogieCommentCmd("---- Logic for payable function END "));

            if (context.TranslateFlags.ModelStubsAsCallbacks())
            {
                fbLocalVars.AddRange(TransUtils.CollectLocalVars(context.ContractDefinitions.ToList(), context));
                // if (*) fn1(from, *, ...)
                // we only redirect the calling contract, but the msg.sender need not be to, as it can call into anohter contract that calls
                // into from
                procBody.AddStatement(TransUtils.GenerateChoiceBlock(context.ContractDefinitions.ToList(), context, Tuple.Create(inParams[0].Name, inParams[1].Name)));
            }
            return(procBody);
        }
Esempio n. 2
0
        private void GenerateCorralChoiceProcForContract(ContractDefinition contract)
        {
            string procName = "CorralChoice_" + contract.Name;
            List <BoogieVariable> inParams = new List <BoogieVariable>()
            {
                new BoogieFormalParam(new BoogieTypedIdent("this", BoogieType.Ref)),
            };
            List <BoogieVariable> outParams = new List <BoogieVariable>();
            BoogieProcedure       harness   = new BoogieProcedure(procName, inParams, outParams);

            context.Program.AddDeclaration(harness);

            List <BoogieVariable> localVars = RemoveThisFromVariables(TransUtils.CollectLocalVars(new List <ContractDefinition>()
            {
                contract
            }, context));
            BoogieStmtList procBody = GenerateHavocBlock(contract, localVars);

            procBody.AddStatement(TransUtils.GenerateChoiceBlock(new List <ContractDefinition>()
            {
                contract
            }, context));
            BoogieImplementation procImpl = new BoogieImplementation(procName, inParams, outParams, localVars, procBody);

            context.Program.AddDeclaration(procImpl);
        }
Esempio n. 3
0
        private BoogieWhileCmd GenerateWhileLoop(ContractDefinition contract, Dictionary <int, BoogieExpr> houdiniVarMap, List <BoogieVariable> localVars)
        {
            // havoc all local variables except `this'
            BoogieStmtList body = GenerateHavocBlock(contract, localVars);

            // generate the choice block
            body.AddStatement(TransUtils.GenerateChoiceBlock(new List <ContractDefinition>()
            {
                contract
            }, context));

            // generate candidate invariants for Houdini
            List <BoogiePredicateCmd> candidateInvs = new List <BoogiePredicateCmd>();

            foreach (int id in houdiniVarMap.Keys)
            {
                BoogieIdentifierExpr houdiniVar   = new BoogieIdentifierExpr(GetHoudiniVarName(id, contract));
                BoogieExpr           candidateInv = houdiniVarMap[id];
                BoogieExpr           invExpr      = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.IMP, houdiniVar, candidateInv);
                BoogieLoopInvCmd     invCmd       = new BoogieLoopInvCmd(invExpr);
                candidateInvs.Add(invCmd);
            }

            // add the contract invariant if present
            if (contractInvariants.ContainsKey(contract.Name))
            {
                contractInvariants[contract.Name].ForEach(x => candidateInvs.Add(new BoogieLoopInvCmd(x)));
            }

            return(new BoogieWhileCmd(new BoogieLiteralExpr(true), body, candidateInvs));
        }
Esempio n. 4
0
        private BoogieStmtList CreateBodyOfUnknownFallback(List <BoogieVariable> fbLocalVars, List <BoogieVariable> inParams)
        {
            Debug.Assert(context.TranslateFlags.ModelStubsAsSkips() || context.TranslateFlags.ModelStubsAsCallbacks() || context.TranslateFlags.ModelStubsAsMultipleCallbacks(),
                         "CreateBodyOfUnknownFallback called in unexpected context");
            var procBody = new BoogieStmtList();

            /*procBody.AddStatement(new BoogieCommentCmd("---- Logic for payable function START "));
             * var balnSender = new BoogieMapSelect(new BoogieIdentifierExpr("Balance"), new BoogieIdentifierExpr(inParams[0].Name));
             * var balnThis = new BoogieMapSelect(new BoogieIdentifierExpr("Balance"), new BoogieIdentifierExpr(inParams[1].Name));
             * var msgVal = new BoogieIdentifierExpr("amount");
             * //assume Balance[msg.sender] >= msg.value
             * procBody.AddStatement(new BoogieAssumeCmd(new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.GE, balnSender, msgVal)));
             * //balance[from] = balance[from] - msg.value
             * procBody.AddStatement(new BoogieAssignCmd(balnSender, new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.SUB, balnSender, msgVal)));
             * //balance[to] = balance[to] + msg.value
             * procBody.AddStatement(new BoogieAssignCmd(balnThis, new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.ADD, balnThis, msgVal)));
             * procBody.AddStatement(new BoogieCommentCmd("---- Logic for payable function END "));*/

            BoogieStmtList body = procBody;

            if (context.TranslateFlags.ModelStubsAsCallbacks() ||
                context.TranslateFlags.ModelStubsAsMultipleCallbacks())
            {
                if (context.TranslateFlags.ModelReverts)
                {
                    BoogieBinaryOperation revertGuard = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.EQ, new BoogieIdentifierExpr("choice"), new BoogieLiteralExpr(BigInteger.Zero));
                    BoogieStmtList        thenBody    = new BoogieStmtList();
                    thenBody.AddStatement(new BoogieAssignCmd(new BoogieIdentifierExpr("revert"), new BoogieLiteralExpr(true)));
                    thenBody.AddStatement(new BoogieReturnCmd());
                    BoogieIfCmd earlyExitCmd = new BoogieIfCmd(revertGuard, thenBody, null);
                    body.AddStatement(earlyExitCmd);
                }
                if (context.TranslateFlags.InstrumentGas)
                {
                    BoogieBinaryOperation gasGuard     = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.LT, new BoogieIdentifierExpr("gas"), new BoogieLiteralExpr(TranslatorContext.TX_GAS_COST));
                    BoogieIfCmd           earlyExitCmd = new BoogieIfCmd(gasGuard, BoogieStmtList.MakeSingletonStmtList(new BoogieReturnCmd()), null);
                    body.AddStatement(earlyExitCmd);
                }
            }

            if (context.TranslateFlags.ModelStubsAsMultipleCallbacks())
            {
                fbLocalVars.Add(new BoogieLocalVariable(new BoogieTypedIdent("iterate", BoogieType.Bool)));
                BoogieBinaryOperation gasGuard = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.GE, new BoogieIdentifierExpr("gas"), new BoogieLiteralExpr(TranslatorContext.TX_GAS_COST));
                BoogieBinaryOperation guard    = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.AND, new BoogieIdentifierExpr("iterate"), gasGuard);
                BoogieStmtList        loopBody = new BoogieStmtList();
                procBody.AddStatement(new BoogieWhileCmd(guard, loopBody, new List <BoogieExpr>()));
                body = loopBody;
            }

            if (context.TranslateFlags.ModelStubsAsCallbacks() || context.TranslateFlags.ModelStubsAsMultipleCallbacks())
            {
                List <BoogieVariable> localVars = TransUtils.CollectLocalVars(context.ContractDefinitions.ToList(), context);
                fbLocalVars.AddRange(localVars);
                // if (*) fn1(from, *, ...)
                // we only redirect the calling contract, but the msg.sender need not be to, as it can call into anohter contract that calls
                // into from

                if (context.TranslateFlags.ModelStubsAsMultipleCallbacks())
                {
                    body.AppendStmtList(HavocLocals(localVars));
                    body.AddStatement(new BoogieHavocCmd(new BoogieIdentifierExpr("iterate")));
                }


                BoogieIfCmd typeIf = null;
                foreach (ContractDefinition curDef in context.ContractDefinitions.ToList())
                {
                    BoogieIfCmd reentrantCalls = TransUtils.GenerateChoiceBlock(new List <ContractDefinition>()
                    {
                        curDef
                    },
                                                                                context, false, Tuple.Create(inParams[0].Name, inParams[1].Name));

                    if (reentrantCalls == null)
                    {
                        continue;
                    }

                    BoogieExpr            dtype = new BoogieMapSelect(new BoogieIdentifierExpr("DType"), new BoogieIdentifierExpr(inParams[0].Name));
                    BoogieBinaryOperation guard = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.EQ, dtype, new BoogieIdentifierExpr(curDef.Name));
                    typeIf = new BoogieIfCmd(guard, BoogieStmtList.MakeSingletonStmtList(reentrantCalls), typeIf == null ? null : BoogieStmtList.MakeSingletonStmtList(typeIf));
                }

                /*BoogieIfCmd ifCmd = null;
                 *
                 * if (context.TranslateFlags.ModelReverts)
                 * {
                 *  BoogieExpr guard = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.EQ,
                 *                      new BoogieIdentifierExpr("choice"),
                 *                      new BoogieLiteralExpr(choices.Item2 + 1));
                 *
                 *  BoogieAssignCmd assign = new BoogieAssignCmd(new BoogieIdentifierExpr("revert"), new BoogieLiteralExpr(true));
                 *  ifCmd = new BoogieIfCmd(guard, BoogieStmtList.MakeSingletonStmtList(assign), BoogieStmtList.MakeSingletonStmtList(choices.Item1));
                 * }
                 * else
                 * {
                 *  ifCmd = choices.Item1;
                 * }*/

                body.AddStatement(typeIf);
            }



            return(procBody);
        }