Coverage Report

Created: 2025-09-08 08:10

/src/solidity/test/tools/ossfuzz/SolidityEvmoneInterface.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
  This file is part of solidity.
3
4
  solidity is free software: you can redistribute it and/or modify
5
  it under the terms of the GNU General Public License as published by
6
  the Free Software Foundation, either version 3 of the License, or
7
  (at your option) any later version.
8
9
  solidity is distributed in the hope that it will be useful,
10
  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
  GNU General Public License for more details.
13
14
  You should have received a copy of the GNU General Public License
15
  along with solidity.  If not, see <http://www.gnu.org/licenses/>.
16
*/
17
// SPDX-License-Identifier: GPL-3.0
18
19
#pragma once
20
21
#include <test/EVMHost.h>
22
23
#include <libsolidity/interface/CompilerStack.h>
24
25
#include <libyul/YulStack.h>
26
27
#include <libsolutil/Keccak256.h>
28
29
#include <evmone/evmone.h>
30
31
namespace solidity::test::fuzzer
32
{
33
struct CompilerOutput
34
{
35
  /// EVM bytecode returned by compiler
36
  solidity::bytes byteCode;
37
  /// Method identifiers in a contract
38
  Json methodIdentifiersInContract;
39
};
40
41
struct CompilerInput
42
{
43
  CompilerInput(
44
    langutil::EVMVersion _evmVersion,
45
    StringMap const& _sourceCode,
46
    std::string const& _contractName,
47
    frontend::OptimiserSettings _optimiserSettings,
48
    std::map<std::string, solidity::util::h160> _libraryAddresses,
49
    bool _debugFailure = false,
50
    bool _viaIR = false
51
  ):
52
    evmVersion(_evmVersion),
53
    sourceCode(_sourceCode),
54
    contractName(_contractName),
55
    optimiserSettings(_optimiserSettings),
56
    libraryAddresses(_libraryAddresses),
57
    debugFailure(_debugFailure),
58
    viaIR(_viaIR)
59
597
  {}
60
  /// EVM target version
61
  langutil::EVMVersion evmVersion;
62
  /// Source code to be compiled
63
  StringMap const& sourceCode;
64
  /// Contract name without a colon prefix
65
  std::string contractName;
66
  /// Optimiser setting to be used during compilation
67
  frontend::OptimiserSettings optimiserSettings;
68
  /// Information on which library is deployed where
69
  std::map<std::string, solidity::util::h160> libraryAddresses;
70
  /// Flag used for debugging
71
  bool debugFailure;
72
  /// Flag to enable new code generator.
73
  bool viaIR;
74
};
75
76
class SolidityCompilationFramework
77
{
78
public:
79
  SolidityCompilationFramework(CompilerInput _input): m_compilerInput(_input)
80
597
  {}
81
  /// Sets contract name to @param _contractName.
82
  void contractName(std::string const& _contractName)
83
597
  {
84
597
    m_compilerInput.contractName = _contractName;
85
597
  }
86
  /// Sets library addresses to @param _libraryAddresses.
87
  void libraryAddresses(std::map<std::string, solidity::util::h160> _libraryAddresses)
88
0
  {
89
0
    m_compilerInput.libraryAddresses = std::move(_libraryAddresses);
90
0
  }
91
  /// @returns method identifiers in contract called @param _contractName.
92
  Json methodIdentifiers(std::string const& _contractName)
93
0
  {
94
0
    return m_compiler.interfaceSymbols(_contractName)["methods"];
95
0
  }
96
  /// @returns Compilation output comprising EVM bytecode and list of
97
  /// method identifiers in contract if compilation is successful,
98
  /// null value otherwise.
99
  std::optional<CompilerOutput> compileContract();
100
private:
101
  frontend::CompilerStack m_compiler;
102
  CompilerInput m_compilerInput;
103
};
104
105
class EvmoneUtility
106
{
107
public:
108
  EvmoneUtility(
109
    solidity::test::EVMHost& _evmHost,
110
    CompilerInput _compilerInput,
111
    std::string const& _contractName,
112
    std::string const& _libraryName,
113
    std::string const& _methodName
114
  ):
115
    m_evmHost(_evmHost),
116
    m_compilationFramework(_compilerInput),
117
    m_contractName(_contractName),
118
    m_libraryName(_libraryName),
119
    m_methodName(_methodName)
120
597
  {}
121
  /// @returns the result returned by the EVM host on compiling, deploying,
122
  /// and executing test configuration.
123
  /// @param _isabelleData contains encoding data to be passed to the
124
  /// isabelle test entry point.
125
  evmc::Result compileDeployAndExecute(std::string _isabelleData = {});
126
  /// Compares the contents of the memory address pointed to
127
  /// by `_result` of `_length` bytes to u256 zero.
128
  /// @returns true if `_result` is zero, false
129
  /// otherwise.
130
  static bool zeroWord(uint8_t const* _result, size_t _length);
131
  /// @returns an evmc_message with all of its fields zero
132
  /// initialized except gas and input fields.
133
  /// The gas field is set to the maximum permissible value so that we
134
  /// don't run into out of gas errors. The input field is copied from
135
  /// @param _input.
136
  static evmc_message initializeMessage(bytes const& _input);
137
private:
138
  /// @returns the result of the execution of the function whose
139
  /// keccak256 hash is @param _functionHash that is deployed at
140
  /// @param _deployedAddress in @param _hostContext.
141
  evmc::Result executeContract(
142
    bytes const& _functionHash,
143
    evmc_address _deployedAddress
144
  );
145
  /// @returns the result of deployment of @param _code on @param _hostContext.
146
  evmc::Result deployContract(bytes const& _code);
147
  /// Deploys and executes EVM byte code in @param _byteCode on
148
  /// EVM Host referenced by @param _hostContext. Input passed
149
  /// to execution context is @param _hexEncodedInput.
150
  /// @returns result returning by @param _hostContext.
151
  evmc::Result deployAndExecute(
152
    bytes const& _byteCode,
153
    std::string const& _hexEncodedInput
154
  );
155
  /// Compiles contract named @param _contractName present in
156
  /// @param _sourceCode, optionally using a precompiled library
157
  /// specified via a library mapping and an optimisation setting.
158
  /// @returns a pair containing the generated byte code and method
159
  /// identifiers for methods in @param _contractName.
160
  std::optional<CompilerOutput> compileContract();
161
162
  /// EVM Host implementation
163
  solidity::test::EVMHost& m_evmHost;
164
  /// Solidity compilation framework
165
  SolidityCompilationFramework m_compilationFramework;
166
  /// Contract name
167
  std::string m_contractName;
168
  /// Library name
169
  std::string m_libraryName;
170
  /// Method name
171
  std::string m_methodName;
172
};
173
174
}