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); }
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); }
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)); }
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); }