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 = CollectLocalVars(contract); 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); }
private void GenerateCorralHarnessForContract(ContractDefinition contract) { string harnessName = "CorralEntry_" + contract.Name; if (context.TranslateFlags.CreateMainHarness && contract.Name.Equals(context.EntryPointContract)) { harnessName = "main"; } 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 = new List <BoogieVariable> { new BoogieLocalVariable(new BoogieTypedIdent("this", BoogieType.Ref)), new BoogieLocalVariable(new BoogieTypedIdent("msgsender_MSG", BoogieType.Ref)), new BoogieLocalVariable(new BoogieTypedIdent("msgvalue_MSG", BoogieType.Int)), }; if (context.IsConstructorDefined(contract)) { FunctionDefinition ctor = context.GetConstructorByContract(contract); localVars.AddRange(GetParamsOfFunction(ctor)); } BoogieStmtList harnessBody = new BoogieStmtList(); //harnessBody.AddStatement(new BoogieAssignCmd(new BoogieIdentifierExpr("this"), )); if (context.TranslateFlags.NoCustomTypes) { harnessBody.AddStatement((new BoogieAssumeCmd(new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.EQ, new BoogieIdentifierExpr("null"), new BoogieLiteralExpr(0))))); } harnessBody.AddStatement(new BoogieCallCmd("FreshRefGenerator", new List <BoogieExpr>(), new List <BoogieIdentifierExpr>() { new BoogieIdentifierExpr("this") })); harnessBody.AddStatement(new BoogieAssumeCmd(new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.GE, new BoogieIdentifierExpr("now"), new BoogieLiteralExpr(0)))); 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(GenerateCorralWhileLoop(contract)); BoogieImplementation harnessImpl = new BoogieImplementation(harnessName, inParams, outParams, localVars, harnessBody); context.Program.AddDeclaration(harnessImpl); }
private BoogieExpr dupAndReplaceExpr(BoogieExpr expr, bool isFail, bool inHarness) { List <BoogieExpr> dupAndReplaceExprList(List <BoogieExpr> exprs) { return(exprs.Select(e => dupAndReplaceExpr(e, isFail, inHarness)).ToList()); } if (expr is BoogieIdentifierExpr) { string idName = ((BoogieIdentifierExpr)expr).Name; if (isFail && shadowGlobals.ContainsKey(idName)) { return(new BoogieIdentifierExpr(shadowGlobals[idName].Name)); } return(expr); } if (expr is BoogieMapSelect) { BoogieMapSelect selectExpr = (BoogieMapSelect)expr; return(new BoogieMapSelect(dupAndReplaceExpr(selectExpr.BaseExpr, isFail, inHarness), dupAndReplaceExprList(selectExpr.Arguments))); } if (expr is BoogieMapUpdate) { BoogieMapUpdate updateExpr = (BoogieMapUpdate)expr; return(new BoogieMapUpdate(dupAndReplaceExpr(updateExpr.BaseExpr, isFail, inHarness), dupAndReplaceExprList(updateExpr.Arguments), dupAndReplaceExpr(updateExpr.Value, isFail, inHarness))); } if (expr is BoogieUnaryOperation) { BoogieUnaryOperation unaryOperation = (BoogieUnaryOperation)expr; return(new BoogieUnaryOperation(unaryOperation.Op, dupAndReplaceExpr(unaryOperation.Expr, isFail, inHarness))); } if (expr is BoogieBinaryOperation) { BoogieBinaryOperation binOperation = (BoogieBinaryOperation)expr; return(new BoogieBinaryOperation(binOperation.Op, dupAndReplaceExpr(binOperation.Lhs, isFail, inHarness), dupAndReplaceExpr(binOperation.Rhs, isFail, inHarness))); } if (expr is BoogieITE) { BoogieITE iteExpr = (BoogieITE)expr; return(new BoogieITE(dupAndReplaceExpr(iteExpr.Guard, isFail, inHarness), dupAndReplaceExpr(iteExpr.ThenExpr, isFail, inHarness), dupAndReplaceExpr(iteExpr.ElseExpr, isFail, inHarness))); } if (expr is BoogieQuantifiedExpr) { BoogieQuantifiedExpr quantifiedExpr = (BoogieQuantifiedExpr)expr; return(new BoogieQuantifiedExpr(quantifiedExpr.IsForall, quantifiedExpr.QVars, quantifiedExpr.QVarTypes, dupAndReplaceExpr(quantifiedExpr.BodyExpr, isFail, inHarness), quantifiedExpr.Trigger)); } if (expr is BoogieFuncCallExpr) { BoogieFuncCallExpr callExpr = (BoogieFuncCallExpr)expr; string calledFun = callExpr.Function; // TODO: handle this properly. // if (!isHarnessProcudure(calledFun) && procsWiltImplNames.Contains(calledFun)) // { // if (!inHarness || (!isConstructor(calledFun) && !isPublic(proceduresInProgram[calledFun]))) // calledFun = calledFun + (isFail ? "__fail" : "__success"); // } return(new BoogieFuncCallExpr(calledFun, dupAndReplaceExprList(callExpr.Arguments))); } if (expr is BoogieTupleExpr) { BoogieTupleExpr tupleExpr = (BoogieTupleExpr)expr; return(new BoogieTupleExpr(dupAndReplaceExprList(tupleExpr.Arguments))); } return(expr); }
private BoogieImplementation CreateSendSucess() { // send__success(from: Ref, to: Ref, amt: uint) returns (success: boolean) // { // var __exception: bool; // havoc __exception; // // if(__exception) // { // //set tmps // if ((__tmp__Balance[from]) >= (amt)) { // call FallbackDispatch__fail(from, to, amt); // } // // success := false; // assume(__revert); // // revert := false; // } // else { // if ((Balance[from]) >= (amt)) { // call FallbackDispatch__success(from, to, amt); // success := true; // } else { // success := false; // } // // assume(!(__revert)); // } // } List <BoogieVariable> inParams = new List <BoogieVariable>() { new BoogieFormalParam(new BoogieTypedIdent("from", BoogieType.Ref)), new BoogieFormalParam(new BoogieTypedIdent("to", BoogieType.Ref)), new BoogieFormalParam(new BoogieTypedIdent("amount", BoogieType.Int)) }; List <BoogieVariable> outParms = new List <BoogieVariable>() { new BoogieFormalParam(new BoogieTypedIdent("success", BoogieType.Bool)) }; List <BoogieVariable> locals = new List <BoogieVariable>() { new BoogieLocalVariable(new BoogieTypedIdent("__exception", BoogieType.Bool)) }; var fromId = new BoogieIdentifierExpr("from"); var toId = new BoogieIdentifierExpr("to"); var amtId = new BoogieIdentifierExpr("amount"); var successId = new BoogieIdentifierExpr("success"); var revertId = new BoogieIdentifierExpr("revert"); var exceptionId = new BoogieIdentifierExpr("__exception"); BoogieStmtList body = new BoogieStmtList(); body.AddStatement(new BoogieHavocCmd(exceptionId)); BoogieStmtList exceptionCase = new BoogieStmtList(); foreach (var shadowGlobalPair in shadowGlobals) { string origVarName = shadowGlobalPair.Key; string shadowName = shadowGlobalPair.Value.Name; exceptionCase.AddStatement(new BoogieAssignCmd(new BoogieIdentifierExpr(shadowName), new BoogieIdentifierExpr(origVarName))); } var checkTmpBalGuard = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.GE, new BoogieMapSelect(new BoogieIdentifierExpr(shadowGlobals["Balance"].Name), fromId), amtId); var callFailDispatch = new BoogieCallCmd("FallbackDispatch__fail", new List <BoogieExpr>() { fromId, toId, amtId }, null); exceptionCase.AddStatement(new BoogieIfCmd(checkTmpBalGuard, BoogieStmtList.MakeSingletonStmtList(callFailDispatch), null)); exceptionCase.AddStatement(new BoogieAssignCmd(successId, new BoogieLiteralExpr(false))); BoogieExpr failAssumePred = revertId; if (context.TranslateFlags.InstrumentGas) { failAssumePred = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.OR, failAssumePred, new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.LT, new BoogieIdentifierExpr("gas"), new BoogieLiteralExpr(0))); } exceptionCase.AddStatement(new BoogieAssumeCmd(failAssumePred)); exceptionCase.AddStatement(new BoogieAssignCmd(revertId, new BoogieLiteralExpr(false))); var successCase = new BoogieStmtList(); var checkBalGuard = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.GE, new BoogieMapSelect(new BoogieIdentifierExpr("Balance"), fromId), amtId); var successCaseStmts = new BoogieStmtList(); var callSuccessDispatch = new BoogieCallCmd("FallbackDispatch__success", new List <BoogieExpr>() { fromId, toId, amtId }, null); successCaseStmts.AddStatement(callSuccessDispatch); successCaseStmts.AddStatement(new BoogieAssignCmd(successId, new BoogieLiteralExpr(true))); successCase.AddStatement(new BoogieIfCmd(checkBalGuard, successCaseStmts, BoogieStmtList.MakeSingletonStmtList(new BoogieAssignCmd(successId, new BoogieLiteralExpr(false))))); BoogieExpr successAssumePred = new BoogieUnaryOperation(BoogieUnaryOperation.Opcode.NOT, revertId); if (context.TranslateFlags.InstrumentGas) { successAssumePred = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.AND, successAssumePred, new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.GE, new BoogieIdentifierExpr("gas"), new BoogieLiteralExpr(0))); } successCase.AddStatement(new BoogieAssumeCmd(successAssumePred)); body.AddStatement(new BoogieIfCmd(exceptionId, exceptionCase, successCase)); return(new BoogieImplementation("send__success", inParams, outParms, locals, body)); }
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]; if (!originalProcName.Equals("send")) { context.Program.AddDeclaration(createFailImplementation(proc.Name, originalImpl)); context.Program.AddDeclaration(createSuccessImplementation(originalProcName + "__success", originalImpl)); } else { context.Program.AddDeclaration(CreateSendFail()); context.Program.AddDeclaration(CreateSendSucess()); } // 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())); BoogieExpr successAssumePred = new BoogieUnaryOperation(BoogieUnaryOperation.Opcode.NOT, new BoogieIdentifierExpr(revertGlobalName)); if (context.TranslateFlags.InstrumentGas) { successAssumePred = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.AND, successAssumePred, new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.GE, new BoogieIdentifierExpr("gas"), new BoogieLiteralExpr(0))); } successCallStmtList.AddStatement(new BoogieAssumeCmd(successAssumePred)); // 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())); BoogieExpr failAssumePred = new BoogieIdentifierExpr(revertGlobalName); if (context.TranslateFlags.InstrumentGas) { failAssumePred = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.OR, failAssumePred, new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.LT, new BoogieIdentifierExpr("gas"), new BoogieLiteralExpr(0))); } failCallStmtList.AddStatement(new BoogieAssumeCmd(failAssumePred)); stmtList.AddStatement(new BoogieIfCmd(new BoogieIdentifierExpr(exceptionVarName), failCallStmtList, successCallStmtList)); } } }
private BoogieImplementation CreateSendFail() { // send__fail(from: Ref, to: Ref, amt: uint) returns (success: boolean) // { // var __exception: bool; // havoc __exception; // // if(__exception) // { // //save current temps // if ((__tmp__Balance[from]) >= (amt)) { // call FallbackDispatch__fail(from, to, amt); // } // // success := false; // assume(__revert); // // // restore old temps // revert := false; // } // else { // if ((__tmp__Balance[from]) >= (amt)) { // call FallbackDispatch__fail(from, to, amt); // success := true; // } else { // success := false; // } // // assume(!(__revert)); // } // } List <BoogieVariable> inParams = new List <BoogieVariable>() { new BoogieFormalParam(new BoogieTypedIdent("from", BoogieType.Ref)), new BoogieFormalParam(new BoogieTypedIdent("to", BoogieType.Ref)), new BoogieFormalParam(new BoogieTypedIdent("amount", BoogieType.Int)) }; List <BoogieVariable> outParms = new List <BoogieVariable>() { new BoogieFormalParam(new BoogieTypedIdent("success", BoogieType.Bool)) }; List <BoogieVariable> locals = new List <BoogieVariable>() { new BoogieLocalVariable(new BoogieTypedIdent("__exception", BoogieType.Bool)) }; var fromId = new BoogieIdentifierExpr("from"); var toId = new BoogieIdentifierExpr("to"); var amtId = new BoogieIdentifierExpr("amount"); var successId = new BoogieIdentifierExpr("success"); var revertId = new BoogieIdentifierExpr("revert"); var exceptionId = new BoogieIdentifierExpr("__exception"); var body = new BoogieStmtList(); body.AddStatement(new BoogieHavocCmd(exceptionId)); var checkTmpBalGuard = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.GE, new BoogieMapSelect(new BoogieIdentifierExpr(shadowGlobals["Balance"].Name), fromId), amtId); var callFailDispatch = new BoogieCallCmd("FallbackDispatch__fail", new List <BoogieExpr>() { fromId, toId, amtId }, null); var exceptionCase = new BoogieStmtList(); foreach (var shadowGlobalPair in shadowGlobals) { var shadowName = shadowGlobalPair.Value.Name; var tmpLocalName = "__snap_" + shadowName; locals.Add(new BoogieLocalVariable(new BoogieTypedIdent(tmpLocalName, shadowGlobalPair.Value.TypedIdent.Type))); exceptionCase.AddStatement(new BoogieAssignCmd(new BoogieIdentifierExpr(tmpLocalName), new BoogieIdentifierExpr(shadowName))); } BoogieStmtList exStmtList = new BoogieStmtList(); exStmtList.AddStatement(new BoogieCommentCmd("---- Logic for payable function START ")); var exBalFrom = new BoogieMapSelect(new BoogieIdentifierExpr(shadowGlobals["Balance"].Name), new BoogieIdentifierExpr(inParams[0].Name)); var exBalTo = new BoogieMapSelect(new BoogieIdentifierExpr(shadowGlobals["Balance"].Name), new BoogieIdentifierExpr(inParams[1].Name)); var exMsgVal = new BoogieIdentifierExpr(inParams[2].Name); //balance[msg.sender] = balance[msg.sender] - msg.value exStmtList.AddStatement(new BoogieAssignCmd(exBalFrom, new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.SUB, exBalFrom, exMsgVal))); //balance[this] = balance[this] + msg.value exStmtList.AddStatement(new BoogieAssignCmd(exBalTo, new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.ADD, exBalTo, exMsgVal))); exStmtList.AddStatement(new BoogieCommentCmd("---- Logic for payable function END ")); exStmtList.AddStatement(callFailDispatch); exceptionCase.AddStatement(new BoogieIfCmd(checkTmpBalGuard, exStmtList, null)); exceptionCase.AddStatement(new BoogieAssignCmd(successId, new BoogieLiteralExpr(false))); BoogieExpr failAssumePred = revertId; if (context.TranslateFlags.InstrumentGas) { failAssumePred = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.OR, failAssumePred, new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.LT, new BoogieIdentifierExpr("gas"), new BoogieLiteralExpr(0))); } exceptionCase.AddStatement(new BoogieAssumeCmd(failAssumePred)); foreach (var shadowGlobalPair in shadowGlobals) { var shadowName = shadowGlobalPair.Value.Name; var tmpLocalName = "__snap_" + shadowName; exceptionCase.AddStatement(new BoogieAssignCmd(new BoogieIdentifierExpr(shadowName), new BoogieIdentifierExpr(tmpLocalName))); } exceptionCase.AddStatement(new BoogieAssignCmd(revertId, new BoogieLiteralExpr(false))); var successCase = new BoogieStmtList(); var successDispatchCall = new BoogieStmtList(); successDispatchCall.AddStatement(new BoogieCommentCmd("---- Logic for payable function START ")); //balance[msg.sender] = balance[msg.sender] - msg.value successDispatchCall.AddStatement(new BoogieAssignCmd(exBalFrom, new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.SUB, exBalFrom, exMsgVal))); //balance[this] = balance[this] + msg.value successDispatchCall.AddStatement(new BoogieAssignCmd(exBalTo, new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.ADD, exBalTo, exMsgVal))); successDispatchCall.AddStatement(new BoogieCommentCmd("---- Logic for payable function END ")); successDispatchCall.AddStatement(callFailDispatch); successDispatchCall.AddStatement(new BoogieAssignCmd(successId, new BoogieLiteralExpr(true))); successCase.AddStatement(new BoogieIfCmd(checkTmpBalGuard, successDispatchCall, BoogieStmtList.MakeSingletonStmtList(new BoogieAssignCmd(successId, new BoogieLiteralExpr(false))))); BoogieExpr successAssumePred = new BoogieUnaryOperation(BoogieUnaryOperation.Opcode.NOT, revertId); if (context.TranslateFlags.InstrumentGas) { successAssumePred = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.AND, successAssumePred, new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.GE, new BoogieIdentifierExpr("gas"), new BoogieLiteralExpr(0))); } successCase.AddStatement(new BoogieAssumeCmd(successAssumePred)); body.AddStatement(new BoogieIfCmd(exceptionId, exceptionCase, successCase)); return(new BoogieImplementation("send__fail", inParams, outParms, locals, body)); }