Пример #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);
        }
Пример #2
0
        private void GenerateBoogieHarnessForContract(ContractDefinition contract, Dictionary <int, BoogieExpr> houdiniVarMap)
        {
            string harnessName              = "BoogieEntry_" + contract.Name;
            List <BoogieVariable> inParams  = new List <BoogieVariable>();
            List <BoogieVariable> outParams = new List <BoogieVariable>();
            BoogieProcedure       harness   = new BoogieProcedure(harnessName, inParams, outParams);

            context.Program.AddDeclaration(harness);

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

            harnessBody.AddStatement(GenerateDynamicTypeAssumes(contract));
            GenerateConstructorCall(contract).ForEach(x => harnessBody.AddStatement(x));
            if (context.TranslateFlags.ModelReverts)
            {
                BoogieExpr assumePred = new BoogieUnaryOperation(BoogieUnaryOperation.Opcode.NOT, new BoogieIdentifierExpr("revert"));
                if (context.TranslateFlags.InstrumentGas)
                {
                    assumePred = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.AND, assumePred, new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.GE, new BoogieIdentifierExpr("gas"), new BoogieLiteralExpr(0)));
                }

                harnessBody.AddStatement(new BoogieAssumeCmd(assumePred));
            }
            harnessBody.AddStatement(GenerateWhileLoop(contract, houdiniVarMap, localVars));
            BoogieImplementation harnessImpl = new BoogieImplementation(harnessName, inParams, outParams, localVars, harnessBody);

            context.Program.AddDeclaration(harnessImpl);
        }
Пример #3
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);
        }
Пример #4
0
        private List <BoogieVariable> CollectLocalVars(ContractDefinition contract)
        {
            List <ContractDefinition> contracts = new List <ContractDefinition>()
            {
                contract
            };

            if (context.TranslateFlags.TxnsOnFields)
            {
                HashSet <VariableDeclaration> contractFields = context.GetStateVarsByContract(contract);
                foreach (VariableDeclaration contractField in contractFields)
                {
                    if (contractField.TypeDescriptions.IsContract() && contractField.TypeName is UserDefinedTypeName)
                    {
                        String             fieldContractName = contractField.TypeName.ToString();
                        ContractDefinition fieldDef          = context.GetContractByName(fieldContractName);
                        contracts.Add(fieldDef);
                    }
                }
            }

            return(TransUtils.CollectLocalVars(contracts, context));
        }
Пример #5
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);
        }