Merge remote-tracking branch 'origin/develop' into HEAD

This commit is contained in:
chriseth 2020-11-09 14:28:05 +01:00
commit 04195439b7
238 changed files with 2662 additions and 762 deletions

View File

@ -14,7 +14,7 @@ indent_size = 4
indent_style = space indent_style = space
indent_size = 4 indent_size = 4
[std/**.sol] [*.sol]
indent_style = space indent_style = space
indent_size = 4 indent_size = 4

View File

@ -31,6 +31,8 @@ Language Features:
Compiler Features: Compiler Features:
* SMTChecker: Add division by zero checks in the CHC engine. * SMTChecker: Add division by zero checks in the CHC engine.
* SMTChecker: Support ``selector`` for expressions with value known at compile-time. * SMTChecker: Support ``selector`` for expressions with value known at compile-time.
* Command Line Interface: New option ``--model-checker-timeout`` sets a timeout in milliseconds for each individual query performed by the SMTChecker.
* Standard JSON: New option ``modelCheckerSettings.timeout`` sets a timeout in milliseconds for each individual query performed by the SMTChecker.
Bugfixes: Bugfixes:

View File

@ -558,7 +558,7 @@ Yes::
return x + 1; return x + 1;
} }
function increment(uint x) public pure onlyowner returns (uint) { function increment(uint x) public pure onlyOwner returns (uint) {
return x + 1; return x + 1;
} }
@ -594,7 +594,7 @@ Yes::
return balanceOf[from]; return balanceOf[from];
} }
function shutdown() public onlyowner { function shutdown() public onlyOwner {
selfdestruct(owner); selfdestruct(owner);
} }
@ -604,7 +604,7 @@ No::
return balanceOf[from]; return balanceOf[from];
} }
function shutdown() onlyowner public { function shutdown() onlyOwner public {
selfdestruct(owner); selfdestruct(owner);
} }
@ -661,7 +661,7 @@ Yes::
function thisFunctionNameIsReallyLong(address x, address y, address z) function thisFunctionNameIsReallyLong(address x, address y, address z)
public public
onlyowner onlyOwner
priced priced
returns (address) returns (address)
{ {
@ -674,7 +674,7 @@ Yes::
address z, address z,
) )
public public
onlyowner onlyOwner
priced priced
returns (address) returns (address)
{ {
@ -685,21 +685,21 @@ No::
function thisFunctionNameIsReallyLong(address x, address y, address z) function thisFunctionNameIsReallyLong(address x, address y, address z)
public public
onlyowner onlyOwner
priced priced
returns (address) { returns (address) {
doSomething(); doSomething();
} }
function thisFunctionNameIsReallyLong(address x, address y, address z) function thisFunctionNameIsReallyLong(address x, address y, address z)
public onlyowner priced returns (address) public onlyOwner priced returns (address)
{ {
doSomething(); doSomething();
} }
function thisFunctionNameIsReallyLong(address x, address y, address z) function thisFunctionNameIsReallyLong(address x, address y, address z)
public public
onlyowner onlyOwner
priced priced
returns (address) { returns (address) {
doSomething(); doSomething();

View File

@ -346,7 +346,12 @@ Input Description
"modelCheckerSettings": "modelCheckerSettings":
{ {
// Choose which model checker engine to use: all (default), bmc, chc, none. // Choose which model checker engine to use: all (default), bmc, chc, none.
"engine": "chc" "engine": "chc",
// Timeout for each SMT query in milliseconds.
// If this option is not given, the SMTChecker will use a deterministic
// resource limit by default.
// A given timeout of 0 means no resource/time restrictions for any query.
"timeout": 20000
} }
} }

View File

@ -54,7 +54,7 @@ be omitted to help readability.
To keep the language simple and flexible, Yul does not have To keep the language simple and flexible, Yul does not have
any built-in operations, functions or types in its pure form. any built-in operations, functions or types in its pure form.
These are added together with their semantics when specifying a dialect of Yul, These are added together with their semantics when specifying a dialect of Yul,
which allows to specialize Yul to the requirements of different which allows specializing Yul to the requirements of different
target platforms and feature sets. target platforms and feature sets.
Currently, there is only one specified dialect of Yul. This dialect uses Currently, there is only one specified dialect of Yul. This dialect uses
@ -526,7 +526,7 @@ The ``leave`` statement can only be used inside a function.
Functions cannot be defined anywhere inside for loop init blocks. Functions cannot be defined anywhere inside for loop init blocks.
Literals cannot be larger than the their type. The largest type defined is 256-bit wide. Literals cannot be larger than their type. The largest type defined is 256-bit wide.
During assignments and function calls, the types of the respective values have to match. During assignments and function calls, the types of the respective values have to match.
There is no implicit type conversion. Type conversion in general can only be achieved There is no implicit type conversion. Type conversion in general can only be achieved

View File

@ -36,11 +36,13 @@ using namespace solidity::frontend;
using namespace solidity::smtutil; using namespace solidity::smtutil;
CHCSmtLib2Interface::CHCSmtLib2Interface( CHCSmtLib2Interface::CHCSmtLib2Interface(
map<h256, string> const& _queryResponses, map<h256, string> _queryResponses,
ReadCallback::Callback const& _smtCallback ReadCallback::Callback _smtCallback,
optional<unsigned> _queryTimeout
): ):
m_smtlib2(make_unique<SMTLib2Interface>(_queryResponses, _smtCallback)), CHCSolverInterface(_queryTimeout),
m_queryResponses(_queryResponses), m_smtlib2(make_unique<SMTLib2Interface>(_queryResponses, _smtCallback, m_queryTimeout)),
m_queryResponses(move(_queryResponses)),
m_smtCallback(_smtCallback) m_smtCallback(_smtCallback)
{ {
reset(); reset();
@ -51,6 +53,8 @@ void CHCSmtLib2Interface::reset()
m_accumulatedOutput.clear(); m_accumulatedOutput.clear();
m_variables.clear(); m_variables.clear();
m_unhandledQueries.clear(); m_unhandledQueries.clear();
if (m_queryTimeout)
write("(set-option :timeout " + to_string(*m_queryTimeout) + ")");
} }
void CHCSmtLib2Interface::registerRelation(Expression const& _expr) void CHCSmtLib2Interface::registerRelation(Expression const& _expr)

View File

@ -33,8 +33,9 @@ class CHCSmtLib2Interface: public CHCSolverInterface
{ {
public: public:
explicit CHCSmtLib2Interface( explicit CHCSmtLib2Interface(
std::map<util::h256, std::string> const& _queryResponses, std::map<util::h256, std::string> _queryResponses = {},
frontend::ReadCallback::Callback const& _smtCallback frontend::ReadCallback::Callback _smtCallback = {},
std::optional<unsigned> _queryTimeout = {}
); );
void reset(); void reset();

View File

@ -33,6 +33,8 @@ namespace solidity::smtutil
class CHCSolverInterface class CHCSolverInterface
{ {
public: public:
CHCSolverInterface(std::optional<unsigned> _queryTimeout = {}): m_queryTimeout(_queryTimeout) {}
virtual ~CHCSolverInterface() = default; virtual ~CHCSolverInterface() = default;
virtual void declareVariable(std::string const& _name, SortPointer const& _sort) = 0; virtual void declareVariable(std::string const& _name, SortPointer const& _sort) = 0;
@ -56,6 +58,9 @@ public:
virtual std::pair<CheckResult, CexGraph> query( virtual std::pair<CheckResult, CexGraph> query(
Expression const& _expr Expression const& _expr
) = 0; ) = 0;
protected:
std::optional<unsigned> m_queryTimeout;
}; };
} }

View File

@ -27,7 +27,8 @@ using namespace solidity;
using namespace solidity::util; using namespace solidity::util;
using namespace solidity::smtutil; using namespace solidity::smtutil;
CVC4Interface::CVC4Interface(): CVC4Interface::CVC4Interface(optional<unsigned> _queryTimeout):
SolverInterface(_queryTimeout),
m_solver(&m_context) m_solver(&m_context)
{ {
reset(); reset();
@ -38,7 +39,10 @@ void CVC4Interface::reset()
m_variables.clear(); m_variables.clear();
m_solver.reset(); m_solver.reset();
m_solver.setOption("produce-models", true); m_solver.setOption("produce-models", true);
m_solver.setResourceLimit(resourceLimit); if (m_queryTimeout)
m_solver.setTimeLimit(*m_queryTimeout);
else
m_solver.setResourceLimit(resourceLimit);
} }
void CVC4Interface::push() void CVC4Interface::push()

View File

@ -40,7 +40,7 @@ namespace solidity::smtutil
class CVC4Interface: public SolverInterface, public boost::noncopyable class CVC4Interface: public SolverInterface, public boost::noncopyable
{ {
public: public:
CVC4Interface(); CVC4Interface(std::optional<unsigned> _queryTimeout = {});
void reset() override; void reset() override;

View File

@ -39,8 +39,10 @@ using namespace solidity::smtutil;
SMTLib2Interface::SMTLib2Interface( SMTLib2Interface::SMTLib2Interface(
map<h256, string> _queryResponses, map<h256, string> _queryResponses,
ReadCallback::Callback _smtCallback ReadCallback::Callback _smtCallback,
optional<unsigned> _queryTimeout
): ):
SolverInterface(_queryTimeout),
m_queryResponses(move(_queryResponses)), m_queryResponses(move(_queryResponses)),
m_smtCallback(move(_smtCallback)) m_smtCallback(move(_smtCallback))
{ {
@ -54,6 +56,8 @@ void SMTLib2Interface::reset()
m_variables.clear(); m_variables.clear();
m_userSorts.clear(); m_userSorts.clear();
write("(set-option :produce-models true)"); write("(set-option :produce-models true)");
if (m_queryTimeout)
write("(set-option :timeout " + to_string(*m_queryTimeout) + ")");
write("(set-logic ALL)"); write("(set-logic ALL)");
} }

View File

@ -40,7 +40,8 @@ class SMTLib2Interface: public SolverInterface, public boost::noncopyable
public: public:
explicit SMTLib2Interface( explicit SMTLib2Interface(
std::map<util::h256, std::string> _queryResponses = {}, std::map<util::h256, std::string> _queryResponses = {},
frontend::ReadCallback::Callback _smtCallback = {} frontend::ReadCallback::Callback _smtCallback = {},
std::optional<unsigned> _queryTimeout = {}
); );
void reset() override; void reset() override;

View File

@ -35,17 +35,19 @@ using namespace solidity::smtutil;
SMTPortfolio::SMTPortfolio( SMTPortfolio::SMTPortfolio(
map<h256, string> _smtlib2Responses, map<h256, string> _smtlib2Responses,
frontend::ReadCallback::Callback _smtCallback, frontend::ReadCallback::Callback _smtCallback,
[[maybe_unused]] SMTSolverChoice _enabledSolvers [[maybe_unused]] SMTSolverChoice _enabledSolvers,
) optional<unsigned> _queryTimeout
):
SolverInterface(_queryTimeout)
{ {
m_solvers.emplace_back(make_unique<SMTLib2Interface>(move(_smtlib2Responses), move(_smtCallback))); m_solvers.emplace_back(make_unique<SMTLib2Interface>(move(_smtlib2Responses), move(_smtCallback), m_queryTimeout));
#ifdef HAVE_Z3 #ifdef HAVE_Z3
if (_enabledSolvers.z3) if (_enabledSolvers.z3)
m_solvers.emplace_back(make_unique<Z3Interface>()); m_solvers.emplace_back(make_unique<Z3Interface>(m_queryTimeout));
#endif #endif
#ifdef HAVE_CVC4 #ifdef HAVE_CVC4
if (_enabledSolvers.cvc4) if (_enabledSolvers.cvc4)
m_solvers.emplace_back(make_unique<CVC4Interface>()); m_solvers.emplace_back(make_unique<CVC4Interface>(m_queryTimeout));
#endif #endif
} }

View File

@ -42,7 +42,8 @@ public:
SMTPortfolio( SMTPortfolio(
std::map<util::h256, std::string> _smtlib2Responses = {}, std::map<util::h256, std::string> _smtlib2Responses = {},
frontend::ReadCallback::Callback _smtCallback = {}, frontend::ReadCallback::Callback _smtCallback = {},
SMTSolverChoice _enabledSolvers = SMTSolverChoice::All() SMTSolverChoice _enabledSolvers = SMTSolverChoice::All(),
std::optional<unsigned> _queryTimeout = {}
); );
void reset() override; void reset() override;

View File

@ -374,6 +374,8 @@ DEV_SIMPLE_EXCEPTION(SolverError);
class SolverInterface class SolverInterface
{ {
public: public:
SolverInterface(std::optional<unsigned> _queryTimeout = {}): m_queryTimeout(_queryTimeout) {}
virtual ~SolverInterface() = default; virtual ~SolverInterface() = default;
virtual void reset() = 0; virtual void reset() = 0;
@ -401,6 +403,9 @@ public:
/// @returns how many SMT solvers this interface has. /// @returns how many SMT solvers this interface has.
virtual unsigned solvers() { return 1; } virtual unsigned solvers() { return 1; }
protected:
std::optional<unsigned> m_queryTimeout;
}; };
} }

View File

@ -27,14 +27,19 @@ using namespace std;
using namespace solidity; using namespace solidity;
using namespace solidity::smtutil; using namespace solidity::smtutil;
Z3CHCInterface::Z3CHCInterface(): Z3CHCInterface::Z3CHCInterface(optional<unsigned> _queryTimeout):
m_z3Interface(make_unique<Z3Interface>()), CHCSolverInterface(_queryTimeout),
m_z3Interface(make_unique<Z3Interface>(m_queryTimeout)),
m_context(m_z3Interface->context()), m_context(m_z3Interface->context()),
m_solver(*m_context) m_solver(*m_context)
{ {
// These need to be set globally. // These need to be set globally.
z3::set_param("rewriter.pull_cheap_ite", true); z3::set_param("rewriter.pull_cheap_ite", true);
z3::set_param("rlimit", Z3Interface::resourceLimit);
if (m_queryTimeout)
m_context->set("timeout", int(*m_queryTimeout));
else
z3::set_param("rlimit", Z3Interface::resourceLimit);
setSpacerOptions(); setSpacerOptions();
} }
@ -97,7 +102,13 @@ pair<CheckResult, CHCSolverInterface::CexGraph> Z3CHCInterface::query(Expression
} }
catch (z3::exception const& _err) catch (z3::exception const& _err)
{ {
if (_err.msg() == string("max. resource limit exceeded")) set<string> msgs{
/// Resource limit (rlimit) exhausted.
"max. resource limit exceeded",
/// User given timeout exhausted.
"canceled"
};
if (msgs.count(_err.msg()))
result = CheckResult::UNKNOWN; result = CheckResult::UNKNOWN;
else else
result = CheckResult::ERROR; result = CheckResult::ERROR;

View File

@ -33,7 +33,7 @@ namespace solidity::smtutil
class Z3CHCInterface: public CHCSolverInterface class Z3CHCInterface: public CHCSolverInterface
{ {
public: public:
Z3CHCInterface(); Z3CHCInterface(std::optional<unsigned> _queryTimeout = {});
/// Forwards variable declaration to Z3Interface. /// Forwards variable declaration to Z3Interface.
void declareVariable(std::string const& _name, SortPointer const& _sort) override; void declareVariable(std::string const& _name, SortPointer const& _sort) override;

View File

@ -27,12 +27,17 @@ using namespace std;
using namespace solidity::smtutil; using namespace solidity::smtutil;
using namespace solidity::util; using namespace solidity::util;
Z3Interface::Z3Interface(): Z3Interface::Z3Interface(std::optional<unsigned> _queryTimeout):
SolverInterface(_queryTimeout),
m_solver(m_context) m_solver(m_context)
{ {
// These need to be set globally. // These need to be set globally.
z3::set_param("rewriter.pull_cheap_ite", true); z3::set_param("rewriter.pull_cheap_ite", true);
z3::set_param("rlimit", resourceLimit);
if (m_queryTimeout)
m_context.set("timeout", int(*m_queryTimeout));
else
z3::set_param("rlimit", resourceLimit);
} }
void Z3Interface::reset() void Z3Interface::reset()
@ -104,9 +109,19 @@ pair<CheckResult, vector<string>> Z3Interface::check(vector<Expression> const& _
values.push_back(util::toString(m.eval(toZ3Expr(e)))); values.push_back(util::toString(m.eval(toZ3Expr(e))));
} }
} }
catch (z3::exception const&) catch (z3::exception const& _err)
{ {
result = CheckResult::ERROR; set<string> msgs{
/// Resource limit (rlimit) exhausted.
"max. resource limit exceeded",
/// User given timeout exhausted.
"canceled"
};
if (msgs.count(_err.msg()))
result = CheckResult::UNKNOWN;
else
result = CheckResult::ERROR;
values.clear(); values.clear();
} }

View File

@ -28,7 +28,7 @@ namespace solidity::smtutil
class Z3Interface: public SolverInterface, public boost::noncopyable class Z3Interface: public SolverInterface, public boost::noncopyable
{ {
public: public:
Z3Interface(); Z3Interface(std::optional<unsigned> _queryTimeout = {});
void reset() override; void reset() override;

View File

@ -2761,7 +2761,8 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess)
if (!funType->bound()) if (!funType->bound())
if (auto contractType = dynamic_cast<ContractType const*>(exprType)) if (auto contractType = dynamic_cast<ContractType const*>(exprType))
requiredLookup = contractType->isSuper() ? VirtualLookup::Super : VirtualLookup::Virtual; if (contractType->isSuper())
requiredLookup = VirtualLookup::Super;
} }
annotation.requiredLookup = requiredLookup; annotation.requiredLookup = requiredLookup;

View File

@ -802,7 +802,7 @@ string ABIFunctions::abiEncodingFunctionCompactStorageArray(
items[i]["inRange"] = "1"; items[i]["inRange"] = "1";
else else
items[i]["inRange"] = "0"; items[i]["inRange"] = "0";
items[i]["extractFromSlot"] = m_utils.extractFromStorageValue(*_from.baseType(), i * storageBytes, false); items[i]["extractFromSlot"] = m_utils.extractFromStorageValue(*_from.baseType(), i * storageBytes);
} }
templ("items", items); templ("items", items);
return templ.render(); return templ.render();
@ -888,7 +888,7 @@ string ABIFunctions::abiEncodingFunctionStruct(
members.back()["preprocess"] = "slotValue := sload(add(value, " + toCompactHexWithPrefix(storageSlotOffset) + "))"; members.back()["preprocess"] = "slotValue := sload(add(value, " + toCompactHexWithPrefix(storageSlotOffset) + "))";
previousSlotOffset = storageSlotOffset; previousSlotOffset = storageSlotOffset;
} }
members.back()["retrieveValue"] = m_utils.extractFromStorageValue(*memberTypeFrom, intraSlotOffset, false) + "(slotValue)"; members.back()["retrieveValue"] = m_utils.extractFromStorageValue(*memberTypeFrom, intraSlotOffset) + "(slotValue)";
} }
else else
{ {

View File

@ -702,26 +702,7 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly)
{ {
int const depositBefore = _assembly.stackHeight(); int const depositBefore = _assembly.stackHeight();
solAssert(!!decl->type(), "Type of declaration required but not yet determined."); solAssert(!!decl->type(), "Type of declaration required but not yet determined.");
if (FunctionDefinition const* functionDef = dynamic_cast<FunctionDefinition const*>(decl)) if (auto variable = dynamic_cast<VariableDeclaration const*>(decl))
{
solAssert(!ref->second.isOffset && !ref->second.isSlot, "");
functionDef = &functionDef->resolveVirtual(m_context.mostDerivedContract());
auto functionEntryLabel = m_context.functionEntryLabel(*functionDef).pushTag();
solAssert(functionEntryLabel.data() <= std::numeric_limits<size_t>::max(), "");
_assembly.appendLabelReference(static_cast<size_t>(functionEntryLabel.data()));
// If there is a runtime context, we have to merge both labels into the same
// stack slot in case we store it in storage.
if (CompilerContext* rtc = m_context.runtimeContext())
{
_assembly.appendConstant(u256(1) << 32);
_assembly.appendInstruction(Instruction::MUL);
auto runtimeEntryLabel = rtc->functionEntryLabel(*functionDef).toSubAssemblyTag(m_context.runtimeSub());
solAssert(runtimeEntryLabel.data() <= std::numeric_limits<size_t>::max(), "");
_assembly.appendLabelReference(static_cast<size_t>(runtimeEntryLabel.data()));
_assembly.appendInstruction(Instruction::OR);
}
}
else if (auto variable = dynamic_cast<VariableDeclaration const*>(decl))
{ {
solAssert(!variable->immutable(), ""); solAssert(!variable->immutable(), "");
if (variable->isConstant()) if (variable->isConstant())

View File

@ -2153,58 +2153,47 @@ string YulUtilFunctions::readFromStorage(Type const& _type, size_t _offset, bool
string YulUtilFunctions::readFromStorageDynamic(Type const& _type, bool _splitFunctionTypes) string YulUtilFunctions::readFromStorageDynamic(Type const& _type, bool _splitFunctionTypes)
{ {
solAssert(_type.isValueType(), ""); solAssert(_type.isValueType(), "");
return readFromStorageValueTypeDynamic(_type, _splitFunctionTypes); return readFromStorageValueType(_type, {}, _splitFunctionTypes);
} }
string YulUtilFunctions::readFromStorageValueType(Type const& _type, size_t _offset, bool _splitFunctionTypes) string YulUtilFunctions::readFromStorageValueType(Type const& _type, optional<size_t> _offset, bool _splitFunctionTypes)
{ {
solAssert(_type.isValueType(), ""); solAssert(_type.isValueType(), "");
if (_type.category() == Type::Category::Function)
solUnimplementedAssert(!_splitFunctionTypes, "");
string functionName = string functionName =
"read_from_storage_" + "read_from_storage_" +
string(_splitFunctionTypes ? "split_" : "") + string(_splitFunctionTypes ? "split_" : "") + (
"offset_" + _offset.has_value() ?
to_string(_offset) + "offset_" + to_string(*_offset) :
"dynamic"
) +
"_" + "_" +
_type.identifier(); _type.identifier();
return m_functionCollector.createFunction(functionName, [&] { return m_functionCollector.createFunction(functionName, [&] {
solAssert(_type.sizeOnStack() == 1, ""); Whiskers templ(R"(
return Whiskers(R"( function <functionName>(slot<?dynamic>, offset</dynamic>) -> <?split>addr, selector<!split>value</split> {
function <functionName>(slot) -> value { <?split>let</split> value := <extract>(sload(slot)<?dynamic>, offset</dynamic>)
value := <extract>(sload(slot)) <?split>
addr, selector := <splitFunction>(value)
</split>
} }
)") )");
("functionName", functionName) templ("functionName", functionName);
("extract", extractFromStorageValue(_type, _offset, false)) templ("dynamic", !_offset.has_value());
.render(); if (_offset.has_value())
templ("extract", extractFromStorageValue(_type, *_offset));
else
templ("extract", extractFromStorageValueDynamic(_type));
auto const* funType = dynamic_cast<FunctionType const*>(&_type);
bool split = _splitFunctionTypes && funType && funType->kind() == FunctionType::Kind::External;
templ("split", split);
if (split)
templ("splitFunction", splitExternalFunctionIdFunction());
return templ.render();
}); });
} }
string YulUtilFunctions::readFromStorageValueTypeDynamic(Type const& _type, bool _splitFunctionTypes)
{
solAssert(_type.isValueType(), "");
if (_type.category() == Type::Category::Function)
solUnimplementedAssert(!_splitFunctionTypes, "");
string functionName =
"read_from_storage_value_type_dynamic" +
string(_splitFunctionTypes ? "split_" : "") +
"_" +
_type.identifier();
return m_functionCollector.createFunction(functionName, [&] {
solAssert(_type.sizeOnStack() == 1, "");
return Whiskers(R"(
function <functionName>(slot, offset) -> value {
value := <extract>(sload(slot), offset)
}
)")
("functionName", functionName)
("extract", extractFromStorageValueDynamic(_type, _splitFunctionTypes))
.render();
});
}
string YulUtilFunctions::readFromStorageReferenceType(Type const& _type) string YulUtilFunctions::readFromStorageReferenceType(Type const& _type)
{ {
solUnimplementedAssert(_type.category() == Type::Category::Struct, ""); solUnimplementedAssert(_type.category() == Type::Category::Struct, "");
@ -2437,9 +2426,7 @@ string YulUtilFunctions::updateStorageValueFunction(
string YulUtilFunctions::writeToMemoryFunction(Type const& _type) string YulUtilFunctions::writeToMemoryFunction(Type const& _type)
{ {
string const functionName = string const functionName = "write_to_memory_" + _type.identifier();
string("write_to_memory_") +
_type.identifier();
return m_functionCollector.createFunction(functionName, [&] { return m_functionCollector.createFunction(functionName, [&] {
solAssert(!dynamic_cast<StringLiteralType const*>(&_type), ""); solAssert(!dynamic_cast<StringLiteralType const*>(&_type), "");
@ -2493,14 +2480,10 @@ string YulUtilFunctions::writeToMemoryFunction(Type const& _type)
}); });
} }
string YulUtilFunctions::extractFromStorageValueDynamic(Type const& _type, bool _splitFunctionTypes) string YulUtilFunctions::extractFromStorageValueDynamic(Type const& _type)
{ {
if (_type.category() == Type::Category::Function)
solUnimplementedAssert(!_splitFunctionTypes, "");
string functionName = string functionName =
"extract_from_storage_value_dynamic" + "extract_from_storage_value_dynamic" +
string(_splitFunctionTypes ? "split_" : "") +
_type.identifier(); _type.identifier();
return m_functionCollector.createFunction(functionName, [&] { return m_functionCollector.createFunction(functionName, [&] {
return Whiskers(R"( return Whiskers(R"(
@ -2510,21 +2493,14 @@ string YulUtilFunctions::extractFromStorageValueDynamic(Type const& _type, bool
)") )")
("functionName", functionName) ("functionName", functionName)
("shr", shiftRightFunctionDynamic()) ("shr", shiftRightFunctionDynamic())
("cleanupStorage", cleanupFromStorageFunction(_type, _splitFunctionTypes)) ("cleanupStorage", cleanupFromStorageFunction(_type))
.render(); .render();
}); });
} }
string YulUtilFunctions::extractFromStorageValue(Type const& _type, size_t _offset, bool _splitFunctionTypes) string YulUtilFunctions::extractFromStorageValue(Type const& _type, size_t _offset)
{ {
solUnimplementedAssert(!_splitFunctionTypes, ""); string functionName = "extract_from_storage_value_offset_" + to_string(_offset) + _type.identifier();
string functionName =
"extract_from_storage_value_" +
string(_splitFunctionTypes ? "split_" : "") +
"offset_" +
to_string(_offset) +
_type.identifier();
return m_functionCollector.createFunction(functionName, [&] { return m_functionCollector.createFunction(functionName, [&] {
return Whiskers(R"( return Whiskers(R"(
function <functionName>(slot_value) -> value { function <functionName>(slot_value) -> value {
@ -2533,18 +2509,16 @@ string YulUtilFunctions::extractFromStorageValue(Type const& _type, size_t _offs
)") )")
("functionName", functionName) ("functionName", functionName)
("shr", shiftRightFunction(_offset * 8)) ("shr", shiftRightFunction(_offset * 8))
("cleanupStorage", cleanupFromStorageFunction(_type, _splitFunctionTypes)) ("cleanupStorage", cleanupFromStorageFunction(_type))
.render(); .render();
}); });
} }
string YulUtilFunctions::cleanupFromStorageFunction(Type const& _type, bool _splitFunctionTypes) string YulUtilFunctions::cleanupFromStorageFunction(Type const& _type)
{ {
solAssert(_type.isValueType(), ""); solAssert(_type.isValueType(), "");
if (_type.category() == Type::Category::Function)
solUnimplementedAssert(!_splitFunctionTypes, "");
string functionName = string("cleanup_from_storage_") + (_splitFunctionTypes ? "split_" : "") + _type.identifier(); string functionName = string("cleanup_from_storage_") + _type.identifier();
return m_functionCollector.createFunction(functionName, [&] { return m_functionCollector.createFunction(functionName, [&] {
Whiskers templ(R"( Whiskers templ(R"(
function <functionName>(value) -> cleaned { function <functionName>(value) -> cleaned {
@ -2581,22 +2555,37 @@ string YulUtilFunctions::cleanupFromStorageFunction(Type const& _type, bool _spl
string YulUtilFunctions::prepareStoreFunction(Type const& _type) string YulUtilFunctions::prepareStoreFunction(Type const& _type)
{ {
if (_type.category() == Type::Category::Function)
solUnimplementedAssert(dynamic_cast<FunctionType const&>(_type).kind() == FunctionType::Kind::Internal, "");
string functionName = "prepare_store_" + _type.identifier(); string functionName = "prepare_store_" + _type.identifier();
return m_functionCollector.createFunction(functionName, [&]() { return m_functionCollector.createFunction(functionName, [&]() {
Whiskers templ(R"( solAssert(_type.isValueType(), "");
function <functionName>(value) -> ret { auto const* funType = dynamic_cast<FunctionType const*>(&_type);
ret := <actualPrepare> if (funType && funType->kind() == FunctionType::Kind::External)
} {
)"); Whiskers templ(R"(
templ("functionName", functionName); function <functionName>(addr, selector) -> ret {
if (_type.category() == Type::Category::FixedBytes) ret := <prepareBytes>(<combine>(addr, selector))
templ("actualPrepare", shiftRightFunction(256 - 8 * _type.storageBytes()) + "(value)"); }
)");
templ("functionName", functionName);
templ("prepareBytes", prepareStoreFunction(*TypeProvider::fixedBytes(24)));
templ("combine", combineExternalFunctionIdFunction());
return templ.render();
}
else else
templ("actualPrepare", "value"); {
return templ.render(); solAssert(_type.sizeOnStack() == 1, "");
Whiskers templ(R"(
function <functionName>(value) -> ret {
ret := <actualPrepare>
}
)");
templ("functionName", functionName);
if (_type.category() == Type::Category::FixedBytes)
templ("actualPrepare", shiftRightFunction(256 - 8 * _type.storageBytes()) + "(value)");
else
templ("actualPrepare", "value");
return templ.render();
}
}); });
} }
@ -3683,37 +3672,44 @@ string YulUtilFunctions::readFromMemoryOrCalldata(Type const& _type, bool _fromC
} }
solAssert(_type.isValueType(), ""); solAssert(_type.isValueType(), "");
if (auto const* funType = dynamic_cast<FunctionType const*>(&_type)) Whiskers templ(R"(
if (funType->kind() == FunctionType::Kind::External) function <functionName>(ptr) -> <returnVariables> {
return Whiskers(R"(
function <functionName>(memPtr) -> addr, selector {
let combined := <load>(memPtr)
addr, selector := <splitFunction>(combined)
}
)")
("functionName", functionName)
("load", _fromCalldata ? "calldataload" : "mload")
("splitFunction", splitExternalFunctionIdFunction())
.render();
return Whiskers(R"(
function <functionName>(ptr) -> value {
<?fromCalldata> <?fromCalldata>
value := calldataload(ptr) let value := calldataload(ptr)
<validate>(value) <validate>(value)
<!fromCalldata> <!fromCalldata>
value := <cleanup>(mload(ptr)) let value := <cleanup>(mload(ptr))
</fromCalldata> </fromCalldata>
<returnVariables> :=
<?externalFunction>
<splitFunction>(value)
<!externalFunction>
value
</externalFunction>
} }
)") )");
("functionName", functionName) templ("functionName", functionName);
("fromCalldata", _fromCalldata) templ("fromCalldata", _fromCalldata);
("validate", validatorFunction(_type, true)) if (_fromCalldata)
templ("validate", validatorFunction(_type, true));
auto const* funType = dynamic_cast<FunctionType const*>(&_type);
if (funType && funType->kind() == FunctionType::Kind::External)
{
templ("externalFunction", true);
templ("splitFunction", splitExternalFunctionIdFunction());
templ("returnVariables", "addr, selector");
}
else
{
templ("externalFunction", false);
templ("returnVariables", "returnValue");
}
// Byte array elements generally need cleanup. // Byte array elements generally need cleanup.
// Other types are cleaned as well to account for dirty memory e.g. due to inline assembly. // Other types are cleaned as well to account for dirty memory e.g. due to inline assembly.
("cleanup", cleanupFunction(_type)) templ("cleanup", cleanupFunction(_type));
.render(); return templ.render();
}); });
} }

View File

@ -283,10 +283,10 @@ public:
/// @returns a function that extracts a value type from storage slot that has been /// @returns a function that extracts a value type from storage slot that has been
/// retrieved already. /// retrieved already.
/// Performs bit mask/sign extend cleanup and appropriate left / right shift, but not validation. /// Performs bit mask/sign extend cleanup and appropriate left / right shift, but not validation.
/// @param _splitFunctionTypes if false, returns the address and function signature in a ///
/// single variable. /// For external function types, input and output is in "compressed"/"unsplit" form.
std::string extractFromStorageValue(Type const& _type, size_t _offset, bool _splitFunctionTypes); std::string extractFromStorageValue(Type const& _type, size_t _offset);
std::string extractFromStorageValueDynamic(Type const& _type, bool _splitFunctionTypes); std::string extractFromStorageValueDynamic(Type const& _type);
/// Returns the name of a function will write the given value to /// Returns the name of a function will write the given value to
/// the specified slot and offset. If offset is not given, it is expected as /// the specified slot and offset. If offset is not given, it is expected as
@ -309,9 +309,8 @@ public:
/// higher order bytes or left-aligns (in case of bytesNN). /// higher order bytes or left-aligns (in case of bytesNN).
/// The storage cleanup expects the value to be right-aligned with potentially /// The storage cleanup expects the value to be right-aligned with potentially
/// dirty higher order bytes. /// dirty higher order bytes.
/// @param _splitFunctionTypes if false, returns the address and function signature in a /// For external functions, input and output is in "compressed"/"unsplit" form.
/// single variable. std::string cleanupFromStorageFunction(Type const& _type);
std::string cleanupFromStorageFunction(Type const& _type, bool _splitFunctionTypes);
/// @returns the name of a function that prepares a value of the given type /// @returns the name of a function that prepares a value of the given type
/// for being stored in storage. This usually includes cleanup and right-alignment /// for being stored in storage. This usually includes cleanup and right-alignment
@ -459,8 +458,8 @@ private:
/// Performs bit mask/sign extend cleanup and appropriate left / right shift, but not validation. /// Performs bit mask/sign extend cleanup and appropriate left / right shift, but not validation.
/// @param _splitFunctionTypes if false, returns the address and function signature in a /// @param _splitFunctionTypes if false, returns the address and function signature in a
/// single variable. /// single variable.
std::string readFromStorageValueType(Type const& _type, size_t _offset, bool _splitFunctionTypes); /// @param _offset if provided, read from static offset, otherwise offset is a parameter of the Yul function.
std::string readFromStorageValueTypeDynamic(Type const& _type, bool _splitFunctionTypes); std::string readFromStorageValueType(Type const& _type, std::optional<size_t> _offset, bool _splitFunctionTypes);
/// @returns a function that reads a reference type from storage to memory (performing a deep copy). /// @returns a function that reads a reference type from storage to memory (performing a deep copy).
std::string readFromStorageReferenceType(Type const& _type); std::string readFromStorageReferenceType(Type const& _type);

View File

@ -2720,7 +2720,7 @@ IRVariable IRGeneratorForStatements::readFromLValue(IRLValue const& _lvalue)
define(result) << _storage.slot << "\n"; define(result) << _storage.slot << "\n";
else if (std::holds_alternative<string>(_storage.offset)) else if (std::holds_alternative<string>(_storage.offset))
define(result) << define(result) <<
m_utils.readFromStorageDynamic(_lvalue.type, false) << m_utils.readFromStorageDynamic(_lvalue.type, true) <<
"(" << "(" <<
_storage.slot << _storage.slot <<
", " << ", " <<
@ -2728,7 +2728,7 @@ IRVariable IRGeneratorForStatements::readFromLValue(IRLValue const& _lvalue)
")\n"; ")\n";
else else
define(result) << define(result) <<
m_utils.readFromStorage(_lvalue.type, std::get<unsigned>(_storage.offset), false) << m_utils.readFromStorage(_lvalue.type, std::get<unsigned>(_storage.offset), true) <<
"(" << "(" <<
_storage.slot << _storage.slot <<
")\n"; ")\n";

View File

@ -34,10 +34,11 @@ BMC::BMC(
ErrorReporter& _errorReporter, ErrorReporter& _errorReporter,
map<h256, string> const& _smtlib2Responses, map<h256, string> const& _smtlib2Responses,
ReadCallback::Callback const& _smtCallback, ReadCallback::Callback const& _smtCallback,
smtutil::SMTSolverChoice _enabledSolvers smtutil::SMTSolverChoice _enabledSolvers,
optional<unsigned> _timeout
): ):
SMTEncoder(_context), SMTEncoder(_context),
m_interface(make_unique<smtutil::SMTPortfolio>(_smtlib2Responses, _smtCallback, _enabledSolvers)), m_interface(make_unique<smtutil::SMTPortfolio>(_smtlib2Responses, _smtCallback, _enabledSolvers, _timeout)),
m_outerErrorReporter(_errorReporter) m_outerErrorReporter(_errorReporter)
{ {
#if defined (HAVE_Z3) || defined (HAVE_CVC4) #if defined (HAVE_Z3) || defined (HAVE_CVC4)
@ -491,7 +492,7 @@ void BMC::internalOrExternalFunctionCall(FunctionCall const& _funCall)
m_errorReporter.warning( m_errorReporter.warning(
5729_error, 5729_error,
_funCall.location(), _funCall.location(),
"Assertion checker does not yet implement this type of function call." "BMC does not yet implement this type of function call."
); );
else else
{ {
@ -909,9 +910,9 @@ void BMC::checkBooleanNotConstant(
m_interface->pop(); m_interface->pop();
if (positiveResult == smtutil::CheckResult::ERROR || negatedResult == smtutil::CheckResult::ERROR) if (positiveResult == smtutil::CheckResult::ERROR || negatedResult == smtutil::CheckResult::ERROR)
m_errorReporter.warning(8592_error, _condition.location(), "Error trying to invoke SMT solver."); m_errorReporter.warning(8592_error, _condition.location(), "BMC: Error trying to invoke SMT solver.");
else if (positiveResult == smtutil::CheckResult::CONFLICTING || negatedResult == smtutil::CheckResult::CONFLICTING) else if (positiveResult == smtutil::CheckResult::CONFLICTING || negatedResult == smtutil::CheckResult::CONFLICTING)
m_errorReporter.warning(3356_error, _condition.location(), "At least two SMT solvers provided conflicting answers. Results might not be sound."); m_errorReporter.warning(3356_error, _condition.location(), "BMC: At least two SMT solvers provided conflicting answers. Results might not be sound.");
else if (positiveResult == smtutil::CheckResult::SATISFIABLE && negatedResult == smtutil::CheckResult::SATISFIABLE) else if (positiveResult == smtutil::CheckResult::SATISFIABLE && negatedResult == smtutil::CheckResult::SATISFIABLE)
{ {
// everything fine. // everything fine.
@ -921,7 +922,7 @@ void BMC::checkBooleanNotConstant(
// can't do anything. // can't do anything.
} }
else if (positiveResult == smtutil::CheckResult::UNSATISFIABLE && negatedResult == smtutil::CheckResult::UNSATISFIABLE) else if (positiveResult == smtutil::CheckResult::UNSATISFIABLE && negatedResult == smtutil::CheckResult::UNSATISFIABLE)
m_errorReporter.warning(2512_error, _condition.location(), "Condition unreachable.", SMTEncoder::callStackMessage(_callStack)); m_errorReporter.warning(2512_error, _condition.location(), "BMC: Condition unreachable.", SMTEncoder::callStackMessage(_callStack));
else else
{ {
string description; string description;
@ -956,7 +957,7 @@ BMC::checkSatisfiableAndGenerateModel(vector<smtutil::Expression> const& _expres
} }
catch (smtutil::SolverError const& _e) catch (smtutil::SolverError const& _e)
{ {
string description("Error querying SMT solver"); string description("BMC: Error querying SMT solver");
if (_e.comment()) if (_e.comment())
description += ": " + *_e.comment(); description += ": " + *_e.comment();
m_errorReporter.warning(8140_error, description); m_errorReporter.warning(8140_error, description);

View File

@ -61,7 +61,8 @@ public:
langutil::ErrorReporter& _errorReporter, langutil::ErrorReporter& _errorReporter,
std::map<h256, std::string> const& _smtlib2Responses, std::map<h256, std::string> const& _smtlib2Responses,
ReadCallback::Callback const& _smtCallback, ReadCallback::Callback const& _smtCallback,
smtutil::SMTSolverChoice _enabledSolvers smtutil::SMTSolverChoice _enabledSolvers,
std::optional<unsigned> timeout
); );
void analyze(SourceUnit const& _sources, std::map<ASTNode const*, std::set<VerificationTarget::Type>> _solvedTargets); void analyze(SourceUnit const& _sources, std::map<ASTNode const*, std::set<VerificationTarget::Type>> _solvedTargets);

View File

@ -49,18 +49,20 @@ CHC::CHC(
ErrorReporter& _errorReporter, ErrorReporter& _errorReporter,
[[maybe_unused]] map<util::h256, string> const& _smtlib2Responses, [[maybe_unused]] map<util::h256, string> const& _smtlib2Responses,
[[maybe_unused]] ReadCallback::Callback const& _smtCallback, [[maybe_unused]] ReadCallback::Callback const& _smtCallback,
SMTSolverChoice _enabledSolvers SMTSolverChoice _enabledSolvers,
optional<unsigned> _timeout
): ):
SMTEncoder(_context), SMTEncoder(_context),
m_outerErrorReporter(_errorReporter), m_outerErrorReporter(_errorReporter),
m_enabledSolvers(_enabledSolvers) m_enabledSolvers(_enabledSolvers),
m_queryTimeout(_timeout)
{ {
bool usesZ3 = _enabledSolvers.z3; bool usesZ3 = _enabledSolvers.z3;
#ifndef HAVE_Z3 #ifndef HAVE_Z3
usesZ3 = false; usesZ3 = false;
#endif #endif
if (!usesZ3) if (!usesZ3)
m_interface = make_unique<CHCSmtLib2Interface>(_smtlib2Responses, _smtCallback); m_interface = make_unique<CHCSmtLib2Interface>(_smtlib2Responses, _smtCallback, m_queryTimeout);
} }
void CHC::analyze(SourceUnit const& _source) void CHC::analyze(SourceUnit const& _source)
@ -69,7 +71,7 @@ void CHC::analyze(SourceUnit const& _source)
resetSourceAnalysis(); resetSourceAnalysis();
set<SourceUnit const*, IdCompare> sources; set<SourceUnit const*, EncodingContext::IdCompare> sources;
sources.insert(&_source); sources.insert(&_source);
for (auto const& source: _source.referencedSourceUnits(true)) for (auto const& source: _source.referencedSourceUnits(true))
sources.insert(source); sources.insert(source);
@ -79,6 +81,24 @@ void CHC::analyze(SourceUnit const& _source)
source->accept(*this); source->accept(*this);
checkVerificationTargets(); checkVerificationTargets();
bool ranSolver = true;
#ifndef HAVE_Z3
ranSolver = dynamic_cast<CHCSmtLib2Interface const*>(m_interface.get())->unhandledQueries().empty();
#endif
if (!ranSolver && !m_noSolverWarning)
{
m_noSolverWarning = true;
m_outerErrorReporter.warning(
3996_error,
SourceLocation(),
"CHC analysis was not possible since no integrated z3 SMT solver was found."
);
}
else
m_outerErrorReporter.append(m_errorReporter.errors());
m_errorReporter.clear();
} }
vector<string> CHC::unhandledQueries() const vector<string> CHC::unhandledQueries() const
@ -681,7 +701,7 @@ void CHC::resetSourceAnalysis()
if (usesZ3) if (usesZ3)
{ {
/// z3::fixedpoint does not have a reset mechanism, so we need to create another. /// z3::fixedpoint does not have a reset mechanism, so we need to create another.
m_interface.reset(new Z3CHCInterface()); m_interface.reset(new Z3CHCInterface(m_queryTimeout));
auto z3Interface = dynamic_cast<Z3CHCInterface const*>(m_interface.get()); auto z3Interface = dynamic_cast<Z3CHCInterface const*>(m_interface.get());
solAssert(z3Interface, ""); solAssert(z3Interface, "");
m_context.setSolver(z3Interface->z3Interface()); m_context.setSolver(z3Interface->z3Interface());
@ -1076,10 +1096,10 @@ pair<CheckResult, CHCSolverInterface::CexGraph> CHC::query(smtutil::Expression c
case CheckResult::UNKNOWN: case CheckResult::UNKNOWN:
break; break;
case CheckResult::CONFLICTING: case CheckResult::CONFLICTING:
m_outerErrorReporter.warning(1988_error, _location, "CHC: At least two SMT solvers provided conflicting answers. Results might not be sound."); m_errorReporter.warning(1988_error, _location, "CHC: At least two SMT solvers provided conflicting answers. Results might not be sound.");
break; break;
case CheckResult::ERROR: case CheckResult::ERROR:
m_outerErrorReporter.warning(1218_error, _location, "CHC: Error trying to invoke SMT solver."); m_errorReporter.warning(1218_error, _location, "CHC: Error trying to invoke SMT solver.");
break; break;
} }
return {result, cex}; return {result, cex};
@ -1233,21 +1253,21 @@ void CHC::checkAndReportTarget(
m_unsafeTargets[_target.errorNode].insert(_target.type); m_unsafeTargets[_target.errorNode].insert(_target.type);
auto cex = generateCounterexample(model, error().name); auto cex = generateCounterexample(model, error().name);
if (cex) if (cex)
m_outerErrorReporter.warning( m_errorReporter.warning(
_errorReporterId, _errorReporterId,
location, location,
"CHC: " + _satMsg, "CHC: " + _satMsg,
SecondarySourceLocation().append("Counterexample:\n" + *cex, SourceLocation{}) SecondarySourceLocation().append("Counterexample:\n" + *cex, SourceLocation{})
); );
else else
m_outerErrorReporter.warning( m_errorReporter.warning(
_errorReporterId, _errorReporterId,
location, location,
"CHC: " + _satMsg "CHC: " + _satMsg
); );
} }
else if (!_unknownMsg.empty()) else if (!_unknownMsg.empty())
m_outerErrorReporter.warning( m_errorReporter.warning(
_errorReporterId, _errorReporterId,
location, location,
"CHC: " + _unknownMsg "CHC: " + _unknownMsg

View File

@ -55,7 +55,8 @@ public:
langutil::ErrorReporter& _errorReporter, langutil::ErrorReporter& _errorReporter,
std::map<util::h256, std::string> const& _smtlib2Responses, std::map<util::h256, std::string> const& _smtlib2Responses,
ReadCallback::Callback const& _smtCallback, ReadCallback::Callback const& _smtCallback,
smtutil::SMTSolverChoice _enabledSolvers smtutil::SMTSolverChoice _enabledSolvers,
std::optional<unsigned> timeout
); );
void analyze(SourceUnit const& _sources); void analyze(SourceUnit const& _sources);
@ -99,14 +100,6 @@ private:
) override; ) override;
//@} //@}
struct IdCompare
{
bool operator()(ASTNode const* lhs, ASTNode const* rhs) const
{
return lhs->id() < rhs->id();
}
};
/// Helpers. /// Helpers.
//@{ //@{
void resetSourceAnalysis(); void resetSourceAnalysis();
@ -286,12 +279,12 @@ private:
/// Query placeholders for constructors, if the key has type ContractDefinition*, /// Query placeholders for constructors, if the key has type ContractDefinition*,
/// or external functions, if the key has type FunctionDefinition*. /// or external functions, if the key has type FunctionDefinition*.
/// A placeholder is created for each possible context of a function (e.g. multiple contracts in contract inheritance hierarchy). /// A placeholder is created for each possible context of a function (e.g. multiple contracts in contract inheritance hierarchy).
std::map<ASTNode const*, std::vector<CHCQueryPlaceholder>, IdCompare> m_queryPlaceholders; std::map<ASTNode const*, std::vector<CHCQueryPlaceholder>, smt::EncodingContext::IdCompare> m_queryPlaceholders;
/// Records verification conditions IDs per function encountered during an analysis of that function. /// Records verification conditions IDs per function encountered during an analysis of that function.
/// The key is the ASTNode of the function where the verification condition has been encountered, /// The key is the ASTNode of the function where the verification condition has been encountered,
/// or the ASTNode of the contract if the verification condition happens inside an implicit constructor. /// or the ASTNode of the contract if the verification condition happens inside an implicit constructor.
std::map<ASTNode const*, std::vector<unsigned>, IdCompare> m_functionTargetIds; std::map<ASTNode const*, std::vector<unsigned>, smt::EncodingContext::IdCompare> m_functionTargetIds;
/// Helper mapping unique IDs to actual verification targets. /// Helper mapping unique IDs to actual verification targets.
std::map<unsigned, CHCVerificationTarget> m_verificationTargets; std::map<unsigned, CHCVerificationTarget> m_verificationTargets;
@ -305,7 +298,7 @@ private:
//@{ //@{
FunctionDefinition const* m_currentFunction = nullptr; FunctionDefinition const* m_currentFunction = nullptr;
std::map<ASTNode const*, std::set<ASTNode const*, IdCompare>, IdCompare> m_callGraph; std::map<ASTNode const*, std::set<ASTNode const*, smt::EncodingContext::IdCompare>, smt::EncodingContext::IdCompare> m_callGraph;
/// The current block. /// The current block.
smtutil::Expression m_currentBlock = smtutil::Expression(true); smtutil::Expression m_currentBlock = smtutil::Expression(true);
@ -330,6 +323,9 @@ private:
/// SMT solvers that are chosen at runtime. /// SMT solvers that are chosen at runtime.
smtutil::SMTSolverChoice m_enabledSolvers; smtutil::SMTSolverChoice m_enabledSolvers;
/// SMT query timeout in seconds.
std::optional<unsigned> m_queryTimeout;
}; };
} }

View File

@ -23,8 +23,7 @@
#include <libsmtutil/SolverInterface.h> #include <libsmtutil/SolverInterface.h>
#include <unordered_map> #include <map>
#include <set>
namespace solidity::frontend::smt namespace solidity::frontend::smt
{ {
@ -67,12 +66,20 @@ public:
return m_solver->newVariable(move(_name), move(_sort)); return m_solver->newVariable(move(_name), move(_sort));
} }
struct IdCompare
{
bool operator()(ASTNode const* lhs, ASTNode const* rhs) const
{
return lhs->id() < rhs->id();
}
};
/// Variables. /// Variables.
//@{ //@{
/// @returns the symbolic representation of a program variable. /// @returns the symbolic representation of a program variable.
std::shared_ptr<SymbolicVariable> variable(frontend::VariableDeclaration const& _varDecl); std::shared_ptr<SymbolicVariable> variable(frontend::VariableDeclaration const& _varDecl);
/// @returns all symbolic variables. /// @returns all symbolic variables.
std::unordered_map<frontend::VariableDeclaration const*, std::shared_ptr<SymbolicVariable>> const& variables() const { return m_variables; } std::map<frontend::VariableDeclaration const*, std::shared_ptr<SymbolicVariable>, IdCompare> const& variables() const { return m_variables; }
/// Creates a symbolic variable and /// Creates a symbolic variable and
/// @returns true if a variable's type is not supported and is therefore abstract. /// @returns true if a variable's type is not supported and is therefore abstract.
@ -105,7 +112,7 @@ public:
/// @returns the symbolic representation of an AST node expression. /// @returns the symbolic representation of an AST node expression.
std::shared_ptr<SymbolicVariable> expression(frontend::Expression const& _e); std::shared_ptr<SymbolicVariable> expression(frontend::Expression const& _e);
/// @returns all symbolic expressions. /// @returns all symbolic expressions.
std::unordered_map<frontend::Expression const*, std::shared_ptr<SymbolicVariable>> const& expressions() const { return m_expressions; } std::map<frontend::Expression const*, std::shared_ptr<SymbolicVariable>, IdCompare> const& expressions() const { return m_expressions; }
/// Creates the expression (value can be arbitrary). /// Creates the expression (value can be arbitrary).
/// @returns true if type is not supported. /// @returns true if type is not supported.
@ -119,7 +126,7 @@ public:
/// Global variables and functions. /// Global variables and functions.
std::shared_ptr<SymbolicVariable> globalSymbol(std::string const& _name); std::shared_ptr<SymbolicVariable> globalSymbol(std::string const& _name);
/// @returns all symbolic globals. /// @returns all symbolic globals.
std::unordered_map<std::string, std::shared_ptr<SymbolicVariable>> const& globalSymbols() const { return m_globalContext; } std::map<std::string, std::shared_ptr<SymbolicVariable>> const& globalSymbols() const { return m_globalContext; }
/// Defines a new global variable or function /// Defines a new global variable or function
/// and @returns true if type was abstracted. /// and @returns true if type was abstracted.
@ -149,14 +156,14 @@ private:
/// Symbolic expressions. /// Symbolic expressions.
//{@ //{@
/// Symbolic variables. /// Symbolic variables.
std::unordered_map<frontend::VariableDeclaration const*, std::shared_ptr<SymbolicVariable>> m_variables; std::map<frontend::VariableDeclaration const*, std::shared_ptr<SymbolicVariable>, IdCompare> m_variables;
/// Symbolic expressions. /// Symbolic expressions.
std::unordered_map<frontend::Expression const*, std::shared_ptr<SymbolicVariable>> m_expressions; std::map<frontend::Expression const*, std::shared_ptr<SymbolicVariable>, IdCompare> m_expressions;
/// Symbolic representation of global symbols including /// Symbolic representation of global symbols including
/// variables and functions. /// variables and functions.
std::unordered_map<std::string, std::shared_ptr<smt::SymbolicVariable>> m_globalContext; std::map<std::string, std::shared_ptr<smt::SymbolicVariable>> m_globalContext;
/// Symbolic representation of the blockchain state. /// Symbolic representation of the blockchain state.
SymbolicState m_state; SymbolicState m_state;

View File

@ -27,14 +27,14 @@ using namespace solidity::frontend;
ModelChecker::ModelChecker( ModelChecker::ModelChecker(
ErrorReporter& _errorReporter, ErrorReporter& _errorReporter,
map<h256, string> const& _smtlib2Responses, map<h256, string> const& _smtlib2Responses,
ModelCheckerEngine _engine, ModelCheckerSettings _settings,
ReadCallback::Callback const& _smtCallback, ReadCallback::Callback const& _smtCallback,
smtutil::SMTSolverChoice _enabledSolvers smtutil::SMTSolverChoice _enabledSolvers
): ):
m_engine(_engine), m_settings(_settings),
m_context(), m_context(),
m_bmc(m_context, _errorReporter, _smtlib2Responses, _smtCallback, _enabledSolvers), m_bmc(m_context, _errorReporter, _smtlib2Responses, _smtCallback, _enabledSolvers, _settings.timeout),
m_chc(m_context, _errorReporter, _smtlib2Responses, _smtCallback, _enabledSolvers) m_chc(m_context, _errorReporter, _smtlib2Responses, _smtCallback, _enabledSolvers, _settings.timeout)
{ {
} }
@ -43,14 +43,14 @@ void ModelChecker::analyze(SourceUnit const& _source)
if (!_source.annotation().experimentalFeatures.count(ExperimentalFeature::SMTChecker)) if (!_source.annotation().experimentalFeatures.count(ExperimentalFeature::SMTChecker))
return; return;
if (m_engine.chc) if (m_settings.engine.chc)
m_chc.analyze(_source); m_chc.analyze(_source);
auto solvedTargets = m_chc.safeTargets(); auto solvedTargets = m_chc.safeTargets();
for (auto const& target: m_chc.unsafeTargets()) for (auto const& target: m_chc.unsafeTargets())
solvedTargets[target.first] += target.second; solvedTargets[target.first] += target.second;
if (m_engine.bmc) if (m_settings.engine.bmc)
m_bmc.analyze(_source, solvedTargets); m_bmc.analyze(_source, solvedTargets);
} }

View File

@ -71,6 +71,12 @@ struct ModelCheckerEngine
} }
}; };
struct ModelCheckerSettings
{
ModelCheckerEngine engine = ModelCheckerEngine::All();
std::optional<unsigned> timeout;
};
class ModelChecker class ModelChecker
{ {
public: public:
@ -79,7 +85,7 @@ public:
ModelChecker( ModelChecker(
langutil::ErrorReporter& _errorReporter, langutil::ErrorReporter& _errorReporter,
std::map<solidity::util::h256, std::string> const& _smtlib2Responses, std::map<solidity::util::h256, std::string> const& _smtlib2Responses,
ModelCheckerEngine _engine = ModelCheckerEngine::All(), ModelCheckerSettings _settings = ModelCheckerSettings{},
ReadCallback::Callback const& _smtCallback = ReadCallback::Callback(), ReadCallback::Callback const& _smtCallback = ReadCallback::Callback(),
smtutil::SMTSolverChoice _enabledSolvers = smtutil::SMTSolverChoice::All() smtutil::SMTSolverChoice _enabledSolvers = smtutil::SMTSolverChoice::All()
); );
@ -95,7 +101,7 @@ public:
static smtutil::SMTSolverChoice availableSolvers(); static smtutil::SMTSolverChoice availableSolvers();
private: private:
ModelCheckerEngine m_engine; ModelCheckerSettings m_settings;
/// Stores the context of the encoding. /// Stores the context of the encoding.
smt::EncodingContext m_context; smt::EncodingContext m_context;

View File

@ -1799,23 +1799,25 @@ pair<smtutil::Expression, smtutil::Expression> SMTEncoder::divModWithSlacks(
{ {
IntegerType const* intType = &_type; IntegerType const* intType = &_type;
string suffix = "div_mod_" + to_string(m_context.newUniqueId()); string suffix = "div_mod_" + to_string(m_context.newUniqueId());
smt::SymbolicIntVariable d(intType, intType, "d_" + suffix, m_context); smt::SymbolicIntVariable dSymb(intType, intType, "d_" + suffix, m_context);
smt::SymbolicIntVariable r(intType, intType, "r_" + suffix, m_context); smt::SymbolicIntVariable rSymb(intType, intType, "r_" + suffix, m_context);
auto d = dSymb.currentValue();
auto r = rSymb.currentValue();
// x / y = d and x % y = r iff d * y + r = x and // x / y = d and x % y = r iff d * y + r = x and
// either x >= 0 and 0 <= r < abs(y) (or just 0 <= r < y for unsigned) // either x >= 0 and 0 <= r < abs(y) (or just 0 <= r < y for unsigned)
// or x < 0 and -abs(y) < r <= 0 // or x < 0 and -abs(y) < r <= 0
m_context.addAssertion(((d.currentValue() * _right) + r.currentValue()) == _left); m_context.addAssertion(((d * _right) + r) == _left);
if (_type.isSigned()) if (_type.isSigned())
m_context.addAssertion( m_context.addAssertion(
(_left >= 0 && 0 <= r.currentValue() && (_right == 0 || r.currentValue() < smtutil::abs(_right))) || (_left >= 0 && 0 <= r && (_right == 0 || r < smtutil::abs(_right))) ||
(_left < 0 && ((_right == 0 || 0 - smtutil::abs(_right) < r.currentValue()) && r.currentValue() <= 0)) (_left < 0 && ((_right == 0 || 0 - smtutil::abs(_right) < r) && r <= 0))
); );
else // unsigned version else // unsigned version
m_context.addAssertion(0 <= r.currentValue() && (_right == 0 || r.currentValue() < _right)); m_context.addAssertion(0 <= r && (_right == 0 || r < _right));
auto divResult = smtutil::Expression::ite(_right == 0, 0, d.currentValue()); auto divResult = smtutil::Expression::ite(_right == 0, 0, d);
auto modResult = smtutil::Expression::ite(_right == 0, 0, r.currentValue()); auto modResult = smtutil::Expression::ite(_right == 0, 0, r);
return {divResult, modResult}; return {divResult, modResult};
} }

View File

@ -87,7 +87,6 @@ static int g_compilerStackCounts = 0;
CompilerStack::CompilerStack(ReadCallback::Callback _readFile): CompilerStack::CompilerStack(ReadCallback::Callback _readFile):
m_readFile{std::move(_readFile)}, m_readFile{std::move(_readFile)},
m_modelCheckerEngine{ModelCheckerEngine::All()},
m_enabledSMTSolvers{smtutil::SMTSolverChoice::All()}, m_enabledSMTSolvers{smtutil::SMTSolverChoice::All()},
m_errorReporter{m_errorList} m_errorReporter{m_errorList}
{ {
@ -139,11 +138,11 @@ void CompilerStack::setEVMVersion(langutil::EVMVersion _version)
m_evmVersion = _version; m_evmVersion = _version;
} }
void CompilerStack::setModelCheckerEngine(ModelCheckerEngine _engine) void CompilerStack::setModelCheckerSettings(ModelCheckerSettings _settings)
{ {
if (m_stackState >= ParsedAndImported) if (m_stackState >= ParsedAndImported)
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Must set enabled model checking engines before parsing.")); BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Must set model checking settings before parsing."));
m_modelCheckerEngine = _engine; m_modelCheckerSettings = _settings;
} }
void CompilerStack::setSMTSolverChoice(smtutil::SMTSolverChoice _enabledSMTSolvers) void CompilerStack::setSMTSolverChoice(smtutil::SMTSolverChoice _enabledSMTSolvers)
@ -215,7 +214,7 @@ void CompilerStack::reset(bool _keepSettings)
m_remappings.clear(); m_remappings.clear();
m_libraries.clear(); m_libraries.clear();
m_evmVersion = langutil::EVMVersion(); m_evmVersion = langutil::EVMVersion();
m_modelCheckerEngine = ModelCheckerEngine::All(); m_modelCheckerSettings = ModelCheckerSettings{};
m_enabledSMTSolvers = smtutil::SMTSolverChoice::All(); m_enabledSMTSolvers = smtutil::SMTSolverChoice::All();
m_generateIR = false; m_generateIR = false;
m_generateEwasm = false; m_generateEwasm = false;
@ -452,7 +451,7 @@ bool CompilerStack::analyze()
if (noErrors) if (noErrors)
{ {
ModelChecker modelChecker(m_errorReporter, m_smtlib2Responses, m_modelCheckerEngine, m_readFile, m_enabledSMTSolvers); ModelChecker modelChecker(m_errorReporter, m_smtlib2Responses, m_modelCheckerSettings, m_readFile, m_enabledSMTSolvers);
for (Source const* source: m_sourceOrder) for (Source const* source: m_sourceOrder)
if (source->ast) if (source->ast)
modelChecker.analyze(*source->ast); modelChecker.analyze(*source->ast);

View File

@ -167,8 +167,8 @@ public:
/// Must be set before parsing. /// Must be set before parsing.
void setEVMVersion(langutil::EVMVersion _version = langutil::EVMVersion{}); void setEVMVersion(langutil::EVMVersion _version = langutil::EVMVersion{});
/// Set which model checking engines should be used. /// Set model checker settings.
void setModelCheckerEngine(ModelCheckerEngine _engine); void setModelCheckerSettings(ModelCheckerSettings _settings);
/// Set which SMT solvers should be enabled. /// Set which SMT solvers should be enabled.
void setSMTSolverChoice(smtutil::SMTSolverChoice _enabledSolvers); void setSMTSolverChoice(smtutil::SMTSolverChoice _enabledSolvers);
@ -456,7 +456,7 @@ private:
RevertStrings m_revertStrings = RevertStrings::Default; RevertStrings m_revertStrings = RevertStrings::Default;
State m_stopAfter = State::CompilationSuccessful; State m_stopAfter = State::CompilationSuccessful;
langutil::EVMVersion m_evmVersion; langutil::EVMVersion m_evmVersion;
ModelCheckerEngine m_modelCheckerEngine; ModelCheckerSettings m_modelCheckerSettings;
smtutil::SMTSolverChoice m_enabledSMTSolvers; smtutil::SMTSolverChoice m_enabledSMTSolvers;
std::map<std::string, std::set<std::string>> m_requestedContractNames; std::map<std::string, std::set<std::string>> m_requestedContractNames;
bool m_generateEvmBytecode = true; bool m_generateEvmBytecode = true;

View File

@ -420,7 +420,7 @@ std::optional<Json::Value> checkSettingsKeys(Json::Value const& _input)
std::optional<Json::Value> checkModelCheckerSettingsKeys(Json::Value const& _input) std::optional<Json::Value> checkModelCheckerSettingsKeys(Json::Value const& _input)
{ {
static set<string> keys{"engine"}; static set<string> keys{"engine", "timeout"};
return checkKeys(_input, keys, "modelCheckerSettings"); return checkKeys(_input, keys, "modelCheckerSettings");
} }
@ -885,7 +885,14 @@ std::variant<StandardCompiler::InputsAndSettings, Json::Value> StandardCompiler:
std::optional<ModelCheckerEngine> engine = ModelCheckerEngine::fromString(modelCheckerSettings["engine"].asString()); std::optional<ModelCheckerEngine> engine = ModelCheckerEngine::fromString(modelCheckerSettings["engine"].asString());
if (!engine) if (!engine)
return formatFatalError("JSONError", "Invalid model checker engine requested."); return formatFatalError("JSONError", "Invalid model checker engine requested.");
ret.modelCheckerEngine = *engine; ret.modelCheckerSettings.engine = *engine;
}
if (modelCheckerSettings.isMember("timeout"))
{
if (!modelCheckerSettings["timeout"].isUInt())
return formatFatalError("JSONError", "modelCheckerSettings.timeout must be an unsigned integer.");
ret.modelCheckerSettings.timeout = modelCheckerSettings["timeout"].asUInt();
} }
return { std::move(ret) }; return { std::move(ret) };
@ -908,7 +915,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting
compilerStack.useMetadataLiteralSources(_inputsAndSettings.metadataLiteralSources); compilerStack.useMetadataLiteralSources(_inputsAndSettings.metadataLiteralSources);
compilerStack.setMetadataHash(_inputsAndSettings.metadataHash); compilerStack.setMetadataHash(_inputsAndSettings.metadataHash);
compilerStack.setRequestedContractNames(requestedContractNames(_inputsAndSettings.outputSelection)); compilerStack.setRequestedContractNames(requestedContractNames(_inputsAndSettings.outputSelection));
compilerStack.setModelCheckerEngine(_inputsAndSettings.modelCheckerEngine); compilerStack.setModelCheckerSettings(_inputsAndSettings.modelCheckerSettings);
compilerStack.enableEvmBytecodeGeneration(isEvmBytecodeRequested(_inputsAndSettings.outputSelection)); compilerStack.enableEvmBytecodeGeneration(isEvmBytecodeRequested(_inputsAndSettings.outputSelection));
compilerStack.enableIRGeneration(isIRRequested(_inputsAndSettings.outputSelection)); compilerStack.enableIRGeneration(isIRRequested(_inputsAndSettings.outputSelection));

View File

@ -71,7 +71,7 @@ private:
bool metadataLiteralSources = false; bool metadataLiteralSources = false;
CompilerStack::MetadataHash metadataHash = CompilerStack::MetadataHash::IPFS; CompilerStack::MetadataHash metadataHash = CompilerStack::MetadataHash::IPFS;
Json::Value outputSelection; Json::Value outputSelection;
ModelCheckerEngine modelCheckerEngine = ModelCheckerEngine::All(); ModelCheckerSettings modelCheckerSettings = ModelCheckerSettings{};
}; };
/// Parses the input json (and potentially invokes the read callback) and either returns /// Parses the input json (and potentially invokes the read callback) and either returns

View File

@ -220,16 +220,17 @@ def examine_id_coverage(top_dir, source_id_to_file_names, new_ids_only=False):
return False return False
old_source_only_ids = { old_source_only_ids = {
"1123", "1133", "1218", "1220", "1584", "1823", "1950", "1123", "1220", "1584", "1823", "1950",
"1988", "2418", "2461", "2512", "2592", "2657", "2800", "2842", "2856", "1988", "2657", "2800",
"3046", "3263", "3356", "3441", "3682", "3876", "3263", "3356", "3682", "3876",
"3893", "4010", "4281", "4802", "4805", "4828", "3893", "3996", "4010", "4802",
"4904", "4990", "5052", "5073", "5170", "5188", "5272", "5347", "5473", "5073", "5188", "5272",
"5622", "6041", "6052", "6084", "6272", "6708", "6792", "6931", "7110", "7128", "7186", "5622", "6272", "7128", "7186",
"7589", "7593", "7653", "7812", "7885", "8065", "8084", "8140", "7589", "7593", "7653", "7885", "8065", "8084", "8140",
"8261", "8312", "8592", "8758", "9011", "8312", "8592", "9011",
"9085", "9390", "9440", "9547", "9551", "9615", "9980" "9085", "9390", "9551",
} }
new_source_only_ids = source_only_ids - old_source_only_ids new_source_only_ids = source_only_ids - old_source_only_ids
if len(new_source_only_ids) != 0: if len(new_source_only_ids) != 0:
print("The following new error code(s), not covered by tests, found:") print("The following new error code(s), not covered by tests, found:")

View File

@ -147,6 +147,7 @@ static string const g_strMetadata = "metadata";
static string const g_strMetadataHash = "metadata-hash"; static string const g_strMetadataHash = "metadata-hash";
static string const g_strMetadataLiteral = "metadata-literal"; static string const g_strMetadataLiteral = "metadata-literal";
static string const g_strModelCheckerEngine = "model-checker-engine"; static string const g_strModelCheckerEngine = "model-checker-engine";
static string const g_strModelCheckerTimeout = "model-checker-timeout";
static string const g_strNatspecDev = "devdoc"; static string const g_strNatspecDev = "devdoc";
static string const g_strNatspecUser = "userdoc"; static string const g_strNatspecUser = "userdoc";
static string const g_strNone = "none"; static string const g_strNone = "none";
@ -217,6 +218,7 @@ static string const g_argMetadata = g_strMetadata;
static string const g_argMetadataHash = g_strMetadataHash; static string const g_argMetadataHash = g_strMetadataHash;
static string const g_argMetadataLiteral = g_strMetadataLiteral; static string const g_argMetadataLiteral = g_strMetadataLiteral;
static string const g_argModelCheckerEngine = g_strModelCheckerEngine; static string const g_argModelCheckerEngine = g_strModelCheckerEngine;
static string const g_argModelCheckerTimeout = g_strModelCheckerTimeout;
static string const g_argNatspecDev = g_strNatspecDev; static string const g_argNatspecDev = g_strNatspecDev;
static string const g_argNatspecUser = g_strNatspecUser; static string const g_argNatspecUser = g_strNatspecUser;
static string const g_argOpcodes = g_strOpcodes; static string const g_argOpcodes = g_strOpcodes;
@ -1002,6 +1004,13 @@ General Information)").c_str(),
po::value<string>()->value_name("all,bmc,chc,none")->default_value("all"), po::value<string>()->value_name("all,bmc,chc,none")->default_value("all"),
"Select model checker engine." "Select model checker engine."
) )
(
g_strModelCheckerTimeout.c_str(),
po::value<unsigned>()->value_name("ms"),
"Set model checker timeout per query in milliseconds. "
"The default is a deterministic resource limit. "
"A timeout of 0 means no resource/time restrictions for any query."
)
; ;
desc.add(smtCheckerOptions); desc.add(smtCheckerOptions);
@ -1400,9 +1409,12 @@ bool CommandLineInterface::processInput()
serr() << "Invalid option for --" << g_argModelCheckerEngine << ": " << engineStr << endl; serr() << "Invalid option for --" << g_argModelCheckerEngine << ": " << engineStr << endl;
return false; return false;
} }
m_modelCheckerEngine = *engine; m_modelCheckerSettings.engine = *engine;
} }
if (m_args.count(g_argModelCheckerTimeout))
m_modelCheckerSettings.timeout = m_args[g_argModelCheckerTimeout].as<unsigned>();
m_compiler = make_unique<CompilerStack>(fileReader); m_compiler = make_unique<CompilerStack>(fileReader);
unique_ptr<SourceReferenceFormatter> formatter; unique_ptr<SourceReferenceFormatter> formatter;
@ -1417,8 +1429,8 @@ bool CommandLineInterface::processInput()
m_compiler->useMetadataLiteralSources(true); m_compiler->useMetadataLiteralSources(true);
if (m_args.count(g_argMetadataHash)) if (m_args.count(g_argMetadataHash))
m_compiler->setMetadataHash(m_metadataHash); m_compiler->setMetadataHash(m_metadataHash);
if (m_args.count(g_argModelCheckerEngine)) if (m_args.count(g_argModelCheckerEngine) || m_args.count(g_argModelCheckerTimeout))
m_compiler->setModelCheckerEngine(m_modelCheckerEngine); m_compiler->setModelCheckerSettings(m_modelCheckerSettings);
if (m_args.count(g_argInputFile)) if (m_args.count(g_argInputFile))
m_compiler->setRemappings(m_remappings); m_compiler->setRemappings(m_remappings);

View File

@ -133,8 +133,8 @@ private:
RevertStrings m_revertStrings = RevertStrings::Default; RevertStrings m_revertStrings = RevertStrings::Default;
/// Chosen hash method for the bytecode metadata. /// Chosen hash method for the bytecode metadata.
CompilerStack::MetadataHash m_metadataHash = CompilerStack::MetadataHash::IPFS; CompilerStack::MetadataHash m_metadataHash = CompilerStack::MetadataHash::IPFS;
/// Chosen model checker engine. /// Model checker settings.
ModelCheckerEngine m_modelCheckerEngine = ModelCheckerEngine::All(); ModelCheckerSettings m_modelCheckerSettings;
/// Whether or not to colorize diagnostics output. /// Whether or not to colorize diagnostics output.
bool m_coloredOutput = true; bool m_coloredOutput = true;
/// Whether or not to output error IDs. /// Whether or not to output error IDs.

View File

@ -1,5 +1,5 @@
======= evm_to_wasm/input.sol (Ewasm) ======= ======= evm_to_wasm/input.yul (Ewasm) =======
Pretty printed source: Pretty printed source:
object "object" { object "object" {

View File

@ -1,5 +1,5 @@
======= evm_to_wasm_break/input.sol (Ewasm) ======= ======= evm_to_wasm_break/input.yul (Ewasm) =======
Pretty printed source: Pretty printed source:
object "object" { object "object" {

View File

@ -0,0 +1 @@
--model-checker-timeout 1000

View File

@ -0,0 +1,12 @@
Warning: CHC: Assertion violation might happen here.
--> model_checker_timeout_all/input.sol:10:3:
|
10 | assert(r % k == 0);
| ^^^^^^^^^^^^^^^^^^
Warning: BMC: Assertion violation might happen here.
--> model_checker_timeout_all/input.sol:10:3:
|
10 | assert(r % k == 0);
| ^^^^^^^^^^^^^^^^^^
Note:

View File

@ -0,0 +1,12 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.0;
pragma experimental SMTChecker;
contract test {
function f(uint x, uint y, uint k) public pure {
require(k > 0);
require(x % k == 0);
require(y % k == 0);
uint r = mulmod(x, y, k);
assert(r % k == 0);
}
}

View File

@ -0,0 +1 @@
--model-checker-engine bmc --model-checker-timeout 1000

View File

@ -0,0 +1,6 @@
Warning: BMC: Assertion violation might happen here.
--> model_checker_timeout_bmc/input.sol:10:3:
|
10 | assert(r % k == 0);
| ^^^^^^^^^^^^^^^^^^
Note:

View File

@ -0,0 +1,12 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.0;
pragma experimental SMTChecker;
contract test {
function f(uint x, uint y, uint k) public pure {
require(k > 0);
require(x % k == 0);
require(y % k == 0);
uint r = mulmod(x, y, k);
assert(r % k == 0);
}
}

View File

@ -0,0 +1 @@
--model-checker-engine chc --model-checker-timeout 1000

View File

@ -0,0 +1,5 @@
Warning: CHC: Assertion violation might happen here.
--> model_checker_timeout_chc/input.sol:10:3:
|
10 | assert(r % k == 0);
| ^^^^^^^^^^^^^^^^^^

View File

@ -0,0 +1,12 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.0;
pragma experimental SMTChecker;
contract test {
function f(uint x, uint y, uint k) public pure {
require(k > 0);
require(x % k == 0);
require(y % k == 0);
uint r = mulmod(x, y, k);
assert(r % k == 0);
}
}

View File

@ -1,5 +1,5 @@
======= object_compiler/input.sol (EVM) ======= ======= object_compiler/input.yul (EVM) =======
Pretty printed source: Pretty printed source:
object "MyContract" { object "MyContract" {
@ -26,42 +26,42 @@ Binary representation:
33600055600b806012600039806000f350fe60005460005260206000f3 33600055600b806012600039806000f350fe60005460005260206000f3
Text representation: Text representation:
/* "object_compiler/input.sol":128:136 */ /* "object_compiler/input.yul":128:136 */
caller caller
/* "object_compiler/input.sol":125:126 */ /* "object_compiler/input.yul":125:126 */
0x00 0x00
/* "object_compiler/input.sol":118:137 */ /* "object_compiler/input.yul":118:137 */
sstore sstore
dataSize(sub_0) dataSize(sub_0)
/* "object_compiler/input.sol":240:259 */ /* "object_compiler/input.yul":240:259 */
dup1 dup1
dataOffset(sub_0) dataOffset(sub_0)
/* "object_compiler/input.sol":125:126 */ /* "object_compiler/input.yul":125:126 */
0x00 0x00
/* "object_compiler/input.sol":205:260 */ /* "object_compiler/input.yul":205:260 */
codecopy codecopy
/* "object_compiler/input.sol":275:294 */ /* "object_compiler/input.yul":275:294 */
dup1 dup1
/* "object_compiler/input.sol":125:126 */ /* "object_compiler/input.yul":125:126 */
0x00 0x00
/* "object_compiler/input.sol":265:295 */ /* "object_compiler/input.yul":265:295 */
return return
pop pop
stop stop
sub_0: assembly { sub_0: assembly {
/* "object_compiler/input.sol":397:398 */ /* "object_compiler/input.yul":397:398 */
0x00 0x00
/* "object_compiler/input.sol":391:399 */ /* "object_compiler/input.yul":391:399 */
sload sload
/* "object_compiler/input.sol":397:398 */ /* "object_compiler/input.yul":397:398 */
0x00 0x00
/* "object_compiler/input.sol":381:400 */ /* "object_compiler/input.yul":381:400 */
mstore mstore
/* "object_compiler/input.sol":417:421 */ /* "object_compiler/input.yul":417:421 */
0x20 0x20
/* "object_compiler/input.sol":397:398 */ /* "object_compiler/input.yul":397:398 */
0x00 0x00
/* "object_compiler/input.sol":407:422 */ /* "object_compiler/input.yul":407:422 */
return return
} }

View File

@ -0,0 +1,14 @@
{
"language": "Solidity",
"sources":
{
"A":
{
"content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\npragma experimental SMTChecker;\ncontract test {\nfunction f(uint x, uint y, uint k) public pure {\nrequire(k > 0); require(x % k == 0); require(y % k == 0); uint r = mulmod(x, y, k); assert(r % k == 0);}}"
}
},
"modelCheckerSettings":
{
"timeout": 1000
}
}

View File

@ -0,0 +1,250 @@
{"auxiliaryInputRequested":{"smtlib2queries":{"0x0ab92bf00d2546a23d94ff3a406d009299b43650e321d35e02531726df040b9d":"(set-option :produce-models true)
(set-option :timeout 1000)
(set-logic ALL)
(declare-fun |error_0| () Int)
(declare-fun |this_0| () Int)
(declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int))))))
(declare-fun |state_0| () |state_type|)
(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int)))))
(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.coinbase| Int) (|block.difficulty| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int)))))
(declare-fun |tx_0| () |tx_type|)
(declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int)))))
(declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int))))))
(declare-fun |crypto_0| () |crypto_type|)
(declare-fun |x_4_0| () Int)
(declare-fun |y_6_0| () Int)
(declare-fun |k_8_0| () Int)
(declare-fun |r_34_0| () Int)
(declare-fun |expr_12_0| () Int)
(declare-fun |expr_13_0| () Int)
(declare-fun |expr_14_1| () Bool)
(declare-fun |expr_18_0| () Int)
(declare-fun |expr_19_0| () Int)
(declare-fun |d_div_mod_15_0| () Int)
(declare-fun |r_div_mod_15_0| () Int)
(declare-fun |expr_20_1| () Int)
(declare-fun |expr_21_0| () Int)
(declare-fun |expr_22_1| () Bool)
(assert (and (and true (and (= expr_22_1 (= expr_20_1 expr_21_0)) (and (= expr_21_0 0) (and (= expr_20_1 (ite (= expr_19_0 0) 0 r_div_mod_15_0)) (and (and (<= 0 r_div_mod_15_0) (or (= expr_19_0 0) (< r_div_mod_15_0 expr_19_0))) (and (= (+ (* d_div_mod_15_0 expr_19_0) r_div_mod_15_0) expr_18_0) (and (= expr_19_0 k_8_0) (and (= expr_18_0 x_4_0) (and (implies true expr_14_1) (and (= expr_14_1 (> expr_12_0 expr_13_0)) (and (= expr_13_0 0) (and (= expr_12_0 k_8_0) (and (and (>= k_8_0 0) (<= k_8_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (and (>= y_6_0 0) (<= y_6_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (and (>= x_4_0 0) (<= x_4_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (= r_34_0 0) true)))))))))))))))) expr_22_1))
(check-sat)
","0x34467f46a484d40c850f05c3b05b0817a859573bc546982aeab4a17f9259fb5b":"(set-option :produce-models true)
(set-option :timeout 1000)
(set-logic ALL)
(declare-fun |error_0| () Int)
(declare-fun |this_0| () Int)
(declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int))))))
(declare-fun |state_0| () |state_type|)
(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int)))))
(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.coinbase| Int) (|block.difficulty| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int)))))
(declare-fun |tx_0| () |tx_type|)
(declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int)))))
(declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int))))))
(declare-fun |crypto_0| () |crypto_type|)
(declare-fun |x_4_0| () Int)
(declare-fun |y_6_0| () Int)
(declare-fun |k_8_0| () Int)
(declare-fun |r_34_0| () Int)
(declare-fun |expr_12_0| () Int)
(declare-fun |expr_13_0| () Int)
(declare-fun |expr_14_1| () Bool)
(assert (and (and true (and (= expr_14_1 (> expr_12_0 expr_13_0)) (and (= expr_13_0 0) (and (= expr_12_0 k_8_0) (and (and (>= k_8_0 0) (<= k_8_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (and (>= y_6_0 0) (<= y_6_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (and (>= x_4_0 0) (<= x_4_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (= r_34_0 0) true)))))))) (not expr_14_1)))
(check-sat)
","0x3dd3d755e279cd0bf414fd3fd9830517ee2397e3931ec76a9fd970b5eec46384":"(set-option :produce-models true)
(set-option :timeout 1000)
(set-logic ALL)
(declare-fun |error_0| () Int)
(declare-fun |this_0| () Int)
(declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int))))))
(declare-fun |state_0| () |state_type|)
(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int)))))
(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.coinbase| Int) (|block.difficulty| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int)))))
(declare-fun |tx_0| () |tx_type|)
(declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int)))))
(declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int))))))
(declare-fun |crypto_0| () |crypto_type|)
(declare-fun |x_4_0| () Int)
(declare-fun |y_6_0| () Int)
(declare-fun |k_8_0| () Int)
(declare-fun |r_34_0| () Int)
(declare-fun |expr_12_0| () Int)
(declare-fun |expr_13_0| () Int)
(declare-fun |expr_14_1| () Bool)
(declare-fun |expr_18_0| () Int)
(declare-fun |expr_19_0| () Int)
(declare-fun |d_div_mod_15_0| () Int)
(declare-fun |r_div_mod_15_0| () Int)
(declare-fun |expr_20_1| () Int)
(declare-fun |expr_21_0| () Int)
(declare-fun |expr_22_1| () Bool)
(declare-fun |expr_26_0| () Int)
(declare-fun |expr_27_0| () Int)
(declare-fun |d_div_mod_16_0| () Int)
(declare-fun |r_div_mod_16_0| () Int)
(declare-fun |expr_28_1| () Int)
(declare-fun |expr_29_0| () Int)
(declare-fun |expr_30_1| () Bool)
(declare-fun |t_function_mulmod_pure$_t_uint256_$_t_uint256_$_t_uint256_$returns$_t_uint256_$_0| (Int Int Int ) Int)
(declare-fun |t_function_mulmod_pure$_t_uint256_$_t_uint256_$_t_uint256_$returns$_t_uint256_$_abstract_0| () Int)
(declare-fun |expr_36_0| () Int)
(declare-fun |expr_37_0| () Int)
(declare-fun |expr_38_0| () Int)
(declare-fun |d_div_mod_17_0| () Int)
(declare-fun |r_div_mod_17_0| () Int)
(declare-fun |expr_39_1| () Int)
(declare-fun |r_34_1| () Int)
(declare-fun |expr_42_0| () Int)
(declare-fun |expr_43_0| () Int)
(declare-fun |d_div_mod_18_0| () Int)
(declare-fun |r_div_mod_18_0| () Int)
(declare-fun |expr_44_1| () Int)
(declare-fun |expr_45_0| () Int)
(declare-fun |expr_46_1| () Bool)
(assert (and (and true (and (= expr_46_1 (= expr_44_1 expr_45_0)) (and (= expr_45_0 0) (and (= expr_44_1 (ite (= expr_43_0 0) 0 r_div_mod_18_0)) (and (and (<= 0 r_div_mod_18_0) (or (= expr_43_0 0) (< r_div_mod_18_0 expr_43_0))) (and (= (+ (* d_div_mod_18_0 expr_43_0) r_div_mod_18_0) expr_42_0) (and (= expr_43_0 k_8_0) (and (= expr_42_0 r_34_1) (and (= r_34_1 expr_39_1) (and (= expr_39_1 (ite (= expr_38_0 0) 0 r_div_mod_17_0)) (and (and (<= 0 r_div_mod_17_0) (or (= expr_38_0 0) (< r_div_mod_17_0 expr_38_0))) (and (= (+ (* d_div_mod_17_0 expr_38_0) r_div_mod_17_0) (* expr_36_0 expr_37_0)) (and (= expr_38_0 k_8_0) (and (= expr_37_0 y_6_0) (and (= expr_36_0 x_4_0) (and true (and (implies true expr_30_1) (and (= expr_30_1 (= expr_28_1 expr_29_0)) (and (= expr_29_0 0) (and (= expr_28_1 (ite (= expr_27_0 0) 0 r_div_mod_16_0)) (and (and (<= 0 r_div_mod_16_0) (or (= expr_27_0 0) (< r_div_mod_16_0 expr_27_0))) (and (= (+ (* d_div_mod_16_0 expr_27_0) r_div_mod_16_0) expr_26_0) (and (= expr_27_0 k_8_0) (and (= expr_26_0 y_6_0) (and (implies true expr_22_1) (and (= expr_22_1 (= expr_20_1 expr_21_0)) (and (= expr_21_0 0) (and (= expr_20_1 (ite (= expr_19_0 0) 0 r_div_mod_15_0)) (and (and (<= 0 r_div_mod_15_0) (or (= expr_19_0 0) (< r_div_mod_15_0 expr_19_0))) (and (= (+ (* d_div_mod_15_0 expr_19_0) r_div_mod_15_0) expr_18_0) (and (= expr_19_0 k_8_0) (and (= expr_18_0 x_4_0) (and (implies true expr_14_1) (and (= expr_14_1 (> expr_12_0 expr_13_0)) (and (= expr_13_0 0) (and (= expr_12_0 k_8_0) (and (and (>= k_8_0 0) (<= k_8_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (and (>= y_6_0 0) (<= y_6_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (and (>= x_4_0 0) (<= x_4_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (= r_34_0 0) true)))))))))))))))))))))))))))))))))))))))) (not expr_46_1)))
(declare-const |EVALEXPR_0| Int)
(assert (= |EVALEXPR_0| x_4_0))
(declare-const |EVALEXPR_1| Int)
(assert (= |EVALEXPR_1| y_6_0))
(declare-const |EVALEXPR_2| Int)
(assert (= |EVALEXPR_2| k_8_0))
(declare-const |EVALEXPR_3| Int)
(assert (= |EVALEXPR_3| r_34_1))
(check-sat)
(get-value (|EVALEXPR_0| |EVALEXPR_1| |EVALEXPR_2| |EVALEXPR_3| ))
","0x4b82600501b4619c19bf57eb8d3cdb69f1c0d2a807d5908f1503d07e65ce2fd6":"(set-option :produce-models true)
(set-option :timeout 1000)
(set-logic ALL)
(declare-fun |error_0| () Int)
(declare-fun |this_0| () Int)
(declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int))))))
(declare-fun |state_0| () |state_type|)
(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int)))))
(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.coinbase| Int) (|block.difficulty| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int)))))
(declare-fun |tx_0| () |tx_type|)
(declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int)))))
(declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int))))))
(declare-fun |crypto_0| () |crypto_type|)
(declare-fun |x_4_0| () Int)
(declare-fun |y_6_0| () Int)
(declare-fun |k_8_0| () Int)
(declare-fun |r_34_0| () Int)
(declare-fun |expr_12_0| () Int)
(declare-fun |expr_13_0| () Int)
(declare-fun |expr_14_1| () Bool)
(declare-fun |expr_18_0| () Int)
(declare-fun |expr_19_0| () Int)
(declare-fun |d_div_mod_15_0| () Int)
(declare-fun |r_div_mod_15_0| () Int)
(declare-fun |expr_20_1| () Int)
(declare-fun |expr_21_0| () Int)
(declare-fun |expr_22_1| () Bool)
(declare-fun |expr_26_0| () Int)
(declare-fun |expr_27_0| () Int)
(declare-fun |d_div_mod_16_0| () Int)
(declare-fun |r_div_mod_16_0| () Int)
(declare-fun |expr_28_1| () Int)
(declare-fun |expr_29_0| () Int)
(declare-fun |expr_30_1| () Bool)
(assert (and (and true (and (= expr_30_1 (= expr_28_1 expr_29_0)) (and (= expr_29_0 0) (and (= expr_28_1 (ite (= expr_27_0 0) 0 r_div_mod_16_0)) (and (and (<= 0 r_div_mod_16_0) (or (= expr_27_0 0) (< r_div_mod_16_0 expr_27_0))) (and (= (+ (* d_div_mod_16_0 expr_27_0) r_div_mod_16_0) expr_26_0) (and (= expr_27_0 k_8_0) (and (= expr_26_0 y_6_0) (and (implies true expr_22_1) (and (= expr_22_1 (= expr_20_1 expr_21_0)) (and (= expr_21_0 0) (and (= expr_20_1 (ite (= expr_19_0 0) 0 r_div_mod_15_0)) (and (and (<= 0 r_div_mod_15_0) (or (= expr_19_0 0) (< r_div_mod_15_0 expr_19_0))) (and (= (+ (* d_div_mod_15_0 expr_19_0) r_div_mod_15_0) expr_18_0) (and (= expr_19_0 k_8_0) (and (= expr_18_0 x_4_0) (and (implies true expr_14_1) (and (= expr_14_1 (> expr_12_0 expr_13_0)) (and (= expr_13_0 0) (and (= expr_12_0 k_8_0) (and (and (>= k_8_0 0) (<= k_8_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (and (>= y_6_0 0) (<= y_6_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (and (>= x_4_0 0) (<= x_4_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (= r_34_0 0) true)))))))))))))))))))))))) expr_30_1))
(check-sat)
","0x5d4ad2f9c711b9e187dba2577e849272617d56d0ba3d46427baa3c11804a9143":"(set-option :produce-models true)
(set-option :timeout 1000)
(set-logic ALL)
(declare-fun |error_0| () Int)
(declare-fun |this_0| () Int)
(declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int))))))
(declare-fun |state_0| () |state_type|)
(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int)))))
(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.coinbase| Int) (|block.difficulty| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int)))))
(declare-fun |tx_0| () |tx_type|)
(declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int)))))
(declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int))))))
(declare-fun |crypto_0| () |crypto_type|)
(declare-fun |x_4_0| () Int)
(declare-fun |y_6_0| () Int)
(declare-fun |k_8_0| () Int)
(declare-fun |r_34_0| () Int)
(declare-fun |expr_12_0| () Int)
(declare-fun |expr_13_0| () Int)
(declare-fun |expr_14_1| () Bool)
(declare-fun |expr_18_0| () Int)
(declare-fun |expr_19_0| () Int)
(declare-fun |d_div_mod_15_0| () Int)
(declare-fun |r_div_mod_15_0| () Int)
(declare-fun |expr_20_1| () Int)
(declare-fun |expr_21_0| () Int)
(declare-fun |expr_22_1| () Bool)
(assert (and (and true (and (= expr_22_1 (= expr_20_1 expr_21_0)) (and (= expr_21_0 0) (and (= expr_20_1 (ite (= expr_19_0 0) 0 r_div_mod_15_0)) (and (and (<= 0 r_div_mod_15_0) (or (= expr_19_0 0) (< r_div_mod_15_0 expr_19_0))) (and (= (+ (* d_div_mod_15_0 expr_19_0) r_div_mod_15_0) expr_18_0) (and (= expr_19_0 k_8_0) (and (= expr_18_0 x_4_0) (and (implies true expr_14_1) (and (= expr_14_1 (> expr_12_0 expr_13_0)) (and (= expr_13_0 0) (and (= expr_12_0 k_8_0) (and (and (>= k_8_0 0) (<= k_8_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (and (>= y_6_0 0) (<= y_6_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (and (>= x_4_0 0) (<= x_4_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (= r_34_0 0) true)))))))))))))))) (not expr_22_1)))
(check-sat)
","0xd63dd6c8c7f21f7200de074c7131ab703fcb783425bc609ee7541efc2fc320bf":"(set-option :produce-models true)
(set-option :timeout 1000)
(set-logic ALL)
(declare-fun |error_0| () Int)
(declare-fun |this_0| () Int)
(declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int))))))
(declare-fun |state_0| () |state_type|)
(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int)))))
(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.coinbase| Int) (|block.difficulty| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int)))))
(declare-fun |tx_0| () |tx_type|)
(declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int)))))
(declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int))))))
(declare-fun |crypto_0| () |crypto_type|)
(declare-fun |x_4_0| () Int)
(declare-fun |y_6_0| () Int)
(declare-fun |k_8_0| () Int)
(declare-fun |r_34_0| () Int)
(declare-fun |expr_12_0| () Int)
(declare-fun |expr_13_0| () Int)
(declare-fun |expr_14_1| () Bool)
(declare-fun |expr_18_0| () Int)
(declare-fun |expr_19_0| () Int)
(declare-fun |d_div_mod_15_0| () Int)
(declare-fun |r_div_mod_15_0| () Int)
(declare-fun |expr_20_1| () Int)
(declare-fun |expr_21_0| () Int)
(declare-fun |expr_22_1| () Bool)
(declare-fun |expr_26_0| () Int)
(declare-fun |expr_27_0| () Int)
(declare-fun |d_div_mod_16_0| () Int)
(declare-fun |r_div_mod_16_0| () Int)
(declare-fun |expr_28_1| () Int)
(declare-fun |expr_29_0| () Int)
(declare-fun |expr_30_1| () Bool)
(assert (and (and true (and (= expr_30_1 (= expr_28_1 expr_29_0)) (and (= expr_29_0 0) (and (= expr_28_1 (ite (= expr_27_0 0) 0 r_div_mod_16_0)) (and (and (<= 0 r_div_mod_16_0) (or (= expr_27_0 0) (< r_div_mod_16_0 expr_27_0))) (and (= (+ (* d_div_mod_16_0 expr_27_0) r_div_mod_16_0) expr_26_0) (and (= expr_27_0 k_8_0) (and (= expr_26_0 y_6_0) (and (implies true expr_22_1) (and (= expr_22_1 (= expr_20_1 expr_21_0)) (and (= expr_21_0 0) (and (= expr_20_1 (ite (= expr_19_0 0) 0 r_div_mod_15_0)) (and (and (<= 0 r_div_mod_15_0) (or (= expr_19_0 0) (< r_div_mod_15_0 expr_19_0))) (and (= (+ (* d_div_mod_15_0 expr_19_0) r_div_mod_15_0) expr_18_0) (and (= expr_19_0 k_8_0) (and (= expr_18_0 x_4_0) (and (implies true expr_14_1) (and (= expr_14_1 (> expr_12_0 expr_13_0)) (and (= expr_13_0 0) (and (= expr_12_0 k_8_0) (and (and (>= k_8_0 0) (<= k_8_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (and (>= y_6_0 0) (<= y_6_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (and (>= x_4_0 0) (<= x_4_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (= r_34_0 0) true)))))))))))))))))))))))) (not expr_30_1)))
(check-sat)
","0xee7d96e23195f6aeb74a805122639dcd6a8932788ceeae3cba711aba9050a0b7":"(set-option :produce-models true)
(set-option :timeout 1000)
(set-logic ALL)
(declare-fun |error_0| () Int)
(declare-fun |this_0| () Int)
(declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int))))))
(declare-fun |state_0| () |state_type|)
(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int)))))
(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.coinbase| Int) (|block.difficulty| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int)))))
(declare-fun |tx_0| () |tx_type|)
(declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int)))))
(declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int))))))
(declare-fun |crypto_0| () |crypto_type|)
(declare-fun |x_4_0| () Int)
(declare-fun |y_6_0| () Int)
(declare-fun |k_8_0| () Int)
(declare-fun |r_34_0| () Int)
(declare-fun |expr_12_0| () Int)
(declare-fun |expr_13_0| () Int)
(declare-fun |expr_14_1| () Bool)
(assert (and (and true (and (= expr_14_1 (> expr_12_0 expr_13_0)) (and (= expr_13_0 0) (and (= expr_12_0 k_8_0) (and (and (>= k_8_0 0) (<= k_8_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (and (>= y_6_0 0) (<= y_6_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (and (>= x_4_0 0) (<= x_4_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (= r_34_0 0) true)))))))) expr_14_1))
(check-sat)
"}},"errors":[{"component":"general","errorCode":"6328","formattedMessage":"A:6:85: Warning: CHC: Assertion violation might happen here.
require(k > 0); require(x % k == 0); require(y % k == 0); uint r = mulmod(x, y, k); assert(r % k == 0);}}
^----------------^
","message":"CHC: Assertion violation might happen here.","severity":"warning","sourceLocation":{"end":258,"file":"A","start":240},"type":"Warning"},{"component":"general","errorCode":"7812","formattedMessage":"A:6:85: Warning: BMC: Assertion violation might happen here.
require(k > 0); require(x % k == 0); require(y % k == 0); uint r = mulmod(x, y, k); assert(r % k == 0);}}
^----------------^
","message":"BMC: Assertion violation might happen here.","secondarySourceLocations":[{"message":""}],"severity":"warning","sourceLocation":{"end":258,"file":"A","start":240},"type":"Warning"}],"sources":{"A":{"id":0}}}

View File

@ -0,0 +1,15 @@
{
"language": "Solidity",
"sources":
{
"A":
{
"content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\npragma experimental SMTChecker;\ncontract test {\nfunction f(uint x, uint y, uint k) public pure {\nrequire(k > 0); require(x % k == 0); require(y % k == 0); uint r = mulmod(x, y, k); assert(r % k == 0);}}"
}
},
"modelCheckerSettings":
{
"engine": "bmc",
"timeout": 1000
}
}

View File

@ -0,0 +1,503 @@
{"auxiliaryInputRequested":{"smtlib2queries":{"0x0f5149c7799751d1575c0946ca73f9a1a9dbc6c432db3c5e13625bd301d7fd37":"(set-option :produce-models true)
(set-option :timeout 1000)
(set-logic ALL)
(declare-fun |error_0| () Int)
(declare-fun |this_0| () Int)
(declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int))))))
(declare-fun |state_0| () |state_type|)
(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int)))))
(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.coinbase| Int) (|block.difficulty| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int)))))
(declare-fun |tx_0| () |tx_type|)
(declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int)))))
(declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int))))))
(declare-fun |crypto_0| () |crypto_type|)
(declare-fun |x_4_0| () Int)
(declare-fun |y_6_0| () Int)
(declare-fun |k_8_0| () Int)
(declare-fun |r_34_0| () Int)
(declare-fun |expr_12_0| () Int)
(declare-fun |expr_13_0| () Int)
(declare-fun |expr_14_1| () Bool)
(declare-fun |expr_18_0| () Int)
(declare-fun |expr_19_0| () Int)
(declare-fun |d_div_mod_0_0| () Int)
(declare-fun |r_div_mod_0_0| () Int)
(declare-fun |expr_20_1| () Int)
(declare-fun |expr_21_0| () Int)
(declare-fun |expr_22_1| () Bool)
(declare-fun |expr_26_0| () Int)
(declare-fun |expr_27_0| () Int)
(declare-fun |d_div_mod_1_0| () Int)
(declare-fun |r_div_mod_1_0| () Int)
(declare-fun |expr_28_1| () Int)
(declare-fun |expr_29_0| () Int)
(declare-fun |expr_30_1| () Bool)
(assert (and (and true (and (= expr_30_1 (= expr_28_1 expr_29_0)) (and (= expr_29_0 0) (and (= expr_28_1 (ite (= expr_27_0 0) 0 r_div_mod_1_0)) (and (and (<= 0 r_div_mod_1_0) (or (= expr_27_0 0) (< r_div_mod_1_0 expr_27_0))) (and (= (+ (* d_div_mod_1_0 expr_27_0) r_div_mod_1_0) expr_26_0) (and (= expr_27_0 k_8_0) (and (= expr_26_0 y_6_0) (and (implies true expr_22_1) (and (= expr_22_1 (= expr_20_1 expr_21_0)) (and (= expr_21_0 0) (and (= expr_20_1 (ite (= expr_19_0 0) 0 r_div_mod_0_0)) (and (and (<= 0 r_div_mod_0_0) (or (= expr_19_0 0) (< r_div_mod_0_0 expr_19_0))) (and (= (+ (* d_div_mod_0_0 expr_19_0) r_div_mod_0_0) expr_18_0) (and (= expr_19_0 k_8_0) (and (= expr_18_0 x_4_0) (and (implies true expr_14_1) (and (= expr_14_1 (> expr_12_0 expr_13_0)) (and (= expr_13_0 0) (and (= expr_12_0 k_8_0) (and (and (>= k_8_0 0) (<= k_8_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (and (>= y_6_0 0) (<= y_6_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (and (>= x_4_0 0) (<= x_4_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (= r_34_0 0) true)))))))))))))))))))))))) expr_30_1))
(check-sat)
","0x11444b207b7d8827f8b7503cad8aed1426a8727290a070d1eed04a55e85e2f14":"(set-option :produce-models true)
(set-option :timeout 1000)
(set-logic ALL)
(declare-fun |error_0| () Int)
(declare-fun |this_0| () Int)
(declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int))))))
(declare-fun |state_0| () |state_type|)
(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int)))))
(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.coinbase| Int) (|block.difficulty| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int)))))
(declare-fun |tx_0| () |tx_type|)
(declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int)))))
(declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int))))))
(declare-fun |crypto_0| () |crypto_type|)
(declare-fun |x_4_0| () Int)
(declare-fun |y_6_0| () Int)
(declare-fun |k_8_0| () Int)
(declare-fun |r_34_0| () Int)
(declare-fun |expr_12_0| () Int)
(declare-fun |expr_13_0| () Int)
(declare-fun |expr_14_1| () Bool)
(declare-fun |expr_18_0| () Int)
(declare-fun |expr_19_0| () Int)
(declare-fun |d_div_mod_0_0| () Int)
(declare-fun |r_div_mod_0_0| () Int)
(declare-fun |expr_20_1| () Int)
(declare-fun |expr_21_0| () Int)
(declare-fun |expr_22_1| () Bool)
(declare-fun |expr_26_0| () Int)
(declare-fun |expr_27_0| () Int)
(declare-fun |d_div_mod_1_0| () Int)
(declare-fun |r_div_mod_1_0| () Int)
(declare-fun |expr_28_1| () Int)
(declare-fun |expr_29_0| () Int)
(declare-fun |expr_30_1| () Bool)
(assert (and (and true (and (= expr_30_1 (= expr_28_1 expr_29_0)) (and (= expr_29_0 0) (and (= expr_28_1 (ite (= expr_27_0 0) 0 r_div_mod_1_0)) (and (and (<= 0 r_div_mod_1_0) (or (= expr_27_0 0) (< r_div_mod_1_0 expr_27_0))) (and (= (+ (* d_div_mod_1_0 expr_27_0) r_div_mod_1_0) expr_26_0) (and (= expr_27_0 k_8_0) (and (= expr_26_0 y_6_0) (and (implies true expr_22_1) (and (= expr_22_1 (= expr_20_1 expr_21_0)) (and (= expr_21_0 0) (and (= expr_20_1 (ite (= expr_19_0 0) 0 r_div_mod_0_0)) (and (and (<= 0 r_div_mod_0_0) (or (= expr_19_0 0) (< r_div_mod_0_0 expr_19_0))) (and (= (+ (* d_div_mod_0_0 expr_19_0) r_div_mod_0_0) expr_18_0) (and (= expr_19_0 k_8_0) (and (= expr_18_0 x_4_0) (and (implies true expr_14_1) (and (= expr_14_1 (> expr_12_0 expr_13_0)) (and (= expr_13_0 0) (and (= expr_12_0 k_8_0) (and (and (>= k_8_0 0) (<= k_8_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (and (>= y_6_0 0) (<= y_6_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (and (>= x_4_0 0) (<= x_4_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (= r_34_0 0) true)))))))))))))))))))))))) (not expr_30_1)))
(check-sat)
","0x317d72a016f7a5ff016cda82e96601cfac3a0498f393852410c7ce335d4896c8":"(set-option :produce-models true)
(set-option :timeout 1000)
(set-logic ALL)
(declare-fun |error_0| () Int)
(declare-fun |this_0| () Int)
(declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int))))))
(declare-fun |state_0| () |state_type|)
(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int)))))
(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.coinbase| Int) (|block.difficulty| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int)))))
(declare-fun |tx_0| () |tx_type|)
(declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int)))))
(declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int))))))
(declare-fun |crypto_0| () |crypto_type|)
(declare-fun |x_4_0| () Int)
(declare-fun |y_6_0| () Int)
(declare-fun |k_8_0| () Int)
(declare-fun |r_34_0| () Int)
(declare-fun |expr_12_0| () Int)
(declare-fun |expr_13_0| () Int)
(declare-fun |expr_14_1| () Bool)
(declare-fun |expr_18_0| () Int)
(declare-fun |expr_19_0| () Int)
(declare-fun |d_div_mod_0_0| () Int)
(declare-fun |r_div_mod_0_0| () Int)
(declare-fun |expr_20_1| () Int)
(declare-fun |expr_21_0| () Int)
(declare-fun |expr_22_1| () Bool)
(declare-fun |expr_26_0| () Int)
(declare-fun |expr_27_0| () Int)
(declare-fun |d_div_mod_1_0| () Int)
(declare-fun |r_div_mod_1_0| () Int)
(declare-fun |expr_28_1| () Int)
(declare-fun |expr_29_0| () Int)
(declare-fun |expr_30_1| () Bool)
(declare-fun |t_function_mulmod_pure$_t_uint256_$_t_uint256_$_t_uint256_$returns$_t_uint256_$_0| (Int Int Int ) Int)
(declare-fun |t_function_mulmod_pure$_t_uint256_$_t_uint256_$_t_uint256_$returns$_t_uint256_$_abstract_0| () Int)
(declare-fun |expr_36_0| () Int)
(declare-fun |expr_37_0| () Int)
(declare-fun |expr_38_0| () Int)
(declare-fun |d_div_mod_2_0| () Int)
(declare-fun |r_div_mod_2_0| () Int)
(declare-fun |expr_39_1| () Int)
(declare-fun |r_34_1| () Int)
(declare-fun |expr_42_0| () Int)
(declare-fun |expr_43_0| () Int)
(declare-fun |d_div_mod_3_0| () Int)
(declare-fun |r_div_mod_3_0| () Int)
(declare-fun |expr_44_1| () Int)
(declare-fun |expr_45_0| () Int)
(declare-fun |expr_46_1| () Bool)
(assert (and (and true (and (= expr_43_0 k_8_0) (and (= expr_42_0 r_34_1) (and (= r_34_1 expr_39_1) (and (= expr_39_1 (ite (= expr_38_0 0) 0 r_div_mod_2_0)) (and (and (<= 0 r_div_mod_2_0) (or (= expr_38_0 0) (< r_div_mod_2_0 expr_38_0))) (and (= (+ (* d_div_mod_2_0 expr_38_0) r_div_mod_2_0) (* expr_36_0 expr_37_0)) (and (= expr_38_0 k_8_0) (and (= expr_37_0 y_6_0) (and (= expr_36_0 x_4_0) (and true (and (implies true expr_30_1) (and (= expr_30_1 (= expr_28_1 expr_29_0)) (and (= expr_29_0 0) (and (= expr_28_1 (ite (= expr_27_0 0) 0 r_div_mod_1_0)) (and (and (<= 0 r_div_mod_1_0) (or (= expr_27_0 0) (< r_div_mod_1_0 expr_27_0))) (and (= (+ (* d_div_mod_1_0 expr_27_0) r_div_mod_1_0) expr_26_0) (and (= expr_27_0 k_8_0) (and (= expr_26_0 y_6_0) (and (implies true expr_22_1) (and (= expr_22_1 (= expr_20_1 expr_21_0)) (and (= expr_21_0 0) (and (= expr_20_1 (ite (= expr_19_0 0) 0 r_div_mod_0_0)) (and (and (<= 0 r_div_mod_0_0) (or (= expr_19_0 0) (< r_div_mod_0_0 expr_19_0))) (and (= (+ (* d_div_mod_0_0 expr_19_0) r_div_mod_0_0) expr_18_0) (and (= expr_19_0 k_8_0) (and (= expr_18_0 x_4_0) (and (implies true expr_14_1) (and (= expr_14_1 (> expr_12_0 expr_13_0)) (and (= expr_13_0 0) (and (= expr_12_0 k_8_0) (and (and (>= k_8_0 0) (<= k_8_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (and (>= y_6_0 0) (<= y_6_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (and (>= x_4_0 0) (<= x_4_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (= r_34_0 0) true))))))))))))))))))))))))))))))))))) (= expr_43_0 0)))
(declare-const |EVALEXPR_0| Int)
(assert (= |EVALEXPR_0| x_4_0))
(declare-const |EVALEXPR_1| Int)
(assert (= |EVALEXPR_1| y_6_0))
(declare-const |EVALEXPR_2| Int)
(assert (= |EVALEXPR_2| k_8_0))
(declare-const |EVALEXPR_3| Int)
(assert (= |EVALEXPR_3| r_34_1))
(declare-const |EVALEXPR_4| Int)
(assert (= |EVALEXPR_4| expr_43_0))
(check-sat)
(get-value (|EVALEXPR_0| |EVALEXPR_1| |EVALEXPR_2| |EVALEXPR_3| |EVALEXPR_4| ))
","0x34467f46a484d40c850f05c3b05b0817a859573bc546982aeab4a17f9259fb5b":"(set-option :produce-models true)
(set-option :timeout 1000)
(set-logic ALL)
(declare-fun |error_0| () Int)
(declare-fun |this_0| () Int)
(declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int))))))
(declare-fun |state_0| () |state_type|)
(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int)))))
(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.coinbase| Int) (|block.difficulty| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int)))))
(declare-fun |tx_0| () |tx_type|)
(declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int)))))
(declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int))))))
(declare-fun |crypto_0| () |crypto_type|)
(declare-fun |x_4_0| () Int)
(declare-fun |y_6_0| () Int)
(declare-fun |k_8_0| () Int)
(declare-fun |r_34_0| () Int)
(declare-fun |expr_12_0| () Int)
(declare-fun |expr_13_0| () Int)
(declare-fun |expr_14_1| () Bool)
(assert (and (and true (and (= expr_14_1 (> expr_12_0 expr_13_0)) (and (= expr_13_0 0) (and (= expr_12_0 k_8_0) (and (and (>= k_8_0 0) (<= k_8_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (and (>= y_6_0 0) (<= y_6_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (and (>= x_4_0 0) (<= x_4_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (= r_34_0 0) true)))))))) (not expr_14_1)))
(check-sat)
","0x46b3448dbd021b48635faf7ba42511a38684819cde3808197301d93fa7b482ea":"(set-option :produce-models true)
(set-option :timeout 1000)
(set-logic ALL)
(declare-fun |error_0| () Int)
(declare-fun |this_0| () Int)
(declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int))))))
(declare-fun |state_0| () |state_type|)
(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int)))))
(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.coinbase| Int) (|block.difficulty| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int)))))
(declare-fun |tx_0| () |tx_type|)
(declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int)))))
(declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int))))))
(declare-fun |crypto_0| () |crypto_type|)
(declare-fun |x_4_0| () Int)
(declare-fun |y_6_0| () Int)
(declare-fun |k_8_0| () Int)
(declare-fun |r_34_0| () Int)
(declare-fun |expr_12_0| () Int)
(declare-fun |expr_13_0| () Int)
(declare-fun |expr_14_1| () Bool)
(declare-fun |expr_18_0| () Int)
(declare-fun |expr_19_0| () Int)
(declare-fun |d_div_mod_0_0| () Int)
(declare-fun |r_div_mod_0_0| () Int)
(declare-fun |expr_20_1| () Int)
(declare-fun |expr_21_0| () Int)
(declare-fun |expr_22_1| () Bool)
(assert (and (and true (and (= expr_22_1 (= expr_20_1 expr_21_0)) (and (= expr_21_0 0) (and (= expr_20_1 (ite (= expr_19_0 0) 0 r_div_mod_0_0)) (and (and (<= 0 r_div_mod_0_0) (or (= expr_19_0 0) (< r_div_mod_0_0 expr_19_0))) (and (= (+ (* d_div_mod_0_0 expr_19_0) r_div_mod_0_0) expr_18_0) (and (= expr_19_0 k_8_0) (and (= expr_18_0 x_4_0) (and (implies true expr_14_1) (and (= expr_14_1 (> expr_12_0 expr_13_0)) (and (= expr_13_0 0) (and (= expr_12_0 k_8_0) (and (and (>= k_8_0 0) (<= k_8_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (and (>= y_6_0 0) (<= y_6_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (and (>= x_4_0 0) (<= x_4_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (= r_34_0 0) true)))))))))))))))) (not expr_22_1)))
(check-sat)
","0x6929232f73f56b073cf47977f8ce4ce5c728e02e72812041b60b544333443c3c":"(set-option :produce-models true)
(set-option :timeout 1000)
(set-logic ALL)
(declare-fun |error_0| () Int)
(declare-fun |this_0| () Int)
(declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int))))))
(declare-fun |state_0| () |state_type|)
(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int)))))
(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.coinbase| Int) (|block.difficulty| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int)))))
(declare-fun |tx_0| () |tx_type|)
(declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int)))))
(declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int))))))
(declare-fun |crypto_0| () |crypto_type|)
(declare-fun |x_4_0| () Int)
(declare-fun |y_6_0| () Int)
(declare-fun |k_8_0| () Int)
(declare-fun |r_34_0| () Int)
(declare-fun |expr_12_0| () Int)
(declare-fun |expr_13_0| () Int)
(declare-fun |expr_14_1| () Bool)
(declare-fun |expr_18_0| () Int)
(declare-fun |expr_19_0| () Int)
(declare-fun |d_div_mod_0_0| () Int)
(declare-fun |r_div_mod_0_0| () Int)
(declare-fun |expr_20_1| () Int)
(declare-fun |expr_21_0| () Int)
(declare-fun |expr_22_1| () Bool)
(declare-fun |expr_26_0| () Int)
(declare-fun |expr_27_0| () Int)
(declare-fun |d_div_mod_1_0| () Int)
(declare-fun |r_div_mod_1_0| () Int)
(declare-fun |expr_28_1| () Int)
(declare-fun |expr_29_0| () Int)
(declare-fun |expr_30_1| () Bool)
(declare-fun |t_function_mulmod_pure$_t_uint256_$_t_uint256_$_t_uint256_$returns$_t_uint256_$_0| (Int Int Int ) Int)
(declare-fun |t_function_mulmod_pure$_t_uint256_$_t_uint256_$_t_uint256_$returns$_t_uint256_$_abstract_0| () Int)
(declare-fun |expr_36_0| () Int)
(declare-fun |expr_37_0| () Int)
(declare-fun |expr_38_0| () Int)
(declare-fun |d_div_mod_2_0| () Int)
(declare-fun |r_div_mod_2_0| () Int)
(declare-fun |expr_39_1| () Int)
(declare-fun |r_34_1| () Int)
(declare-fun |expr_42_0| () Int)
(declare-fun |expr_43_0| () Int)
(declare-fun |d_div_mod_3_0| () Int)
(declare-fun |r_div_mod_3_0| () Int)
(declare-fun |expr_44_1| () Int)
(declare-fun |expr_45_0| () Int)
(declare-fun |expr_46_1| () Bool)
(assert (and (and true (and (= expr_46_1 (= expr_44_1 expr_45_0)) (and (= expr_45_0 0) (and (= expr_44_1 (ite (= expr_43_0 0) 0 r_div_mod_3_0)) (and (and (<= 0 r_div_mod_3_0) (or (= expr_43_0 0) (< r_div_mod_3_0 expr_43_0))) (and (= (+ (* d_div_mod_3_0 expr_43_0) r_div_mod_3_0) expr_42_0) (and (= expr_43_0 k_8_0) (and (= expr_42_0 r_34_1) (and (= r_34_1 expr_39_1) (and (= expr_39_1 (ite (= expr_38_0 0) 0 r_div_mod_2_0)) (and (and (<= 0 r_div_mod_2_0) (or (= expr_38_0 0) (< r_div_mod_2_0 expr_38_0))) (and (= (+ (* d_div_mod_2_0 expr_38_0) r_div_mod_2_0) (* expr_36_0 expr_37_0)) (and (= expr_38_0 k_8_0) (and (= expr_37_0 y_6_0) (and (= expr_36_0 x_4_0) (and true (and (implies true expr_30_1) (and (= expr_30_1 (= expr_28_1 expr_29_0)) (and (= expr_29_0 0) (and (= expr_28_1 (ite (= expr_27_0 0) 0 r_div_mod_1_0)) (and (and (<= 0 r_div_mod_1_0) (or (= expr_27_0 0) (< r_div_mod_1_0 expr_27_0))) (and (= (+ (* d_div_mod_1_0 expr_27_0) r_div_mod_1_0) expr_26_0) (and (= expr_27_0 k_8_0) (and (= expr_26_0 y_6_0) (and (implies true expr_22_1) (and (= expr_22_1 (= expr_20_1 expr_21_0)) (and (= expr_21_0 0) (and (= expr_20_1 (ite (= expr_19_0 0) 0 r_div_mod_0_0)) (and (and (<= 0 r_div_mod_0_0) (or (= expr_19_0 0) (< r_div_mod_0_0 expr_19_0))) (and (= (+ (* d_div_mod_0_0 expr_19_0) r_div_mod_0_0) expr_18_0) (and (= expr_19_0 k_8_0) (and (= expr_18_0 x_4_0) (and (implies true expr_14_1) (and (= expr_14_1 (> expr_12_0 expr_13_0)) (and (= expr_13_0 0) (and (= expr_12_0 k_8_0) (and (and (>= k_8_0 0) (<= k_8_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (and (>= y_6_0 0) (<= y_6_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (and (>= x_4_0 0) (<= x_4_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (= r_34_0 0) true)))))))))))))))))))))))))))))))))))))))) (not expr_46_1)))
(declare-const |EVALEXPR_0| Int)
(assert (= |EVALEXPR_0| x_4_0))
(declare-const |EVALEXPR_1| Int)
(assert (= |EVALEXPR_1| y_6_0))
(declare-const |EVALEXPR_2| Int)
(assert (= |EVALEXPR_2| k_8_0))
(declare-const |EVALEXPR_3| Int)
(assert (= |EVALEXPR_3| r_34_1))
(check-sat)
(get-value (|EVALEXPR_0| |EVALEXPR_1| |EVALEXPR_2| |EVALEXPR_3| ))
","0x7d43d079635c11d55bba40ba4b7f9c9beeef336e19e5612f020ab7547affbf54":"(set-option :produce-models true)
(set-option :timeout 1000)
(set-logic ALL)
(declare-fun |error_0| () Int)
(declare-fun |this_0| () Int)
(declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int))))))
(declare-fun |state_0| () |state_type|)
(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int)))))
(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.coinbase| Int) (|block.difficulty| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int)))))
(declare-fun |tx_0| () |tx_type|)
(declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int)))))
(declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int))))))
(declare-fun |crypto_0| () |crypto_type|)
(declare-fun |x_4_0| () Int)
(declare-fun |y_6_0| () Int)
(declare-fun |k_8_0| () Int)
(declare-fun |r_34_0| () Int)
(declare-fun |expr_12_0| () Int)
(declare-fun |expr_13_0| () Int)
(declare-fun |expr_14_1| () Bool)
(declare-fun |expr_18_0| () Int)
(declare-fun |expr_19_0| () Int)
(declare-fun |d_div_mod_0_0| () Int)
(declare-fun |r_div_mod_0_0| () Int)
(declare-fun |expr_20_1| () Int)
(declare-fun |expr_21_0| () Int)
(declare-fun |expr_22_1| () Bool)
(assert (and (and true (and (= expr_22_1 (= expr_20_1 expr_21_0)) (and (= expr_21_0 0) (and (= expr_20_1 (ite (= expr_19_0 0) 0 r_div_mod_0_0)) (and (and (<= 0 r_div_mod_0_0) (or (= expr_19_0 0) (< r_div_mod_0_0 expr_19_0))) (and (= (+ (* d_div_mod_0_0 expr_19_0) r_div_mod_0_0) expr_18_0) (and (= expr_19_0 k_8_0) (and (= expr_18_0 x_4_0) (and (implies true expr_14_1) (and (= expr_14_1 (> expr_12_0 expr_13_0)) (and (= expr_13_0 0) (and (= expr_12_0 k_8_0) (and (and (>= k_8_0 0) (<= k_8_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (and (>= y_6_0 0) (<= y_6_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (and (>= x_4_0 0) (<= x_4_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (= r_34_0 0) true)))))))))))))))) expr_22_1))
(check-sat)
","0x94d4c42b833aeec4b7c67fb46410594966e252d7ca8bf44e5687142a078842b2":"(set-option :produce-models true)
(set-option :timeout 1000)
(set-logic ALL)
(declare-fun |error_0| () Int)
(declare-fun |this_0| () Int)
(declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int))))))
(declare-fun |state_0| () |state_type|)
(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int)))))
(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.coinbase| Int) (|block.difficulty| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int)))))
(declare-fun |tx_0| () |tx_type|)
(declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int)))))
(declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int))))))
(declare-fun |crypto_0| () |crypto_type|)
(declare-fun |x_4_0| () Int)
(declare-fun |y_6_0| () Int)
(declare-fun |k_8_0| () Int)
(declare-fun |r_34_0| () Int)
(declare-fun |expr_12_0| () Int)
(declare-fun |expr_13_0| () Int)
(declare-fun |expr_14_1| () Bool)
(declare-fun |expr_18_0| () Int)
(declare-fun |expr_19_0| () Int)
(declare-fun |d_div_mod_0_0| () Int)
(declare-fun |r_div_mod_0_0| () Int)
(declare-fun |expr_20_1| () Int)
(declare-fun |expr_21_0| () Int)
(declare-fun |expr_22_1| () Bool)
(declare-fun |expr_26_0| () Int)
(declare-fun |expr_27_0| () Int)
(declare-fun |d_div_mod_1_0| () Int)
(declare-fun |r_div_mod_1_0| () Int)
(declare-fun |expr_28_1| () Int)
(declare-fun |expr_29_0| () Int)
(declare-fun |expr_30_1| () Bool)
(declare-fun |t_function_mulmod_pure$_t_uint256_$_t_uint256_$_t_uint256_$returns$_t_uint256_$_0| (Int Int Int ) Int)
(declare-fun |t_function_mulmod_pure$_t_uint256_$_t_uint256_$_t_uint256_$returns$_t_uint256_$_abstract_0| () Int)
(declare-fun |expr_36_0| () Int)
(declare-fun |expr_37_0| () Int)
(declare-fun |expr_38_0| () Int)
(declare-fun |d_div_mod_2_0| () Int)
(declare-fun |r_div_mod_2_0| () Int)
(declare-fun |expr_39_1| () Int)
(declare-fun |r_34_1| () Int)
(declare-fun |expr_42_0| () Int)
(declare-fun |expr_43_0| () Int)
(declare-fun |d_div_mod_3_0| () Int)
(declare-fun |r_div_mod_3_0| () Int)
(declare-fun |expr_44_1| () Int)
(declare-fun |expr_45_0| () Int)
(declare-fun |expr_46_1| () Bool)
(assert (and (and true (and (= expr_38_0 k_8_0) (and (= expr_37_0 y_6_0) (and (= expr_36_0 x_4_0) (and true (and (implies true expr_30_1) (and (= expr_30_1 (= expr_28_1 expr_29_0)) (and (= expr_29_0 0) (and (= expr_28_1 (ite (= expr_27_0 0) 0 r_div_mod_1_0)) (and (and (<= 0 r_div_mod_1_0) (or (= expr_27_0 0) (< r_div_mod_1_0 expr_27_0))) (and (= (+ (* d_div_mod_1_0 expr_27_0) r_div_mod_1_0) expr_26_0) (and (= expr_27_0 k_8_0) (and (= expr_26_0 y_6_0) (and (implies true expr_22_1) (and (= expr_22_1 (= expr_20_1 expr_21_0)) (and (= expr_21_0 0) (and (= expr_20_1 (ite (= expr_19_0 0) 0 r_div_mod_0_0)) (and (and (<= 0 r_div_mod_0_0) (or (= expr_19_0 0) (< r_div_mod_0_0 expr_19_0))) (and (= (+ (* d_div_mod_0_0 expr_19_0) r_div_mod_0_0) expr_18_0) (and (= expr_19_0 k_8_0) (and (= expr_18_0 x_4_0) (and (implies true expr_14_1) (and (= expr_14_1 (> expr_12_0 expr_13_0)) (and (= expr_13_0 0) (and (= expr_12_0 k_8_0) (and (and (>= k_8_0 0) (<= k_8_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (and (>= y_6_0 0) (<= y_6_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (and (>= x_4_0 0) (<= x_4_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (= r_34_0 0) true))))))))))))))))))))))))))))) (= expr_38_0 0)))
(declare-const |EVALEXPR_0| Int)
(assert (= |EVALEXPR_0| x_4_0))
(declare-const |EVALEXPR_1| Int)
(assert (= |EVALEXPR_1| y_6_0))
(declare-const |EVALEXPR_2| Int)
(assert (= |EVALEXPR_2| k_8_0))
(declare-const |EVALEXPR_3| Int)
(assert (= |EVALEXPR_3| r_34_0))
(declare-const |EVALEXPR_4| Int)
(assert (= |EVALEXPR_4| expr_38_0))
(check-sat)
(get-value (|EVALEXPR_0| |EVALEXPR_1| |EVALEXPR_2| |EVALEXPR_3| |EVALEXPR_4| ))
","0x9ccee337d79bf0618f658506fca4179eacaee0de28aebc060fce24a9a2cb21fc":"(set-option :produce-models true)
(set-option :timeout 1000)
(set-logic ALL)
(declare-fun |error_0| () Int)
(declare-fun |this_0| () Int)
(declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int))))))
(declare-fun |state_0| () |state_type|)
(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int)))))
(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.coinbase| Int) (|block.difficulty| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int)))))
(declare-fun |tx_0| () |tx_type|)
(declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int)))))
(declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int))))))
(declare-fun |crypto_0| () |crypto_type|)
(declare-fun |x_4_0| () Int)
(declare-fun |y_6_0| () Int)
(declare-fun |k_8_0| () Int)
(declare-fun |r_34_0| () Int)
(declare-fun |expr_12_0| () Int)
(declare-fun |expr_13_0| () Int)
(declare-fun |expr_14_1| () Bool)
(declare-fun |expr_18_0| () Int)
(declare-fun |expr_19_0| () Int)
(declare-fun |d_div_mod_0_0| () Int)
(declare-fun |r_div_mod_0_0| () Int)
(declare-fun |expr_20_1| () Int)
(declare-fun |expr_21_0| () Int)
(declare-fun |expr_22_1| () Bool)
(declare-fun |expr_26_0| () Int)
(declare-fun |expr_27_0| () Int)
(declare-fun |d_div_mod_1_0| () Int)
(declare-fun |r_div_mod_1_0| () Int)
(declare-fun |expr_28_1| () Int)
(declare-fun |expr_29_0| () Int)
(declare-fun |expr_30_1| () Bool)
(declare-fun |t_function_mulmod_pure$_t_uint256_$_t_uint256_$_t_uint256_$returns$_t_uint256_$_0| (Int Int Int ) Int)
(declare-fun |t_function_mulmod_pure$_t_uint256_$_t_uint256_$_t_uint256_$returns$_t_uint256_$_abstract_0| () Int)
(declare-fun |expr_36_0| () Int)
(declare-fun |expr_37_0| () Int)
(declare-fun |expr_38_0| () Int)
(declare-fun |d_div_mod_2_0| () Int)
(declare-fun |r_div_mod_2_0| () Int)
(declare-fun |expr_39_1| () Int)
(declare-fun |r_34_1| () Int)
(declare-fun |expr_42_0| () Int)
(declare-fun |expr_43_0| () Int)
(declare-fun |d_div_mod_3_0| () Int)
(declare-fun |r_div_mod_3_0| () Int)
(declare-fun |expr_44_1| () Int)
(declare-fun |expr_45_0| () Int)
(declare-fun |expr_46_1| () Bool)
(assert (and (and true (and (= expr_27_0 k_8_0) (and (= expr_26_0 y_6_0) (and (implies true expr_22_1) (and (= expr_22_1 (= expr_20_1 expr_21_0)) (and (= expr_21_0 0) (and (= expr_20_1 (ite (= expr_19_0 0) 0 r_div_mod_0_0)) (and (and (<= 0 r_div_mod_0_0) (or (= expr_19_0 0) (< r_div_mod_0_0 expr_19_0))) (and (= (+ (* d_div_mod_0_0 expr_19_0) r_div_mod_0_0) expr_18_0) (and (= expr_19_0 k_8_0) (and (= expr_18_0 x_4_0) (and (implies true expr_14_1) (and (= expr_14_1 (> expr_12_0 expr_13_0)) (and (= expr_13_0 0) (and (= expr_12_0 k_8_0) (and (and (>= k_8_0 0) (<= k_8_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (and (>= y_6_0 0) (<= y_6_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (and (>= x_4_0 0) (<= x_4_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (= r_34_0 0) true))))))))))))))))))) (= expr_27_0 0)))
(declare-const |EVALEXPR_0| Int)
(assert (= |EVALEXPR_0| x_4_0))
(declare-const |EVALEXPR_1| Int)
(assert (= |EVALEXPR_1| y_6_0))
(declare-const |EVALEXPR_2| Int)
(assert (= |EVALEXPR_2| k_8_0))
(declare-const |EVALEXPR_3| Int)
(assert (= |EVALEXPR_3| r_34_0))
(declare-const |EVALEXPR_4| Int)
(assert (= |EVALEXPR_4| expr_27_0))
(check-sat)
(get-value (|EVALEXPR_0| |EVALEXPR_1| |EVALEXPR_2| |EVALEXPR_3| |EVALEXPR_4| ))
","0xc087609e1dc5e5b58588a60985e4e04dbb5b602e92873c2123a018895f5f9e1a":"(set-option :produce-models true)
(set-option :timeout 1000)
(set-logic ALL)
(declare-fun |error_0| () Int)
(declare-fun |this_0| () Int)
(declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int))))))
(declare-fun |state_0| () |state_type|)
(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int)))))
(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.coinbase| Int) (|block.difficulty| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int)))))
(declare-fun |tx_0| () |tx_type|)
(declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int)))))
(declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int))))))
(declare-fun |crypto_0| () |crypto_type|)
(declare-fun |x_4_0| () Int)
(declare-fun |y_6_0| () Int)
(declare-fun |k_8_0| () Int)
(declare-fun |r_34_0| () Int)
(declare-fun |expr_12_0| () Int)
(declare-fun |expr_13_0| () Int)
(declare-fun |expr_14_1| () Bool)
(declare-fun |expr_18_0| () Int)
(declare-fun |expr_19_0| () Int)
(declare-fun |d_div_mod_0_0| () Int)
(declare-fun |r_div_mod_0_0| () Int)
(declare-fun |expr_20_1| () Int)
(declare-fun |expr_21_0| () Int)
(declare-fun |expr_22_1| () Bool)
(declare-fun |expr_26_0| () Int)
(declare-fun |expr_27_0| () Int)
(declare-fun |d_div_mod_1_0| () Int)
(declare-fun |r_div_mod_1_0| () Int)
(declare-fun |expr_28_1| () Int)
(declare-fun |expr_29_0| () Int)
(declare-fun |expr_30_1| () Bool)
(declare-fun |t_function_mulmod_pure$_t_uint256_$_t_uint256_$_t_uint256_$returns$_t_uint256_$_0| (Int Int Int ) Int)
(declare-fun |t_function_mulmod_pure$_t_uint256_$_t_uint256_$_t_uint256_$returns$_t_uint256_$_abstract_0| () Int)
(declare-fun |expr_36_0| () Int)
(declare-fun |expr_37_0| () Int)
(declare-fun |expr_38_0| () Int)
(declare-fun |d_div_mod_2_0| () Int)
(declare-fun |r_div_mod_2_0| () Int)
(declare-fun |expr_39_1| () Int)
(declare-fun |r_34_1| () Int)
(declare-fun |expr_42_0| () Int)
(declare-fun |expr_43_0| () Int)
(declare-fun |d_div_mod_3_0| () Int)
(declare-fun |r_div_mod_3_0| () Int)
(declare-fun |expr_44_1| () Int)
(declare-fun |expr_45_0| () Int)
(declare-fun |expr_46_1| () Bool)
(assert (and (and true (and (= expr_19_0 k_8_0) (and (= expr_18_0 x_4_0) (and (implies true expr_14_1) (and (= expr_14_1 (> expr_12_0 expr_13_0)) (and (= expr_13_0 0) (and (= expr_12_0 k_8_0) (and (and (>= k_8_0 0) (<= k_8_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (and (>= y_6_0 0) (<= y_6_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (and (>= x_4_0 0) (<= x_4_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (= r_34_0 0) true))))))))))) (= expr_19_0 0)))
(declare-const |EVALEXPR_0| Int)
(assert (= |EVALEXPR_0| x_4_0))
(declare-const |EVALEXPR_1| Int)
(assert (= |EVALEXPR_1| y_6_0))
(declare-const |EVALEXPR_2| Int)
(assert (= |EVALEXPR_2| k_8_0))
(declare-const |EVALEXPR_3| Int)
(assert (= |EVALEXPR_3| r_34_0))
(declare-const |EVALEXPR_4| Int)
(assert (= |EVALEXPR_4| expr_19_0))
(check-sat)
(get-value (|EVALEXPR_0| |EVALEXPR_1| |EVALEXPR_2| |EVALEXPR_3| |EVALEXPR_4| ))
","0xee7d96e23195f6aeb74a805122639dcd6a8932788ceeae3cba711aba9050a0b7":"(set-option :produce-models true)
(set-option :timeout 1000)
(set-logic ALL)
(declare-fun |error_0| () Int)
(declare-fun |this_0| () Int)
(declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int))))))
(declare-fun |state_0| () |state_type|)
(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int)))))
(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.coinbase| Int) (|block.difficulty| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int)))))
(declare-fun |tx_0| () |tx_type|)
(declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int)))))
(declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int))))))
(declare-fun |crypto_0| () |crypto_type|)
(declare-fun |x_4_0| () Int)
(declare-fun |y_6_0| () Int)
(declare-fun |k_8_0| () Int)
(declare-fun |r_34_0| () Int)
(declare-fun |expr_12_0| () Int)
(declare-fun |expr_13_0| () Int)
(declare-fun |expr_14_1| () Bool)
(assert (and (and true (and (= expr_14_1 (> expr_12_0 expr_13_0)) (and (= expr_13_0 0) (and (= expr_12_0 k_8_0) (and (and (>= k_8_0 0) (<= k_8_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (and (>= y_6_0 0) (<= y_6_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (and (>= x_4_0 0) (<= x_4_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (= r_34_0 0) true)))))))) expr_14_1))
(check-sat)
"}},"errors":[{"component":"general","errorCode":"7812","formattedMessage":"A:6:85: Warning: BMC: Assertion violation might happen here.
require(k > 0); require(x % k == 0); require(y % k == 0); uint r = mulmod(x, y, k); assert(r % k == 0);}}
^----------------^
","message":"BMC: Assertion violation might happen here.","secondarySourceLocations":[{"message":""}],"severity":"warning","sourceLocation":{"end":258,"file":"A","start":240},"type":"Warning"}],"sources":{"A":{"id":0}}}

View File

@ -0,0 +1,15 @@
{
"language": "Solidity",
"sources":
{
"A":
{
"content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\npragma experimental SMTChecker;\ncontract test {\nfunction f(uint x, uint y, uint k) public pure {\nrequire(k > 0); require(x % k == 0); require(y % k == 0); uint r = mulmod(x, y, k); assert(r % k == 0);}}"
}
},
"modelCheckerSettings":
{
"engine": "chc",
"timeout": 1000
}
}

View File

@ -0,0 +1,4 @@
{"errors":[{"component":"general","errorCode":"6328","formattedMessage":"A:6:85: Warning: CHC: Assertion violation might happen here.
require(k > 0); require(x % k == 0); require(y % k == 0); uint r = mulmod(x, y, k); assert(r % k == 0);}}
^----------------^
","message":"CHC: Assertion violation might happen here.","severity":"warning","sourceLocation":{"end":258,"file":"A","start":240},"type":"Warning"}],"sources":{"A":{"id":0}}}

View File

@ -0,0 +1,15 @@
{
"language": "Solidity",
"sources":
{
"A":
{
"content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\npragma experimental SMTChecker;\ncontract C { function f(uint x) public pure { assert(x > 0); } }"
}
},
"modelCheckerSettings":
{
"engine": "chc",
"atimeout": 1
}
}

View File

@ -0,0 +1 @@
{"errors":[{"component":"general","formattedMessage":"Unknown key \"atimeout\"","message":"Unknown key \"atimeout\"","severity":"error","type":"JSONError"}]}

View File

@ -0,0 +1,14 @@
{
"language": "Solidity",
"sources":
{
"A":
{
"content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\npragma experimental SMTChecker;\ncontract C { function f(uint x) public pure { assert(x > 0); } }"
}
},
"modelCheckerSettings":
{
"timeout": "asd"
}
}

View File

@ -0,0 +1 @@
{"errors":[{"component":"general","formattedMessage":"modelCheckerSettings.timeout must be an unsigned integer.","message":"modelCheckerSettings.timeout must be an unsigned integer.","severity":"error","type":"JSONError"}]}

View File

@ -1,6 +1,6 @@
Warning: Yul is still experimental. Please use the output with care. Warning: Yul is still experimental. Please use the output with care.
Error: Function not found. Error: Function not found.
--> strict_asm_jump/input.sol:1:3: --> strict_asm_jump/input.yul:1:3:
| |
1 | { jump(1) } 1 | { jump(1) }
| ^^^^ | ^^^^

View File

@ -1,5 +1,5 @@
======= yul_stack_opt/input.sol (EVM) ======= ======= yul_stack_opt/input.yul (EVM) =======
Pretty printed source: Pretty printed source:
object "object" { object "object" {
@ -42,164 +42,164 @@ Binary representation:
6001808155806002558060035580600455806005558060065580600755806008558060095580600a5580600b5580600c5580600d55808155806002558060035580600455806005558060065580600755806008558060095580600a5580600b5580600c5580600d5580815550 6001808155806002558060035580600455806005558060065580600755806008558060095580600a5580600b5580600c5580600d55808155806002558060035580600455806005558060065580600755806008558060095580600a5580600b5580600c5580600d5580815550
Text representation: Text representation:
/* "yul_stack_opt/input.sol":98:99 */ /* "yul_stack_opt/input.yul":98:99 */
0x01 0x01
dup1 dup1
dup2 dup2
/* "yul_stack_opt/input.sol":129:141 */ /* "yul_stack_opt/input.yul":129:141 */
sstore sstore
/* "yul_stack_opt/input.sol":98:99 */ /* "yul_stack_opt/input.yul":98:99 */
dup1 dup1
/* "yul_stack_opt/input.sol":151:160 */ /* "yul_stack_opt/input.yul":151:160 */
0x02 0x02
/* "yul_stack_opt/input.sol":144:164 */ /* "yul_stack_opt/input.yul":144:164 */
sstore sstore
/* "yul_stack_opt/input.sol":98:99 */ /* "yul_stack_opt/input.yul":98:99 */
dup1 dup1
/* "yul_stack_opt/input.sol":174:183 */ /* "yul_stack_opt/input.yul":174:183 */
0x03 0x03
/* "yul_stack_opt/input.sol":167:187 */ /* "yul_stack_opt/input.yul":167:187 */
sstore sstore
/* "yul_stack_opt/input.sol":98:99 */ /* "yul_stack_opt/input.yul":98:99 */
dup1 dup1
/* "yul_stack_opt/input.sol":197:206 */ /* "yul_stack_opt/input.yul":197:206 */
0x04 0x04
/* "yul_stack_opt/input.sol":190:210 */ /* "yul_stack_opt/input.yul":190:210 */
sstore sstore
/* "yul_stack_opt/input.sol":98:99 */ /* "yul_stack_opt/input.yul":98:99 */
dup1 dup1
/* "yul_stack_opt/input.sol":220:229 */ /* "yul_stack_opt/input.yul":220:229 */
0x05 0x05
/* "yul_stack_opt/input.sol":213:233 */ /* "yul_stack_opt/input.yul":213:233 */
sstore sstore
/* "yul_stack_opt/input.sol":98:99 */ /* "yul_stack_opt/input.yul":98:99 */
dup1 dup1
/* "yul_stack_opt/input.sol":243:252 */ /* "yul_stack_opt/input.yul":243:252 */
0x06 0x06
/* "yul_stack_opt/input.sol":236:256 */ /* "yul_stack_opt/input.yul":236:256 */
sstore sstore
/* "yul_stack_opt/input.sol":98:99 */ /* "yul_stack_opt/input.yul":98:99 */
dup1 dup1
/* "yul_stack_opt/input.sol":266:275 */ /* "yul_stack_opt/input.yul":266:275 */
0x07 0x07
/* "yul_stack_opt/input.sol":259:279 */ /* "yul_stack_opt/input.yul":259:279 */
sstore sstore
/* "yul_stack_opt/input.sol":98:99 */ /* "yul_stack_opt/input.yul":98:99 */
dup1 dup1
/* "yul_stack_opt/input.sol":289:298 */ /* "yul_stack_opt/input.yul":289:298 */
0x08 0x08
/* "yul_stack_opt/input.sol":282:302 */ /* "yul_stack_opt/input.yul":282:302 */
sstore sstore
/* "yul_stack_opt/input.sol":98:99 */ /* "yul_stack_opt/input.yul":98:99 */
dup1 dup1
/* "yul_stack_opt/input.sol":312:321 */ /* "yul_stack_opt/input.yul":312:321 */
0x09 0x09
/* "yul_stack_opt/input.sol":305:325 */ /* "yul_stack_opt/input.yul":305:325 */
sstore sstore
/* "yul_stack_opt/input.sol":98:99 */ /* "yul_stack_opt/input.yul":98:99 */
dup1 dup1
/* "yul_stack_opt/input.sol":335:344 */ /* "yul_stack_opt/input.yul":335:344 */
0x0a 0x0a
/* "yul_stack_opt/input.sol":328:348 */ /* "yul_stack_opt/input.yul":328:348 */
sstore sstore
/* "yul_stack_opt/input.sol":98:99 */ /* "yul_stack_opt/input.yul":98:99 */
dup1 dup1
/* "yul_stack_opt/input.sol":358:368 */ /* "yul_stack_opt/input.yul":358:368 */
0x0b 0x0b
/* "yul_stack_opt/input.sol":351:372 */ /* "yul_stack_opt/input.yul":351:372 */
sstore sstore
/* "yul_stack_opt/input.sol":98:99 */ /* "yul_stack_opt/input.yul":98:99 */
dup1 dup1
/* "yul_stack_opt/input.sol":382:392 */ /* "yul_stack_opt/input.yul":382:392 */
0x0c 0x0c
/* "yul_stack_opt/input.sol":375:396 */ /* "yul_stack_opt/input.yul":375:396 */
sstore sstore
/* "yul_stack_opt/input.sol":98:99 */ /* "yul_stack_opt/input.yul":98:99 */
dup1 dup1
/* "yul_stack_opt/input.sol":406:416 */ /* "yul_stack_opt/input.yul":406:416 */
0x0d 0x0d
/* "yul_stack_opt/input.sol":399:420 */ /* "yul_stack_opt/input.yul":399:420 */
sstore sstore
/* "yul_stack_opt/input.sol":98:99 */ /* "yul_stack_opt/input.yul":98:99 */
dup1 dup1
dup2 dup2
/* "yul_stack_opt/input.sol":129:141 */ /* "yul_stack_opt/input.yul":129:141 */
sstore sstore
/* "yul_stack_opt/input.sol":98:99 */ /* "yul_stack_opt/input.yul":98:99 */
dup1 dup1
/* "yul_stack_opt/input.sol":151:160 */ /* "yul_stack_opt/input.yul":151:160 */
0x02 0x02
/* "yul_stack_opt/input.sol":144:164 */ /* "yul_stack_opt/input.yul":144:164 */
sstore sstore
/* "yul_stack_opt/input.sol":98:99 */ /* "yul_stack_opt/input.yul":98:99 */
dup1 dup1
/* "yul_stack_opt/input.sol":174:183 */ /* "yul_stack_opt/input.yul":174:183 */
0x03 0x03
/* "yul_stack_opt/input.sol":167:187 */ /* "yul_stack_opt/input.yul":167:187 */
sstore sstore
/* "yul_stack_opt/input.sol":98:99 */ /* "yul_stack_opt/input.yul":98:99 */
dup1 dup1
/* "yul_stack_opt/input.sol":197:206 */ /* "yul_stack_opt/input.yul":197:206 */
0x04 0x04
/* "yul_stack_opt/input.sol":190:210 */ /* "yul_stack_opt/input.yul":190:210 */
sstore sstore
/* "yul_stack_opt/input.sol":98:99 */ /* "yul_stack_opt/input.yul":98:99 */
dup1 dup1
/* "yul_stack_opt/input.sol":220:229 */ /* "yul_stack_opt/input.yul":220:229 */
0x05 0x05
/* "yul_stack_opt/input.sol":213:233 */ /* "yul_stack_opt/input.yul":213:233 */
sstore sstore
/* "yul_stack_opt/input.sol":98:99 */ /* "yul_stack_opt/input.yul":98:99 */
dup1 dup1
/* "yul_stack_opt/input.sol":243:252 */ /* "yul_stack_opt/input.yul":243:252 */
0x06 0x06
/* "yul_stack_opt/input.sol":236:256 */ /* "yul_stack_opt/input.yul":236:256 */
sstore sstore
/* "yul_stack_opt/input.sol":98:99 */ /* "yul_stack_opt/input.yul":98:99 */
dup1 dup1
/* "yul_stack_opt/input.sol":266:275 */ /* "yul_stack_opt/input.yul":266:275 */
0x07 0x07
/* "yul_stack_opt/input.sol":259:279 */ /* "yul_stack_opt/input.yul":259:279 */
sstore sstore
/* "yul_stack_opt/input.sol":98:99 */ /* "yul_stack_opt/input.yul":98:99 */
dup1 dup1
/* "yul_stack_opt/input.sol":289:298 */ /* "yul_stack_opt/input.yul":289:298 */
0x08 0x08
/* "yul_stack_opt/input.sol":282:302 */ /* "yul_stack_opt/input.yul":282:302 */
sstore sstore
/* "yul_stack_opt/input.sol":98:99 */ /* "yul_stack_opt/input.yul":98:99 */
dup1 dup1
/* "yul_stack_opt/input.sol":312:321 */ /* "yul_stack_opt/input.yul":312:321 */
0x09 0x09
/* "yul_stack_opt/input.sol":305:325 */ /* "yul_stack_opt/input.yul":305:325 */
sstore sstore
/* "yul_stack_opt/input.sol":98:99 */ /* "yul_stack_opt/input.yul":98:99 */
dup1 dup1
/* "yul_stack_opt/input.sol":335:344 */ /* "yul_stack_opt/input.yul":335:344 */
0x0a 0x0a
/* "yul_stack_opt/input.sol":328:348 */ /* "yul_stack_opt/input.yul":328:348 */
sstore sstore
/* "yul_stack_opt/input.sol":98:99 */ /* "yul_stack_opt/input.yul":98:99 */
dup1 dup1
/* "yul_stack_opt/input.sol":358:368 */ /* "yul_stack_opt/input.yul":358:368 */
0x0b 0x0b
/* "yul_stack_opt/input.sol":351:372 */ /* "yul_stack_opt/input.yul":351:372 */
sstore sstore
/* "yul_stack_opt/input.sol":98:99 */ /* "yul_stack_opt/input.yul":98:99 */
dup1 dup1
/* "yul_stack_opt/input.sol":382:392 */ /* "yul_stack_opt/input.yul":382:392 */
0x0c 0x0c
/* "yul_stack_opt/input.sol":375:396 */ /* "yul_stack_opt/input.yul":375:396 */
sstore sstore
/* "yul_stack_opt/input.sol":98:99 */ /* "yul_stack_opt/input.yul":98:99 */
dup1 dup1
/* "yul_stack_opt/input.sol":406:416 */ /* "yul_stack_opt/input.yul":406:416 */
0x0d 0x0d
/* "yul_stack_opt/input.sol":399:420 */ /* "yul_stack_opt/input.yul":399:420 */
sstore sstore
/* "yul_stack_opt/input.sol":98:99 */ /* "yul_stack_opt/input.yul":98:99 */
dup1 dup1
dup2 dup2
/* "yul_stack_opt/input.sol":729:743 */ /* "yul_stack_opt/input.yul":729:743 */
sstore sstore
pop pop

View File

@ -1,5 +1,5 @@
======= yul_stack_opt_disabled/input.sol (EVM) ======= ======= yul_stack_opt_disabled/input.yul (EVM) =======
Pretty printed source: Pretty printed source:
object "object" { object "object" {

View File

@ -170,343 +170,7 @@ do { successParse((text), false, false, AssemblyStack::Language::StrictAssembly)
BOOST_AUTO_TEST_SUITE(SolidityInlineAssembly) BOOST_AUTO_TEST_SUITE(SolidityInlineAssembly)
BOOST_AUTO_TEST_SUITE(Printing) // {{{
BOOST_AUTO_TEST_SUITE(Parsing)
BOOST_AUTO_TEST_CASE(smoke_test)
{
BOOST_CHECK(successParse("{ }"));
}
BOOST_AUTO_TEST_CASE(surplus_input)
{
CHECK_PARSE_ERROR("{ } { }", ParserError, "Expected end of source but got '{'");
}
BOOST_AUTO_TEST_CASE(simple_instructions)
{
BOOST_CHECK(successParse("{ let y := mul(0x10, mul(0x20, mload(0x40)))}"));
}
BOOST_AUTO_TEST_CASE(selfdestruct)
{
BOOST_CHECK(successParse("{ selfdestruct(0x02) }"));
}
BOOST_AUTO_TEST_CASE(keywords)
{
BOOST_CHECK(successParse("{ return (byte(1, 2), 2) pop(address()) }"));
}
BOOST_AUTO_TEST_CASE(constants)
{
BOOST_CHECK(successParse("{ pop(mul(7, 8)) }"));
}
BOOST_AUTO_TEST_CASE(vardecl)
{
BOOST_CHECK(successParse("{ let x := 7 }"));
}
BOOST_AUTO_TEST_CASE(vardecl_name_clashes)
{
CHECK_PARSE_ERROR("{ let x := 1 let x := 2 }", DeclarationError, "Variable name x already taken in this scope.");
}
BOOST_AUTO_TEST_CASE(vardecl_multi)
{
BOOST_CHECK(successParse("{ function f() -> x, y {} let x, y := f() }"));
}
BOOST_AUTO_TEST_CASE(vardecl_multi_conflict)
{
CHECK_PARSE_ERROR("{ function f() -> x, y {} let x, x := f() }", DeclarationError, "Variable name x already taken in this scope.");
}
BOOST_AUTO_TEST_CASE(vardecl_bool)
{
successParse("{ let x := true }");
successParse("{ let x := false }");
}
BOOST_AUTO_TEST_CASE(vardecl_empty)
{
BOOST_CHECK(successParse("{ let x }"));
}
BOOST_AUTO_TEST_CASE(functional)
{
BOOST_CHECK(successParse("{ let x := 2 x := add(add(7, mul(6, x)), mul(7, 8)) }"));
}
BOOST_AUTO_TEST_CASE(functional_partial)
{
CHECK_PARSE_ERROR("{ let x := byte }", ParserError, "Expected '(' but got '}'");
}
BOOST_AUTO_TEST_CASE(functional_partial_success)
{
BOOST_CHECK(successParse("{ let x := byte(1, 2) }"));
}
BOOST_AUTO_TEST_CASE(functional_assignment)
{
BOOST_CHECK(successParse("{ let x := 2 x := 7 }"));
}
BOOST_AUTO_TEST_CASE(functional_assignment_complex)
{
BOOST_CHECK(successParse("{ let x := 2 x := add(add(7, mul(6, x)), mul(7, 8)) }"));
}
BOOST_AUTO_TEST_CASE(vardecl_complex)
{
BOOST_CHECK(successParse("{ let y := 2 let x := add(add(7, mul(6, y)), mul(7, 8)) }"));
}
BOOST_AUTO_TEST_CASE(variable_use_before_decl)
{
CHECK_PARSE_ERROR("{ x := 2 let x := 3 }", DeclarationError, "Variable x used before it was declared.");
CHECK_PARSE_ERROR("{ let x := mul(2, x) }", DeclarationError, "Variable x used before it was declared.");
}
BOOST_AUTO_TEST_CASE(if_statement)
{
BOOST_CHECK(successParse("{ if 42 {} }"));
BOOST_CHECK(successParse("{ if 42 { let x := 3 } }"));
BOOST_CHECK(successParse("{ function f() -> x {} if f() { pop(f()) } }"));
}
BOOST_AUTO_TEST_CASE(if_statement_scope)
{
BOOST_CHECK(successParse("{ let x := 2 if 42 { x := 3 } }"));
CHECK_PARSE_ERROR("{ if 32 { let x := 3 } x := 2 }", DeclarationError, "Variable not found or variable not lvalue.");
}
BOOST_AUTO_TEST_CASE(if_statement_invalid)
{
CHECK_PARSE_ERROR("{ if mload {} }", ParserError, "Expected '(' but got '{'");
BOOST_CHECK("{ if calldatasize() {}");
CHECK_PARSE_ERROR("{ if mstore(1, 1) {} }", TypeError, "Expected expression to evaluate to one value, but got 0 values instead.");
CHECK_PARSE_ERROR("{ if 32 let x := 3 }", ParserError, "Expected '{' but got reserved keyword 'let'");
}
BOOST_AUTO_TEST_CASE(switch_statement)
{
BOOST_CHECK(successParse("{ switch 42 default {} }"));
BOOST_CHECK(successParse("{ switch 42 case 1 {} }"));
BOOST_CHECK(successParse("{ switch 42 case 1 {} case 2 {} }"));
BOOST_CHECK(successParse("{ switch 42 case 1 {} default {} }"));
BOOST_CHECK(successParse("{ switch 42 case 1 {} case 2 {} default {} }"));
BOOST_CHECK(successParse("{ switch mul(1, 2) case 1 {} case 2 {} default {} }"));
BOOST_CHECK(successParse("{ function f() -> x {} switch f() case 1 {} case 2 {} default {} }"));
}
BOOST_AUTO_TEST_CASE(switch_no_cases)
{
CHECK_PARSE_ERROR("{ switch 42 }", ParserError, "Switch statement without any cases.");
}
BOOST_AUTO_TEST_CASE(switch_duplicate_case)
{
CHECK_PARSE_ERROR("{ switch 42 case 1 {} case 1 {} default {} }", DeclarationError, "Duplicate case defined.");
}
BOOST_AUTO_TEST_CASE(switch_invalid_expression)
{
CHECK_PARSE_ERROR("{ switch {} case 1 {} default {} }", ParserError, "Literal or identifier expected.");
CHECK_PARSE_ERROR(
"{ switch mload case 1 {} default {} }",
ParserError,
"Expected '(' but got reserved keyword 'case'"
);
CHECK_PARSE_ERROR(
"{ switch mstore(1, 1) case 1 {} default {} }",
TypeError,
"Expected expression to evaluate to one value, but got 0 values instead."
);
}
BOOST_AUTO_TEST_CASE(switch_default_before_case)
{
CHECK_PARSE_ERROR("{ switch 42 default {} case 1 {} }", ParserError, "Case not allowed after default case.");
}
BOOST_AUTO_TEST_CASE(switch_duplicate_default_case)
{
CHECK_PARSE_ERROR("{ switch 42 default {} default {} }", ParserError, "Only one default case allowed.");
}
BOOST_AUTO_TEST_CASE(switch_invalid_case)
{
CHECK_PARSE_ERROR("{ switch 42 case mul(1, 2) {} case 2 {} default {} }", ParserError, "Literal expected.");
}
BOOST_AUTO_TEST_CASE(switch_invalid_body)
{
CHECK_PARSE_ERROR("{ switch 42 case 1 mul case 2 {} default {} }", ParserError, "Expected '{' but got identifier");
}
BOOST_AUTO_TEST_CASE(for_statement)
{
BOOST_CHECK(successParse("{ for {} 1 {} {} }"));
BOOST_CHECK(successParse("{ for { let i := 1 } lt(i, 5) { i := add(i, 1) } {} }"));
}
BOOST_AUTO_TEST_CASE(for_invalid_expression)
{
CHECK_PARSE_ERROR("{ for {} {} {} {} }", ParserError, "Literal or identifier expected.");
CHECK_PARSE_ERROR("{ for 1 1 {} {} }", ParserError, "Expected '{' but got 'Number'");
CHECK_PARSE_ERROR("{ for {} 1 1 {} }", ParserError, "Expected '{' but got 'Number'");
CHECK_PARSE_ERROR("{ for {} 1 {} 1 }", ParserError, "Expected '{' but got 'Number'");
CHECK_PARSE_ERROR("{ for {} mload {} {} }", ParserError, "Expected '(' but got '{'");
CHECK_PARSE_ERROR("{ for {} mstore(1, 1) {} {} }", TypeError, "Expected expression to evaluate to one value, but got 0 values instead.");
}
BOOST_AUTO_TEST_CASE(for_visibility)
{
BOOST_CHECK(successParse("{ for { let i := 1 } i { pop(i) } { pop(i) } }"));
CHECK_PARSE_ERROR("{ for {} i { let i := 1 } {} }", DeclarationError, "Identifier not found");
CHECK_PARSE_ERROR("{ for {} 1 { let i := 1 } { pop(i) } }", DeclarationError, "Identifier not found");
CHECK_PARSE_ERROR("{ for {} 1 { pop(i) } { let i := 1 } }", DeclarationError, "Identifier not found");
CHECK_PARSE_ERROR("{ for { pop(i) } 1 { let i := 1 } {} }", DeclarationError, "Identifier not found");
CHECK_PARSE_ERROR("{ for { pop(i) } 1 { } { let i := 1 } }", DeclarationError, "Identifier not found");
CHECK_PARSE_ERROR("{ for {} i {} { let i := 1 } }", DeclarationError, "Identifier not found");
CHECK_PARSE_ERROR("{ for {} 1 { pop(i) } { let i := 1 } }", DeclarationError, "Identifier not found");
CHECK_PARSE_ERROR("{ for { let x := 1 } 1 { let x := 1 } {} }", DeclarationError, "Variable name x already taken in this scope");
CHECK_PARSE_ERROR("{ for { let x := 1 } 1 {} { let x := 1 } }", DeclarationError, "Variable name x already taken in this scope");
CHECK_PARSE_ERROR("{ let x := 1 for { let x := 1 } 1 {} {} }", DeclarationError, "Variable name x already taken in this scope");
CHECK_PARSE_ERROR("{ let x := 1 for {} 1 { let x := 1 } {} }", DeclarationError, "Variable name x already taken in this scope");
CHECK_PARSE_ERROR("{ let x := 1 for {} 1 {} { let x := 1 } }", DeclarationError, "Variable name x already taken in this scope");
// Check that body and post are not sub-scopes of each other.
BOOST_CHECK(successParse("{ for {} 1 { let x := 1 } { let x := 1 } }"));
}
BOOST_AUTO_TEST_CASE(blocks)
{
BOOST_CHECK(successParse("{ let x := 7 { let y := 3 } { let z := 2 } }"));
}
BOOST_AUTO_TEST_CASE(number_literals)
{
BOOST_CHECK(successParse("{ let x := 1 }"));
CHECK_PARSE_ERROR("{ let x := .1 }", ParserError, "Invalid number literal.");
CHECK_PARSE_ERROR("{ let x := 1e5 }", ParserError, "Invalid number literal.");
CHECK_PARSE_ERROR("{ let x := 67.235 }", ParserError, "Invalid number literal.");
CHECK_STRICT_ERROR("{ let x := 0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff }", TypeError, "Number literal too large (> 256 bits)");
}
BOOST_AUTO_TEST_CASE(function_definitions)
{
BOOST_CHECK(successParse("{ function f() { } function g(a) -> x { } }"));
}
BOOST_AUTO_TEST_CASE(function_definitions_multiple_args)
{
BOOST_CHECK(successParse("{ function f(a, d) { } function g(a, d) -> x, y { } }"));
}
BOOST_AUTO_TEST_CASE(function_calls)
{
BOOST_CHECK(successParse("{ function f(a) -> b {} function g(a, b, c) {} function x() { g(1, 2, f(mul(2, 3))) x() } }"));
}
BOOST_AUTO_TEST_CASE(opcode_for_functions)
{
CHECK_PARSE_ERROR("{ function gas() { } }", ParserError, "Cannot use builtin");
}
BOOST_AUTO_TEST_CASE(opcode_for_function_args)
{
CHECK_PARSE_ERROR("{ function f(gas) { } }", ParserError, "Cannot use builtin");
CHECK_PARSE_ERROR("{ function f() -> gas { } }", ParserError, "Cannot use builtin");
}
BOOST_AUTO_TEST_CASE(name_clashes)
{
CHECK_PARSE_ERROR("{ let g := 2 function g() { } }", DeclarationError, "Variable name g already taken in this scope");
}
BOOST_AUTO_TEST_CASE(name_clashes_function_subscope)
{
CHECK_PARSE_ERROR("{ function g() { function g() {} } }", DeclarationError, "Function name g already taken in this scope");
}
BOOST_AUTO_TEST_CASE(name_clashes_function_subscope_reverse)
{
CHECK_PARSE_ERROR("{ { function g() {} } function g() { } }", DeclarationError, "Function name g already taken in this scope");
}
BOOST_AUTO_TEST_CASE(name_clashes_function_variable_subscope)
{
CHECK_PARSE_ERROR("{ function g() { let g := 0 } }", DeclarationError, "Variable name g already taken in this scope");
}
BOOST_AUTO_TEST_CASE(name_clashes_function_variable_subscope_reverse)
{
CHECK_PARSE_ERROR("{ { let g := 0 } function g() { } }", DeclarationError, "Variable name g already taken in this scope");
}
BOOST_AUTO_TEST_CASE(functions_in_parallel_scopes)
{
BOOST_CHECK(successParse("{ { function g() {} } { function g() {} } }"));
}
BOOST_AUTO_TEST_CASE(variable_access_cross_functions)
{
CHECK_PARSE_ERROR("{ let x := 2 function g() { pop(x) } }", DeclarationError, "Identifier not found.");
}
BOOST_AUTO_TEST_CASE(invalid_tuple_assignment)
{
CHECK_PARSE_ERROR("{ let x, y := 1 }", DeclarationError, "Variable count mismatch: 2 variables and 1 values");
}
BOOST_AUTO_TEST_CASE(instruction_too_few_arguments)
{
CHECK_PARSE_ERROR("{ pop(mul()) }", TypeError, "Function expects 2 arguments but got 0.");
CHECK_PARSE_ERROR("{ pop(mul(1)) }", TypeError, "Function expects 2 arguments but got 1.");
}
BOOST_AUTO_TEST_CASE(instruction_too_many_arguments)
{
CHECK_PARSE_ERROR("{ pop(mul(1, 2, 3)) }", TypeError, "Function expects 2 arguments but got 3");
}
BOOST_AUTO_TEST_CASE(recursion_depth)
{
string input;
for (size_t i = 0; i < 20000; i++)
input += "{";
input += "let x := 0";
for (size_t i = 0; i < 20000; i++)
input += "}";
CHECK_PARSE_ERROR(input, ParserError, "recursion");
}
BOOST_AUTO_TEST_CASE(multiple_assignment)
{
CHECK_PARSE_ERROR("{ let x function f() -> a, b {} 123, x := f() }", ParserError, "Variable name must precede \",\" in multiple assignment.");
CHECK_PARSE_ERROR("{ let x function f() -> a, b {} x, 123 := f() }", ParserError, "Variable name must precede \":=\" in assignment.");
/// NOTE: Travis hiccups if not having a variable
char const* text = R"(
{
function f(a) -> r1, r2 {
r1 := a
r2 := 7
}
let x := 9
let y := 2
x, y := f(x)
}
)";
BOOST_CHECK(successParse(text));
}
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_SUITE(Printing)
BOOST_AUTO_TEST_CASE(print_smoke) BOOST_AUTO_TEST_CASE(print_smoke)
{ {
@ -593,8 +257,9 @@ BOOST_AUTO_TEST_CASE(function_calls)
} }
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()
// }}}
BOOST_AUTO_TEST_SUITE(Analysis) BOOST_AUTO_TEST_SUITE(Analysis) // {{{
BOOST_AUTO_TEST_CASE(string_literals) BOOST_AUTO_TEST_CASE(string_literals)
{ {
@ -633,50 +298,6 @@ BOOST_AUTO_TEST_CASE(revert)
BOOST_CHECK(successAssemble("{ revert(0, 0) }")); BOOST_CHECK(successAssemble("{ revert(0, 0) }"));
} }
BOOST_AUTO_TEST_CASE(function_calls)
{
BOOST_CHECK(successAssemble("{ function f() {} }"));
BOOST_CHECK(successAssemble("{ function f() { let y := 2 } }"));
BOOST_CHECK(successAssemble("{ function f() -> z { let y := 2 } }"));
BOOST_CHECK(successAssemble("{ function f(a) { let y := 2 } }"));
BOOST_CHECK(successAssemble("{ function f(a) { let y := a } }"));
BOOST_CHECK(successAssemble("{ function f() -> x, y, z {} }"));
BOOST_CHECK(successAssemble("{ function f(x, y, z) {} }"));
BOOST_CHECK(successAssemble("{ function f(a, b) -> x, y, z { y := a } }"));
BOOST_CHECK(successAssemble("{ function f() {} f() }"));
BOOST_CHECK(successAssemble("{ function f() -> x, y { x := 1 y := 2} let a, b := f() }"));
BOOST_CHECK(successAssemble("{ function f(a, b) -> x, y { x := b y := a } let a, b := f(2, 3) }"));
BOOST_CHECK(successAssemble("{ function rec(a) { rec(sub(a, 1)) } rec(2) }"));
BOOST_CHECK(successAssemble("{ let r := 2 function f() -> x, y { x := 1 y := 2} let a, b := f() b := r }"));
BOOST_CHECK(successAssemble("{ function f() { g() } function g() { f() } }"));
}
BOOST_AUTO_TEST_CASE(embedded_functions)
{
BOOST_CHECK(successAssemble("{ function f(r, s) -> x { function g(a) -> b { } x := g(2) } let x := f(2, 3) }"));
}
BOOST_AUTO_TEST_CASE(switch_statement)
{
BOOST_CHECK(successAssemble("{ switch 1 default {} }"));
BOOST_CHECK(successAssemble("{ switch 1 case 1 {} default {} }"));
BOOST_CHECK(successAssemble("{ switch 1 case 1 {} }"));
BOOST_CHECK(successAssemble("{ let a := 3 switch a case 1 { a := 1 } case 2 { a := 5 } a := 9}"));
BOOST_CHECK(successAssemble("{ let a := 2 switch calldataload(0) case 1 { a := 1 } case 2 { a := 5 } }"));
}
BOOST_AUTO_TEST_CASE(for_statement)
{
BOOST_CHECK(successAssemble("{ for {} 1 {} {} }"));
BOOST_CHECK(successAssemble("{ let x := calldatasize() for { let i := 0} lt(i, x) { i := add(i, 1) } { mstore(i, 2) } }"));
}
BOOST_AUTO_TEST_CASE(if_statement)
{
BOOST_CHECK(successAssemble("{ if 1 {} }"));
BOOST_CHECK(successAssemble("{ let x := 0 if eq(calldatasize(), 0) { x := 1 } mstore(0, x) }"));
}
BOOST_AUTO_TEST_CASE(large_constant) BOOST_AUTO_TEST_CASE(large_constant)
{ {
auto source = R"({ auto source = R"({
@ -706,13 +327,6 @@ BOOST_AUTO_TEST_CASE(returndatacopy)
BOOST_CHECK(successAssemble("{ returndatacopy(0, 32, 64) }")); BOOST_CHECK(successAssemble("{ returndatacopy(0, 32, 64) }"));
} }
BOOST_AUTO_TEST_CASE(returndatacopy_functional)
{
if (!solidity::test::CommonOptions::get().evmVersion().supportsReturndata())
return;
BOOST_CHECK(successAssemble("{ returndatacopy(0, 32, 64) }"));
}
BOOST_AUTO_TEST_CASE(staticcall) BOOST_AUTO_TEST_CASE(staticcall)
{ {
if (!solidity::test::CommonOptions::get().evmVersion().hasStaticCall()) if (!solidity::test::CommonOptions::get().evmVersion().hasStaticCall())
@ -751,7 +365,7 @@ BOOST_AUTO_TEST_CASE(jump_error)
CHECK_PARSE_WARNING("{ jumpi(44, 2) }", DeclarationError, "Function not found."); CHECK_PARSE_WARNING("{ jumpi(44, 2) }", DeclarationError, "Function not found.");
} }
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END() // }}}
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()

View File

@ -19,8 +19,6 @@
#include <test/libsolidity/SMTCheckerTest.h> #include <test/libsolidity/SMTCheckerTest.h>
#include <test/Common.h> #include <test/Common.h>
#include <libsolidity/formal/ModelChecker.h>
using namespace std; using namespace std;
using namespace solidity; using namespace solidity;
using namespace solidity::langutil; using namespace solidity::langutil;
@ -47,7 +45,13 @@ SMTCheckerTest::SMTCheckerTest(string const& _filename): SyntaxTest(_filename, E
if (!available.cvc4) if (!available.cvc4)
m_enabledSolvers.cvc4 = false; m_enabledSolvers.cvc4 = false;
if (m_enabledSolvers.none()) auto engine = ModelCheckerEngine::fromString(m_reader.stringSetting("SMTEngine", "all"));
if (engine)
m_modelCheckerSettings.engine = *engine;
else
BOOST_THROW_EXCEPTION(runtime_error("Invalid SMT engine choice."));
if (m_enabledSolvers.none() || m_modelCheckerSettings.engine.none())
m_shouldRun = false; m_shouldRun = false;
} }
@ -55,6 +59,7 @@ TestCase::TestResult SMTCheckerTest::run(ostream& _stream, string const& _linePr
{ {
setupCompiler(); setupCompiler();
compiler().setSMTSolverChoice(m_enabledSolvers); compiler().setSMTSolverChoice(m_enabledSolvers);
compiler().setModelCheckerSettings(m_modelCheckerSettings);
parseAndAnalyze(); parseAndAnalyze();
filterObtainedErrors(); filterObtainedErrors();

View File

@ -22,6 +22,8 @@
#include <libsmtutil/SolverInterface.h> #include <libsmtutil/SolverInterface.h>
#include <libsolidity/formal/ModelChecker.h>
#include <string> #include <string>
namespace solidity::frontend::test namespace solidity::frontend::test
@ -39,6 +41,12 @@ public:
TestResult run(std::ostream& _stream, std::string const& _linePrefix = "", bool _formatted = false) override; TestResult run(std::ostream& _stream, std::string const& _linePrefix = "", bool _formatted = false) override;
protected: protected:
/// This contains engine and timeout.
/// The engine can be set via option SMTEngine in the test.
/// The possible options are `all`, `chc`, `bmc`, `none`,
/// where the default is `all`.
ModelCheckerSettings m_modelCheckerSettings;
/// This is set via option SMTSolvers in the test. /// This is set via option SMTSolvers in the test.
/// The possible options are `all`, `z3`, `cvc4`, `none`, /// The possible options are `all`, `z3`, `cvc4`, `none`,
/// where if none is given the default used option is `all`. /// where if none is given the default used option is `all`.

View File

@ -0,0 +1,34 @@
contract C {
function f1() public returns (bytes memory) {
return abi.encode("");
}
function f2(string calldata msg) public returns (bytes memory) {
return abi.encode(msg);
}
function g1() public returns (bytes memory) {
return abi.encodePacked("");
}
function g2(string calldata msg) public returns (bytes memory) {
return abi.encodePacked(msg);
}
function h1() public returns (bytes memory) {
return abi.encodeWithSelector(0x00000001, "");
}
function h2(string calldata msg) public returns (bytes memory) {
return abi.encodeWithSelector(0x00000001, msg);
}
}
// ====
// ABIEncoderV1Only: true
// compileViaYul: false
// ----
// f1() -> 0x20, 0x60, 0x20, 0, 0
// f2(string): 0x20, 0 -> 0x20, 0x40, 0x20, 0
// f2(string): 0x20, 0, 0 -> 0x20, 0x40, 0x20, 0
// g1() -> 32, 0
// g2(string): 0x20, 0 -> 0x20, 0
// g2(string): 0x20, 0, 0 -> 0x20, 0
// h1() -> 0x20, 0x64, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0, 0
// h2(string): 0x20, 0 -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0
// h2(string): 0x20, 0, 0 -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0

View File

@ -16,6 +16,8 @@ contract C {
return (this.ggg(s.f), this.h(s)); return (this.ggg(s.f), this.h(s));
} }
} }
// ====
// compileViaYul: also
// ---- // ----
// ffff(uint256): 0 -> 0, 0 // ffff(uint256): 0 -> 0, 0
// ggg(function): 0 -> 0 // ggg(function): 0 -> 0

View File

@ -24,5 +24,7 @@ contract C {
} }
} }
// ====
// compileViaYul: also
// ---- // ----
// t() -> 9 // t() -> 9

View File

@ -0,0 +1,34 @@
struct S {
uint16 a;
function() external returns (uint) x;
uint16 b;
}
contract Flow {
S[2] t;
function X() public pure returns (uint) {
return 1;
}
function Y() public pure returns (uint) {
return 2;
}
constructor() {
t[0].a = 0xff07;
t[0].b = 0xff07;
t[1].x = this.Y;
t[1].a = 0xff07;
t[1].b = 0xff07;
t[0].x = this.X;
}
function f() public returns (uint, uint) {
return (t[0].x(), t[1].x());
}
}
// ====
// compileViaYul: also
// ----
// f() -> 1, 2

View File

@ -0,0 +1,18 @@
pragma abicoder v1;
contract C {
function f() public {
revert("");
}
function g(string calldata msg) public {
revert(msg);
}
}
// ====
// ABIEncoderV1Only: true
// EVMVersion: >=byzantium
// compileViaYul: false
// revertStrings: debug
// ----
// f() -> FAILURE, hex"08c379a0", 0x20, 0, ""
// g(string): 0x20, 0, "" -> FAILURE, hex"08c379a0", 0x20, 0
// g(string): 0x20, 0 -> FAILURE, hex"08c379a0", 0x20, 0

View File

@ -0,0 +1,18 @@
contract C {
function f() public {
revert("");
}
function g(string calldata msg) public {
revert(msg);
}
}
// ====
// ABIEncoderV1Only: true
// EVMVersion: >=byzantium
// compileViaYul: true
// revertStrings: debug
// ----
// f() -> FAILURE, hex"08c379a0", 0x20, 0
// g(string): "" -> FAILURE, hex"08c379a0", 0x20, 0
// g(string): 0x20, 0, "" -> FAILURE, hex"08c379a0", 0x20, 0
// g(string): 0x20, 0 -> FAILURE, hex"08c379a0", 0x20, 0

View File

@ -0,0 +1,18 @@
pragma experimental ABIEncoderV2;
contract C {
function f() public {
revert("");
}
function g(string calldata msg) public {
revert(msg);
}
}
// ====
// EVMVersion: >=byzantium
// compileViaYul: also
// revertStrings: debug
// ----
// f() -> FAILURE, hex"08c379a0", 0x20, 0
// g(string): "" -> FAILURE, hex"08c379a0", 0x20, 0
// g(string): 0x20, 0, "" -> FAILURE, hex"08c379a0", 0x20, 0
// g(string): 0x20, 0 -> FAILURE, hex"08c379a0", 0x20, 0

View File

@ -39,6 +39,8 @@ contract C {
} }
} }
// ====
// compileViaYul: also
// ---- // ----
// set() -> // set() ->
// t1() -> 7 // t1() -> 7

View File

@ -0,0 +1,9 @@
contract C {
function f() public pure returns (string memory) {
return "";
}
}
// ====
// compileViaYul: also
// ----
// f() -> 0x20, 0

View File

@ -0,0 +1,30 @@
contract C {
function f() public pure returns (string memory) {
return "";
}
function g(string calldata msg) public pure returns (string memory) {
return msg;
}
function h(string calldata msg, uint256 v) public pure returns (string memory, uint256) {
return (msg, v);
}
// Adjusting order of input/output intentionally.
function i(string calldata msg1, uint256 v, string calldata msg2) public pure returns (string memory, string memory, uint256) {
return (msg1, msg2, v);
}
function j(string calldata msg1, uint256 v) public pure returns (string memory, string memory, uint256) {
return (msg1, "", v);
}
}
// ====
// compileViaYul: also
// ----
// f() -> 0x20, 0
// g(string): 0x20, 0, "" -> 0x20, 0
// g(string): 0x20, 0 -> 0x20, 0
// h(string,uint256): 0x40, 0x888, 0, "" -> 0x40, 0x0888, 0
// h(string,uint256): 0x40, 0x888, 0 -> 0x40, 0x0888, 0
// i(string,uint256,string): 0x60, 0x888, 0x60, 0, "" -> 0x60, 0x80, 0x0888, 0, 0
// i(string,uint256,string): 0x60, 0x888, 0x60, 0 -> 0x60, 0x80, 0x0888, 0, 0
// j(string,uint256): 0x40, 0x888, 0, "" -> 0x60, 0x80, 0x0888, 0, 0
// j(string,uint256): 0x40, 0x888, 0 -> 0x60, 0x80, 0x0888, 0, 0

View File

@ -0,0 +1,20 @@
contract C {
function _() public pure returns (uint) {
return 88;
}
function g() public pure returns (uint){
return _();
}
function h() public pure returns (uint) {
_;
return 33;
}
}
// ====
// compileViaYul: also
// ----
// _() -> 88
// g() -> 88
// h() -> 33

View File

@ -0,0 +1,16 @@
contract C {
function f() public pure returns (uint) {
uint _;
return _;
}
function g() public pure returns (uint) {
uint _ = 1;
return _;
}
}
// ====
// compileViaYul: also
// ----
// f() -> 0
// g() -> 1

View File

@ -0,0 +1,23 @@
contract C {
modifier m() {
_;
}
modifier n() {
string memory _ = "failed";
_;
revert(_);
}
function f() m() public returns (uint) {
return 88;
}
function g() n() public returns (uint) {
}
}
// ====
// EVMVersion: >=byzantium
// ----
// f() -> 88
// g() -> FAILURE, hex"08c379a0", 0x20, 6, "failed"

View File

@ -0,0 +1,26 @@
pragma experimental SMTChecker;
contract C {
function f(uint x) public pure {
assert(x > 0);
}
function g(uint x) public pure {
require(x >= 0);
}
function h(uint x) public pure {
require(x == 2);
require(x != 2);
}
function i(uint x) public pure {
if (false) {
if (x != 2) {
}
}
}
}
// ====
// SMTEngine: bmc
// ----
// Warning 4661: (81-94): BMC: Assertion violation happens here.
// Warning 6838: (143-149): BMC: Condition is always true.
// Warning 6838: (218-224): BMC: Condition is always false.
// Warning 2512: (286-292): BMC: Condition unreachable.

View File

@ -0,0 +1,10 @@
pragma experimental SMTChecker;
contract C {
function f(address payable a) public {
a.transfer(200);
}
}
// ====
// SMTEngine: bmc
// ----
// Warning 1236: (87-102): BMC: Insufficient funds happens here.

View File

@ -0,0 +1,25 @@
pragma experimental SMTChecker;
contract C {
uint z = 1;
uint w = z - 3;
function a(uint x, uint y) public pure returns (uint) {
return x + y;
}
function s(uint x, uint y) public pure returns (uint) {
return x - y;
}
function m(uint x, uint y) public pure returns (uint) {
return x * y;
}
function d(uint x, uint y) public pure returns (uint) {
return x / y;
}
}
// ====
// SMTEngine: bmc
// ----
// Warning 2661: (141-146): BMC: Overflow (resulting value larger than 2**256 - 1) happens here.
// Warning 4144: (217-222): BMC: Underflow (resulting value less than 0) happens here.
// Warning 2661: (293-298): BMC: Overflow (resulting value larger than 2**256 - 1) happens here.
// Warning 3046: (369-374): BMC: Division by zero happens here.
// Warning 6084: (68-73): BMC: Underflow (resulting value less than 0) happens here.

View File

@ -36,3 +36,5 @@ library MerkleProof {
// ---- // ----
// Warning 4588: (988-1032): Assertion checker does not yet implement this type of function call. // Warning 4588: (988-1032): Assertion checker does not yet implement this type of function call.
// Warning 4588: (1175-1219): Assertion checker does not yet implement this type of function call. // Warning 4588: (1175-1219): Assertion checker does not yet implement this type of function call.
// Warning 4588: (988-1032): Assertion checker does not yet implement this type of function call.
// Warning 4588: (1175-1219): Assertion checker does not yet implement this type of function call.

View File

@ -84,4 +84,5 @@ contract InternalCall {
// Warning 2018: (1212-1274): Function state mutability can be restricted to pure // Warning 2018: (1212-1274): Function state mutability can be restricted to pure
// Warning 2018: (1280-1342): Function state mutability can be restricted to pure // Warning 2018: (1280-1342): Function state mutability can be restricted to pure
// Warning 4588: (771-814): Assertion checker does not yet implement this type of function call. // Warning 4588: (771-814): Assertion checker does not yet implement this type of function call.
// Warning 5729: (1403-1408): Assertion checker does not yet implement this type of function call. // Warning 4588: (771-814): Assertion checker does not yet implement this type of function call.
// Warning 5729: (1403-1408): BMC does not yet implement this type of function call.

View File

@ -11,3 +11,5 @@ contract C {
// Warning 2072: (133-143): Unused local variable. // Warning 2072: (133-143): Unused local variable.
// Warning 8364: (146-147): Assertion checker does not yet implement type type(struct C.A storage pointer) // Warning 8364: (146-147): Assertion checker does not yet implement type type(struct C.A storage pointer)
// Warning 4639: (146-163): Assertion checker does not yet implement this expression. // Warning 4639: (146-163): Assertion checker does not yet implement this expression.
// Warning 8364: (146-147): Assertion checker does not yet implement type type(struct C.A storage pointer)
// Warning 4639: (146-163): Assertion checker does not yet implement this expression.

View File

@ -11,3 +11,5 @@ contract C {
// Warning 6321: (75-79): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable. // Warning 6321: (75-79): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.
// Warning 7645: (98-121): Assertion checker does not support try/catch clauses. // Warning 7645: (98-121): Assertion checker does not support try/catch clauses.
// Warning 7645: (124-159): Assertion checker does not support try/catch clauses. // Warning 7645: (124-159): Assertion checker does not support try/catch clauses.
// Warning 7645: (98-121): Assertion checker does not support try/catch clauses.
// Warning 7645: (124-159): Assertion checker does not support try/catch clauses.

View File

@ -12,3 +12,5 @@ contract C {
// ---- // ----
// Warning 7645: (83-85): Assertion checker does not support try/catch clauses. // Warning 7645: (83-85): Assertion checker does not support try/catch clauses.
// Warning 7645: (88-122): Assertion checker does not support try/catch clauses. // Warning 7645: (88-122): Assertion checker does not support try/catch clauses.
// Warning 7645: (83-85): Assertion checker does not support try/catch clauses.
// Warning 7645: (88-122): Assertion checker does not support try/catch clauses.

View File

@ -24,6 +24,8 @@ contract C {
} }
} }
// ---- // ----
// Warning 6031: (261-267): Internal error: Expression undefined for SMT solver.
// Warning 7650: (284-296): Assertion checker does not yet support this expression.
// Warning 6328: (470-495): CHC: Assertion violation happens here. // Warning 6328: (470-495): CHC: Assertion violation happens here.
// Warning 6328: (540-565): CHC: Assertion violation happens here. // Warning 6328: (540-565): CHC: Assertion violation happens here.
// Warning 6031: (261-267): Internal error: Expression undefined for SMT solver. // Warning 6031: (261-267): Internal error: Expression undefined for SMT solver.

View File

@ -7,3 +7,5 @@ contract C {
// ---- // ----
// Warning 4588: (162-176): Assertion checker does not yet implement this type of function call. // Warning 4588: (162-176): Assertion checker does not yet implement this type of function call.
// Warning 4588: (178-203): Assertion checker does not yet implement this type of function call. // Warning 4588: (178-203): Assertion checker does not yet implement this type of function call.
// Warning 4588: (162-176): Assertion checker does not yet implement this type of function call.
// Warning 4588: (178-203): Assertion checker does not yet implement this type of function call.

View File

@ -18,3 +18,4 @@ contract C
} }
// ---- // ----
// Warning 8364: (228-229): Assertion checker does not yet implement type type(library L) // Warning 8364: (228-229): Assertion checker does not yet implement type type(library L)
// Warning 8364: (228-229): Assertion checker does not yet implement type type(library L)

View File

@ -17,5 +17,6 @@ contract C
} }
} }
// ---- // ----
// Warning 8364: (228-229): Assertion checker does not yet implement type type(library L)
// Warning 6328: (245-261): CHC: Assertion violation happens here. // Warning 6328: (245-261): CHC: Assertion violation happens here.
// Warning 8364: (228-229): Assertion checker does not yet implement type type(library L) // Warning 8364: (228-229): Assertion checker does not yet implement type type(library L)

View File

@ -16,3 +16,4 @@ library L {
// ---- // ----
// Warning 2018: (131-190): Function state mutability can be restricted to pure // Warning 2018: (131-190): Function state mutability can be restricted to pure
// Warning 8364: (86-87): Assertion checker does not yet implement type type(library L) // Warning 8364: (86-87): Assertion checker does not yet implement type type(library L)
// Warning 8364: (86-87): Assertion checker does not yet implement type type(library L)

Some files were not shown because too many files have changed in this diff Show More