public BatchExeResult Execute(string filename, out string expected, out string current)
        {
            BatchExeResult result   = BatchExeResult.SolcError;
            string         filePath = Path.Combine(testDirectory, filename);

            // compile the program
            SolidityCompiler compiler       = new SolidityCompiler();
            CompilerOutput   compilerOutput = compiler.Compile(solcPath, filePath);

            if (compilerOutput.ContainsError())
            {
                compilerOutput.PrintErrorsToConsole();
                throw new SystemException("Compilation Error");
            }

            // build the Solidity AST from solc output
            AST solidityAST = new AST(compilerOutput, Path.GetDirectoryName(filePath));

            // translate Solidity to Boogie
            try
            {
                BoogieTranslator translator = new BoogieTranslator();
                var translatorFlags         = new TranslatorFlags();
                translatorFlags.GenerateInlineAttributes = false;
                BoogieAST boogieAST = translator.Translate(solidityAST, new HashSet <Tuple <string, string> >(), translatorFlags);

                // dump the Boogie program to a file
                using (var outWriter = new StreamWriter(outFile))
                {
                    outWriter.WriteLine(boogieAST.GetRoot());
                }
            } catch (Exception e)
            {
                Console.WriteLine($"VeriSol translation error: {e.Message}");
                result   = BatchExeResult.SolToBoogieError;
                expected = current = null;
                return(result);
            }

            // read the corral configuration from Json
            string configJsonPath            = Path.Combine(configDirectory, Path.GetFileNameWithoutExtension(filename) + ".json");
            string jsonString                = File.ReadAllText(configJsonPath);
            CorralConfiguration corralConfig = JsonConvert.DeserializeObject <CorralConfiguration>(jsonString);

            string corralOutput = RunCorral(corralConfig);

            expected = corralConfig.ExpectedResult;
            current  = corralOutput;
            result   = CompareCorralOutput(corralConfig.ExpectedResult, corralOutput);
            return(result);
        }
Beispiel #2
0
 public VeriSolExecutor(string solidityFilePath, string contractName, int corralRecursionLimit, HashSet <Tuple <string, string> > ignoreMethods, bool tryRefutation, bool tryProofFlag, ILogger logger, bool _printTransactionSequence, TranslatorFlags _translatorFlags = null)
 {
     this.SolidityFilePath = solidityFilePath;
     this.ContractName     = contractName;
     this.SolidityFileDir  = Path.GetDirectoryName(solidityFilePath);
     Console.WriteLine($"SpecFilesDir = {SolidityFileDir}");
     this.CorralPath           = ExternalToolsManager.Corral.Command;
     this.BoogiePath           = ExternalToolsManager.Boogie.Command;
     this.SolcPath             = ExternalToolsManager.Solc.Command;
     this.CorralRecursionLimit = corralRecursionLimit;
     this.ignoreMethods        = new HashSet <Tuple <string, string> >(ignoreMethods);
     this.Logger                   = logger;
     this.TryProof                 = tryProofFlag;
     this.TryRefutation            = tryRefutation;
     this.printTransactionSequence = _printTransactionSequence;
     //this.GenInlineAttrs = genInlineAttrs;
     this.translatorFlags = _translatorFlags;
 }
Beispiel #3
0
        public static int Main(string[] args)
        {
            if (args.Length < 2)
            {
                ShowUsage();
                return(1);
            }

            ExternalToolsManager.EnsureAllExisted();

            string  solidityFile, entryPointContractName;
            bool    tryProofFlag, tryRefutation;
            int     recursionBound;
            ILogger logger;
            HashSet <Tuple <string, string> > ignoredMethods;
            bool            printTransactionSequence = false;
            TranslatorFlags translatorFlags          = new TranslatorFlags();

            ParseCommandLineArgs(args,
                                 out solidityFile,
                                 out entryPointContractName,
                                 out tryProofFlag,
                                 out tryRefutation,
                                 out recursionBound,
                                 out logger,
                                 out ignoredMethods,
                                 out printTransactionSequence,
                                 ref translatorFlags);

            var verisolExecuter =
                new VeriSolExecutor(
                    Path.Combine(Directory.GetCurrentDirectory(), solidityFile),
                    entryPointContractName,
                    recursionBound,
                    ignoredMethods,
                    tryRefutation,
                    tryProofFlag,
                    logger,
                    printTransactionSequence,
                    translatorFlags);

            return(verisolExecuter.Execute());
        }
        private void ParseTranslatorFlags(TranslatorFlags translatorFlags, string args)
        {
            string  solidityFile, entryPointContractName;
            bool    tryProofFlag, tryRefutation;
            int     recursionBound;
            ILogger logger;
            HashSet <Tuple <string, string> > ignoredMethods;
            bool   printTransactionSequence = false;
            string verisolCmdLineArgs       = "Foo Bar " + args; //Parser expects dirst two args to be present

            SolToBoogie.ParseUtils.ParseCommandLineArgs(verisolCmdLineArgs.Split(" "),
                                                        out solidityFile,
                                                        out entryPointContractName,
                                                        out tryProofFlag,
                                                        out tryRefutation,
                                                        out recursionBound,
                                                        out logger,
                                                        out ignoredMethods,
                                                        out printTransactionSequence,
                                                        ref translatorFlags);
        }
Beispiel #5
0
        private bool ExecuteSolToBoogie()
        {
            // compile the program
            Console.WriteLine($"\n----- Running Solc on {SpecFilePath}....");

            SolidityCompiler compiler       = new SolidityCompiler();
            CompilerOutput   compilerOutput = compiler.Compile(SolcPath, SpecFilePath);

            if (compilerOutput.ContainsError())
            {
                compilerOutput.PrintErrorsToConsole();
                throw new SystemException("Compilation Error");
            }

            // build the Solidity AST from solc output
            AST solidityAST = new AST(compilerOutput, Path.GetDirectoryName(SpecFilePath));

            // translate Solidity to Boogie
            try
            {
                BoogieTranslator translator = new BoogieTranslator();
                Console.WriteLine($"\n----- Running SolToBoogie....");
                var translatorFlags = new TranslatorFlags();
                translatorFlags.GenerateInlineAttributes = true;
                BoogieAST boogieAST = translator.Translate(solidityAST, ignoreMethods, translatorFlags);

                // dump the Boogie program to a file
                var outFilePath = Path.Combine(SpecFileDir, outFileName);
                using (var outWriter = new StreamWriter(outFileName))
                {
                    outWriter.WriteLine(boogieAST.GetRoot());
                }
            }
            catch (Exception e)
            {
                Console.WriteLine($"VeriSol translation error: {e.Message}");
                return(false);
            }
            return(true);
        }
Beispiel #6
0
        public static int Main(string[] args)



        {
            if (args.Length < 2)
            {
                ShowUsage();
                return(1);
            }

            string  solidityFile, entryPointContractName, solcName;
            bool    tryProofFlag, tryRefutation;
            int     recursionBound;
            ILogger logger;
            HashSet <Tuple <string, string> > ignoredMethods;
            bool            printTransactionSequence = false;
            TranslatorFlags translatorFlags          = new TranslatorFlags();

            ParseCommandLineArgs(args,
                                 out solidityFile,
                                 out entryPointContractName,
                                 out tryProofFlag,
                                 out tryRefutation,
                                 out recursionBound,
                                 out solcName,
                                 out logger,
                                 out ignoredMethods,
                                 out printTransactionSequence,
                                 ref translatorFlags);

            var    assemblyLocation = Assembly.GetExecutingAssembly().Location;
            string solcPath         = Path.Combine(
                Path.GetDirectoryName(assemblyLocation),
                solcName);

            if (!File.Exists(solcPath))
            {
                ShowUsage();
                Console.WriteLine($"Cannot find {solcName} at {solcPath}");
                return(1);
            }

            string corralPath = Path.Combine(
                Path.GetDirectoryName(assemblyLocation),
                "corral.dll");

            if (!File.Exists(corralPath))
            {
                ShowUsage();
                Console.WriteLine($"Cannot find corral.dll at {corralPath}");
                return(1);
            }

            string boogiePath = Path.Combine(
                Path.GetDirectoryName(assemblyLocation),
                "BoogieDriver.dll");

            if (!File.Exists(boogiePath))
            {
                ShowUsage();
                Console.WriteLine($"Cannot find BoogieDriver.dll at {boogiePath}");
                return(1);
            }

            var verisolExecuter =
                new VeriSolExecutor(
                    Path.Combine(Directory.GetCurrentDirectory(), solidityFile),
                    entryPointContractName,
                    corralPath,
                    boogiePath,
                    solcPath,
                    solcName,
                    recursionBound,
                    ignoredMethods,
                    tryRefutation,
                    tryProofFlag,
                    logger,
                    printTransactionSequence,
                    translatorFlags);

            return(verisolExecuter.Execute());
        }
Beispiel #7
0
        private static void ParseCommandLineArgs(string[] args, out string solidityFile, out string entryPointContractName, out bool tryProofFlag, out bool tryRefutation, out int recursionBound, out string solcName, out ILogger logger, out HashSet <Tuple <string, string> > ignoredMethods, out bool printTransactionSeq, ref TranslatorFlags translatorFlags)
        {
            Console.WriteLine($"Command line args ==> {string.Join(", ", args.ToList())}");
            solidityFile = args[0];
            // Debug.Assert(!solidityFile.Contains("/"), $"Illegal solidity file name {solidityFile}"); //the file name can be foo/bar/baz.sol
            entryPointContractName = args[1];
            Debug.Assert(!entryPointContractName.Contains("/"), $"Illegal contract name {entryPointContractName}");

            tryProofFlag   = args.Any(x => x.Equals("/tryProof"));
            tryRefutation  = false;
            recursionBound = 2;
            if (args.Any(x => x.StartsWith("/tryRefutation:")))
            {
                Debug.Assert(!tryRefutation, "Multiple declaration of /tryRefutation:k in command line");
                var arg = args.First(x => x.StartsWith("/tryRefutation:"));
                tryRefutation  = true;
                recursionBound = int.Parse(arg.Substring("/tryRefutation:".Length));
            }

            solcName = GetSolcNameByOSPlatform();
            ILoggerFactory loggerFactory = new LoggerFactory().AddConsole(LogLevel.Information);

            logger         = loggerFactory.CreateLogger("VeriSol");
            ignoredMethods = new HashSet <Tuple <string, string> >();
            foreach (var arg in args.Where(x => x.StartsWith("/ignoreMethod:")))
            {
                Debug.Assert(arg.Contains("@"), $"Error: incorrect use of /ignoreMethod in {arg}");
                Debug.Assert(arg.LastIndexOf("@") == arg.IndexOf("@"), $"Error: incorrect use of /ignoreMethod in {arg}");
                var str      = arg.Substring("/ignoreMethod:".Length);
                var method   = str.Substring(0, str.IndexOf("@"));
                var contract = str.Substring(str.IndexOf("@") + 1);
                ignoredMethods.Add(Tuple.Create(method, contract));
            }
            if (args.Any(x => x.StartsWith("/ignoreMethod:")))
            {
                Console.WriteLine($"Ignored method/contract pairs ==> \n\t {string.Join(",", ignoredMethods.Select(x => x.Item1 + "@" + x.Item2))}");
            }
            translatorFlags.GenerateInlineAttributes = true;
            if (args.Any(x => x.Equals("/noInlineAttrs")))
            {
                translatorFlags.GenerateInlineAttributes = false;
                if (tryProofFlag)
                {
                    throw new Exception("/noInlineAttrs cannot be used when /tryProof is used");
                }
            }
            if (args.Any(x => x.Equals("/break")))
            {
                Debugger.Launch();
            }
            if (args.Any(x => x.Equals("/omitSourceLineInfo")))
            {
                translatorFlags.NoSourceLineInfoFlag = true;
            }
            if (args.Any(x => x.Equals("/omitDataValuesInTrace")))
            {
                translatorFlags.NoDataValuesInfoFlag = true;
            }
            if (args.Any(x => x.Equals("/omitUnsignedSemantics")))
            {
                translatorFlags.NoUnsignedAssumesFlag = true;
            }
            if (args.Any(x => x.Equals("/omitAxioms")))
            {
                translatorFlags.NoAxiomsFlag = true;
            }
            if (args.Any(x => x.Equals("/omitHarness")))
            {
                translatorFlags.NoHarness = true;
            }

            if (args.Any(x => x.Equals("/modelReverts")))
            {
                translatorFlags.ModelReverts = true;
            }

            if (args.Any(x => x.Equals("/instrumentGas")))
            {
                translatorFlags.InstrumentGas = true;
            }

            // don't perform verification for some of these omitFlags
            if (tryProofFlag || tryRefutation)
            {
                Debug.Assert(!translatorFlags.NoHarness &&
                             !translatorFlags.NoAxiomsFlag &&
                             !translatorFlags.NoUnsignedAssumesFlag &&
                             !translatorFlags.NoDataValuesInfoFlag &&
                             !translatorFlags.NoSourceLineInfoFlag,
                             "Cannot perform verification when any of " +
                             "/omitSourceLineInfo, " +
                             "/omitDataValuesInTrace, " +
                             "/omitAxioms, " +
                             "/omitHarness, " +
                             "/omitUnsignedSemantics are specified");
            }

            printTransactionSeq = args.Any(x => x.Equals("/printTransactionSequence"));
        }
Beispiel #8
0
        private static void ParseCommandLineArgs(string[] args, out string solidityFile, out string entryPointContractName, out bool tryProofFlag, out bool tryRefutation, out int recursionBound, out ILogger logger, out HashSet <Tuple <string, string> > ignoredMethods, out bool printTransactionSeq, ref TranslatorFlags translatorFlags)
        {
            Console.WriteLine($"Command line args = {{{string.Join(", ", args.ToList())}}}");
            solidityFile = args[0];
            // Debug.Assert(!solidityFile.Contains("/"), $"Illegal solidity file name {solidityFile}"); //the file name can be foo/bar/baz.sol
            entryPointContractName = args[1];
            Debug.Assert(!entryPointContractName.Contains("/"), $"Illegal contract name {entryPointContractName}");

            tryProofFlag   = !(args.Any(x => x.Equals("/noPrf")) || args.Any(x => x.Equals("/noChk"))); //args.Any(x => x.Equals("/tryProof"));
            tryRefutation  = !args.Any(x => x.Equals("/noChk"));
            recursionBound = 4;
            var txBounds = args.Where(x => x.StartsWith("/txBound:"));

            if (txBounds.Count() > 0)
            {
                Debug.Assert(txBounds.Count() == 1, $"At most 1 /txBound:k expected, found {txBounds.Count()}");
                recursionBound = int.Parse(txBounds.First().Substring("/txBound:".Length));
                Debug.Assert(recursionBound > 0, $"Argument of /txBound:k should be positive, found {recursionBound}");
            }

            ILoggerFactory loggerFactory = new LoggerFactory().AddConsole(LogLevel.Information);

            logger         = loggerFactory.CreateLogger("VeriSol");
            ignoredMethods = new HashSet <Tuple <string, string> >();
            foreach (var arg in args.Where(x => x.StartsWith("/ignoreMethod:")))
            {
                Debug.Assert(arg.Contains("@"), $"Error: incorrect use of /ignoreMethod in {arg}");
                Debug.Assert(arg.LastIndexOf("@") == arg.IndexOf("@"), $"Error: incorrect use of /ignoreMethod in {arg}");
                var str      = arg.Substring("/ignoreMethod:".Length);
                var method   = str.Substring(0, str.IndexOf("@"));
                var contract = str.Substring(str.IndexOf("@") + 1);
                ignoredMethods.Add(Tuple.Create(method, contract));
            }
            if (args.Any(x => x.StartsWith("/ignoreMethod:")))
            {
                Console.WriteLine($"Ignored method/contract pairs ==> \n\t {string.Join(",", ignoredMethods.Select(x => x.Item1 + "@" + x.Item2))}");
            }
            translatorFlags.GenerateInlineAttributes = true;
            if (args.Any(x => x.Equals("/noInlineAttrs")))
            {
                translatorFlags.GenerateInlineAttributes = false;
                if (tryProofFlag)
                {
                    throw new Exception("/noInlineAttrs cannot be used when /tryProof is used");
                }
            }
            if (args.Any(x => x.Equals("/break")))
            {
                Debugger.Launch();
            }
            if (args.Any(x => x.Equals("/omitSourceLineInfo")))
            {
                translatorFlags.NoSourceLineInfoFlag = true;
            }
            if (args.Any(x => x.Equals("/omitDataValuesInTrace")))
            {
                translatorFlags.NoDataValuesInfoFlag = true;
            }
            if (args.Any(x => x.Equals("/useModularArithmetic")))
            {
                translatorFlags.UseModularArithmetic = true;
            }
            if (args.Any(x => x.Equals("/omitUnsignedSemantics")))
            {
                translatorFlags.NoUnsignedAssumesFlag = true;
            }
            if (args.Any(x => x.Equals("/omitAxioms")))
            {
                translatorFlags.NoAxiomsFlag = true;
            }
            if (args.Any(x => x.Equals("/omitHarness")))
            {
                translatorFlags.NoHarness = true;
            }

            if (args.Any(x => x.Equals("/modelReverts")))
            {
                translatorFlags.ModelReverts = true;
            }

            if (args.Any(x => x.Equals("/instrumentGas")))
            {
                translatorFlags.InstrumentGas = true;
            }

            var stubModels = args.Where(x => x.StartsWith("/stubModel:"));

            if (stubModels.Count() > 0)
            {
                Debug.Assert(stubModels.Count() == 1, "Multiple instances of /stubModel:");
                var model = stubModels.First().Substring("/stubModel:".Length);
                Debug.Assert(model.Equals("skip") || model.Equals("havoc") || model.Equals("callback"),
                             $"The argument to /stubModel: can be either {{skip, havoc, callback}}, found {model}");
                translatorFlags.ModelOfStubs = model;
            }
            if (args.Any(x => x.StartsWith("/inlineDepth:")))
            {
                var depth = args.Where(x => x.StartsWith("/inlineDepth:")).First();
                translatorFlags.InlineDepthForBoogie = int.Parse(depth.Substring("/inlineDepth:".Length));
            }
            if (args.Any(x => x.Equals("/doModSet")))
            {
                translatorFlags.DoModSetAnalysis = true;
            }

            translatorFlags.PerformContractInferce = args.Any(x => x.StartsWith("/contractInfer"));

            // don't perform verification for some of these omitFlags
            if (tryProofFlag || tryRefutation)
            {
                Debug.Assert(!translatorFlags.NoHarness &&
                             !translatorFlags.NoAxiomsFlag &&
                             !translatorFlags.NoUnsignedAssumesFlag &&
                             !translatorFlags.NoDataValuesInfoFlag &&
                             !translatorFlags.NoSourceLineInfoFlag,
                             "Cannot perform verification when any of " +
                             "/omitSourceLineInfo, " +
                             "/omitDataValuesInTrace, " +
                             "/omitAxioms, " +
                             "/omitHarness, " +
                             "/omitUnsignedSemantics are specified");
            }

            printTransactionSeq = !args.Any(x => x.Equals("/noTxSeq"));
        }