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_size = 4
[std/**.sol]
[*.sol]
indent_style = space
indent_size = 4

View File

@ -31,6 +31,8 @@ Language Features:
Compiler Features:
* SMTChecker: Add division by zero checks in the CHC engine.
* 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:

View File

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

View File

@ -346,7 +346,12 @@ Input Description
"modelCheckerSettings":
{
// 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
any built-in operations, functions or types in its pure form.
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.
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.
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.
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;
CHCSmtLib2Interface::CHCSmtLib2Interface(
map<h256, string> const& _queryResponses,
ReadCallback::Callback const& _smtCallback
map<h256, string> _queryResponses,
ReadCallback::Callback _smtCallback,
optional<unsigned> _queryTimeout
):
m_smtlib2(make_unique<SMTLib2Interface>(_queryResponses, _smtCallback)),
m_queryResponses(_queryResponses),
CHCSolverInterface(_queryTimeout),
m_smtlib2(make_unique<SMTLib2Interface>(_queryResponses, _smtCallback, m_queryTimeout)),
m_queryResponses(move(_queryResponses)),
m_smtCallback(_smtCallback)
{
reset();
@ -51,6 +53,8 @@ void CHCSmtLib2Interface::reset()
m_accumulatedOutput.clear();
m_variables.clear();
m_unhandledQueries.clear();
if (m_queryTimeout)
write("(set-option :timeout " + to_string(*m_queryTimeout) + ")");
}
void CHCSmtLib2Interface::registerRelation(Expression const& _expr)

View File

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

View File

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

View File

@ -27,7 +27,8 @@ using namespace solidity;
using namespace solidity::util;
using namespace solidity::smtutil;
CVC4Interface::CVC4Interface():
CVC4Interface::CVC4Interface(optional<unsigned> _queryTimeout):
SolverInterface(_queryTimeout),
m_solver(&m_context)
{
reset();
@ -38,7 +39,10 @@ void CVC4Interface::reset()
m_variables.clear();
m_solver.reset();
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()

View File

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

View File

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

View File

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

View File

@ -35,17 +35,19 @@ using namespace solidity::smtutil;
SMTPortfolio::SMTPortfolio(
map<h256, string> _smtlib2Responses,
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
if (_enabledSolvers.z3)
m_solvers.emplace_back(make_unique<Z3Interface>());
m_solvers.emplace_back(make_unique<Z3Interface>(m_queryTimeout));
#endif
#ifdef HAVE_CVC4
if (_enabledSolvers.cvc4)
m_solvers.emplace_back(make_unique<CVC4Interface>());
m_solvers.emplace_back(make_unique<CVC4Interface>(m_queryTimeout));
#endif
}

View File

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

View File

@ -374,6 +374,8 @@ DEV_SIMPLE_EXCEPTION(SolverError);
class SolverInterface
{
public:
SolverInterface(std::optional<unsigned> _queryTimeout = {}): m_queryTimeout(_queryTimeout) {}
virtual ~SolverInterface() = default;
virtual void reset() = 0;
@ -401,6 +403,9 @@ public:
/// @returns how many SMT solvers this interface has.
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::smtutil;
Z3CHCInterface::Z3CHCInterface():
m_z3Interface(make_unique<Z3Interface>()),
Z3CHCInterface::Z3CHCInterface(optional<unsigned> _queryTimeout):
CHCSolverInterface(_queryTimeout),
m_z3Interface(make_unique<Z3Interface>(m_queryTimeout)),
m_context(m_z3Interface->context()),
m_solver(*m_context)
{
// These need to be set globally.
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();
}
@ -97,7 +102,13 @@ pair<CheckResult, CHCSolverInterface::CexGraph> Z3CHCInterface::query(Expression
}
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;
else
result = CheckResult::ERROR;

View File

@ -33,7 +33,7 @@ namespace solidity::smtutil
class Z3CHCInterface: public CHCSolverInterface
{
public:
Z3CHCInterface();
Z3CHCInterface(std::optional<unsigned> _queryTimeout = {});
/// Forwards variable declaration to Z3Interface.
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::util;
Z3Interface::Z3Interface():
Z3Interface::Z3Interface(std::optional<unsigned> _queryTimeout):
SolverInterface(_queryTimeout),
m_solver(m_context)
{
// These need to be set globally.
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()
@ -104,9 +109,19 @@ pair<CheckResult, vector<string>> Z3Interface::check(vector<Expression> const& _
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();
}

View File

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

View File

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

View File

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

View File

@ -702,26 +702,7 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly)
{
int const depositBefore = _assembly.stackHeight();
solAssert(!!decl->type(), "Type of declaration required but not yet determined.");
if (FunctionDefinition const* functionDef = dynamic_cast<FunctionDefinition 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))
if (auto variable = dynamic_cast<VariableDeclaration const*>(decl))
{
solAssert(!variable->immutable(), "");
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)
{
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(), "");
if (_type.category() == Type::Category::Function)
solUnimplementedAssert(!_splitFunctionTypes, "");
string functionName =
"read_from_storage_" +
string(_splitFunctionTypes ? "split_" : "") +
"offset_" +
to_string(_offset) +
string(_splitFunctionTypes ? "split_" : "") + (
_offset.has_value() ?
"offset_" + to_string(*_offset) :
"dynamic"
) +
"_" +
_type.identifier();
return m_functionCollector.createFunction(functionName, [&] {
solAssert(_type.sizeOnStack() == 1, "");
return Whiskers(R"(
function <functionName>(slot) -> value {
value := <extract>(sload(slot))
Whiskers templ(R"(
function <functionName>(slot<?dynamic>, offset</dynamic>) -> <?split>addr, selector<!split>value</split> {
<?split>let</split> value := <extract>(sload(slot)<?dynamic>, offset</dynamic>)
<?split>
addr, selector := <splitFunction>(value)
</split>
}
)")
("functionName", functionName)
("extract", extractFromStorageValue(_type, _offset, false))
.render();
)");
templ("functionName", functionName);
templ("dynamic", !_offset.has_value());
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)
{
solUnimplementedAssert(_type.category() == Type::Category::Struct, "");
@ -2437,9 +2426,7 @@ string YulUtilFunctions::updateStorageValueFunction(
string YulUtilFunctions::writeToMemoryFunction(Type const& _type)
{
string const functionName =
string("write_to_memory_") +
_type.identifier();
string const functionName = "write_to_memory_" + _type.identifier();
return m_functionCollector.createFunction(functionName, [&] {
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 =
"extract_from_storage_value_dynamic" +
string(_splitFunctionTypes ? "split_" : "") +
_type.identifier();
return m_functionCollector.createFunction(functionName, [&] {
return Whiskers(R"(
@ -2510,21 +2493,14 @@ string YulUtilFunctions::extractFromStorageValueDynamic(Type const& _type, bool
)")
("functionName", functionName)
("shr", shiftRightFunctionDynamic())
("cleanupStorage", cleanupFromStorageFunction(_type, _splitFunctionTypes))
("cleanupStorage", cleanupFromStorageFunction(_type))
.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_" +
string(_splitFunctionTypes ? "split_" : "") +
"offset_" +
to_string(_offset) +
_type.identifier();
string functionName = "extract_from_storage_value_offset_" + to_string(_offset) + _type.identifier();
return m_functionCollector.createFunction(functionName, [&] {
return Whiskers(R"(
function <functionName>(slot_value) -> value {
@ -2533,18 +2509,16 @@ string YulUtilFunctions::extractFromStorageValue(Type const& _type, size_t _offs
)")
("functionName", functionName)
("shr", shiftRightFunction(_offset * 8))
("cleanupStorage", cleanupFromStorageFunction(_type, _splitFunctionTypes))
("cleanupStorage", cleanupFromStorageFunction(_type))
.render();
});
}
string YulUtilFunctions::cleanupFromStorageFunction(Type const& _type, bool _splitFunctionTypes)
string YulUtilFunctions::cleanupFromStorageFunction(Type const& _type)
{
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, [&] {
Whiskers templ(R"(
function <functionName>(value) -> cleaned {
@ -2581,22 +2555,37 @@ string YulUtilFunctions::cleanupFromStorageFunction(Type const& _type, bool _spl
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();
return m_functionCollector.createFunction(functionName, [&]() {
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)");
solAssert(_type.isValueType(), "");
auto const* funType = dynamic_cast<FunctionType const*>(&_type);
if (funType && funType->kind() == FunctionType::Kind::External)
{
Whiskers templ(R"(
function <functionName>(addr, selector) -> ret {
ret := <prepareBytes>(<combine>(addr, selector))
}
)");
templ("functionName", functionName);
templ("prepareBytes", prepareStoreFunction(*TypeProvider::fixedBytes(24)));
templ("combine", combineExternalFunctionIdFunction());
return templ.render();
}
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(), "");
if (auto const* funType = dynamic_cast<FunctionType const*>(&_type))
if (funType->kind() == FunctionType::Kind::External)
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 {
Whiskers templ(R"(
function <functionName>(ptr) -> <returnVariables> {
<?fromCalldata>
value := calldataload(ptr)
let value := calldataload(ptr)
<validate>(value)
<!fromCalldata>
value := <cleanup>(mload(ptr))
let value := <cleanup>(mload(ptr))
</fromCalldata>
<returnVariables> :=
<?externalFunction>
<splitFunction>(value)
<!externalFunction>
value
</externalFunction>
}
)")
("functionName", functionName)
("fromCalldata", _fromCalldata)
("validate", validatorFunction(_type, true))
)");
templ("functionName", functionName);
templ("fromCalldata", _fromCalldata);
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.
// Other types are cleaned as well to account for dirty memory e.g. due to inline assembly.
("cleanup", cleanupFunction(_type))
.render();
templ("cleanup", cleanupFunction(_type));
return templ.render();
});
}

View File

@ -283,10 +283,10 @@ public:
/// @returns a function that extracts a value type from storage slot that has been
/// retrieved already.
/// 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.
std::string extractFromStorageValue(Type const& _type, size_t _offset, bool _splitFunctionTypes);
std::string extractFromStorageValueDynamic(Type const& _type, bool _splitFunctionTypes);
///
/// For external function types, input and output is in "compressed"/"unsplit" form.
std::string extractFromStorageValue(Type const& _type, size_t _offset);
std::string extractFromStorageValueDynamic(Type const& _type);
/// 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
@ -309,9 +309,8 @@ public:
/// higher order bytes or left-aligns (in case of bytesNN).
/// The storage cleanup expects the value to be right-aligned with potentially
/// dirty higher order bytes.
/// @param _splitFunctionTypes if false, returns the address and function signature in a
/// single variable.
std::string cleanupFromStorageFunction(Type const& _type, bool _splitFunctionTypes);
/// For external functions, input and output is in "compressed"/"unsplit" form.
std::string cleanupFromStorageFunction(Type const& _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
@ -459,8 +458,8 @@ private:
/// 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.
std::string readFromStorageValueType(Type const& _type, size_t _offset, bool _splitFunctionTypes);
std::string readFromStorageValueTypeDynamic(Type const& _type, bool _splitFunctionTypes);
/// @param _offset if provided, read from static offset, otherwise offset is a parameter of the Yul function.
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).
std::string readFromStorageReferenceType(Type const& _type);

View File

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

View File

@ -34,10 +34,11 @@ BMC::BMC(
ErrorReporter& _errorReporter,
map<h256, string> const& _smtlib2Responses,
ReadCallback::Callback const& _smtCallback,
smtutil::SMTSolverChoice _enabledSolvers
smtutil::SMTSolverChoice _enabledSolvers,
optional<unsigned> _timeout
):
SMTEncoder(_context),
m_interface(make_unique<smtutil::SMTPortfolio>(_smtlib2Responses, _smtCallback, _enabledSolvers)),
m_interface(make_unique<smtutil::SMTPortfolio>(_smtlib2Responses, _smtCallback, _enabledSolvers, _timeout)),
m_outerErrorReporter(_errorReporter)
{
#if defined (HAVE_Z3) || defined (HAVE_CVC4)
@ -491,7 +492,7 @@ void BMC::internalOrExternalFunctionCall(FunctionCall const& _funCall)
m_errorReporter.warning(
5729_error,
_funCall.location(),
"Assertion checker does not yet implement this type of function call."
"BMC does not yet implement this type of function call."
);
else
{
@ -909,9 +910,9 @@ void BMC::checkBooleanNotConstant(
m_interface->pop();
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)
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)
{
// everything fine.
@ -921,7 +922,7 @@ void BMC::checkBooleanNotConstant(
// can't do anything.
}
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
{
string description;
@ -956,7 +957,7 @@ BMC::checkSatisfiableAndGenerateModel(vector<smtutil::Expression> const& _expres
}
catch (smtutil::SolverError const& _e)
{
string description("Error querying SMT solver");
string description("BMC: Error querying SMT solver");
if (_e.comment())
description += ": " + *_e.comment();
m_errorReporter.warning(8140_error, description);

View File

@ -61,7 +61,8 @@ public:
langutil::ErrorReporter& _errorReporter,
std::map<h256, std::string> const& _smtlib2Responses,
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);

View File

@ -49,18 +49,20 @@ CHC::CHC(
ErrorReporter& _errorReporter,
[[maybe_unused]] map<util::h256, string> const& _smtlib2Responses,
[[maybe_unused]] ReadCallback::Callback const& _smtCallback,
SMTSolverChoice _enabledSolvers
SMTSolverChoice _enabledSolvers,
optional<unsigned> _timeout
):
SMTEncoder(_context),
m_outerErrorReporter(_errorReporter),
m_enabledSolvers(_enabledSolvers)
m_enabledSolvers(_enabledSolvers),
m_queryTimeout(_timeout)
{
bool usesZ3 = _enabledSolvers.z3;
#ifndef HAVE_Z3
usesZ3 = false;
#endif
if (!usesZ3)
m_interface = make_unique<CHCSmtLib2Interface>(_smtlib2Responses, _smtCallback);
m_interface = make_unique<CHCSmtLib2Interface>(_smtlib2Responses, _smtCallback, m_queryTimeout);
}
void CHC::analyze(SourceUnit const& _source)
@ -69,7 +71,7 @@ void CHC::analyze(SourceUnit const& _source)
resetSourceAnalysis();
set<SourceUnit const*, IdCompare> sources;
set<SourceUnit const*, EncodingContext::IdCompare> sources;
sources.insert(&_source);
for (auto const& source: _source.referencedSourceUnits(true))
sources.insert(source);
@ -79,6 +81,24 @@ void CHC::analyze(SourceUnit const& _source)
source->accept(*this);
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
@ -681,7 +701,7 @@ void CHC::resetSourceAnalysis()
if (usesZ3)
{
/// 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());
solAssert(z3Interface, "");
m_context.setSolver(z3Interface->z3Interface());
@ -1076,10 +1096,10 @@ pair<CheckResult, CHCSolverInterface::CexGraph> CHC::query(smtutil::Expression c
case CheckResult::UNKNOWN:
break;
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;
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;
}
return {result, cex};
@ -1233,21 +1253,21 @@ void CHC::checkAndReportTarget(
m_unsafeTargets[_target.errorNode].insert(_target.type);
auto cex = generateCounterexample(model, error().name);
if (cex)
m_outerErrorReporter.warning(
m_errorReporter.warning(
_errorReporterId,
location,
"CHC: " + _satMsg,
SecondarySourceLocation().append("Counterexample:\n" + *cex, SourceLocation{})
);
else
m_outerErrorReporter.warning(
m_errorReporter.warning(
_errorReporterId,
location,
"CHC: " + _satMsg
);
}
else if (!_unknownMsg.empty())
m_outerErrorReporter.warning(
m_errorReporter.warning(
_errorReporterId,
location,
"CHC: " + _unknownMsg

View File

@ -55,7 +55,8 @@ public:
langutil::ErrorReporter& _errorReporter,
std::map<util::h256, std::string> const& _smtlib2Responses,
ReadCallback::Callback const& _smtCallback,
smtutil::SMTSolverChoice _enabledSolvers
smtutil::SMTSolverChoice _enabledSolvers,
std::optional<unsigned> timeout
);
void analyze(SourceUnit const& _sources);
@ -99,14 +100,6 @@ private:
) override;
//@}
struct IdCompare
{
bool operator()(ASTNode const* lhs, ASTNode const* rhs) const
{
return lhs->id() < rhs->id();
}
};
/// Helpers.
//@{
void resetSourceAnalysis();
@ -286,12 +279,12 @@ private:
/// Query placeholders for constructors, if the key has type ContractDefinition*,
/// 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).
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.
/// 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.
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.
std::map<unsigned, CHCVerificationTarget> m_verificationTargets;
@ -305,7 +298,7 @@ private:
//@{
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.
smtutil::Expression m_currentBlock = smtutil::Expression(true);
@ -330,6 +323,9 @@ private:
/// SMT solvers that are chosen at runtime.
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 <unordered_map>
#include <set>
#include <map>
namespace solidity::frontend::smt
{
@ -67,12 +66,20 @@ public:
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.
//@{
/// @returns the symbolic representation of a program variable.
std::shared_ptr<SymbolicVariable> variable(frontend::VariableDeclaration const& _varDecl);
/// @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
/// @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.
std::shared_ptr<SymbolicVariable> expression(frontend::Expression const& _e);
/// @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).
/// @returns true if type is not supported.
@ -119,7 +126,7 @@ public:
/// Global variables and functions.
std::shared_ptr<SymbolicVariable> globalSymbol(std::string const& _name);
/// @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
/// and @returns true if type was abstracted.
@ -149,14 +156,14 @@ private:
/// Symbolic expressions.
//{@
/// 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.
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
/// 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.
SymbolicState m_state;

View File

@ -27,14 +27,14 @@ using namespace solidity::frontend;
ModelChecker::ModelChecker(
ErrorReporter& _errorReporter,
map<h256, string> const& _smtlib2Responses,
ModelCheckerEngine _engine,
ModelCheckerSettings _settings,
ReadCallback::Callback const& _smtCallback,
smtutil::SMTSolverChoice _enabledSolvers
):
m_engine(_engine),
m_settings(_settings),
m_context(),
m_bmc(m_context, _errorReporter, _smtlib2Responses, _smtCallback, _enabledSolvers),
m_chc(m_context, _errorReporter, _smtlib2Responses, _smtCallback, _enabledSolvers)
m_bmc(m_context, _errorReporter, _smtlib2Responses, _smtCallback, _enabledSolvers, _settings.timeout),
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))
return;
if (m_engine.chc)
if (m_settings.engine.chc)
m_chc.analyze(_source);
auto solvedTargets = m_chc.safeTargets();
for (auto const& target: m_chc.unsafeTargets())
solvedTargets[target.first] += target.second;
if (m_engine.bmc)
if (m_settings.engine.bmc)
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
{
public:
@ -79,7 +85,7 @@ public:
ModelChecker(
langutil::ErrorReporter& _errorReporter,
std::map<solidity::util::h256, std::string> const& _smtlib2Responses,
ModelCheckerEngine _engine = ModelCheckerEngine::All(),
ModelCheckerSettings _settings = ModelCheckerSettings{},
ReadCallback::Callback const& _smtCallback = ReadCallback::Callback(),
smtutil::SMTSolverChoice _enabledSolvers = smtutil::SMTSolverChoice::All()
);
@ -95,7 +101,7 @@ public:
static smtutil::SMTSolverChoice availableSolvers();
private:
ModelCheckerEngine m_engine;
ModelCheckerSettings m_settings;
/// Stores the context of the encoding.
smt::EncodingContext m_context;

View File

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

View File

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

View File

@ -167,8 +167,8 @@ public:
/// Must be set before parsing.
void setEVMVersion(langutil::EVMVersion _version = langutil::EVMVersion{});
/// Set which model checking engines should be used.
void setModelCheckerEngine(ModelCheckerEngine _engine);
/// Set model checker settings.
void setModelCheckerSettings(ModelCheckerSettings _settings);
/// Set which SMT solvers should be enabled.
void setSMTSolverChoice(smtutil::SMTSolverChoice _enabledSolvers);
@ -456,7 +456,7 @@ private:
RevertStrings m_revertStrings = RevertStrings::Default;
State m_stopAfter = State::CompilationSuccessful;
langutil::EVMVersion m_evmVersion;
ModelCheckerEngine m_modelCheckerEngine;
ModelCheckerSettings m_modelCheckerSettings;
smtutil::SMTSolverChoice m_enabledSMTSolvers;
std::map<std::string, std::set<std::string>> m_requestedContractNames;
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)
{
static set<string> keys{"engine"};
static set<string> keys{"engine", "timeout"};
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());
if (!engine)
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) };
@ -908,7 +915,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting
compilerStack.useMetadataLiteralSources(_inputsAndSettings.metadataLiteralSources);
compilerStack.setMetadataHash(_inputsAndSettings.metadataHash);
compilerStack.setRequestedContractNames(requestedContractNames(_inputsAndSettings.outputSelection));
compilerStack.setModelCheckerEngine(_inputsAndSettings.modelCheckerEngine);
compilerStack.setModelCheckerSettings(_inputsAndSettings.modelCheckerSettings);
compilerStack.enableEvmBytecodeGeneration(isEvmBytecodeRequested(_inputsAndSettings.outputSelection));
compilerStack.enableIRGeneration(isIRRequested(_inputsAndSettings.outputSelection));

View File

@ -71,7 +71,7 @@ private:
bool metadataLiteralSources = false;
CompilerStack::MetadataHash metadataHash = CompilerStack::MetadataHash::IPFS;
Json::Value outputSelection;
ModelCheckerEngine modelCheckerEngine = ModelCheckerEngine::All();
ModelCheckerSettings modelCheckerSettings = ModelCheckerSettings{};
};
/// 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
old_source_only_ids = {
"1123", "1133", "1218", "1220", "1584", "1823", "1950",
"1988", "2418", "2461", "2512", "2592", "2657", "2800", "2842", "2856",
"3046", "3263", "3356", "3441", "3682", "3876",
"3893", "4010", "4281", "4802", "4805", "4828",
"4904", "4990", "5052", "5073", "5170", "5188", "5272", "5347", "5473",
"5622", "6041", "6052", "6084", "6272", "6708", "6792", "6931", "7110", "7128", "7186",
"7589", "7593", "7653", "7812", "7885", "8065", "8084", "8140",
"8261", "8312", "8592", "8758", "9011",
"9085", "9390", "9440", "9547", "9551", "9615", "9980"
"1123", "1220", "1584", "1823", "1950",
"1988", "2657", "2800",
"3263", "3356", "3682", "3876",
"3893", "3996", "4010", "4802",
"5073", "5188", "5272",
"5622", "6272", "7128", "7186",
"7589", "7593", "7653", "7885", "8065", "8084", "8140",
"8312", "8592", "9011",
"9085", "9390", "9551",
}
new_source_only_ids = source_only_ids - old_source_only_ids
if len(new_source_only_ids) != 0:
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_strMetadataLiteral = "metadata-literal";
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_strNatspecUser = "userdoc";
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_argMetadataLiteral = g_strMetadataLiteral;
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_argNatspecUser = g_strNatspecUser;
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"),
"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);
@ -1400,9 +1409,12 @@ bool CommandLineInterface::processInput()
serr() << "Invalid option for --" << g_argModelCheckerEngine << ": " << engineStr << endl;
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);
unique_ptr<SourceReferenceFormatter> formatter;
@ -1417,8 +1429,8 @@ bool CommandLineInterface::processInput()
m_compiler->useMetadataLiteralSources(true);
if (m_args.count(g_argMetadataHash))
m_compiler->setMetadataHash(m_metadataHash);
if (m_args.count(g_argModelCheckerEngine))
m_compiler->setModelCheckerEngine(m_modelCheckerEngine);
if (m_args.count(g_argModelCheckerEngine) || m_args.count(g_argModelCheckerTimeout))
m_compiler->setModelCheckerSettings(m_modelCheckerSettings);
if (m_args.count(g_argInputFile))
m_compiler->setRemappings(m_remappings);

View File

@ -133,8 +133,8 @@ private:
RevertStrings m_revertStrings = RevertStrings::Default;
/// Chosen hash method for the bytecode metadata.
CompilerStack::MetadataHash m_metadataHash = CompilerStack::MetadataHash::IPFS;
/// Chosen model checker engine.
ModelCheckerEngine m_modelCheckerEngine = ModelCheckerEngine::All();
/// Model checker settings.
ModelCheckerSettings m_modelCheckerSettings;
/// Whether or not to colorize diagnostics output.
bool m_coloredOutput = true;
/// 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:
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:
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:
object "MyContract" {
@ -26,42 +26,42 @@ Binary representation:
33600055600b806012600039806000f350fe60005460005260206000f3
Text representation:
/* "object_compiler/input.sol":128:136 */
/* "object_compiler/input.yul":128:136 */
caller
/* "object_compiler/input.sol":125:126 */
/* "object_compiler/input.yul":125:126 */
0x00
/* "object_compiler/input.sol":118:137 */
/* "object_compiler/input.yul":118:137 */
sstore
dataSize(sub_0)
/* "object_compiler/input.sol":240:259 */
/* "object_compiler/input.yul":240:259 */
dup1
dataOffset(sub_0)
/* "object_compiler/input.sol":125:126 */
/* "object_compiler/input.yul":125:126 */
0x00
/* "object_compiler/input.sol":205:260 */
/* "object_compiler/input.yul":205:260 */
codecopy
/* "object_compiler/input.sol":275:294 */
/* "object_compiler/input.yul":275:294 */
dup1
/* "object_compiler/input.sol":125:126 */
/* "object_compiler/input.yul":125:126 */
0x00
/* "object_compiler/input.sol":265:295 */
/* "object_compiler/input.yul":265:295 */
return
pop
stop
sub_0: assembly {
/* "object_compiler/input.sol":397:398 */
/* "object_compiler/input.yul":397:398 */
0x00
/* "object_compiler/input.sol":391:399 */
/* "object_compiler/input.yul":391:399 */
sload
/* "object_compiler/input.sol":397:398 */
/* "object_compiler/input.yul":397:398 */
0x00
/* "object_compiler/input.sol":381:400 */
/* "object_compiler/input.yul":381:400 */
mstore
/* "object_compiler/input.sol":417:421 */
/* "object_compiler/input.yul":417:421 */
0x20
/* "object_compiler/input.sol":397:398 */
/* "object_compiler/input.yul":397:398 */
0x00
/* "object_compiler/input.sol":407:422 */
/* "object_compiler/input.yul":407:422 */
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.
Error: Function not found.
--> strict_asm_jump/input.sol:1:3:
--> strict_asm_jump/input.yul:1:3:
|
1 | { jump(1) }
| ^^^^

View File

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

View File

@ -1,5 +1,5 @@
======= yul_stack_opt_disabled/input.sol (EVM) =======
======= yul_stack_opt_disabled/input.yul (EVM) =======
Pretty printed source:
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(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_SUITE(Printing) // {{{
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(Analysis)
BOOST_AUTO_TEST_SUITE(Analysis) // {{{
BOOST_AUTO_TEST_CASE(string_literals)
{
@ -633,50 +298,6 @@ BOOST_AUTO_TEST_CASE(revert)
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)
{
auto source = R"({
@ -706,13 +327,6 @@ BOOST_AUTO_TEST_CASE(returndatacopy)
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)
{
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.");
}
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/Common.h>
#include <libsolidity/formal/ModelChecker.h>
using namespace std;
using namespace solidity;
using namespace solidity::langutil;
@ -47,7 +45,13 @@ SMTCheckerTest::SMTCheckerTest(string const& _filename): SyntaxTest(_filename, E
if (!available.cvc4)
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;
}
@ -55,6 +59,7 @@ TestCase::TestResult SMTCheckerTest::run(ostream& _stream, string const& _linePr
{
setupCompiler();
compiler().setSMTSolverChoice(m_enabledSolvers);
compiler().setModelCheckerSettings(m_modelCheckerSettings);
parseAndAnalyze();
filterObtainedErrors();

View File

@ -22,6 +22,8 @@
#include <libsmtutil/SolverInterface.h>
#include <libsolidity/formal/ModelChecker.h>
#include <string>
namespace solidity::frontend::test
@ -39,6 +41,12 @@ public:
TestResult run(std::ostream& _stream, std::string const& _linePrefix = "", bool _formatted = false) override;
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.
/// The possible options are `all`, `z3`, `cvc4`, `none`,
/// 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));
}
}
// ====
// compileViaYul: also
// ----
// ffff(uint256): 0 -> 0, 0
// ggg(function): 0 -> 0

View File

@ -24,5 +24,7 @@ contract C {
}
}
// ====
// compileViaYul: also
// ----
// 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() ->
// 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: (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: (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 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 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 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 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: (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: (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: (540-565): CHC: Assertion violation happens here.
// 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: (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)

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 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 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