mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge remote-tracking branch 'origin/develop' into HEAD
This commit is contained in:
+30
-21
@@ -2,6 +2,8 @@ set(sources
|
||||
boostTest.cpp
|
||||
Common.cpp
|
||||
Common.h
|
||||
CommonSyntaxTest.cpp
|
||||
CommonSyntaxTest.h
|
||||
EVMHost.cpp
|
||||
EVMHost.h
|
||||
ExecutionFramework.cpp
|
||||
@@ -9,8 +11,6 @@ set(sources
|
||||
InteractiveTests.h
|
||||
Metadata.cpp
|
||||
Metadata.h
|
||||
Options.cpp
|
||||
Options.h
|
||||
TestCase.cpp
|
||||
TestCase.h
|
||||
)
|
||||
@@ -51,19 +51,6 @@ set(liblangutil_sources
|
||||
)
|
||||
detect_stray_source_files("${liblangutil_sources}" "liblangutil/")
|
||||
|
||||
if(LLL)
|
||||
set (liblll_sources
|
||||
liblll/Compiler.cpp
|
||||
liblll/EndToEndTest.cpp
|
||||
liblll/ExecutionFramework.cpp
|
||||
liblll/ExecutionFramework.h
|
||||
liblll/LLL_ENS.cpp
|
||||
liblll/LLL_ERC20.cpp
|
||||
liblll/Parser.cpp
|
||||
)
|
||||
detect_stray_source_files("${liblll_sources}" "liblll/")
|
||||
endif(LLL)
|
||||
|
||||
set(libsolidity_sources
|
||||
libsolidity/ABIDecoderTests.cpp
|
||||
libsolidity/ABIEncoderTests.cpp
|
||||
@@ -142,6 +129,8 @@ set(libyul_sources
|
||||
libyul/ObjectParser.cpp
|
||||
libyul/Parser.cpp
|
||||
libyul/StackReuseCodegen.cpp
|
||||
libyul/SyntaxTest.h
|
||||
libyul/SyntaxTest.cpp
|
||||
libyul/YulInterpreterTest.cpp
|
||||
libyul/YulInterpreterTest.h
|
||||
libyul/YulOptimizerTest.cpp
|
||||
@@ -149,15 +138,40 @@ set(libyul_sources
|
||||
)
|
||||
detect_stray_source_files("${libyul_sources}" "libyul/")
|
||||
|
||||
set(yul_phaser_sources
|
||||
yulPhaser/Common.h
|
||||
yulPhaser/Common.cpp
|
||||
yulPhaser/CommonTest.cpp
|
||||
yulPhaser/Chromosome.cpp
|
||||
yulPhaser/FitnessMetrics.cpp
|
||||
yulPhaser/GeneticAlgorithms.cpp
|
||||
yulPhaser/Population.cpp
|
||||
yulPhaser/Program.cpp
|
||||
yulPhaser/Selections.cpp
|
||||
yulPhaser/SimulationRNG.cpp
|
||||
|
||||
# FIXME: yul-phaser is not a library so I can't just add it to target_link_libraries().
|
||||
# My current workaround is just to include its source files here but this introduces
|
||||
# unnecessary duplication. Create a library or find a way to reuse the list in both places.
|
||||
../tools/yulPhaser/Chromosome.cpp
|
||||
../tools/yulPhaser/FitnessMetrics.cpp
|
||||
../tools/yulPhaser/GeneticAlgorithms.cpp
|
||||
../tools/yulPhaser/Population.cpp
|
||||
../tools/yulPhaser/Program.cpp
|
||||
../tools/yulPhaser/Selections.cpp
|
||||
../tools/yulPhaser/SimulationRNG.cpp
|
||||
)
|
||||
detect_stray_source_files("${yul_phaser_sources}" "yulPhaser/")
|
||||
|
||||
add_executable(soltest ${sources}
|
||||
${contracts_sources}
|
||||
${libsolutil_sources}
|
||||
${liblangutil_sources}
|
||||
${libevmasm_sources}
|
||||
${libyul_sources}
|
||||
${liblll_sources}
|
||||
${libsolidity_sources}
|
||||
${libsolidity_util_sources}
|
||||
${yul_phaser_sources}
|
||||
)
|
||||
target_link_libraries(soltest PRIVATE libsolc yul solidity yulInterpreter evmasm solutil Boost::boost Boost::program_options Boost::unit_test_framework evmc)
|
||||
|
||||
@@ -170,11 +184,6 @@ if (MSVC)
|
||||
target_compile_options(soltest PUBLIC "/bigobj")
|
||||
endif()
|
||||
|
||||
if (LLL)
|
||||
target_link_libraries(soltest PRIVATE lll)
|
||||
target_compile_definitions(soltest PRIVATE HAVE_LLL=1)
|
||||
endif()
|
||||
|
||||
if (NOT Boost_USE_STATIC_LIBS)
|
||||
target_compile_definitions(soltest PUBLIC -DBOOST_TEST_DYN_LINK)
|
||||
endif()
|
||||
|
||||
+22
-1
@@ -15,6 +15,7 @@
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdexcept>
|
||||
#include <test/Common.h>
|
||||
|
||||
#include <libsolutil/Assertions.h>
|
||||
@@ -91,7 +92,11 @@ CommonOptions::CommonOptions(std::string _caption):
|
||||
("evm-version", po::value(&evmVersionString), "which evm version to use")
|
||||
("testpath", po::value<fs::path>(&this->testPath)->default_value(solidity::test::testPath()), "path to test files")
|
||||
("evmonepath", po::value<fs::path>(&evmonePath)->default_value(EVMOneEnvOrDefaultPath()), "path to evmone library")
|
||||
("no-smt", po::bool_switch(&disableSMT), "disable SMT checker");
|
||||
("no-smt", po::bool_switch(&disableSMT), "disable SMT checker")
|
||||
("optimize", po::bool_switch(&optimize), "enables optimization")
|
||||
("optimize-yul", po::bool_switch(&optimizeYul), "enables Yul optimization")
|
||||
("abiencoderv2", po::bool_switch(&useABIEncoderV2), "enables abi encoder v2")
|
||||
("show-messages", po::bool_switch(&showMessages), "enables message output");
|
||||
}
|
||||
|
||||
void CommonOptions::validate() const
|
||||
@@ -151,4 +156,20 @@ langutil::EVMVersion CommonOptions::evmVersion() const
|
||||
return langutil::EVMVersion();
|
||||
}
|
||||
|
||||
|
||||
CommonOptions const& CommonOptions::get()
|
||||
{
|
||||
if (!m_singleton)
|
||||
throw std::runtime_error("Options not yet constructed!");
|
||||
|
||||
return *m_singleton;
|
||||
}
|
||||
|
||||
void CommonOptions::setSingleton(std::unique_ptr<CommonOptions const>&& _instance)
|
||||
{
|
||||
m_singleton = std::move(_instance);
|
||||
}
|
||||
|
||||
std::unique_ptr<CommonOptions const> CommonOptions::m_singleton = nullptr;
|
||||
|
||||
}
|
||||
|
||||
+9
-2
@@ -21,8 +21,8 @@
|
||||
#include <liblangutil/EVMVersion.h>
|
||||
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <boost/program_options.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/program_options.hpp>
|
||||
|
||||
namespace solidity::test
|
||||
{
|
||||
@@ -48,6 +48,8 @@ struct CommonOptions: boost::noncopyable
|
||||
bool optimize = false;
|
||||
bool optimizeYul = false;
|
||||
bool disableSMT = false;
|
||||
bool useABIEncoderV2 = false;
|
||||
bool showMessages = false;
|
||||
|
||||
langutil::EVMVersion evmVersion() const;
|
||||
|
||||
@@ -55,13 +57,18 @@ struct CommonOptions: boost::noncopyable
|
||||
// Throws a ConfigException on error
|
||||
virtual void validate() const;
|
||||
|
||||
protected:
|
||||
static CommonOptions const& get();
|
||||
static void setSingleton(std::unique_ptr<CommonOptions const>&& _instance);
|
||||
|
||||
CommonOptions(std::string caption = "");
|
||||
virtual ~CommonOptions() {};
|
||||
protected:
|
||||
|
||||
boost::program_options::options_description options;
|
||||
|
||||
private:
|
||||
std::string evmVersionString;
|
||||
static std::unique_ptr<CommonOptions const> m_singleton;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,252 @@
|
||||
/*
|
||||
This file is part of solidity.
|
||||
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <test/CommonSyntaxTest.h>
|
||||
#include <test/Common.h>
|
||||
#include <test/TestCase.h>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
|
||||
using namespace std;
|
||||
using namespace solidity;
|
||||
using namespace solidity::util;
|
||||
using namespace solidity::util::formatting;
|
||||
using namespace solidity::langutil;
|
||||
using namespace solidity::frontend;
|
||||
using namespace solidity::frontend::test;
|
||||
using namespace solidity::test;
|
||||
using namespace boost::unit_test;
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
int parseUnsignedInteger(string::iterator& _it, string::iterator _end)
|
||||
{
|
||||
if (_it == _end || !isdigit(*_it))
|
||||
throw runtime_error("Invalid test expectation. Source location expected.");
|
||||
int result = 0;
|
||||
while (_it != _end && isdigit(*_it))
|
||||
{
|
||||
result *= 10;
|
||||
result += *_it - '0';
|
||||
++_it;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
CommonSyntaxTest::CommonSyntaxTest(string const& _filename, langutil::EVMVersion _evmVersion): m_evmVersion(_evmVersion)
|
||||
{
|
||||
ifstream file(_filename);
|
||||
if (!file)
|
||||
BOOST_THROW_EXCEPTION(runtime_error("Cannot open test contract: \"" + _filename + "\"."));
|
||||
file.exceptions(ios::badbit);
|
||||
|
||||
m_sources = parseSourcesAndSettings(file);
|
||||
|
||||
m_expectations = parseExpectations(file);
|
||||
}
|
||||
|
||||
TestCase::TestResult CommonSyntaxTest::run(ostream& _stream, string const& _linePrefix, bool _formatted)
|
||||
{
|
||||
parseAndAnalyze();
|
||||
|
||||
return printExpectationAndError(_stream, _linePrefix, _formatted) ? TestResult::Success : TestResult::Failure;
|
||||
}
|
||||
|
||||
bool CommonSyntaxTest::printExpectationAndError(ostream& _stream, string const& _linePrefix, bool _formatted)
|
||||
{
|
||||
if (m_expectations != m_errorList)
|
||||
{
|
||||
string nextIndentLevel = _linePrefix + " ";
|
||||
AnsiColorized(_stream, _formatted, {BOLD, CYAN}) << _linePrefix << "Expected result:" << endl;
|
||||
printErrorList(_stream, m_expectations, nextIndentLevel, _formatted);
|
||||
AnsiColorized(_stream, _formatted, {BOLD, CYAN}) << _linePrefix << "Obtained result:" << endl;
|
||||
printErrorList(_stream, m_errorList, nextIndentLevel, _formatted);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CommonSyntaxTest::printSource(ostream& _stream, string const& _linePrefix, bool _formatted) const
|
||||
{
|
||||
if (m_sources.empty())
|
||||
return;
|
||||
|
||||
bool outputSourceNames = true;
|
||||
if (m_sources.size() == 1 && m_sources.begin()->first.empty())
|
||||
outputSourceNames = false;
|
||||
|
||||
if (_formatted)
|
||||
for (auto const& [name, source]: m_sources)
|
||||
{
|
||||
if (source.empty())
|
||||
continue;
|
||||
|
||||
if (outputSourceNames)
|
||||
_stream << _linePrefix << formatting::CYAN << "==== Source: " << name << " ====" << formatting::RESET << endl;
|
||||
vector<char const*> sourceFormatting(source.length(), formatting::RESET);
|
||||
for (auto const& error: m_errorList)
|
||||
if (error.sourceName == name && error.locationStart >= 0 && error.locationEnd >= 0)
|
||||
{
|
||||
assert(static_cast<size_t>(error.locationStart) <= source.length());
|
||||
assert(static_cast<size_t>(error.locationEnd) <= source.length());
|
||||
bool isWarning = error.type == "Warning";
|
||||
for (int i = error.locationStart; i < error.locationEnd; i++)
|
||||
if (isWarning)
|
||||
{
|
||||
if (sourceFormatting[i] == formatting::RESET)
|
||||
sourceFormatting[i] = formatting::ORANGE_BACKGROUND_256;
|
||||
}
|
||||
else
|
||||
sourceFormatting[i] = formatting::RED_BACKGROUND;
|
||||
}
|
||||
|
||||
_stream << _linePrefix << sourceFormatting.front() << source.front();
|
||||
for (size_t i = 1; i < source.length(); i++)
|
||||
{
|
||||
if (sourceFormatting[i] != sourceFormatting[i - 1])
|
||||
_stream << sourceFormatting[i];
|
||||
if (source[i] != '\n')
|
||||
_stream << source[i];
|
||||
else
|
||||
{
|
||||
_stream << formatting::RESET << endl;
|
||||
if (i + 1 < source.length())
|
||||
_stream << _linePrefix << sourceFormatting[i];
|
||||
}
|
||||
}
|
||||
_stream << formatting::RESET;
|
||||
}
|
||||
else
|
||||
for (auto const& [name, source]: m_sources)
|
||||
{
|
||||
if (outputSourceNames)
|
||||
_stream << _linePrefix << "==== Source: " + name << " ====" << endl;
|
||||
stringstream stream(source);
|
||||
string line;
|
||||
while (getline(stream, line))
|
||||
_stream << _linePrefix << line << endl;
|
||||
}
|
||||
}
|
||||
|
||||
void CommonSyntaxTest::printErrorList(
|
||||
ostream& _stream,
|
||||
vector<SyntaxTestError> const& _errorList,
|
||||
string const& _linePrefix,
|
||||
bool _formatted
|
||||
)
|
||||
{
|
||||
if (_errorList.empty())
|
||||
AnsiColorized(_stream, _formatted, {BOLD, GREEN}) << _linePrefix << "Success" << endl;
|
||||
else
|
||||
for (auto const& error: _errorList)
|
||||
{
|
||||
{
|
||||
AnsiColorized scope(_stream, _formatted, {BOLD, (error.type == "Warning") ? YELLOW : RED});
|
||||
_stream << _linePrefix;
|
||||
_stream << error.type << ": ";
|
||||
}
|
||||
if (!error.sourceName.empty() || error.locationStart >= 0 || error.locationEnd >= 0)
|
||||
{
|
||||
_stream << "(";
|
||||
if (!error.sourceName.empty())
|
||||
_stream << error.sourceName << ":";
|
||||
if (error.locationStart >= 0)
|
||||
_stream << error.locationStart;
|
||||
_stream << "-";
|
||||
if (error.locationEnd >= 0)
|
||||
_stream << error.locationEnd;
|
||||
_stream << "): ";
|
||||
}
|
||||
_stream << error.message << endl;
|
||||
}
|
||||
}
|
||||
|
||||
string CommonSyntaxTest::errorMessage(Exception const& _e)
|
||||
{
|
||||
if (_e.comment() && !_e.comment()->empty())
|
||||
return boost::replace_all_copy(*_e.comment(), "\n", "\\n");
|
||||
else
|
||||
return "NONE";
|
||||
}
|
||||
|
||||
vector<SyntaxTestError> CommonSyntaxTest::parseExpectations(istream& _stream)
|
||||
{
|
||||
vector<SyntaxTestError> expectations;
|
||||
string line;
|
||||
while (getline(_stream, line))
|
||||
{
|
||||
auto it = line.begin();
|
||||
|
||||
skipSlashes(it, line.end());
|
||||
skipWhitespace(it, line.end());
|
||||
|
||||
if (it == line.end()) continue;
|
||||
|
||||
auto typeBegin = it;
|
||||
while (it != line.end() && *it != ':')
|
||||
++it;
|
||||
string errorType(typeBegin, it);
|
||||
|
||||
// skip colon
|
||||
if (it != line.end()) it++;
|
||||
|
||||
skipWhitespace(it, line.end());
|
||||
|
||||
int locationStart = -1;
|
||||
int locationEnd = -1;
|
||||
std::string sourceName;
|
||||
|
||||
if (it != line.end() && *it == '(')
|
||||
{
|
||||
++it;
|
||||
if (it != line.end() && !isdigit(*it))
|
||||
{
|
||||
auto sourceNameStart = it;
|
||||
while (it != line.end() && *it != ':')
|
||||
++it;
|
||||
sourceName = std::string(sourceNameStart, it);
|
||||
expect(it, line.end(), ':');
|
||||
}
|
||||
locationStart = parseUnsignedInteger(it, line.end());
|
||||
expect(it, line.end(), '-');
|
||||
locationEnd = parseUnsignedInteger(it, line.end());
|
||||
expect(it, line.end(), ')');
|
||||
expect(it, line.end(), ':');
|
||||
}
|
||||
|
||||
skipWhitespace(it, line.end());
|
||||
|
||||
string errorMessage(it, line.end());
|
||||
expectations.emplace_back(SyntaxTestError{
|
||||
move(errorType),
|
||||
move(errorMessage),
|
||||
move(sourceName),
|
||||
locationStart,
|
||||
locationEnd
|
||||
});
|
||||
}
|
||||
return expectations;
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
This file is part of solidity.
|
||||
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <test/libsolidity/AnalysisFramework.h>
|
||||
#include <test/TestCase.h>
|
||||
#include <liblangutil/Exceptions.h>
|
||||
#include <libsolutil/AnsiColorized.h>
|
||||
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
|
||||
namespace solidity::test
|
||||
{
|
||||
|
||||
struct SyntaxTestError
|
||||
{
|
||||
std::string type;
|
||||
std::string message;
|
||||
std::string sourceName;
|
||||
int locationStart = -1;
|
||||
int locationEnd = -1;
|
||||
bool operator==(SyntaxTestError const& _rhs) const
|
||||
{
|
||||
return type == _rhs.type &&
|
||||
message == _rhs.message &&
|
||||
sourceName == _rhs.sourceName &&
|
||||
locationStart == _rhs.locationStart &&
|
||||
locationEnd == _rhs.locationEnd;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class CommonSyntaxTest: public frontend::test::EVMVersionRestrictedTestCase
|
||||
{
|
||||
public:
|
||||
CommonSyntaxTest(std::string const& _filename, langutil::EVMVersion _evmVersion);
|
||||
|
||||
TestResult run(std::ostream& _stream, std::string const& _linePrefix = "", bool _formatted = false) override;
|
||||
|
||||
void printSource(std::ostream& _stream, std::string const &_linePrefix = "", bool _formatted = false) const override;
|
||||
void printUpdatedExpectations(std::ostream& _stream, std::string const& _linePrefix) const override
|
||||
{
|
||||
if (!m_errorList.empty())
|
||||
printErrorList(_stream, m_errorList, _linePrefix, false);
|
||||
}
|
||||
|
||||
static std::string errorMessage(util::Exception const& _e);
|
||||
protected:
|
||||
virtual void parseAndAnalyze() = 0;
|
||||
|
||||
static void printErrorList(
|
||||
std::ostream& _stream,
|
||||
std::vector<SyntaxTestError> const& _errors,
|
||||
std::string const& _linePrefix,
|
||||
bool _formatted = false
|
||||
);
|
||||
|
||||
virtual bool printExpectationAndError(std::ostream& _stream, std::string const& _linePrefix = "", bool _formatted = false);
|
||||
|
||||
static std::vector<SyntaxTestError> parseExpectations(std::istream& _stream);
|
||||
|
||||
std::map<std::string, std::string> m_sources;
|
||||
std::vector<SyntaxTestError> m_expectations;
|
||||
std::vector<SyntaxTestError> m_errorList;
|
||||
langutil::EVMVersion const m_evmVersion;
|
||||
};
|
||||
|
||||
}
|
||||
+23
-2
@@ -172,6 +172,28 @@ evmc::result EVMHost::call(evmc_message const& _message) noexcept
|
||||
message.destination = convertToEVMC(createAddress);
|
||||
code = evmc::bytes(message.input_data, message.input_data + message.input_size);
|
||||
}
|
||||
else if (message.kind == EVMC_CREATE2)
|
||||
{
|
||||
Address createAddress(keccak256(
|
||||
bytes(1, 0xff) +
|
||||
bytes(begin(message.sender.bytes), end(message.sender.bytes)) +
|
||||
bytes(begin(message.create2_salt.bytes), end(message.create2_salt.bytes)) +
|
||||
keccak256(bytes(message.input_data, message.input_data + message.input_size)).asBytes()
|
||||
));
|
||||
message.destination = convertToEVMC(createAddress);
|
||||
if (accounts.count(message.destination) && (
|
||||
accounts[message.destination].nonce > 0 ||
|
||||
!accounts[message.destination].code.empty()
|
||||
))
|
||||
{
|
||||
evmc::result result({});
|
||||
result.status_code = EVMC_OUT_OF_GAS;
|
||||
accounts = stateBackup;
|
||||
return result;
|
||||
}
|
||||
|
||||
code = evmc::bytes(message.input_data, message.input_data + message.input_size);
|
||||
}
|
||||
else if (message.kind == EVMC_DELEGATECALL)
|
||||
{
|
||||
code = accounts[message.destination].code;
|
||||
@@ -184,7 +206,6 @@ evmc::result EVMHost::call(evmc_message const& _message) noexcept
|
||||
}
|
||||
else
|
||||
code = accounts[message.destination].code;
|
||||
//TODO CREATE2
|
||||
|
||||
auto& destination = accounts[message.destination];
|
||||
|
||||
@@ -199,7 +220,7 @@ evmc::result EVMHost::call(evmc_message const& _message) noexcept
|
||||
evmc::result result = m_vm.execute(*this, m_evmRevision, message, code.data(), code.size());
|
||||
m_currentAddress = currentAddress;
|
||||
|
||||
if (message.kind == EVMC_CREATE)
|
||||
if (message.kind == EVMC_CREATE || message.kind == EVMC_CREATE2)
|
||||
{
|
||||
result.gas_left -= evmasm::GasCosts::createDataGas * result.output_size;
|
||||
if (result.gas_left < 0)
|
||||
|
||||
@@ -39,19 +39,19 @@ using namespace solidity::util;
|
||||
using namespace solidity::test;
|
||||
|
||||
ExecutionFramework::ExecutionFramework():
|
||||
ExecutionFramework(solidity::test::Options::get().evmVersion())
|
||||
ExecutionFramework(solidity::test::CommonOptions::get().evmVersion())
|
||||
{
|
||||
}
|
||||
|
||||
ExecutionFramework::ExecutionFramework(langutil::EVMVersion _evmVersion):
|
||||
m_evmVersion(_evmVersion),
|
||||
m_optimiserSettings(solidity::frontend::OptimiserSettings::minimal()),
|
||||
m_showMessages(solidity::test::Options::get().showMessages),
|
||||
m_showMessages(solidity::test::CommonOptions::get().showMessages),
|
||||
m_evmHost(make_shared<EVMHost>(m_evmVersion))
|
||||
{
|
||||
if (solidity::test::Options::get().optimizeYul)
|
||||
if (solidity::test::CommonOptions::get().optimizeYul)
|
||||
m_optimiserSettings = solidity::frontend::OptimiserSettings::full();
|
||||
else if (solidity::test::Options::get().optimize)
|
||||
else if (solidity::test::CommonOptions::get().optimize)
|
||||
m_optimiserSettings = solidity::frontend::OptimiserSettings::standard();
|
||||
m_evmHost->reset();
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <test/Options.h>
|
||||
#include <test/Common.h>
|
||||
|
||||
#include <libsolidity/interface/OptimiserSettings.h>
|
||||
#include <libsolidity/interface/DebugSettings.h>
|
||||
@@ -34,6 +34,8 @@
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
namespace solidity::test
|
||||
{
|
||||
class EVMHost;
|
||||
@@ -177,8 +179,8 @@ public:
|
||||
return _padLeft ? padding + _value : _value + padding;
|
||||
}
|
||||
static bytes encode(std::string const& _value) { return encode(util::asBytes(_value), false); }
|
||||
template <class _T>
|
||||
static bytes encode(std::vector<_T> const& _value)
|
||||
template <class T>
|
||||
static bytes encode(std::vector<T> const& _value)
|
||||
{
|
||||
bytes ret;
|
||||
for (auto const& v: _value)
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <test/libyul/YulInterpreterTest.h>
|
||||
#include <test/libyul/ObjectCompilerTest.h>
|
||||
#include <test/libyul/FunctionSideEffects.h>
|
||||
#include <test/libyul/SyntaxTest.h>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
@@ -57,6 +58,7 @@ Testsuite const g_interactiveTestsuites[] = {
|
||||
{"Yul Interpreter", "libyul", "yulInterpreterTests", false, false, &yul::test::YulInterpreterTest::create},
|
||||
{"Yul Object Compiler", "libyul", "objectCompiler", false, false, &yul::test::ObjectCompilerTest::create},
|
||||
{"Function Side Effects","libyul", "functionSideEffects", false, false, &yul::test::FunctionSideEffects::create},
|
||||
{"Yul Syntax", "libyul", "yulSyntaxTests", false, false, &yul::test::SyntaxTest::create},
|
||||
{"Syntax", "libsolidity", "syntaxTests", false, false, &SyntaxTest::create},
|
||||
{"Error Recovery", "libsolidity", "errorRecoveryTests", false, false, &SyntaxTest::createErrorRecovery},
|
||||
{"Semantic", "libsolidity", "semanticTests", false, true, &SemanticTest::create},
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
This file is part of solidity.
|
||||
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/** @file TestHelper.h
|
||||
* @author Marko Simovic <markobarko@gmail.com>
|
||||
* @date 2014
|
||||
*/
|
||||
|
||||
#include <test/Options.h>
|
||||
|
||||
#include <test/Common.h>
|
||||
|
||||
#include <liblangutil/EVMVersion.h>
|
||||
#include <liblangutil/Exceptions.h>
|
||||
|
||||
#include <boost/test/framework.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/program_options.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace solidity::test;
|
||||
namespace fs = boost::filesystem;
|
||||
namespace po = boost::program_options;
|
||||
|
||||
|
||||
Options const& Options::get()
|
||||
{
|
||||
static Options instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
Options::Options()
|
||||
{
|
||||
auto const& suite = boost::unit_test::framework::master_test_suite();
|
||||
|
||||
if (suite.argc == 0)
|
||||
return;
|
||||
|
||||
options.add_options()
|
||||
("optimize", po::bool_switch(&optimize), "enables optimization")
|
||||
("optimize-yul", po::bool_switch(&optimizeYul), "enables Yul optimization")
|
||||
("abiencoderv2", po::bool_switch(&useABIEncoderV2), "enables abi encoder v2")
|
||||
("show-messages", po::bool_switch(&showMessages), "enables message output");
|
||||
|
||||
parse(suite.argc, suite.argv);
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
This file is part of solidity.
|
||||
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <liblangutil/EVMVersion.h>
|
||||
#include <test/Common.h>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/program_options.hpp>
|
||||
#include <boost/version.hpp>
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace solidity::test
|
||||
{
|
||||
|
||||
struct Options: CommonOptions
|
||||
{
|
||||
bool showMessages = false;
|
||||
bool useABIEncoderV2 = false;
|
||||
|
||||
static Options const& get();
|
||||
|
||||
private:
|
||||
Options();
|
||||
};
|
||||
|
||||
}
|
||||
+19
-12
@@ -36,7 +36,7 @@
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
#include <test/InteractiveTests.h>
|
||||
#include <test/Options.h>
|
||||
#include <test/Common.h>
|
||||
#include <test/EVMHost.h>
|
||||
#include <test/Common.h>
|
||||
|
||||
@@ -69,7 +69,7 @@ int registerTests(
|
||||
{
|
||||
int numTestsAdded = 0;
|
||||
fs::path fullpath = _basepath / _path;
|
||||
TestCase::Config config{fullpath.string(), solidity::test::Options::get().evmVersion()};
|
||||
TestCase::Config config{fullpath.string(), solidity::test::CommonOptions::get().evmVersion()};
|
||||
if (fs::is_directory(fullpath))
|
||||
{
|
||||
test_suite* sub_suite = BOOST_TEST_SUITE(_path.filename().string());
|
||||
@@ -94,7 +94,7 @@ int registerTests(
|
||||
{
|
||||
stringstream errorStream;
|
||||
auto testCase = _testCaseCreator(config);
|
||||
if (testCase->validateSettings(solidity::test::Options::get().evmVersion()))
|
||||
if (testCase->validateSettings(solidity::test::CommonOptions::get().evmVersion()))
|
||||
switch (testCase->run(errorStream))
|
||||
{
|
||||
case TestCase::TestResult::Success:
|
||||
@@ -121,15 +121,27 @@ int registerTests(
|
||||
}
|
||||
return numTestsAdded;
|
||||
}
|
||||
|
||||
void initializeOptions()
|
||||
{
|
||||
auto const& suite = boost::unit_test::framework::master_test_suite();
|
||||
|
||||
auto options = std::make_unique<solidity::test::CommonOptions>();
|
||||
solAssert(options->parse(suite.argc, suite.argv), "Failed to parse options!");
|
||||
options->validate();
|
||||
|
||||
solidity::test::CommonOptions::setSingleton(std::move(options));
|
||||
}
|
||||
}
|
||||
|
||||
test_suite* init_unit_test_suite( int /*argc*/, char* /*argv*/[] )
|
||||
{
|
||||
master_test_suite_t& master = framework::master_test_suite();
|
||||
master.p_name.value = "SolidityTests";
|
||||
solidity::test::Options::get().validate();
|
||||
|
||||
bool disableSemantics = !solidity::test::EVMHost::getVM(solidity::test::Options::get().evmonePath.string());
|
||||
initializeOptions();
|
||||
|
||||
bool disableSemantics = !solidity::test::EVMHost::getVM(solidity::test::CommonOptions::get().evmonePath.string());
|
||||
if (disableSemantics)
|
||||
{
|
||||
cout << "Unable to find " << solidity::test::evmoneFilename << ". Please provide the path using -- --evmonepath <path>." << endl;
|
||||
@@ -140,7 +152,7 @@ test_suite* init_unit_test_suite( int /*argc*/, char* /*argv*/[] )
|
||||
// Include the interactive tests in the automatic tests as well
|
||||
for (auto const& ts: g_interactiveTestsuites)
|
||||
{
|
||||
auto const& options = solidity::test::Options::get();
|
||||
auto const& options = solidity::test::CommonOptions::get();
|
||||
|
||||
if (ts.smt && options.disableSMT)
|
||||
continue;
|
||||
@@ -164,11 +176,6 @@ test_suite* init_unit_test_suite( int /*argc*/, char* /*argv*/[] )
|
||||
"SolidityAuctionRegistrar",
|
||||
"SolidityFixedFeeRegistrar",
|
||||
"SolidityWallet",
|
||||
#if HAVE_LLL
|
||||
"LLLERC20",
|
||||
"LLLENS",
|
||||
"LLLEndToEndTest",
|
||||
#endif
|
||||
"GasMeterTests",
|
||||
"GasCostTests",
|
||||
"SolidityEndToEndTest",
|
||||
@@ -177,7 +184,7 @@ test_suite* init_unit_test_suite( int /*argc*/, char* /*argv*/[] )
|
||||
removeTestSuite(suite);
|
||||
}
|
||||
|
||||
if (solidity::test::Options::get().disableSMT)
|
||||
if (solidity::test::CommonOptions::get().disableSMT)
|
||||
removeTestSuite("SMTChecker");
|
||||
|
||||
return 0;
|
||||
|
||||
+30
-2
@@ -33,7 +33,19 @@ set -e
|
||||
REPO_ROOT=$(cd $(dirname "$0")/.. && pwd)
|
||||
SOLIDITY_BUILD_DIR=${SOLIDITY_BUILD_DIR:-build}
|
||||
source "${REPO_ROOT}/scripts/common.sh"
|
||||
SOLC="$REPO_ROOT/${SOLIDITY_BUILD_DIR}/solc/solc"
|
||||
|
||||
case "$OSTYPE" in
|
||||
msys)
|
||||
SOLC="$REPO_ROOT/${SOLIDITY_BUILD_DIR}/solc/Release/solc.exe"
|
||||
|
||||
# prevents msys2 path translation for a remapping test
|
||||
export MSYS2_ARG_CONV_EXCL="="
|
||||
;;
|
||||
*)
|
||||
SOLC="$REPO_ROOT/${SOLIDITY_BUILD_DIR}/solc/solc"
|
||||
;;
|
||||
esac
|
||||
|
||||
INTERACTIVE=true
|
||||
if ! tty -s || [ "$CI" ]
|
||||
then
|
||||
@@ -155,6 +167,7 @@ function test_solc_behaviour()
|
||||
rm "$stdout_path.bak"
|
||||
else
|
||||
sed -i.bak -e '/^Warning: This is a pre-release compiler version, please do not use it in production./d' "$stderr_path"
|
||||
sed -i.bak -e 's/\(^[ ]*auxdata: \)0x[0-9a-f]*$/\1AUXDATA REMOVED/' "$stdout_path"
|
||||
sed -i.bak -e 's/ Consider adding "pragma .*$//' "$stderr_path"
|
||||
# Remove trailing empty lines. Needs a line break to make OSX sed happy.
|
||||
sed -i.bak -e '1{/^$/d
|
||||
@@ -395,7 +408,9 @@ printTask "Testing assemble, yul, strict-assembly and optimize..."
|
||||
# Test yul and strict assembly output
|
||||
# Non-empty code results in non-empty binary representation with optimizations turned off,
|
||||
# while it results in empty binary representation with optimizations turned on.
|
||||
test_solc_assembly_output "{ let x:u256 := 0:u256 }" "{ let x:u256 := 0:u256 }" "--yul"
|
||||
test_solc_assembly_output "{ let x:u256 := 0:u256 }" "{ let x := 0 }" "--yul"
|
||||
test_solc_assembly_output "{ let x:u256 := bitnot(7:u256) }" "{ let x := bitnot(7) }" "--yul"
|
||||
test_solc_assembly_output "{ let t:bool := not(true) }" "{ let t:bool := not(true) }" "--yul"
|
||||
test_solc_assembly_output "{ let x := 0 }" "{ let x := 0 }" "--strict-assembly"
|
||||
test_solc_assembly_output "{ let x := 0 }" "{ { } }" "--strict-assembly --optimize"
|
||||
)
|
||||
@@ -437,6 +452,19 @@ SOLTMPDIR=$(mktemp -d)
|
||||
fi
|
||||
)
|
||||
|
||||
printTask "Testing AST import..."
|
||||
SOLTMPDIR=$(mktemp -d)
|
||||
(
|
||||
cd "$SOLTMPDIR"
|
||||
$REPO_ROOT/scripts/ASTImportTest.sh
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
rm -rf "$SOLTMPDIR"
|
||||
exit 1
|
||||
fi
|
||||
)
|
||||
rm -rf "$SOLTMPDIR"
|
||||
|
||||
printTask "Testing soljson via the fuzzer..."
|
||||
SOLTMPDIR=$(mktemp -d)
|
||||
(
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
--evm-version=homestead --import-ast --combined-json ast,compact-format --pretty-json
|
||||
@@ -0,0 +1 @@
|
||||
Failed to import AST: Imported tree evm version differs from configured evm version!
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,117 @@
|
||||
{
|
||||
"contracts":
|
||||
{
|
||||
"test/cmdlineTests/ast_json_import_wrong_evmVersion/input.sol:C": {}
|
||||
},
|
||||
"sourceList":
|
||||
[
|
||||
"test/cmdlineTests/ast_json_import_wrong_evmVersion/input.sol"
|
||||
],
|
||||
"sources":
|
||||
{
|
||||
"test/cmdlineTests/ast_json_import_wrong_evmVersion/input.sol":
|
||||
{
|
||||
"AST":
|
||||
{
|
||||
"absolutePath": "test/cmdlineTests/ast_json_import_wrong_evmVersion/input.sol",
|
||||
"exportedSymbols":
|
||||
{
|
||||
"C":
|
||||
[
|
||||
7
|
||||
]
|
||||
},
|
||||
"id": 8,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes":
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"literals":
|
||||
[
|
||||
"solidity",
|
||||
">=",
|
||||
"0.0"
|
||||
],
|
||||
"nodeType": "PragmaDirective",
|
||||
"src": "0:22:0"
|
||||
},
|
||||
{
|
||||
"abstract": false,
|
||||
"baseContracts": [],
|
||||
"contractDependencies": [],
|
||||
"contractKind": "contract",
|
||||
"documentation": null,
|
||||
"fullyImplemented": true,
|
||||
"id": 7,
|
||||
"linearizedBaseContracts":
|
||||
[
|
||||
7
|
||||
],
|
||||
"name": "C",
|
||||
"nodeType": "ContractDefinition",
|
||||
"nodes":
|
||||
[
|
||||
{
|
||||
"body":
|
||||
{
|
||||
"id": 5,
|
||||
"nodeType": "Block",
|
||||
"src": "65:21:0",
|
||||
"statements":
|
||||
[
|
||||
{
|
||||
"AST":
|
||||
{
|
||||
"nodeType": "YulBlock",
|
||||
"src": "78:2:0",
|
||||
"statements": []
|
||||
},
|
||||
"evmVersion": "istanbul",
|
||||
"externalReferences": [],
|
||||
"id": 4,
|
||||
"nodeType": "InlineAssembly",
|
||||
"src": "69:11:0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"documentation": null,
|
||||
"functionSelector": "26121ff0",
|
||||
"id": 6,
|
||||
"implemented": true,
|
||||
"kind": "function",
|
||||
"modifiers": [],
|
||||
"name": "f",
|
||||
"nodeType": "FunctionDefinition",
|
||||
"overrides": null,
|
||||
"parameters":
|
||||
{
|
||||
"id": 2,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [],
|
||||
"src": "50:2:0"
|
||||
},
|
||||
"returnParameters":
|
||||
{
|
||||
"id": 3,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [],
|
||||
"src": "65:0:0"
|
||||
},
|
||||
"scope": 7,
|
||||
"src": "40:46:0",
|
||||
"stateMutability": "pure",
|
||||
"virtual": false,
|
||||
"visibility": "public"
|
||||
}
|
||||
],
|
||||
"scope": 8,
|
||||
"src": "23:65:0"
|
||||
}
|
||||
],
|
||||
"src": "0:89:0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"version": "0.6.2-develop.2020.1.14+commit.e8556fa1.mod.Linux.g++"
|
||||
}
|
||||
@@ -15,9 +15,9 @@ object "object" {
|
||||
function main()
|
||||
{
|
||||
let _1 := 0
|
||||
mstore_internal(0, _1, _1, _1, _1)
|
||||
mstore_internal(32, _1, _1, _1, 1)
|
||||
eth.storageStore(0, 32)
|
||||
mstore_internal(0:i32, _1, _1, _1, _1)
|
||||
mstore_internal(32:i32, _1, _1, _1, 1)
|
||||
eth.storageStore(0:i32, 32:i32)
|
||||
}
|
||||
function endian_swap_16(x) -> y
|
||||
{
|
||||
@@ -33,19 +33,19 @@ object "object" {
|
||||
let hi := i64.shl(endian_swap_32(x), 32)
|
||||
y := i64.or(hi, endian_swap_32(i64.shr_u(x, 32)))
|
||||
}
|
||||
function mstore_internal(pos, y1, y2, y3, y4)
|
||||
function mstore_internal(pos:i32, y1, y2, y3, y4)
|
||||
{
|
||||
i64.store(pos, endian_swap(y1))
|
||||
i64.store(i64.add(pos, 8), endian_swap(y2))
|
||||
i64.store(i64.add(pos, 16), endian_swap(y3))
|
||||
i64.store(i64.add(pos, 24), endian_swap(y4))
|
||||
i64.store(i32.add(pos, 8:i32), endian_swap(y2))
|
||||
i64.store(i32.add(pos, 16:i32), endian_swap(y3))
|
||||
i64.store(i32.add(pos, 24:i32), endian_swap(y4))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Binary representation:
|
||||
0061736d0100000001160460000060017e017e60057e7e7e7e7e0060027f7f0002190108657468657265756d0c73746f7261676553746f7265000303060500010101020503010001060100071102066d656d6f72790200046d61696e00010ab501052801017e420021004200200020002000200010054220200020002000420110054200a74220a710000b1c01017e20004208864280fe0383200042088842ff018384210120010b1b01027e20001002421086210220022000421088100284210120010b1b01027e20001003422086210220022000422088100384210120010b3501007e2000a720011004370300200042087ca720021004370300200042107ca720031004370300200042187ca7200410043703000b
|
||||
0061736d0100000001160460000060017e017e60057e7e7e7e7e0060027f7f0002190108657468657265756d0c73746f7261676553746f7265000303060500010101020503010001060100071102066d656d6f72790200046d61696e00010abe01052801017e420021004200200020002000200010054220200020002000420110054200a74220a710000b1c01017e20004208864280fe0383200042088842ff018384210120010b1b01027e20001002421086210220022000421088100284210120010b1b01027e20001003422086210220022000422088100384210120010b3e01007e2000a7200110043703002000a74208a76aada7200210043703002000a74210a76aada7200310043703002000a74218a76aada7200410043703000b
|
||||
|
||||
Text representation:
|
||||
(module
|
||||
@@ -96,9 +96,9 @@ Text representation:
|
||||
(param $y3 i64)
|
||||
(param $y4 i64)
|
||||
(i64.store (i32.wrap_i64 (local.get $pos)) (call $endian_swap (local.get $y1)))
|
||||
(i64.store (i32.wrap_i64 (i64.add (local.get $pos) (i64.const 8))) (call $endian_swap (local.get $y2)))
|
||||
(i64.store (i32.wrap_i64 (i64.add (local.get $pos) (i64.const 16))) (call $endian_swap (local.get $y3)))
|
||||
(i64.store (i32.wrap_i64 (i64.add (local.get $pos) (i64.const 24))) (call $endian_swap (local.get $y4)))
|
||||
(i64.store (i32.wrap_i64 (i64.extend_i32_u (i32.add (i32.wrap_i64 (local.get $pos)) (i32.wrap_i64 (i64.const 8))))) (call $endian_swap (local.get $y2)))
|
||||
(i64.store (i32.wrap_i64 (i64.extend_i32_u (i32.add (i32.wrap_i64 (local.get $pos)) (i32.wrap_i64 (i64.const 16))))) (call $endian_swap (local.get $y3)))
|
||||
(i64.store (i32.wrap_i64 (i64.extend_i32_u (i32.add (i32.wrap_i64 (local.get $pos)) (i32.wrap_i64 (i64.const 24))))) (call $endian_swap (local.get $y4)))
|
||||
)
|
||||
|
||||
)
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
--optimize --asm --metadata-hash none
|
||||
@@ -0,0 +1,37 @@
|
||||
pragma solidity >=0.0;
|
||||
|
||||
contract C
|
||||
{
|
||||
constructor() public payable
|
||||
{
|
||||
int a;
|
||||
|
||||
// Can't be optimized due to external reference "a"
|
||||
assembly
|
||||
{
|
||||
let x,y,z
|
||||
|
||||
sstore(0, 1)
|
||||
|
||||
for { } sload(4) { } {
|
||||
z := exp(x, y)
|
||||
}
|
||||
|
||||
a := 2
|
||||
}
|
||||
|
||||
// Can be optimized due to no external references
|
||||
assembly
|
||||
{
|
||||
let x,y,z
|
||||
|
||||
sstore(2, 3)
|
||||
|
||||
for { } sload(5) { } {
|
||||
// Expected to be optimized out for yulOptimizer, but not for
|
||||
// old optimizer
|
||||
z := exp(x, y)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
|
||||
======= optimizer_user_yul/input.sol:C =======
|
||||
EVM assembly:
|
||||
/* "optimizer_user_yul/input.sol":24:489 contract C... */
|
||||
mstore(0x40, 0x80)
|
||||
/* "optimizer_user_yul/input.sol":72:77 int a */
|
||||
0x00
|
||||
/* "optimizer_user_yul/input.sol":38:487 constructor() public payable... */
|
||||
dup1
|
||||
0x00
|
||||
dup1
|
||||
/* "optimizer_user_yul/input.sol":176:177 1 */
|
||||
0x01
|
||||
/* "optimizer_user_yul/input.sol":173:174 0 */
|
||||
0x00
|
||||
/* "optimizer_user_yul/input.sol":166:178 sstore(0, 1) */
|
||||
sstore
|
||||
/* "optimizer_user_yul/input.sol":183:229 for { } sload(4) { } {... */
|
||||
tag_3:
|
||||
/* "optimizer_user_yul/input.sol":197:198 4 */
|
||||
0x04
|
||||
/* "optimizer_user_yul/input.sol":191:199 sload(4) */
|
||||
sload
|
||||
/* "optimizer_user_yul/input.sol":183:229 for { } sload(4) { } {... */
|
||||
iszero
|
||||
tag_5
|
||||
jumpi
|
||||
pop
|
||||
/* "optimizer_user_yul/input.sol":215:224 exp(x, y) */
|
||||
dup1
|
||||
dup3
|
||||
exp
|
||||
/* "optimizer_user_yul/input.sol":183:229 for { } sload(4) { } {... */
|
||||
jump(tag_3)
|
||||
tag_5:
|
||||
/* "optimizer_user_yul/input.sol":187:190 { } */
|
||||
pop
|
||||
pop
|
||||
pop
|
||||
/* "optimizer_user_yul/input.sol":239:240 2 */
|
||||
0x02
|
||||
/* "optimizer_user_yul/input.sol":234:240 a := 2 */
|
||||
swap1
|
||||
pop
|
||||
/* "optimizer_user_yul/input.sol":340:341 3 */
|
||||
0x03
|
||||
/* "optimizer_user_yul/input.sol":337:338 2 */
|
||||
0x02
|
||||
/* "optimizer_user_yul/input.sol":330:342 sstore(2, 3) */
|
||||
sstore
|
||||
/* "optimizer_user_yul/input.sol":347:480 for { } sload(5) { } {... */
|
||||
tag_6:
|
||||
/* "optimizer_user_yul/input.sol":361:362 5 */
|
||||
0x05
|
||||
/* "optimizer_user_yul/input.sol":355:363 sload(5) */
|
||||
sload
|
||||
tag_9
|
||||
jumpi
|
||||
jump(tag_8)
|
||||
tag_9:
|
||||
/* "optimizer_user_yul/input.sol":347:480 for { } sload(5) { } {... */
|
||||
jump(tag_6)
|
||||
tag_8:
|
||||
/* "optimizer_user_yul/input.sol":311:484 {... */
|
||||
pop
|
||||
/* "optimizer_user_yul/input.sol":24:489 contract C... */
|
||||
dataSize(sub_0)
|
||||
dup1
|
||||
dataOffset(sub_0)
|
||||
0x00
|
||||
codecopy
|
||||
0x00
|
||||
return
|
||||
stop
|
||||
|
||||
sub_0: assembly {
|
||||
/* "optimizer_user_yul/input.sol":24:489 contract C... */
|
||||
mstore(0x40, 0x80)
|
||||
/* "--CODEGEN--":12:13 */
|
||||
0x00
|
||||
/* "--CODEGEN--":9:10 */
|
||||
dup1
|
||||
/* "--CODEGEN--":2:14 */
|
||||
revert
|
||||
|
||||
auxdata: AUXDATA REMOVED
|
||||
}
|
||||
@@ -1,10 +1,6 @@
|
||||
{"contracts":{"a.sol":{"A1":{"evm":{"bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}}},"b.sol":{"A1":{"evm":{"bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}}}},"errors":[{"component":"general","formattedMessage":"a.sol:1:1: Warning: Source file does not specify required compiler version!
|
||||
contract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }
|
||||
^---------------------------------------------------------------------------------------------------------------------------------^
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":131,"file":"a.sol","start":0},"type":"Warning"},{"component":"general","formattedMessage":"b.sol:1:1: Warning: Source file does not specify required compiler version!
|
||||
contract A1 { function b(uint x) public { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }
|
||||
^----------------------------------------------------------------------------------------------------------------------------^
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":126,"file":"b.sol","start":0},"type":"Warning"},{"component":"general","formattedMessage":"b.sol:1:15: Warning: Function state mutability can be restricted to pure
|
||||
{"contracts":{"a.sol":{"A1":{"evm":{"bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}}},"b.sol":{"A1":{"evm":{"bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}}}},"errors":[{"component":"general","formattedMessage":"a.sol: Warning: Source file does not specify required compiler version!
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"a.sol","start":-1},"type":"Warning"},{"component":"general","formattedMessage":"b.sol: Warning: Source file does not specify required compiler version!
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"b.sol","start":-1},"type":"Warning"},{"component":"general","formattedMessage":"b.sol:1:15: Warning: Function state mutability can be restricted to pure
|
||||
contract A1 { function b(uint x) public { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }
|
||||
^------------------------------------------^
|
||||
","message":"Function state mutability can be restricted to pure","severity":"warning","sourceLocation":{"end":58,"file":"b.sol","start":14},"type":"Warning"}],"sources":{"a.sol":{"id":0},"b.sol":{"id":1}}}
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
{"contracts":{"a.sol":{"A2":{"evm":{"bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}}}},"errors":[{"component":"general","formattedMessage":"a.sol:1:1: Warning: Source file does not specify required compiler version!
|
||||
contract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }
|
||||
^---------------------------------------------------------------------------------------------------------------------------------^
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":131,"file":"a.sol","start":0},"type":"Warning"},{"component":"general","formattedMessage":"b.sol:1:1: Warning: Source file does not specify required compiler version!
|
||||
contract A1 { function b(uint x) public { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }
|
||||
^----------------------------------------------------------------------------------------------------------------------------^
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":126,"file":"b.sol","start":0},"type":"Warning"},{"component":"general","formattedMessage":"b.sol:1:15: Warning: Function state mutability can be restricted to pure
|
||||
{"contracts":{"a.sol":{"A2":{"evm":{"bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}}}},"errors":[{"component":"general","formattedMessage":"a.sol: Warning: Source file does not specify required compiler version!
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"a.sol","start":-1},"type":"Warning"},{"component":"general","formattedMessage":"b.sol: Warning: Source file does not specify required compiler version!
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"b.sol","start":-1},"type":"Warning"},{"component":"general","formattedMessage":"b.sol:1:15: Warning: Function state mutability can be restricted to pure
|
||||
contract A1 { function b(uint x) public { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }
|
||||
^------------------------------------------^
|
||||
","message":"Function state mutability can be restricted to pure","severity":"warning","sourceLocation":{"end":58,"file":"b.sol","start":14},"type":"Warning"}],"sources":{"a.sol":{"id":0},"b.sol":{"id":1}}}
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
{"errors":[{"component":"general","formattedMessage":"a.sol:1:1: Warning: Source file does not specify required compiler version!
|
||||
contract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }
|
||||
^---------------------------------------------------------------------------------------------------------------------------------^
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":131,"file":"a.sol","start":0},"type":"Warning"},{"component":"general","formattedMessage":"b.sol:1:1: Warning: Source file does not specify required compiler version!
|
||||
contract A1 { function b(uint x) public { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }
|
||||
^----------------------------------------------------------------------------------------------------------------------------^
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":126,"file":"b.sol","start":0},"type":"Warning"},{"component":"general","formattedMessage":"b.sol:1:15: Warning: Function state mutability can be restricted to pure
|
||||
{"errors":[{"component":"general","formattedMessage":"a.sol: Warning: Source file does not specify required compiler version!
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"a.sol","start":-1},"type":"Warning"},{"component":"general","formattedMessage":"b.sol: Warning: Source file does not specify required compiler version!
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"b.sol","start":-1},"type":"Warning"},{"component":"general","formattedMessage":"b.sol:1:15: Warning: Function state mutability can be restricted to pure
|
||||
contract A1 { function b(uint x) public { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }
|
||||
^------------------------------------------^
|
||||
","message":"Function state mutability can be restricted to pure","severity":"warning","sourceLocation":{"end":58,"file":"b.sol","start":14},"type":"Warning"}],"sources":{"a.sol":{"id":0},"b.sol":{"id":1}}}
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
{"contracts":{"a.sol":{"A1":{"evm":{"bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}},"A2":{"evm":{"bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}}},"b.sol":{"A1":{"evm":{"bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}},"B2":{"evm":{"bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}}}},"errors":[{"component":"general","formattedMessage":"a.sol:1:1: Warning: Source file does not specify required compiler version!
|
||||
contract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }
|
||||
^---------------------------------------------------------------------------------------------------------------------------------^
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":131,"file":"a.sol","start":0},"type":"Warning"},{"component":"general","formattedMessage":"b.sol:1:1: Warning: Source file does not specify required compiler version!
|
||||
contract A1 { function b(uint x) public { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }
|
||||
^----------------------------------------------------------------------------------------------------------------------------^
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":126,"file":"b.sol","start":0},"type":"Warning"},{"component":"general","formattedMessage":"b.sol:1:15: Warning: Function state mutability can be restricted to pure
|
||||
{"contracts":{"a.sol":{"A1":{"evm":{"bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}},"A2":{"evm":{"bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}}},"b.sol":{"A1":{"evm":{"bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}},"B2":{"evm":{"bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}}}},"errors":[{"component":"general","formattedMessage":"a.sol: Warning: Source file does not specify required compiler version!
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"a.sol","start":-1},"type":"Warning"},{"component":"general","formattedMessage":"b.sol: Warning: Source file does not specify required compiler version!
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"b.sol","start":-1},"type":"Warning"},{"component":"general","formattedMessage":"b.sol:1:15: Warning: Function state mutability can be restricted to pure
|
||||
contract A1 { function b(uint x) public { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }
|
||||
^------------------------------------------^
|
||||
","message":"Function state mutability can be restricted to pure","severity":"warning","sourceLocation":{"end":58,"file":"b.sol","start":14},"type":"Warning"}],"sources":{"a.sol":{"id":0},"b.sol":{"id":1}}}
|
||||
|
||||
@@ -1,4 +1,2 @@
|
||||
{"contracts":{"a.sol":{"A1":{"evm":{"bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}}}},"errors":[{"component":"general","formattedMessage":"a.sol:1:1: Warning: Source file does not specify required compiler version!
|
||||
contract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }
|
||||
^---------------------------------------------------------------------------------------------------------------------------------^
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":131,"file":"a.sol","start":0},"type":"Warning"}],"sources":{"a.sol":{"id":0},"b.sol":{"id":1}}}
|
||||
{"contracts":{"a.sol":{"A1":{"evm":{"bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}}}},"errors":[{"component":"general","formattedMessage":"a.sol: Warning: Source file does not specify required compiler version!
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"a.sol","start":-1},"type":"Warning"}],"sources":{"a.sol":{"id":0},"b.sol":{"id":1}}}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
{"contracts":{"b.sol":{"B2":{"evm":{"bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}}}},"errors":[{"component":"general","formattedMessage":"b.sol:1:1: Warning: Source file does not specify required compiler version!
|
||||
contract A1 { function b(uint x) public { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }
|
||||
^----------------------------------------------------------------------------------------------------------------------------^
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":126,"file":"b.sol","start":0},"type":"Warning"},{"component":"general","formattedMessage":"b.sol:1:15: Warning: Function state mutability can be restricted to pure
|
||||
{"contracts":{"b.sol":{"B2":{"evm":{"bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}}}},"errors":[{"component":"general","formattedMessage":"b.sol: Warning: Source file does not specify required compiler version!
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"b.sol","start":-1},"type":"Warning"},{"component":"general","formattedMessage":"b.sol:1:15: Warning: Function state mutability can be restricted to pure
|
||||
contract A1 { function b(uint x) public { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }
|
||||
^------------------------------------------^
|
||||
","message":"Function state mutability can be restricted to pure","severity":"warning","sourceLocation":{"end":58,"file":"b.sol","start":14},"type":"Warning"}],"sources":{"a.sol":{"id":0},"b.sol":{"id":1}}}
|
||||
|
||||
@@ -1,4 +1,2 @@
|
||||
{"contracts":{"a.sol":{"A1":{"evm":{"bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}},"A2":{"evm":{"bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}}}},"errors":[{"component":"general","formattedMessage":"a.sol:1:1: Warning: Source file does not specify required compiler version!
|
||||
contract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }
|
||||
^---------------------------------------------------------------------------------------------------------------------------------^
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":131,"file":"a.sol","start":0},"type":"Warning"}],"sources":{"a.sol":{"id":0},"b.sol":{"id":1}}}
|
||||
{"contracts":{"a.sol":{"A1":{"evm":{"bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}},"A2":{"evm":{"bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}}}},"errors":[{"component":"general","formattedMessage":"a.sol: Warning: Source file does not specify required compiler version!
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"a.sol","start":-1},"type":"Warning"}],"sources":{"a.sol":{"id":0},"b.sol":{"id":1}}}
|
||||
|
||||
@@ -16,17 +16,17 @@
|
||||
(local $_2 i64)
|
||||
(local.set $_1 (i64.const 0))
|
||||
(local.set $p (call $u256_to_i32 (local.get $_1) (local.get $_1) (local.get $_1) (i64.const 64)))
|
||||
(local.set $r (i64.add (local.get $p) (i64.const 64)))
|
||||
(if (i64.ne (i64.extend_i32_u (i64.lt_u (local.get $r) (local.get $p))) (i64.const 0)) (then
|
||||
(local.set $r (i64.extend_i32_u (i32.add (i32.wrap_i64 (local.get $p)) (i32.wrap_i64 (i64.const 64)))))
|
||||
(if (i64.ne (i64.extend_i32_u (i32.lt_u (i32.wrap_i64 (local.get $r)) (i32.wrap_i64 (local.get $p)))) (i64.const 0)) (then
|
||||
(unreachable)))
|
||||
(local.set $hi (i64.shl (call $endian_swap_16 (local.get $_1)) (i64.const 16)))
|
||||
(local.set $hi_1 (i64.shl (i64.or (local.get $hi) (call $endian_swap_16 (i64.shr_u (local.get $_1) (i64.const 16)))) (i64.const 32)))
|
||||
(local.set $y (i64.or (local.get $hi_1) (call $endian_swap_32 (i64.shr_u (local.get $_1) (i64.const 32)))))
|
||||
(i64.store (i32.wrap_i64 (local.get $r)) (local.get $y))
|
||||
(i64.store (i32.wrap_i64 (i64.add (local.get $r) (i64.const 8))) (local.get $y))
|
||||
(i64.store (i32.wrap_i64 (i64.add (local.get $r) (i64.const 16))) (local.get $y))
|
||||
(i64.store (i32.wrap_i64 (i64.extend_i32_u (i32.add (i32.wrap_i64 (local.get $r)) (i32.wrap_i64 (i64.const 8))))) (local.get $y))
|
||||
(i64.store (i32.wrap_i64 (i64.extend_i32_u (i32.add (i32.wrap_i64 (local.get $r)) (i32.wrap_i64 (i64.const 16))))) (local.get $y))
|
||||
(local.set $hi_2 (i64.shl (call $endian_swap_32 (i64.const 128)) (i64.const 32)))
|
||||
(i64.store (i32.wrap_i64 (i64.add (local.get $r) (i64.const 24))) (i64.or (local.get $hi_2) (call $endian_swap_32 (i64.shr_u (i64.const 128) (i64.const 32)))))
|
||||
(i64.store (i32.wrap_i64 (i64.extend_i32_u (i32.add (i32.wrap_i64 (local.get $r)) (i32.wrap_i64 (i64.const 24))))) (i64.or (local.get $hi_2) (call $endian_swap_32 (i64.shr_u (i64.const 128) (i64.const 32)))))
|
||||
(local.set $_2 (datasize \"C_2_deployed\"))
|
||||
(call $eth.codeCopy (i32.wrap_i64 (call $to_internal_i32ptr (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1))) (i32.wrap_i64 (call $u256_to_i32 (local.get $_1) (local.get $_1) (local.get $_1) (dataoffset \"C_2_deployed\"))) (i32.wrap_i64 (call $u256_to_i32 (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_2))))
|
||||
(call $eth.finish (i32.wrap_i64 (call $to_internal_i32ptr (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1))) (i32.wrap_i64 (call $u256_to_i32 (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_2))))
|
||||
@@ -39,11 +39,11 @@
|
||||
(param $x4 i64)
|
||||
(result i64)
|
||||
(local $v i64)
|
||||
(if (i64.ne (i64.extend_i32_u (i64.ne (local.get $v) (i64.or (i64.or (local.get $x1) (local.get $x2)) (local.get $x3)))) (i64.const 0)) (then
|
||||
(if (i64.ne (i64.extend_i32_u (i64.ne (i64.const 0) (i64.or (i64.or (local.get $x1) (local.get $x2)) (local.get $x3)))) (i64.const 0)) (then
|
||||
(unreachable)))
|
||||
(if (i64.ne (i64.extend_i32_u (i64.ne (local.get $v) (i64.shr_u (local.get $x4) (i64.const 32)))) (i64.const 0)) (then
|
||||
(if (i64.ne (i64.extend_i32_u (i64.ne (i64.const 0) (i64.shr_u (local.get $x4) (i64.const 32)))) (i64.const 0)) (then
|
||||
(unreachable)))
|
||||
(local.set $v (local.get $x4))
|
||||
(local.set $v (i64.extend_i32_u (i32.wrap_i64 (local.get $x4))))
|
||||
(local.get $v)
|
||||
)
|
||||
|
||||
@@ -56,8 +56,8 @@
|
||||
(local $r i64)
|
||||
(local $p i64)
|
||||
(local.set $p (call $u256_to_i32 (local.get $x1) (local.get $x2) (local.get $x3) (local.get $x4)))
|
||||
(local.set $r (i64.add (local.get $p) (i64.const 64)))
|
||||
(if (i64.ne (i64.extend_i32_u (i64.lt_u (local.get $r) (local.get $p))) (i64.const 0)) (then
|
||||
(local.set $r (i64.extend_i32_u (i32.add (i32.wrap_i64 (local.get $p)) (i32.wrap_i64 (i64.const 64)))))
|
||||
(if (i64.ne (i64.extend_i32_u (i32.lt_u (i32.wrap_i64 (local.get $r)) (i32.wrap_i64 (local.get $p)))) (i64.const 0)) (then
|
||||
(unreachable)))
|
||||
(local.get $r)
|
||||
)
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
0
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"language": "Solidity",
|
||||
"sources":
|
||||
{
|
||||
"":
|
||||
{
|
||||
"content": "pragma solidity >=0.0; import {A} from \".\";"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{"errors":[{"component":"general","formattedMessage":":1:24: DeclarationError: Declaration \"A\" not found in \"\" (referenced as \".\").
|
||||
pragma solidity >=0.0; import {A} from \".\";
|
||||
^------------------^
|
||||
","message":"Declaration \"A\" not found in \"\" (referenced as \".\").","severity":"error","type":"DeclarationError"}],"sources":{}}
|
||||
@@ -14,7 +14,7 @@
|
||||
sstore
|
||||
/* \"A\":0:42 */
|
||||
pop
|
||||
","bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":""}},"ir":"object \"object\" {
|
||||
","bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}},"ir":"object \"object\" {
|
||||
code {
|
||||
let x := mload(0)
|
||||
sstore(add(x, 0), 0)
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
pop
|
||||
stop
|
||||
data_4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45 616263
|
||||
","bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":""}},"ir":"object \"NamedObject\" {
|
||||
","bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}},"ir":"object \"NamedObject\" {
|
||||
code {
|
||||
let x := dataoffset(\"DataName\")
|
||||
sstore(add(x, 0), 0)
|
||||
|
||||
@@ -22,7 +22,7 @@ sub_0: assembly {
|
||||
/* \"A\":137:149 */
|
||||
revert
|
||||
}
|
||||
","bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":""}},"ir":"object \"NamedObject\" {
|
||||
","bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}},"ir":"object \"NamedObject\" {
|
||||
code {
|
||||
let x := dataoffset(\"DataName\")
|
||||
sstore(add(x, 0), 0)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
mload
|
||||
/* \"A\":20:40 */
|
||||
sstore
|
||||
","bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":""}},"ir":"object \"object\" {
|
||||
","bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}},"ir":"object \"object\" {
|
||||
code {
|
||||
let x := mload(0)
|
||||
sstore(add(x, 0), 0)
|
||||
|
||||
@@ -1,4 +1,2 @@
|
||||
{"contracts":{"fileA":{"A":{"storageLayout":{"storage":[{"astId":3,"contract":"fileA:A","label":"s1","offset":0,"slot":"0","type":"t_bytes_storage"},{"astId":5,"contract":"fileA:A","label":"s2","offset":0,"slot":"1","type":"t_bytes_storage"}],"types":{"t_bytes_storage":{"encoding":"bytes","label":"bytes","numberOfBytes":"32"}}}}}},"errors":[{"component":"general","formattedMessage":"fileA:1:1: Warning: Source file does not specify required compiler version!
|
||||
contract A { bytes s1 = \"test\"; bytes s2; }
|
||||
^-----------------------------------------^
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":43,"file":"fileA","start":0},"type":"Warning"}],"sources":{"fileA":{"id":0}}}
|
||||
{"contracts":{"fileA":{"A":{"storageLayout":{"storage":[{"astId":3,"contract":"fileA:A","label":"s1","offset":0,"slot":"0","type":"t_bytes_storage"},{"astId":5,"contract":"fileA:A","label":"s2","offset":0,"slot":"1","type":"t_bytes_storage"}],"types":{"t_bytes_storage":{"encoding":"bytes","label":"bytes","numberOfBytes":"32"}}}}}},"errors":[{"component":"general","formattedMessage":"fileA: Warning: Source file does not specify required compiler version!
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"fileA","start":-1},"type":"Warning"}],"sources":{"fileA":{"id":0}}}
|
||||
|
||||
@@ -1,4 +1,2 @@
|
||||
{"contracts":{"fileA":{"A":{"storageLayout":{"storage":[{"astId":3,"contract":"fileA:A","label":"array1","offset":0,"slot":"0","type":"t_array(t_uint256)dyn_storage"},{"astId":6,"contract":"fileA:A","label":"array2","offset":0,"slot":"1","type":"t_array(t_bool)dyn_storage"}],"types":{"t_array(t_bool)dyn_storage":{"base":"t_bool","encoding":"dynamic_array","label":"bool[]","numberOfBytes":"32"},"t_array(t_uint256)dyn_storage":{"base":"t_uint256","encoding":"dynamic_array","label":"uint256[]","numberOfBytes":"32"},"t_bool":{"encoding":"inplace","label":"bool","numberOfBytes":"1"},"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}}}}},"errors":[{"component":"general","formattedMessage":"fileA:1:1: Warning: Source file does not specify required compiler version!
|
||||
contract A { uint[] array1; bool[] array2; }
|
||||
^------------------------------------------^
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":44,"file":"fileA","start":0},"type":"Warning"}],"sources":{"fileA":{"id":0}}}
|
||||
{"contracts":{"fileA":{"A":{"storageLayout":{"storage":[{"astId":3,"contract":"fileA:A","label":"array1","offset":0,"slot":"0","type":"t_array(t_uint256)dyn_storage"},{"astId":6,"contract":"fileA:A","label":"array2","offset":0,"slot":"1","type":"t_array(t_bool)dyn_storage"}],"types":{"t_array(t_bool)dyn_storage":{"base":"t_bool","encoding":"dynamic_array","label":"bool[]","numberOfBytes":"32"},"t_array(t_uint256)dyn_storage":{"base":"t_uint256","encoding":"dynamic_array","label":"uint256[]","numberOfBytes":"32"},"t_bool":{"encoding":"inplace","label":"bool","numberOfBytes":"1"},"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}}}}},"errors":[{"component":"general","formattedMessage":"fileA: Warning: Source file does not specify required compiler version!
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"fileA","start":-1},"type":"Warning"}],"sources":{"fileA":{"id":0}}}
|
||||
|
||||
@@ -1,4 +1,2 @@
|
||||
{"contracts":{"fileA":{"A":{"storageLayout":{"storage":[{"astId":14,"contract":"fileA:A","label":"x","offset":0,"slot":"0","type":"t_uint256"},{"astId":16,"contract":"fileA:A","label":"y","offset":0,"slot":"1","type":"t_uint256"},{"astId":18,"contract":"fileA:A","label":"s","offset":0,"slot":"2","type":"t_struct(S)12_storage"},{"astId":20,"contract":"fileA:A","label":"addr","offset":0,"slot":"6","type":"t_address"},{"astId":26,"contract":"fileA:A","label":"map","offset":0,"slot":"7","type":"t_mapping(t_uint256,t_mapping(t_address,t_bool))"},{"astId":29,"contract":"fileA:A","label":"array","offset":0,"slot":"8","type":"t_array(t_uint256)dyn_storage"},{"astId":31,"contract":"fileA:A","label":"s1","offset":0,"slot":"9","type":"t_string_storage"},{"astId":33,"contract":"fileA:A","label":"b1","offset":0,"slot":"10","type":"t_bytes_storage"}],"types":{"t_address":{"encoding":"inplace","label":"address","numberOfBytes":"20"},"t_array(t_uint256)2_storage":{"base":"t_uint256","encoding":"inplace","label":"uint256[2]","numberOfBytes":"64"},"t_array(t_uint256)dyn_storage":{"base":"t_uint256","encoding":"dynamic_array","label":"uint256[]","numberOfBytes":"32"},"t_bool":{"encoding":"inplace","label":"bool","numberOfBytes":"1"},"t_bytes_storage":{"encoding":"bytes","label":"bytes","numberOfBytes":"32"},"t_mapping(t_address,t_bool)":{"encoding":"mapping","key":"t_address","label":"mapping(address => bool)","numberOfBytes":"32","value":"t_bool"},"t_mapping(t_uint256,t_mapping(t_address,t_bool))":{"encoding":"mapping","key":"t_uint256","label":"mapping(uint256 => mapping(address => bool))","numberOfBytes":"32","value":"t_mapping(t_address,t_bool)"},"t_string_storage":{"encoding":"bytes","label":"string","numberOfBytes":"32"},"t_struct(S)12_storage":{"encoding":"inplace","label":"struct A.S","members":[{"astId":2,"contract":"fileA:A","label":"a","offset":0,"slot":"0","type":"t_uint128"},{"astId":4,"contract":"fileA:A","label":"b","offset":16,"slot":"0","type":"t_uint128"},{"astId":8,"contract":"fileA:A","label":"staticArray","offset":0,"slot":"1","type":"t_array(t_uint256)2_storage"},{"astId":11,"contract":"fileA:A","label":"dynArray","offset":0,"slot":"3","type":"t_array(t_uint256)dyn_storage"}],"numberOfBytes":"128"},"t_uint128":{"encoding":"inplace","label":"uint128","numberOfBytes":"16"},"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}}}}},"errors":[{"component":"general","formattedMessage":"fileA:1:1: Warning: Source file does not specify required compiler version!
|
||||
contract A { struct S { uint128 a; ... int[] array; string s1; bytes b1; }
|
||||
^-------------------------------------------------------------------------^
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":206,"file":"fileA","start":0},"type":"Warning"}],"sources":{"fileA":{"id":0}}}
|
||||
{"contracts":{"fileA":{"A":{"storageLayout":{"storage":[{"astId":14,"contract":"fileA:A","label":"x","offset":0,"slot":"0","type":"t_uint256"},{"astId":16,"contract":"fileA:A","label":"y","offset":0,"slot":"1","type":"t_uint256"},{"astId":18,"contract":"fileA:A","label":"s","offset":0,"slot":"2","type":"t_struct(S)12_storage"},{"astId":20,"contract":"fileA:A","label":"addr","offset":0,"slot":"6","type":"t_address"},{"astId":26,"contract":"fileA:A","label":"map","offset":0,"slot":"7","type":"t_mapping(t_uint256,t_mapping(t_address,t_bool))"},{"astId":29,"contract":"fileA:A","label":"array","offset":0,"slot":"8","type":"t_array(t_uint256)dyn_storage"},{"astId":31,"contract":"fileA:A","label":"s1","offset":0,"slot":"9","type":"t_string_storage"},{"astId":33,"contract":"fileA:A","label":"b1","offset":0,"slot":"10","type":"t_bytes_storage"}],"types":{"t_address":{"encoding":"inplace","label":"address","numberOfBytes":"20"},"t_array(t_uint256)2_storage":{"base":"t_uint256","encoding":"inplace","label":"uint256[2]","numberOfBytes":"64"},"t_array(t_uint256)dyn_storage":{"base":"t_uint256","encoding":"dynamic_array","label":"uint256[]","numberOfBytes":"32"},"t_bool":{"encoding":"inplace","label":"bool","numberOfBytes":"1"},"t_bytes_storage":{"encoding":"bytes","label":"bytes","numberOfBytes":"32"},"t_mapping(t_address,t_bool)":{"encoding":"mapping","key":"t_address","label":"mapping(address => bool)","numberOfBytes":"32","value":"t_bool"},"t_mapping(t_uint256,t_mapping(t_address,t_bool))":{"encoding":"mapping","key":"t_uint256","label":"mapping(uint256 => mapping(address => bool))","numberOfBytes":"32","value":"t_mapping(t_address,t_bool)"},"t_string_storage":{"encoding":"bytes","label":"string","numberOfBytes":"32"},"t_struct(S)12_storage":{"encoding":"inplace","label":"struct A.S","members":[{"astId":2,"contract":"fileA:A","label":"a","offset":0,"slot":"0","type":"t_uint128"},{"astId":4,"contract":"fileA:A","label":"b","offset":16,"slot":"0","type":"t_uint128"},{"astId":8,"contract":"fileA:A","label":"staticArray","offset":0,"slot":"1","type":"t_array(t_uint256)2_storage"},{"astId":11,"contract":"fileA:A","label":"dynArray","offset":0,"slot":"3","type":"t_array(t_uint256)dyn_storage"}],"numberOfBytes":"128"},"t_uint128":{"encoding":"inplace","label":"uint128","numberOfBytes":"16"},"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}}}}},"errors":[{"component":"general","formattedMessage":"fileA: Warning: Source file does not specify required compiler version!
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"fileA","start":-1},"type":"Warning"}],"sources":{"fileA":{"id":0}}}
|
||||
|
||||
@@ -1,4 +1,2 @@
|
||||
{"contracts":{"fileA":{"A":{"storageLayout":{"storage":[{"astId":2,"contract":"fileA:A","label":"x","offset":0,"slot":"0","type":"t_uint256"},{"astId":4,"contract":"fileA:A","label":"y","offset":0,"slot":"1","type":"t_uint256"},{"astId":10,"contract":"fileA:A","label":"map","offset":0,"slot":"2","type":"t_mapping(t_uint256,t_mapping(t_address,t_bool))"}],"types":{"t_address":{"encoding":"inplace","label":"address","numberOfBytes":"20"},"t_bool":{"encoding":"inplace","label":"bool","numberOfBytes":"1"},"t_mapping(t_address,t_bool)":{"encoding":"mapping","key":"t_address","label":"mapping(address => bool)","numberOfBytes":"32","value":"t_bool"},"t_mapping(t_uint256,t_mapping(t_address,t_bool))":{"encoding":"mapping","key":"t_uint256","label":"mapping(uint256 => mapping(address => bool))","numberOfBytes":"32","value":"t_mapping(t_address,t_bool)"},"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}}}}},"errors":[{"component":"general","formattedMessage":"fileA:1:1: Warning: Source file does not specify required compiler version!
|
||||
contract A { uint x; uint y; mapping (uint => mapping (address => bool)) map; }
|
||||
^-----------------------------------------------------------------------------^
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":79,"file":"fileA","start":0},"type":"Warning"}],"sources":{"fileA":{"id":0}}}
|
||||
{"contracts":{"fileA":{"A":{"storageLayout":{"storage":[{"astId":2,"contract":"fileA:A","label":"x","offset":0,"slot":"0","type":"t_uint256"},{"astId":4,"contract":"fileA:A","label":"y","offset":0,"slot":"1","type":"t_uint256"},{"astId":10,"contract":"fileA:A","label":"map","offset":0,"slot":"2","type":"t_mapping(t_uint256,t_mapping(t_address,t_bool))"}],"types":{"t_address":{"encoding":"inplace","label":"address","numberOfBytes":"20"},"t_bool":{"encoding":"inplace","label":"bool","numberOfBytes":"1"},"t_mapping(t_address,t_bool)":{"encoding":"mapping","key":"t_address","label":"mapping(address => bool)","numberOfBytes":"32","value":"t_bool"},"t_mapping(t_uint256,t_mapping(t_address,t_bool))":{"encoding":"mapping","key":"t_uint256","label":"mapping(uint256 => mapping(address => bool))","numberOfBytes":"32","value":"t_mapping(t_address,t_bool)"},"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}}}}},"errors":[{"component":"general","formattedMessage":"fileA: Warning: Source file does not specify required compiler version!
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"fileA","start":-1},"type":"Warning"}],"sources":{"fileA":{"id":0}}}
|
||||
|
||||
@@ -1,4 +1,2 @@
|
||||
{"contracts":{"fileA":{"A":{"storageLayout":{"storage":[],"types":null}}}},"errors":[{"component":"general","formattedMessage":"fileA:1:1: Warning: Source file does not specify required compiler version!
|
||||
contract A { }
|
||||
^------------^
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":14,"file":"fileA","start":0},"type":"Warning"}],"sources":{"fileA":{"id":0}}}
|
||||
{"contracts":{"fileA":{"A":{"storageLayout":{"storage":[],"types":null}}}},"errors":[{"component":"general","formattedMessage":"fileA: Warning: Source file does not specify required compiler version!
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"fileA","start":-1},"type":"Warning"}],"sources":{"fileA":{"id":0}}}
|
||||
|
||||
@@ -1,4 +1,2 @@
|
||||
{"contracts":{"fileA":{"A":{"storageLayout":{"storage":[],"types":null}}}},"errors":[{"component":"general","formattedMessage":"fileA:1:1: Warning: Source file does not specify required compiler version!
|
||||
contract A { }
|
||||
^------------^
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":14,"file":"fileA","start":0},"type":"Warning"}],"sources":{"fileA":{"id":0},"fileB":{"id":1}}}
|
||||
{"contracts":{"fileA":{"A":{"storageLayout":{"storage":[],"types":null}}}},"errors":[{"component":"general","formattedMessage":"fileA: Warning: Source file does not specify required compiler version!
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"fileA","start":-1},"type":"Warning"}],"sources":{"fileA":{"id":0},"fileB":{"id":1}}}
|
||||
|
||||
@@ -1,4 +1,2 @@
|
||||
{"contracts":{"fileA":{"A":{"storageLayout":{"storage":[{"astId":3,"contract":"fileA:A","label":"s1","offset":0,"slot":"0","type":"t_string_storage"},{"astId":5,"contract":"fileA:A","label":"s2","offset":0,"slot":"1","type":"t_string_storage"}],"types":{"t_string_storage":{"encoding":"bytes","label":"string","numberOfBytes":"32"}}}}}},"errors":[{"component":"general","formattedMessage":"fileA:1:1: Warning: Source file does not specify required compiler version!
|
||||
contract A { string s1 = \"test\"; string s2; }
|
||||
^-------------------------------------------^
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":45,"file":"fileA","start":0},"type":"Warning"}],"sources":{"fileA":{"id":0}}}
|
||||
{"contracts":{"fileA":{"A":{"storageLayout":{"storage":[{"astId":3,"contract":"fileA:A","label":"s1","offset":0,"slot":"0","type":"t_string_storage"},{"astId":5,"contract":"fileA:A","label":"s2","offset":0,"slot":"1","type":"t_string_storage"}],"types":{"t_string_storage":{"encoding":"bytes","label":"string","numberOfBytes":"32"}}}}}},"errors":[{"component":"general","formattedMessage":"fileA: Warning: Source file does not specify required compiler version!
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"fileA","start":-1},"type":"Warning"}],"sources":{"fileA":{"id":0}}}
|
||||
|
||||
@@ -1,4 +1,2 @@
|
||||
{"contracts":{"fileA":{"A":{"storageLayout":{"storage":[{"astId":14,"contract":"fileA:A","label":"x","offset":0,"slot":"0","type":"t_uint256"},{"astId":16,"contract":"fileA:A","label":"y","offset":0,"slot":"1","type":"t_uint256"},{"astId":18,"contract":"fileA:A","label":"s","offset":0,"slot":"2","type":"t_struct(S)12_storage"},{"astId":20,"contract":"fileA:A","label":"addr","offset":0,"slot":"7","type":"t_address"}],"types":{"t_address":{"encoding":"inplace","label":"address","numberOfBytes":"20"},"t_array(t_uint256)2_storage":{"base":"t_uint256","encoding":"inplace","label":"uint256[2]","numberOfBytes":"64"},"t_array(t_uint256)dyn_storage":{"base":"t_uint256","encoding":"dynamic_array","label":"uint256[]","numberOfBytes":"32"},"t_struct(S)12_storage":{"encoding":"inplace","label":"struct A.S","members":[{"astId":2,"contract":"fileA:A","label":"a","offset":0,"slot":"0","type":"t_uint256"},{"astId":4,"contract":"fileA:A","label":"b","offset":0,"slot":"1","type":"t_uint256"},{"astId":8,"contract":"fileA:A","label":"staticArray","offset":0,"slot":"2","type":"t_array(t_uint256)2_storage"},{"astId":11,"contract":"fileA:A","label":"dynArray","offset":0,"slot":"4","type":"t_array(t_uint256)dyn_storage"}],"numberOfBytes":"160"},"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}}}}},"errors":[{"component":"general","formattedMessage":"fileA:1:1: Warning: Source file does not specify required compiler version!
|
||||
contract A { struct S { uint a; uint b; uint[2] staticArray; uint[] dynArray; } uint x; uint y; S s; address addr; }
|
||||
^------------------------------------------------------------------------------------------------------------------^
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":116,"file":"fileA","start":0},"type":"Warning"}],"sources":{"fileA":{"id":0}}}
|
||||
{"contracts":{"fileA":{"A":{"storageLayout":{"storage":[{"astId":14,"contract":"fileA:A","label":"x","offset":0,"slot":"0","type":"t_uint256"},{"astId":16,"contract":"fileA:A","label":"y","offset":0,"slot":"1","type":"t_uint256"},{"astId":18,"contract":"fileA:A","label":"s","offset":0,"slot":"2","type":"t_struct(S)12_storage"},{"astId":20,"contract":"fileA:A","label":"addr","offset":0,"slot":"7","type":"t_address"}],"types":{"t_address":{"encoding":"inplace","label":"address","numberOfBytes":"20"},"t_array(t_uint256)2_storage":{"base":"t_uint256","encoding":"inplace","label":"uint256[2]","numberOfBytes":"64"},"t_array(t_uint256)dyn_storage":{"base":"t_uint256","encoding":"dynamic_array","label":"uint256[]","numberOfBytes":"32"},"t_struct(S)12_storage":{"encoding":"inplace","label":"struct A.S","members":[{"astId":2,"contract":"fileA:A","label":"a","offset":0,"slot":"0","type":"t_uint256"},{"astId":4,"contract":"fileA:A","label":"b","offset":0,"slot":"1","type":"t_uint256"},{"astId":8,"contract":"fileA:A","label":"staticArray","offset":0,"slot":"2","type":"t_array(t_uint256)2_storage"},{"astId":11,"contract":"fileA:A","label":"dynArray","offset":0,"slot":"4","type":"t_array(t_uint256)dyn_storage"}],"numberOfBytes":"160"},"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}}}}},"errors":[{"component":"general","formattedMessage":"fileA: Warning: Source file does not specify required compiler version!
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"fileA","start":-1},"type":"Warning"}],"sources":{"fileA":{"id":0}}}
|
||||
|
||||
@@ -1,4 +1,2 @@
|
||||
{"contracts":{"fileA":{"A":{"storageLayout":{"storage":[{"astId":14,"contract":"fileA:A","label":"x","offset":0,"slot":"0","type":"t_uint256"},{"astId":16,"contract":"fileA:A","label":"y","offset":0,"slot":"1","type":"t_uint256"},{"astId":18,"contract":"fileA:A","label":"s","offset":0,"slot":"2","type":"t_struct(S)12_storage"},{"astId":20,"contract":"fileA:A","label":"addr","offset":0,"slot":"6","type":"t_address"}],"types":{"t_address":{"encoding":"inplace","label":"address","numberOfBytes":"20"},"t_array(t_uint256)2_storage":{"base":"t_uint256","encoding":"inplace","label":"uint256[2]","numberOfBytes":"64"},"t_array(t_uint256)dyn_storage":{"base":"t_uint256","encoding":"dynamic_array","label":"uint256[]","numberOfBytes":"32"},"t_struct(S)12_storage":{"encoding":"inplace","label":"struct A.S","members":[{"astId":2,"contract":"fileA:A","label":"a","offset":0,"slot":"0","type":"t_uint128"},{"astId":4,"contract":"fileA:A","label":"b","offset":16,"slot":"0","type":"t_uint128"},{"astId":8,"contract":"fileA:A","label":"staticArray","offset":0,"slot":"1","type":"t_array(t_uint256)2_storage"},{"astId":11,"contract":"fileA:A","label":"dynArray","offset":0,"slot":"3","type":"t_array(t_uint256)dyn_storage"}],"numberOfBytes":"128"},"t_uint128":{"encoding":"inplace","label":"uint128","numberOfBytes":"16"},"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}}}}},"errors":[{"component":"general","formattedMessage":"fileA:1:1: Warning: Source file does not specify required compiler version!
|
||||
contract A { struct S { uint128 a; uint128 b; uint[2] staticArray; uint[] dynArray; } uint x; uint y; S s; address addr; }
|
||||
^------------------------------------------------------------------------------------------------------------------------^
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":122,"file":"fileA","start":0},"type":"Warning"}],"sources":{"fileA":{"id":0}}}
|
||||
{"contracts":{"fileA":{"A":{"storageLayout":{"storage":[{"astId":14,"contract":"fileA:A","label":"x","offset":0,"slot":"0","type":"t_uint256"},{"astId":16,"contract":"fileA:A","label":"y","offset":0,"slot":"1","type":"t_uint256"},{"astId":18,"contract":"fileA:A","label":"s","offset":0,"slot":"2","type":"t_struct(S)12_storage"},{"astId":20,"contract":"fileA:A","label":"addr","offset":0,"slot":"6","type":"t_address"}],"types":{"t_address":{"encoding":"inplace","label":"address","numberOfBytes":"20"},"t_array(t_uint256)2_storage":{"base":"t_uint256","encoding":"inplace","label":"uint256[2]","numberOfBytes":"64"},"t_array(t_uint256)dyn_storage":{"base":"t_uint256","encoding":"dynamic_array","label":"uint256[]","numberOfBytes":"32"},"t_struct(S)12_storage":{"encoding":"inplace","label":"struct A.S","members":[{"astId":2,"contract":"fileA:A","label":"a","offset":0,"slot":"0","type":"t_uint128"},{"astId":4,"contract":"fileA:A","label":"b","offset":16,"slot":"0","type":"t_uint128"},{"astId":8,"contract":"fileA:A","label":"staticArray","offset":0,"slot":"1","type":"t_array(t_uint256)2_storage"},{"astId":11,"contract":"fileA:A","label":"dynArray","offset":0,"slot":"3","type":"t_array(t_uint256)dyn_storage"}],"numberOfBytes":"128"},"t_uint128":{"encoding":"inplace","label":"uint128","numberOfBytes":"16"},"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}}}}},"errors":[{"component":"general","formattedMessage":"fileA: Warning: Source file does not specify required compiler version!
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"fileA","start":-1},"type":"Warning"}],"sources":{"fileA":{"id":0}}}
|
||||
|
||||
@@ -1,4 +1,2 @@
|
||||
{"contracts":{"fileA":{"A":{"storageLayout":{"storage":[{"astId":2,"contract":"fileA:A","label":"x","offset":0,"slot":"0","type":"t_uint256"},{"astId":4,"contract":"fileA:A","label":"y","offset":0,"slot":"1","type":"t_uint256"},{"astId":6,"contract":"fileA:A","label":"addr","offset":0,"slot":"2","type":"t_address"},{"astId":10,"contract":"fileA:A","label":"array","offset":0,"slot":"3","type":"t_array(t_uint256)2_storage"}],"types":{"t_address":{"encoding":"inplace","label":"address","numberOfBytes":"20"},"t_array(t_uint256)2_storage":{"base":"t_uint256","encoding":"inplace","label":"uint256[2]","numberOfBytes":"64"},"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}}}}},"errors":[{"component":"general","formattedMessage":"fileA:1:1: Warning: Source file does not specify required compiler version!
|
||||
contract A { uint x; uint y; address addr; uint[2] array; }
|
||||
^---------------------------------------------------------^
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":59,"file":"fileA","start":0},"type":"Warning"}],"sources":{"fileA":{"id":0}}}
|
||||
{"contracts":{"fileA":{"A":{"storageLayout":{"storage":[{"astId":2,"contract":"fileA:A","label":"x","offset":0,"slot":"0","type":"t_uint256"},{"astId":4,"contract":"fileA:A","label":"y","offset":0,"slot":"1","type":"t_uint256"},{"astId":6,"contract":"fileA:A","label":"addr","offset":0,"slot":"2","type":"t_address"},{"astId":10,"contract":"fileA:A","label":"array","offset":0,"slot":"3","type":"t_array(t_uint256)2_storage"}],"types":{"t_address":{"encoding":"inplace","label":"address","numberOfBytes":"20"},"t_array(t_uint256)2_storage":{"base":"t_uint256","encoding":"inplace","label":"uint256[2]","numberOfBytes":"64"},"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}}}}},"errors":[{"component":"general","formattedMessage":"fileA: Warning: Source file does not specify required compiler version!
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"fileA","start":-1},"type":"Warning"}],"sources":{"fileA":{"id":0}}}
|
||||
|
||||
@@ -1,4 +1,2 @@
|
||||
{"contracts":{"fileA":{"A":{"storageLayout":{"storage":[{"astId":2,"contract":"fileA:A","label":"x","offset":0,"slot":"0","type":"t_uint64"},{"astId":4,"contract":"fileA:A","label":"y","offset":8,"slot":"0","type":"t_uint128"},{"astId":6,"contract":"fileA:A","label":"z","offset":0,"slot":"1","type":"t_uint128"},{"astId":8,"contract":"fileA:A","label":"addr","offset":0,"slot":"2","type":"t_address"},{"astId":12,"contract":"fileA:A","label":"array","offset":0,"slot":"3","type":"t_array(t_uint256)2_storage"}],"types":{"t_address":{"encoding":"inplace","label":"address","numberOfBytes":"20"},"t_array(t_uint256)2_storage":{"base":"t_uint256","encoding":"inplace","label":"uint256[2]","numberOfBytes":"64"},"t_uint128":{"encoding":"inplace","label":"uint128","numberOfBytes":"16"},"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"},"t_uint64":{"encoding":"inplace","label":"uint64","numberOfBytes":"8"}}}}}},"errors":[{"component":"general","formattedMessage":"fileA:1:1: Warning: Source file does not specify required compiler version!
|
||||
contract A { uint64 x; uint128 y; uint128 z; address addr; uint[2] array; }
|
||||
^-------------------------------------------------------------------------^
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":75,"file":"fileA","start":0},"type":"Warning"}],"sources":{"fileA":{"id":0}}}
|
||||
{"contracts":{"fileA":{"A":{"storageLayout":{"storage":[{"astId":2,"contract":"fileA:A","label":"x","offset":0,"slot":"0","type":"t_uint64"},{"astId":4,"contract":"fileA:A","label":"y","offset":8,"slot":"0","type":"t_uint128"},{"astId":6,"contract":"fileA:A","label":"z","offset":0,"slot":"1","type":"t_uint128"},{"astId":8,"contract":"fileA:A","label":"addr","offset":0,"slot":"2","type":"t_address"},{"astId":12,"contract":"fileA:A","label":"array","offset":0,"slot":"3","type":"t_array(t_uint256)2_storage"}],"types":{"t_address":{"encoding":"inplace","label":"address","numberOfBytes":"20"},"t_array(t_uint256)2_storage":{"base":"t_uint256","encoding":"inplace","label":"uint256[2]","numberOfBytes":"64"},"t_uint128":{"encoding":"inplace","label":"uint128","numberOfBytes":"16"},"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"},"t_uint64":{"encoding":"inplace","label":"uint64","numberOfBytes":"8"}}}}}},"errors":[{"component":"general","formattedMessage":"fileA: Warning: Source file does not specify required compiler version!
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"fileA","start":-1},"type":"Warning"}],"sources":{"fileA":{"id":0}}}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
Error: Documentation tag "@return No value returned" does not contain the name of its return parameter.
|
||||
--> structured_documentation_source_location/input.sol:3:5:
|
||||
|
|
||||
3 | /// @param id Some identifier
|
||||
| ^ (Relevant source part starts here and spans across multiple lines).
|
||||
|
||||
Error: Documentation tag "@return No value returned" does not contain the name of its return parameter.
|
||||
--> structured_documentation_source_location/input.sol:7:5:
|
||||
|
|
||||
7 | /// @return No value returned
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
+5
-3
@@ -1,7 +1,9 @@
|
||||
pragma solidity >= 0.0;
|
||||
abstract contract C {
|
||||
/// @param id Some identifier
|
||||
/// @return No value returned
|
||||
function vote(uint id) public virtual returns (uint value);
|
||||
}
|
||||
// ----
|
||||
// DocstringParsingError: Documentation tag "@return No value returned" does not contain the name of its return parameter.
|
||||
|
||||
/// @return No value returned
|
||||
function unvote(uint id) public virtual returns (uint value);
|
||||
}
|
||||
@@ -1,8 +1,5 @@
|
||||
Warning: Source file does not specify required compiler version!
|
||||
--> too_long_line/input.sol:1:1:
|
||||
|
|
||||
1 | contract C {
|
||||
| ^ (Relevant source part starts here and spans across multiple lines).
|
||||
--> too_long_line/input.sol
|
||||
|
||||
Error: Identifier not found or not unique.
|
||||
--> too_long_line/input.sol:2:164:
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
Warning: Source file does not specify required compiler version!
|
||||
--> too_long_line_both_sides_short/input.sol:1:1:
|
||||
|
|
||||
1 | contract C {
|
||||
| ^ (Relevant source part starts here and spans across multiple lines).
|
||||
--> too_long_line_both_sides_short/input.sol
|
||||
|
||||
Error: Identifier not found or not unique.
|
||||
--> too_long_line_both_sides_short/input.sol:2:15:
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
Warning: Source file does not specify required compiler version!
|
||||
--> too_long_line_edge_in/input.sol:1:1:
|
||||
|
|
||||
1 | contract C {
|
||||
| ^ (Relevant source part starts here and spans across multiple lines).
|
||||
--> too_long_line_edge_in/input.sol
|
||||
|
||||
Error: Identifier not found or not unique.
|
||||
--> too_long_line_edge_in/input.sol:2:36:
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
Warning: Source file does not specify required compiler version!
|
||||
--> too_long_line_edge_out/input.sol:1:1:
|
||||
|
|
||||
1 | contract C {
|
||||
| ^ (Relevant source part starts here and spans across multiple lines).
|
||||
--> too_long_line_edge_out/input.sol
|
||||
|
||||
Error: Identifier not found or not unique.
|
||||
--> too_long_line_edge_out/input.sol:2:37:
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
Warning: Source file does not specify required compiler version!
|
||||
--> too_long_line_left_short/input.sol:1:1:
|
||||
|
|
||||
1 | contract C {
|
||||
| ^ (Relevant source part starts here and spans across multiple lines).
|
||||
--> too_long_line_left_short/input.sol
|
||||
|
||||
Error: Identifier not found or not unique.
|
||||
--> too_long_line_left_short/input.sol:2:15:
|
||||
|
||||
@@ -5,7 +5,4 @@ Error: No visibility specified. Did you intend to add "public"?
|
||||
| ^ (Relevant source part starts here and spans across multiple lines).
|
||||
|
||||
Warning: Source file does not specify required compiler version!
|
||||
--> too_long_line_multiline/input.sol:1:1:
|
||||
|
|
||||
1 | contract C {
|
||||
| ^ (Relevant source part starts here and spans across multiple lines).
|
||||
--> too_long_line_multiline/input.sol
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
Warning: Source file does not specify required compiler version!
|
||||
--> too_long_line_right_short/input.sol:1:1:
|
||||
|
|
||||
1 | contract C {
|
||||
| ^ (Relevant source part starts here and spans across multiple lines).
|
||||
--> too_long_line_right_short/input.sol
|
||||
|
||||
Error: Identifier not found or not unique.
|
||||
--> too_long_line_right_short/input.sol:2:164:
|
||||
|
||||
@@ -34,8 +34,8 @@ object \"C_10\" {
|
||||
|
||||
}
|
||||
|
||||
function fun_f_9() -> vloc__4 {
|
||||
vloc__4 := convert_t_stringliteral_9f0adad0a59b05d2e04a1373342b10b9eb16c57c164c8a3bfcbf46dccee39a21_to_t_string_memory_ptr()
|
||||
function fun_f_9() -> vloc__4_mpos {
|
||||
vloc__4_mpos := convert_t_stringliteral_9f0adad0a59b05d2e04a1373342b10b9eb16c57c164c8a3bfcbf46dccee39a21_to_t_string_memory_ptr()
|
||||
leave
|
||||
|
||||
}
|
||||
@@ -130,8 +130,8 @@ object \"C_10\" {
|
||||
}
|
||||
}
|
||||
|
||||
function fun_f_9() -> vloc__4 {
|
||||
vloc__4 := convert_t_stringliteral_9f0adad0a59b05d2e04a1373342b10b9eb16c57c164c8a3bfcbf46dccee39a21_to_t_string_memory_ptr()
|
||||
function fun_f_9() -> vloc__4_mpos {
|
||||
vloc__4_mpos := convert_t_stringliteral_9f0adad0a59b05d2e04a1373342b10b9eb16c57c164c8a3bfcbf46dccee39a21_to_t_string_memory_ptr()
|
||||
leave
|
||||
|
||||
}
|
||||
|
||||
@@ -38,8 +38,8 @@ object \"C_10\" {
|
||||
|
||||
}
|
||||
|
||||
function fun_f_9() -> vloc__4 {
|
||||
vloc__4 := convert_t_stringliteral_d6604f85ac07e2b33103a620b3d3d75b0473c7214912beded67b9b624d41c571_to_t_string_memory_ptr()
|
||||
function fun_f_9() -> vloc__4_mpos {
|
||||
vloc__4_mpos := convert_t_stringliteral_d6604f85ac07e2b33103a620b3d3d75b0473c7214912beded67b9b624d41c571_to_t_string_memory_ptr()
|
||||
leave
|
||||
|
||||
}
|
||||
@@ -138,8 +138,8 @@ object \"C_10\" {
|
||||
}
|
||||
}
|
||||
|
||||
function fun_f_9() -> vloc__4 {
|
||||
vloc__4 := convert_t_stringliteral_d6604f85ac07e2b33103a620b3d3d75b0473c7214912beded67b9b624d41c571_to_t_string_memory_ptr()
|
||||
function fun_f_9() -> vloc__4_mpos {
|
||||
vloc__4_mpos := convert_t_stringliteral_d6604f85ac07e2b33103a620b3d3d75b0473c7214912beded67b9b624d41c571_to_t_string_memory_ptr()
|
||||
leave
|
||||
|
||||
}
|
||||
|
||||
@@ -159,7 +159,7 @@ BOOST_AUTO_TEST_CASE(reserve)
|
||||
BOOST_REQUIRE(callContractFunctionWithValue("reserve(string)", m_fee + 1, encodeDyn(name[1])) == encodeArgs());
|
||||
BOOST_CHECK(callContractFunction("owner(string)", encodeDyn(name[1])) == encodeArgs(h256(account(0), h256::AlignRight)));
|
||||
BOOST_REQUIRE(callContractFunctionWithValue("reserve(string)", m_fee - 1, encodeDyn(name[2])) == encodeArgs());
|
||||
BOOST_CHECK(callContractFunction("owner(string)", encodeDyn(name[2])) == encodeArgs(h256(0)));
|
||||
BOOST_CHECK(callContractFunction("owner(string)", encodeDyn(name[2])) == encodeArgs(h256{}));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(double_reserve)
|
||||
|
||||
@@ -464,8 +464,8 @@ BOOST_AUTO_TEST_CASE(creation)
|
||||
{
|
||||
deployWallet(200);
|
||||
BOOST_REQUIRE(callContractFunction("isOwner(address)", h256(m_sender, h256::AlignRight)) == encodeArgs(true));
|
||||
bool v2 = solidity::test::Options::get().useABIEncoderV2;
|
||||
BOOST_REQUIRE(callContractFunction("isOwner(address)", ~h256(m_sender, h256::AlignRight)) == (v2 ? encodeArgs() : encodeArgs(false)));
|
||||
bool v2 = solidity::test::CommonOptions::get().useABIEncoderV2;
|
||||
BOOST_REQUIRE(callContractFunction("isOwner(address)", h256(~0)) == (v2 ? encodeArgs() : encodeArgs(false)));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(add_owners)
|
||||
|
||||
@@ -50,12 +50,16 @@ BOOST_AUTO_TEST_SUITE(Assembler)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(all_assembly_items)
|
||||
{
|
||||
map<string, unsigned> indices = {
|
||||
{ "root.asm", 0 },
|
||||
{ "sub.asm", 1 }
|
||||
};
|
||||
Assembly _assembly;
|
||||
auto root_asm = make_shared<CharStream>("", "root.asm");
|
||||
auto root_asm = make_shared<CharStream>("lorem ipsum", "root.asm");
|
||||
_assembly.setSourceLocation({1, 3, root_asm});
|
||||
|
||||
Assembly _subAsm;
|
||||
auto sub_asm = make_shared<CharStream>("", "sub.asm");
|
||||
auto sub_asm = make_shared<CharStream>("lorem ipsum", "sub.asm");
|
||||
_subAsm.setSourceLocation({6, 8, sub_asm});
|
||||
_subAsm.append(Instruction::INVALID);
|
||||
shared_ptr<Assembly> _subAsmPtr = make_shared<Assembly>(_subAsm);
|
||||
@@ -74,8 +78,6 @@ BOOST_AUTO_TEST_CASE(all_assembly_items)
|
||||
_assembly.appendLibraryAddress("someLibrary");
|
||||
// PushTag + Operation
|
||||
_assembly.appendJump(tag);
|
||||
// PushString
|
||||
_assembly.append("Unused feature for pushing string");
|
||||
// PushData
|
||||
_assembly.append(bytes{0x1, 0x2, 0x3, 0x4});
|
||||
// PushSubSize
|
||||
@@ -93,9 +95,8 @@ BOOST_AUTO_TEST_CASE(all_assembly_items)
|
||||
|
||||
BOOST_CHECK_EQUAL(
|
||||
_assembly.assemble().toHex(),
|
||||
"5b6001600220606773__$bf005014d9d0f534b8fcb268bd84c491a2$__"
|
||||
"6000567f556e75736564206665617475726520666f722070757368696e"
|
||||
"6720737472696e605f6001605e73000000000000000000000000000000000000000000fe"
|
||||
"5b6001600220604673__$bf005014d9d0f534b8fcb268bd84c491a2$__"
|
||||
"600056603e6001603d73000000000000000000000000000000000000000000fe"
|
||||
"fe010203044266eeaa"
|
||||
);
|
||||
BOOST_CHECK_EQUAL(
|
||||
@@ -106,7 +107,6 @@ BOOST_AUTO_TEST_CASE(all_assembly_items)
|
||||
" bytecodeSize\n"
|
||||
" linkerSymbol(\"bf005014d9d0f534b8fcb268bd84c491a2380f4acd260d1ccfe9cd8201f7e994\")\n"
|
||||
" jump(tag_1)\n"
|
||||
" data_027497964124140851e8a9992ba16b5c1aaf9730b78d6036c8d65e3bb5ea4c8f\n"
|
||||
" data_a6885b3731702da62e8e4a8f584ac46a7f6822f4e2ba50fba902f67b1588d23b\n"
|
||||
" dataSize(sub_0)\n"
|
||||
" dataOffset(sub_0)\n"
|
||||
@@ -123,23 +123,23 @@ BOOST_AUTO_TEST_CASE(all_assembly_items)
|
||||
"auxdata: 0x4266eeaa\n"
|
||||
);
|
||||
BOOST_CHECK_EQUAL(
|
||||
util::jsonCompactPrint(_assembly.assemblyJSON()),
|
||||
"{\".auxdata\":\"4266eeaa\",\".code\":[{\"begin\":1,\"end\":3,\"name\":\"tag\",\"value\":\"1\"},"
|
||||
"{\"begin\":1,\"end\":3,\"name\":\"JUMPDEST\"},"
|
||||
"{\"begin\":1,\"end\":3,\"name\":\"PUSH\",\"value\":\"1\"},"
|
||||
"{\"begin\":1,\"end\":3,\"name\":\"PUSH\",\"value\":\"2\"},"
|
||||
"{\"begin\":1,\"end\":3,\"name\":\"KECCAK256\"},"
|
||||
"{\"begin\":1,\"end\":3,\"name\":\"PUSHSIZE\"},"
|
||||
"{\"begin\":1,\"end\":3,\"name\":\"PUSHLIB\",\"value\":\"someLibrary\"},"
|
||||
"{\"begin\":1,\"end\":3,\"name\":\"PUSH [tag]\",\"value\":\"1\"},"
|
||||
"{\"begin\":1,\"end\":3,\"name\":\"JUMP\"},"
|
||||
"{\"begin\":1,\"end\":3,\"name\":\"PUSH tag\",\"value\":\"Unused feature for pushing string\"},"
|
||||
"{\"begin\":1,\"end\":3,\"name\":\"PUSH data\",\"value\":\"A6885B3731702DA62E8E4A8F584AC46A7F6822F4E2BA50FBA902F67B1588D23B\"},"
|
||||
"{\"begin\":1,\"end\":3,\"name\":\"PUSH #[$]\",\"value\":\"0000000000000000000000000000000000000000000000000000000000000000\"},"
|
||||
"{\"begin\":1,\"end\":3,\"name\":\"PUSH [$]\",\"value\":\"0000000000000000000000000000000000000000000000000000000000000000\"},"
|
||||
"{\"begin\":1,\"end\":3,\"name\":\"PUSHDEPLOYADDRESS\"},"
|
||||
"{\"begin\":1,\"end\":3,\"name\":\"STOP\"}],"
|
||||
"\".data\":{\"0\":{\".code\":[{\"begin\":6,\"end\":8,\"name\":\"INVALID\"}]},"
|
||||
util::jsonCompactPrint(_assembly.assemblyJSON(indices)),
|
||||
"{\".auxdata\":\"4266eeaa\",\".code\":["
|
||||
"{\"begin\":1,\"end\":3,\"name\":\"tag\",\"source\":0,\"value\":\"1\"},"
|
||||
"{\"begin\":1,\"end\":3,\"name\":\"JUMPDEST\",\"source\":0},"
|
||||
"{\"begin\":1,\"end\":3,\"name\":\"PUSH\",\"source\":0,\"value\":\"1\"},"
|
||||
"{\"begin\":1,\"end\":3,\"name\":\"PUSH\",\"source\":0,\"value\":\"2\"},"
|
||||
"{\"begin\":1,\"end\":3,\"name\":\"KECCAK256\",\"source\":0},"
|
||||
"{\"begin\":1,\"end\":3,\"name\":\"PUSHSIZE\",\"source\":0},"
|
||||
"{\"begin\":1,\"end\":3,\"name\":\"PUSHLIB\",\"source\":0,\"value\":\"someLibrary\"},"
|
||||
"{\"begin\":1,\"end\":3,\"name\":\"PUSH [tag]\",\"source\":0,\"value\":\"1\"},"
|
||||
"{\"begin\":1,\"end\":3,\"name\":\"JUMP\",\"source\":0},"
|
||||
"{\"begin\":1,\"end\":3,\"name\":\"PUSH data\",\"source\":0,\"value\":\"A6885B3731702DA62E8E4A8F584AC46A7F6822F4E2BA50FBA902F67B1588D23B\"},"
|
||||
"{\"begin\":1,\"end\":3,\"name\":\"PUSH #[$]\",\"source\":0,\"value\":\"0000000000000000000000000000000000000000000000000000000000000000\"},"
|
||||
"{\"begin\":1,\"end\":3,\"name\":\"PUSH [$]\",\"source\":0,\"value\":\"0000000000000000000000000000000000000000000000000000000000000000\"},"
|
||||
"{\"begin\":1,\"end\":3,\"name\":\"PUSHDEPLOYADDRESS\",\"source\":0},"
|
||||
"{\"begin\":1,\"end\":3,\"name\":\"STOP\",\"source\":0}"
|
||||
"],\".data\":{\"0\":{\".code\":[{\"begin\":6,\"end\":8,\"name\":\"INVALID\",\"source\":1}]},"
|
||||
"\"A6885B3731702DA62E8E4A8F584AC46A7F6822F4E2BA50FBA902F67B1588D23B\":\"01020304\"}}"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
* Tests for the Solidity optimizer.
|
||||
*/
|
||||
|
||||
#include <test/Options.h>
|
||||
#include <test/Common.h>
|
||||
|
||||
#include <libevmasm/CommonSubexpressionEliminator.h>
|
||||
#include <libevmasm/PeepholeOptimiser.h>
|
||||
@@ -72,7 +72,7 @@ namespace
|
||||
|
||||
for (AssemblyItem const& item: output)
|
||||
{
|
||||
BOOST_CHECK(item == Instruction::POP || !item.location().isEmpty());
|
||||
BOOST_CHECK(item == Instruction::POP || item.location().isValid());
|
||||
}
|
||||
return output;
|
||||
}
|
||||
@@ -236,7 +236,7 @@ BOOST_AUTO_TEST_CASE(cse_associativity2)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(cse_double_shift_right_overflow)
|
||||
{
|
||||
if (solidity::test::Options::get().evmVersion().hasBitwiseShifting())
|
||||
if (solidity::test::CommonOptions::get().evmVersion().hasBitwiseShifting())
|
||||
{
|
||||
AssemblyItems input{
|
||||
Instruction::CALLVALUE,
|
||||
@@ -251,7 +251,7 @@ BOOST_AUTO_TEST_CASE(cse_double_shift_right_overflow)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(cse_double_shift_left_overflow)
|
||||
{
|
||||
if (solidity::test::Options::get().evmVersion().hasBitwiseShifting())
|
||||
if (solidity::test::CommonOptions::get().evmVersion().hasBitwiseShifting())
|
||||
{
|
||||
AssemblyItems input{
|
||||
Instruction::DUP1,
|
||||
@@ -1132,7 +1132,7 @@ BOOST_AUTO_TEST_CASE(jumpdest_removal_subassemblies)
|
||||
main.append(t1.toSubAssemblyTag(subId));
|
||||
main.append(u256(8));
|
||||
|
||||
main.optimise(true, solidity::test::Options::get().evmVersion(), false, 200);
|
||||
main.optimise(true, solidity::test::CommonOptions::get().evmVersion(), false, 200);
|
||||
|
||||
AssemblyItems expectationMain{
|
||||
AssemblyItem(PushSubSize, 0),
|
||||
@@ -1178,7 +1178,7 @@ BOOST_AUTO_TEST_CASE(cse_sub_zero)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(cse_remove_redundant_shift_masking)
|
||||
{
|
||||
if (!solidity::test::Options::get().evmVersion().hasBitwiseShifting())
|
||||
if (!solidity::test::CommonOptions::get().evmVersion().hasBitwiseShifting())
|
||||
return;
|
||||
|
||||
for (int i = 1; i < 256; i++)
|
||||
@@ -1326,7 +1326,7 @@ BOOST_AUTO_TEST_CASE(cse_remove_unwanted_masking_of_address)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(cse_replace_too_large_shift)
|
||||
{
|
||||
if (!solidity::test::Options::get().evmVersion().hasBitwiseShifting())
|
||||
if (!solidity::test::CommonOptions::get().evmVersion().hasBitwiseShifting())
|
||||
return;
|
||||
|
||||
checkCSE({
|
||||
|
||||
@@ -23,7 +23,9 @@
|
||||
#include <liblangutil/CharStream.h>
|
||||
#include <liblangutil/Exceptions.h>
|
||||
|
||||
#include <test/Options.h>
|
||||
#include <test/Common.h>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
namespace solidity::langutil::test
|
||||
{
|
||||
|
||||
@@ -22,7 +22,9 @@
|
||||
|
||||
#include <liblangutil/SourceLocation.h>
|
||||
|
||||
#include <test/Options.h>
|
||||
#include <test/Common.h>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
namespace solidity::langutil::test
|
||||
{
|
||||
@@ -31,9 +33,9 @@ BOOST_AUTO_TEST_SUITE(SourceLocationTest)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_fail)
|
||||
{
|
||||
auto const source = std::make_shared<CharStream>("", "source");
|
||||
auto const sourceA = std::make_shared<CharStream>("", "sourceA");
|
||||
auto const sourceB = std::make_shared<CharStream>("", "sourceB");
|
||||
auto const source = std::make_shared<CharStream>("lorem ipsum", "source");
|
||||
auto const sourceA = std::make_shared<CharStream>("lorem ipsum", "sourceA");
|
||||
auto const sourceB = std::make_shared<CharStream>("lorem ipsum", "sourceB");
|
||||
|
||||
BOOST_CHECK(SourceLocation{} == SourceLocation{});
|
||||
BOOST_CHECK((SourceLocation{0, 3, sourceA} != SourceLocation{0, 3, sourceB}));
|
||||
|
||||
@@ -1,670 +0,0 @@
|
||||
/*
|
||||
This file is part of solidity.
|
||||
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Alex Beregszaszi
|
||||
* @date 2017
|
||||
* Unit tests for the LLL compiler.
|
||||
*/
|
||||
|
||||
#include <test/Options.h>
|
||||
|
||||
#include <libsolutil/FixedHash.h>
|
||||
|
||||
#include <liblll/Compiler.h>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
using namespace std;
|
||||
using namespace solidity::util;
|
||||
|
||||
namespace solidity::lll::test
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
bool successCompile(string const& _sourceCode)
|
||||
{
|
||||
vector<string> errors;
|
||||
bytes bytecode = lll::compileLLL(_sourceCode, solidity::test::Options::get().evmVersion(), false, &errors);
|
||||
if (!errors.empty())
|
||||
return false;
|
||||
if (bytecode.empty())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(LLLCompiler)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(smoke_test)
|
||||
{
|
||||
char const* sourceCode = "1";
|
||||
BOOST_CHECK(successCompile(sourceCode));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(switch_valid)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
(switch (origin))
|
||||
)";
|
||||
BOOST_CHECK(successCompile(sourceCode));
|
||||
sourceCode = R"(
|
||||
(switch
|
||||
1 (panic)
|
||||
2 (panic))
|
||||
)";
|
||||
BOOST_CHECK(successCompile(sourceCode));
|
||||
sourceCode = R"(
|
||||
(switch
|
||||
1 (panic)
|
||||
2 (panic)
|
||||
(panic))
|
||||
)";
|
||||
BOOST_CHECK(successCompile(sourceCode));
|
||||
sourceCode = R"(
|
||||
(switch
|
||||
1 (origin)
|
||||
2 (origin)
|
||||
(origin))
|
||||
)";
|
||||
BOOST_CHECK(successCompile(sourceCode));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(switch_invalid_arg_count)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
(switch)
|
||||
)";
|
||||
BOOST_CHECK(!successCompile(sourceCode));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(switch_inconsistent_return_count)
|
||||
{
|
||||
// cannot return stack items if the default case is not present
|
||||
char const* sourceCode = R"(
|
||||
(switch
|
||||
1 (origin)
|
||||
2 (origin)
|
||||
)";
|
||||
BOOST_CHECK(!successCompile(sourceCode));
|
||||
// return count mismatch
|
||||
sourceCode = R"(
|
||||
(switch
|
||||
1 (origin)
|
||||
2 (origin)
|
||||
(panic))
|
||||
)";
|
||||
BOOST_CHECK(!successCompile(sourceCode));
|
||||
// return count mismatch
|
||||
sourceCode = R"(
|
||||
(switch
|
||||
1 (panic)
|
||||
2 (panic)
|
||||
(origin))
|
||||
)";
|
||||
BOOST_CHECK(!successCompile(sourceCode));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(disallowed_asm_instructions)
|
||||
{
|
||||
for (unsigned i = 1; i <= 32; i++)
|
||||
BOOST_CHECK(!successCompile("(asm PUSH" + to_string(i) + ")"));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(disallowed_functional_asm_instructions)
|
||||
{
|
||||
for (unsigned i = 1; i <= 32; i++)
|
||||
BOOST_CHECK(!successCompile("(PUSH" + to_string(i) + ")"));
|
||||
for (unsigned i = 1; i <= 16; i++)
|
||||
BOOST_CHECK(!successCompile("(DUP" + to_string(i) + ")"));
|
||||
for (unsigned i = 1; i <= 16; i++)
|
||||
BOOST_CHECK(!successCompile("(SWAP" + to_string(i) + ")"));
|
||||
BOOST_CHECK(!successCompile("(JUMPDEST)"));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(valid_opcodes_functional)
|
||||
{
|
||||
vector<string> opcodes_bytecode {
|
||||
"0000",
|
||||
"600060000100",
|
||||
"600060000200",
|
||||
"600060000300",
|
||||
"600060000400",
|
||||
"600060000500",
|
||||
"600060000600",
|
||||
"600060000700",
|
||||
"6000600060000800",
|
||||
"6000600060000900",
|
||||
"600060000a00",
|
||||
"600060000b00",
|
||||
"600060001000",
|
||||
"600060001100",
|
||||
"600060001200",
|
||||
"600060001300",
|
||||
"600060001400",
|
||||
"60001500",
|
||||
"600060001600",
|
||||
"600060001700",
|
||||
"600060001800",
|
||||
"60001900",
|
||||
"600060001a00",
|
||||
"600060002000",
|
||||
"3000",
|
||||
"60003100",
|
||||
"3200",
|
||||
"3300",
|
||||
"3400",
|
||||
"60003500",
|
||||
"3600",
|
||||
"6000600060003700",
|
||||
"3800",
|
||||
"6000600060003900",
|
||||
"3a00",
|
||||
"60003b00",
|
||||
"60006000600060003c00",
|
||||
"3d00",
|
||||
"6000600060003e00",
|
||||
"60003f00",
|
||||
"60004000",
|
||||
"4100",
|
||||
"4200",
|
||||
"4300",
|
||||
"4400",
|
||||
"4500",
|
||||
"4600",
|
||||
"4700",
|
||||
"60005000",
|
||||
"60005100",
|
||||
"600060005200",
|
||||
"600060005300",
|
||||
"60005400",
|
||||
"600060005500",
|
||||
"60005600",
|
||||
"600060005700",
|
||||
"5800",
|
||||
"5900",
|
||||
"5a00",
|
||||
"60ff00",
|
||||
"61ffff00",
|
||||
"62ffffff00",
|
||||
"63ffffffff00",
|
||||
"64ffffffffff00",
|
||||
"65ffffffffffff00",
|
||||
"66ffffffffffffff00",
|
||||
"67ffffffffffffffff00",
|
||||
"68ffffffffffffffffff00",
|
||||
"69ffffffffffffffffffff00",
|
||||
"6affffffffffffffffffffff00",
|
||||
"6bffffffffffffffffffffffff00",
|
||||
"6cffffffffffffffffffffffffff00",
|
||||
"6dffffffffffffffffffffffffffff00",
|
||||
"6effffffffffffffffffffffffffffff00",
|
||||
"6fffffffffffffffffffffffffffffffff00",
|
||||
"70ffffffffffffffffffffffffffffffffff00",
|
||||
"71ffffffffffffffffffffffffffffffffffff00",
|
||||
"72ffffffffffffffffffffffffffffffffffffff00",
|
||||
"73ffffffffffffffffffffffffffffffffffffffff00",
|
||||
"74ffffffffffffffffffffffffffffffffffffffffff00",
|
||||
"75ffffffffffffffffffffffffffffffffffffffffffff00",
|
||||
"76ffffffffffffffffffffffffffffffffffffffffffffff00",
|
||||
"77ffffffffffffffffffffffffffffffffffffffffffffffff00",
|
||||
"78ffffffffffffffffffffffffffffffffffffffffffffffffff00",
|
||||
"79ffffffffffffffffffffffffffffffffffffffffffffffffffff00",
|
||||
"7affffffffffffffffffffffffffffffffffffffffffffffffffffff00",
|
||||
"7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff00",
|
||||
"7cffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00",
|
||||
"7dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00",
|
||||
"7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00",
|
||||
"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00",
|
||||
"60006000a000",
|
||||
"600060006000a100",
|
||||
"6000600060006000a200",
|
||||
"60006000600060006000a300",
|
||||
"600060006000600060006000a400",
|
||||
"600060006000f000",
|
||||
"6000600060006000600060006000f100",
|
||||
"6000600060006000600060006000f200",
|
||||
"60006000f300",
|
||||
"600060006000600060006000f400",
|
||||
"600060006000600060006000fa00",
|
||||
"60006000fd00",
|
||||
"fe00",
|
||||
"6000ff00"
|
||||
};
|
||||
|
||||
vector<string> opcodes_lll {
|
||||
"(STOP)",
|
||||
"(ADD 0 0)",
|
||||
"(MUL 0 0)",
|
||||
"(SUB 0 0)",
|
||||
"(DIV 0 0)",
|
||||
"(SDIV 0 0)",
|
||||
"(MOD 0 0)",
|
||||
"(SMOD 0 0)",
|
||||
"(ADDMOD 0 0 0)",
|
||||
"(MULMOD 0 0 0)",
|
||||
"(EXP 0 0)",
|
||||
"(SIGNEXTEND 0 0)",
|
||||
"(LT 0 0)",
|
||||
"(GT 0 0)",
|
||||
"(SLT 0 0)",
|
||||
"(SGT 0 0)",
|
||||
"(EQ 0 0)",
|
||||
"(ISZERO 0)",
|
||||
"(AND 0 0)",
|
||||
"(OR 0 0)",
|
||||
"(XOR 0 0)",
|
||||
"(NOT 0)",
|
||||
"(BYTE 0 0)",
|
||||
"(KECCAK256 0 0)",
|
||||
"(ADDRESS)",
|
||||
"(BALANCE 0)",
|
||||
"(ORIGIN)",
|
||||
"(CALLER)",
|
||||
"(CALLVALUE)",
|
||||
"(CALLDATALOAD 0)",
|
||||
"(CALLDATASIZE)",
|
||||
"(CALLDATACOPY 0 0 0)",
|
||||
"(CODESIZE)",
|
||||
"(CODECOPY 0 0 0)",
|
||||
"(GASPRICE)",
|
||||
"(EXTCODESIZE 0)",
|
||||
"(EXTCODECOPY 0 0 0 0)",
|
||||
"(RETURNDATASIZE)",
|
||||
"(RETURNDATACOPY 0 0 0)",
|
||||
"(EXTCODEHASH 0)",
|
||||
"(BLOCKHASH 0)",
|
||||
"(COINBASE)",
|
||||
"(TIMESTAMP)",
|
||||
"(NUMBER)",
|
||||
"(DIFFICULTY)",
|
||||
"(GASLIMIT)",
|
||||
"(CHAINID)",
|
||||
"(SELFBALANCE)",
|
||||
"(POP 0)",
|
||||
"(MLOAD 0)",
|
||||
"(MSTORE 0 0)",
|
||||
"(MSTORE8 0 0)",
|
||||
"(SLOAD 0)",
|
||||
"(SSTORE 0 0)",
|
||||
"(JUMP 0)",
|
||||
"(JUMPI 0 0)",
|
||||
"(PC)",
|
||||
"(MSIZE)",
|
||||
"(GAS)",
|
||||
"0xff",
|
||||
"0xffff",
|
||||
"0xffffff",
|
||||
"0xffffffff",
|
||||
"0xffffffffff",
|
||||
"0xffffffffffff",
|
||||
"0xffffffffffffff",
|
||||
"0xffffffffffffffff",
|
||||
"0xffffffffffffffffff",
|
||||
"0xffffffffffffffffffff",
|
||||
"0xffffffffffffffffffffff",
|
||||
"0xffffffffffffffffffffffff",
|
||||
"0xffffffffffffffffffffffffff",
|
||||
"0xffffffffffffffffffffffffffff",
|
||||
"0xffffffffffffffffffffffffffffff",
|
||||
"0xffffffffffffffffffffffffffffffff",
|
||||
"0xffffffffffffffffffffffffffffffffff",
|
||||
"0xffffffffffffffffffffffffffffffffffff",
|
||||
"0xffffffffffffffffffffffffffffffffffffff",
|
||||
"0xffffffffffffffffffffffffffffffffffffffff",
|
||||
"0xffffffffffffffffffffffffffffffffffffffffff",
|
||||
"0xffffffffffffffffffffffffffffffffffffffffffff",
|
||||
"0xffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
"0xffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
"0xffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
"0xffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
"0xffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
"(LOG0 0 0)",
|
||||
"(LOG1 0 0 0)",
|
||||
"(LOG2 0 0 0 0)",
|
||||
"(LOG3 0 0 0 0 0)",
|
||||
"(LOG4 0 0 0 0 0 0)",
|
||||
"(CREATE 0 0 0)",
|
||||
"(CALL 0 0 0 0 0 0 0)",
|
||||
"(CALLCODE 0 0 0 0 0 0 0)",
|
||||
"(RETURN 0 0)",
|
||||
"(DELEGATECALL 0 0 0 0 0 0)",
|
||||
"(STATICCALL 0 0 0 0 0 0)",
|
||||
"(REVERT 0 0)",
|
||||
"(INVALID)",
|
||||
"(SELFDESTRUCT 0)"
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < opcodes_bytecode.size(); i++)
|
||||
{
|
||||
vector<string> errors;
|
||||
bytes code = lll::compileLLL(opcodes_lll[i], solidity::test::Options::get().evmVersion(), false, &errors);
|
||||
|
||||
BOOST_REQUIRE_MESSAGE(errors.empty(), opcodes_lll[i]);
|
||||
|
||||
BOOST_CHECK_EQUAL(toHex(code), opcodes_bytecode[i]);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(valid_opcodes_asm)
|
||||
{
|
||||
vector<string> opcodes_bytecode {
|
||||
"0000",
|
||||
"600060000100",
|
||||
"600060000200",
|
||||
"600060000300",
|
||||
"600060000400",
|
||||
"600060000500",
|
||||
"600060000600",
|
||||
"600060000700",
|
||||
"6000600060000800",
|
||||
"6000600060000900",
|
||||
"600060000a00",
|
||||
"600060000b00",
|
||||
"600060001000",
|
||||
"600060001100",
|
||||
"600060001200",
|
||||
"600060001300",
|
||||
"600060001400",
|
||||
"60001500",
|
||||
"600060001600",
|
||||
"600060001700",
|
||||
"600060001800",
|
||||
"60001900",
|
||||
"600060001a00",
|
||||
"600060002000",
|
||||
"3000",
|
||||
"60003100",
|
||||
"3200",
|
||||
"3300",
|
||||
"3400",
|
||||
"60003500",
|
||||
"3600",
|
||||
"6000600060003700",
|
||||
"3800",
|
||||
"6000600060003900",
|
||||
"3a00",
|
||||
"60003b00",
|
||||
"60006000600060003c00",
|
||||
"3d00",
|
||||
"6000600060003e00",
|
||||
"60003f00",
|
||||
"4000",
|
||||
"4100",
|
||||
"4200",
|
||||
"4300",
|
||||
"4400",
|
||||
"4500",
|
||||
"4600",
|
||||
"4700",
|
||||
"60005000",
|
||||
"60005100",
|
||||
"600060005200",
|
||||
"600060005300",
|
||||
"60005400",
|
||||
"600060005500",
|
||||
"60005600",
|
||||
"600060005700",
|
||||
"5800",
|
||||
"5900",
|
||||
"5a00",
|
||||
"5b00",
|
||||
"60ff00",
|
||||
"61ffff00",
|
||||
"62ffffff00",
|
||||
"63ffffffff00",
|
||||
"64ffffffffff00",
|
||||
"65ffffffffffff00",
|
||||
"66ffffffffffffff00",
|
||||
"67ffffffffffffffff00",
|
||||
"68ffffffffffffffffff00",
|
||||
"69ffffffffffffffffffff00",
|
||||
"6affffffffffffffffffffff00",
|
||||
"6bffffffffffffffffffffffff00",
|
||||
"6cffffffffffffffffffffffffff00",
|
||||
"6dffffffffffffffffffffffffffff00",
|
||||
"6effffffffffffffffffffffffffffff00",
|
||||
"6fffffffffffffffffffffffffffffffff00",
|
||||
"70ffffffffffffffffffffffffffffffffff00",
|
||||
"71ffffffffffffffffffffffffffffffffffff00",
|
||||
"72ffffffffffffffffffffffffffffffffffffff00",
|
||||
"73ffffffffffffffffffffffffffffffffffffffff00",
|
||||
"74ffffffffffffffffffffffffffffffffffffffffff00",
|
||||
"75ffffffffffffffffffffffffffffffffffffffffffff00",
|
||||
"76ffffffffffffffffffffffffffffffffffffffffffffff00",
|
||||
"77ffffffffffffffffffffffffffffffffffffffffffffffff00",
|
||||
"78ffffffffffffffffffffffffffffffffffffffffffffffffff00",
|
||||
"79ffffffffffffffffffffffffffffffffffffffffffffffffffff00",
|
||||
"7affffffffffffffffffffffffffffffffffffffffffffffffffffff00",
|
||||
"7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff00",
|
||||
"7cffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00",
|
||||
"7dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00",
|
||||
"7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00",
|
||||
"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00",
|
||||
"60006000600060006000600060006000600060006000600060006000600060008000",
|
||||
"60006000600060006000600060006000600060006000600060006000600060008100",
|
||||
"60006000600060006000600060006000600060006000600060006000600060008200",
|
||||
"60006000600060006000600060006000600060006000600060006000600060008300",
|
||||
"60006000600060006000600060006000600060006000600060006000600060008400",
|
||||
"60006000600060006000600060006000600060006000600060006000600060008500",
|
||||
"60006000600060006000600060006000600060006000600060006000600060008600",
|
||||
"60006000600060006000600060006000600060006000600060006000600060008700",
|
||||
"60006000600060006000600060006000600060006000600060006000600060008800",
|
||||
"60006000600060006000600060006000600060006000600060006000600060008900",
|
||||
"60006000600060006000600060006000600060006000600060006000600060008a00",
|
||||
"60006000600060006000600060006000600060006000600060006000600060008b00",
|
||||
"60006000600060006000600060006000600060006000600060006000600060008c00",
|
||||
"60006000600060006000600060006000600060006000600060006000600060008d00",
|
||||
"60006000600060006000600060006000600060006000600060006000600060008e00",
|
||||
"60006000600060006000600060006000600060006000600060006000600060008f00",
|
||||
"60006000600060006000600060006000600060006000600060006000600060009000",
|
||||
"60006000600060006000600060006000600060006000600060006000600060009100",
|
||||
"60006000600060006000600060006000600060006000600060006000600060009200",
|
||||
"60006000600060006000600060006000600060006000600060006000600060009300",
|
||||
"60006000600060006000600060006000600060006000600060006000600060009400",
|
||||
"60006000600060006000600060006000600060006000600060006000600060009500",
|
||||
"60006000600060006000600060006000600060006000600060006000600060009600",
|
||||
"60006000600060006000600060006000600060006000600060006000600060009700",
|
||||
"60006000600060006000600060006000600060006000600060006000600060009800",
|
||||
"60006000600060006000600060006000600060006000600060006000600060009900",
|
||||
"60006000600060006000600060006000600060006000600060006000600060009a00",
|
||||
"60006000600060006000600060006000600060006000600060006000600060009b00",
|
||||
"60006000600060006000600060006000600060006000600060006000600060009c00",
|
||||
"60006000600060006000600060006000600060006000600060006000600060009d00",
|
||||
"60006000600060006000600060006000600060006000600060006000600060009e00",
|
||||
"60006000600060006000600060006000600060006000600060006000600060009f00",
|
||||
"60006000a000",
|
||||
"600060006000a100",
|
||||
"6000600060006000a200",
|
||||
"60006000600060006000a300",
|
||||
"600060006000600060006000a400",
|
||||
"600060006000f000",
|
||||
"600060006000600060006000f100",
|
||||
"600060006000600060006000f200",
|
||||
"60006000f300",
|
||||
"60006000600060006000f400",
|
||||
"60006000600060006000fa00",
|
||||
"60006000fd00",
|
||||
"fe00",
|
||||
"6000ff00"
|
||||
};
|
||||
|
||||
vector<string> opcodes_lll {
|
||||
"(asm STOP)",
|
||||
"(asm 0 0 ADD)",
|
||||
"(asm 0 0 MUL)",
|
||||
"(asm 0 0 SUB)",
|
||||
"(asm 0 0 DIV)",
|
||||
"(asm 0 0 SDIV)",
|
||||
"(asm 0 0 MOD)",
|
||||
"(asm 0 0 SMOD)",
|
||||
"(asm 0 0 0 ADDMOD)",
|
||||
"(asm 0 0 0 MULMOD)",
|
||||
"(asm 0 0 EXP)",
|
||||
"(asm 0 0 SIGNEXTEND)",
|
||||
"(asm 0 0 LT)",
|
||||
"(asm 0 0 GT)",
|
||||
"(asm 0 0 SLT)",
|
||||
"(asm 0 0 SGT)",
|
||||
"(asm 0 0 EQ)",
|
||||
"(asm 0 ISZERO)",
|
||||
"(asm 0 0 AND)",
|
||||
"(asm 0 0 OR)",
|
||||
"(asm 0 0 XOR)",
|
||||
"(asm 0 NOT)",
|
||||
"(asm 0 0 BYTE)",
|
||||
"(asm 0 0 KECCAK256)",
|
||||
"(asm ADDRESS)",
|
||||
"(asm 0 BALANCE)",
|
||||
"(asm ORIGIN)",
|
||||
"(asm CALLER)",
|
||||
"(asm CALLVALUE)",
|
||||
"(asm 0 CALLDATALOAD)",
|
||||
"(asm CALLDATASIZE)",
|
||||
"(asm 0 0 0 CALLDATACOPY)",
|
||||
"(asm CODESIZE)",
|
||||
"(asm 0 0 0 CODECOPY)",
|
||||
"(asm GASPRICE)",
|
||||
"(asm 0 EXTCODESIZE)",
|
||||
"(asm 0 0 0 0 EXTCODECOPY)",
|
||||
"(asm RETURNDATASIZE)",
|
||||
"(asm 0 0 0 RETURNDATACOPY)",
|
||||
"(asm 0 EXTCODEHASH)",
|
||||
"(asm BLOCKHASH)",
|
||||
"(asm COINBASE)",
|
||||
"(asm TIMESTAMP)",
|
||||
"(asm NUMBER)",
|
||||
"(asm DIFFICULTY)",
|
||||
"(asm GASLIMIT)",
|
||||
"(asm CHAINID)",
|
||||
"(asm SELFBALANCE)",
|
||||
"(asm 0 POP)",
|
||||
"(asm 0 MLOAD)",
|
||||
"(asm 0 0 MSTORE)",
|
||||
"(asm 0 0 MSTORE8)",
|
||||
"(asm 0 SLOAD)",
|
||||
"(asm 0 0 SSTORE)",
|
||||
"(asm 0 JUMP)",
|
||||
"(asm 0 0 JUMPI)",
|
||||
"(asm PC)",
|
||||
"(asm MSIZE)",
|
||||
"(asm GAS)",
|
||||
"(asm JUMPDEST)",
|
||||
"(asm 0xff)",
|
||||
"(asm 0xffff)",
|
||||
"(asm 0xffffff)",
|
||||
"(asm 0xffffffff)",
|
||||
"(asm 0xffffffffff)",
|
||||
"(asm 0xffffffffffff)",
|
||||
"(asm 0xffffffffffffff)",
|
||||
"(asm 0xffffffffffffffff)",
|
||||
"(asm 0xffffffffffffffffff)",
|
||||
"(asm 0xffffffffffffffffffff)",
|
||||
"(asm 0xffffffffffffffffffffff)",
|
||||
"(asm 0xffffffffffffffffffffffff)",
|
||||
"(asm 0xffffffffffffffffffffffffff)",
|
||||
"(asm 0xffffffffffffffffffffffffffff)",
|
||||
"(asm 0xffffffffffffffffffffffffffffff)",
|
||||
"(asm 0xffffffffffffffffffffffffffffffff)",
|
||||
"(asm 0xffffffffffffffffffffffffffffffffff)",
|
||||
"(asm 0xffffffffffffffffffffffffffffffffffff)",
|
||||
"(asm 0xffffffffffffffffffffffffffffffffffffff)",
|
||||
"(asm 0xffffffffffffffffffffffffffffffffffffffff)",
|
||||
"(asm 0xffffffffffffffffffffffffffffffffffffffffff)",
|
||||
"(asm 0xffffffffffffffffffffffffffffffffffffffffffff)",
|
||||
"(asm 0xffffffffffffffffffffffffffffffffffffffffffffff)",
|
||||
"(asm 0xffffffffffffffffffffffffffffffffffffffffffffffff)",
|
||||
"(asm 0xffffffffffffffffffffffffffffffffffffffffffffffffff)",
|
||||
"(asm 0xffffffffffffffffffffffffffffffffffffffffffffffffffff)",
|
||||
"(asm 0xffffffffffffffffffffffffffffffffffffffffffffffffffffff)",
|
||||
"(asm 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff)",
|
||||
"(asm 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)",
|
||||
"(asm 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)",
|
||||
"(asm 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)",
|
||||
"(asm 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)",
|
||||
"(asm 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 DUP1)",
|
||||
"(asm 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 DUP2)",
|
||||
"(asm 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 DUP3)",
|
||||
"(asm 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 DUP4)",
|
||||
"(asm 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 DUP5)",
|
||||
"(asm 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 DUP6)",
|
||||
"(asm 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 DUP7)",
|
||||
"(asm 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 DUP8)",
|
||||
"(asm 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 DUP9)",
|
||||
"(asm 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 DUP10)",
|
||||
"(asm 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 DUP11)",
|
||||
"(asm 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 DUP12)",
|
||||
"(asm 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 DUP13)",
|
||||
"(asm 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 DUP14)",
|
||||
"(asm 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 DUP15)",
|
||||
"(asm 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 DUP16)",
|
||||
"(asm 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 SWAP1)",
|
||||
"(asm 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 SWAP2)",
|
||||
"(asm 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 SWAP3)",
|
||||
"(asm 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 SWAP4)",
|
||||
"(asm 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 SWAP5)",
|
||||
"(asm 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 SWAP6)",
|
||||
"(asm 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 SWAP7)",
|
||||
"(asm 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 SWAP8)",
|
||||
"(asm 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 SWAP9)",
|
||||
"(asm 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 SWAP10)",
|
||||
"(asm 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 SWAP11)",
|
||||
"(asm 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 SWAP12)",
|
||||
"(asm 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 SWAP13)",
|
||||
"(asm 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 SWAP14)",
|
||||
"(asm 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 SWAP15)",
|
||||
"(asm 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 SWAP16)",
|
||||
"(asm 0 0 LOG0)",
|
||||
"(asm 0 0 0 LOG1)",
|
||||
"(asm 0 0 0 0 LOG2)",
|
||||
"(asm 0 0 0 0 0 LOG3)",
|
||||
"(asm 0 0 0 0 0 0 LOG4)",
|
||||
"(asm 0 0 0 CREATE)",
|
||||
"(asm 0 0 0 0 0 0 CALL)",
|
||||
"(asm 0 0 0 0 0 0 CALLCODE)",
|
||||
"(asm 0 0 RETURN)",
|
||||
"(asm 0 0 0 0 0 DELEGATECALL)",
|
||||
"(asm 0 0 0 0 0 STATICCALL)",
|
||||
"(asm 0 0 REVERT)",
|
||||
"(asm INVALID)",
|
||||
"(asm 0 SELFDESTRUCT)"
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < opcodes_bytecode.size(); i++)
|
||||
{
|
||||
vector<string> errors;
|
||||
bytes code = lll::compileLLL(opcodes_lll[i], solidity::test::Options::get().evmVersion(), false, &errors);
|
||||
|
||||
BOOST_REQUIRE_MESSAGE(errors.empty(), opcodes_lll[i]);
|
||||
|
||||
BOOST_CHECK_EQUAL(toHex(code), opcodes_bytecode[i]);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
} // end namespaces
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
This file is part of solidity.
|
||||
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Alex Beregszaszi
|
||||
* @date 2016
|
||||
* Framework for executing LLL contracts and testing them via RPC.
|
||||
*/
|
||||
|
||||
#include <cstdlib>
|
||||
#include <boost/test/framework.hpp>
|
||||
#include <test/liblll/ExecutionFramework.h>
|
||||
|
||||
using namespace solidity::test;
|
||||
using namespace solidity::lll::test;
|
||||
|
||||
LLLExecutionFramework::LLLExecutionFramework() :
|
||||
ExecutionFramework()
|
||||
{
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
This file is part of solidity.
|
||||
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Alex Beregszaszi
|
||||
* @date 2016
|
||||
* Framework for executing LLL contracts and testing them via RPC.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <test/ExecutionFramework.h>
|
||||
|
||||
#include <liblll/Compiler.h>
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace solidity::lll::test
|
||||
{
|
||||
|
||||
class LLLExecutionFramework: public solidity::test::ExecutionFramework
|
||||
{
|
||||
public:
|
||||
LLLExecutionFramework();
|
||||
|
||||
virtual bytes const& compileAndRunWithoutCheck(
|
||||
std::string const& _sourceCode,
|
||||
u256 const& _value = 0,
|
||||
std::string const& _contractName = "",
|
||||
bytes const& _arguments = bytes(),
|
||||
std::map<std::string, solidity::test::Address> const& _libraryAddresses = {}
|
||||
) override
|
||||
{
|
||||
BOOST_REQUIRE(_contractName.empty());
|
||||
BOOST_REQUIRE(_libraryAddresses.empty());
|
||||
|
||||
std::vector<std::string> errors;
|
||||
bytes bytecode = lll::compileLLL(
|
||||
_sourceCode,
|
||||
solidity::test::Options::get().evmVersion(),
|
||||
m_optimiserSettings == solidity::frontend::OptimiserSettings::standard(),
|
||||
&errors
|
||||
);
|
||||
if (!errors.empty())
|
||||
{
|
||||
for (auto const& error: errors)
|
||||
std::cerr << error << std::endl;
|
||||
BOOST_ERROR("Compiling contract failed");
|
||||
}
|
||||
sendMessage(bytecode + _arguments, true, _value);
|
||||
return m_output;
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespaces
|
||||
@@ -1,503 +0,0 @@
|
||||
/*
|
||||
This file is part of solidity.
|
||||
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Ben Edgington <ben@benjaminion.xyz>
|
||||
* @date 2017
|
||||
* Tests for the deployed ENS Registry implementation written in LLL
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <test/liblll/ExecutionFramework.h>
|
||||
#include <liblll/Compiler.h>
|
||||
|
||||
#define ACCOUNT(n) h256(account(n), h256::AlignRight)
|
||||
|
||||
using namespace std;
|
||||
using namespace solidity::lll;
|
||||
using namespace solidity::util;
|
||||
using namespace solidity::test;
|
||||
|
||||
namespace solidity::lll::test
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
static char const* ensCode = R"DELIMITER(
|
||||
;;; ---------------------------------------------------------------------------
|
||||
;;; @title The Ethereum Name Service registry.
|
||||
;;; @author Daniel Ellison <daniel@syrinx.net>
|
||||
|
||||
(seq
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; Constant definitions.
|
||||
|
||||
;; Memory layout.
|
||||
(def 'node-bytes 0x00)
|
||||
(def 'label-bytes 0x20)
|
||||
(def 'call-result 0x40)
|
||||
|
||||
;; Struct: Record
|
||||
(def 'resolver 0x00) ; address
|
||||
(def 'owner 0x20) ; address
|
||||
(def 'ttl 0x40) ; uint64
|
||||
|
||||
;; Precomputed function IDs.
|
||||
(def 'get-node-owner 0x02571be3) ; owner(bytes32)
|
||||
(def 'get-node-resolver 0x0178b8bf) ; resolver(bytes32)
|
||||
(def 'get-node-ttl 0x16a25cbd) ; ttl(bytes32)
|
||||
(def 'set-node-owner 0x5b0fc9c3) ; setOwner(bytes32,address)
|
||||
(def 'set-subnode-owner 0x06ab5923) ; setSubnodeOwner(bytes32,bytes32,address)
|
||||
(def 'set-node-resolver 0x1896f70a) ; setResolver(bytes32,address)
|
||||
(def 'set-node-ttl 0x14ab9038) ; setTTL(bytes32,uint64)
|
||||
|
||||
;; Jumping here causes an EVM error.
|
||||
(def 'invalid-location 0x02)
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; @notice Shifts the leftmost 4 bytes of a 32-byte number right by 28 bytes.
|
||||
;; @param input A 32-byte number.
|
||||
|
||||
(def 'shift-right (input)
|
||||
(div input (exp 2 224)))
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; @notice Determines whether the supplied function ID matches a known
|
||||
;; function hash and executes <code-body> if so.
|
||||
;; @dev The function ID is in the leftmost four bytes of the call data.
|
||||
;; @param function-hash The four-byte hash of a known function signature.
|
||||
;; @param code-body The code to run in the case of a match.
|
||||
|
||||
(def 'function (function-hash code-body)
|
||||
(when (= (shift-right (calldataload 0x00)) function-hash)
|
||||
code-body))
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; @notice Calculates record location for the node and label passed in.
|
||||
;; @param node The parent node.
|
||||
;; @param label The hash of the subnode label.
|
||||
|
||||
(def 'get-record (node label)
|
||||
(seq
|
||||
(mstore node-bytes node)
|
||||
(mstore label-bytes label)
|
||||
(sha3 node-bytes 64)))
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; @notice Retrieves owner from node record.
|
||||
;; @param node Get owner of this node.
|
||||
|
||||
(def 'get-owner (node)
|
||||
(sload (+ node owner)))
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; @notice Stores new owner in node record.
|
||||
;; @param node Set owner of this node.
|
||||
;; @param new-owner New owner of this node.
|
||||
|
||||
(def 'set-owner (node new-owner)
|
||||
(sstore (+ node owner) new-owner))
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; @notice Stores new subnode owner in node record.
|
||||
;; @param node Set owner of this node.
|
||||
;; @param label The hash of the label specifying the subnode.
|
||||
;; @param new-owner New owner of the subnode.
|
||||
|
||||
(def 'set-subowner (node label new-owner)
|
||||
(sstore (+ (get-record node label) owner) new-owner))
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; @notice Retrieves resolver from node record.
|
||||
;; @param node Get resolver of this node.
|
||||
|
||||
(def 'get-resolver (node)
|
||||
(sload node))
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; @notice Stores new resolver in node record.
|
||||
;; @param node Set resolver of this node.
|
||||
;; @param new-resolver New resolver for this node.
|
||||
|
||||
(def 'set-resolver (node new-resolver)
|
||||
(sstore node new-resolver))
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; @notice Retrieves TTL From node record.
|
||||
;; @param node Get TTL of this node.
|
||||
|
||||
(def 'get-ttl (node)
|
||||
(sload (+ node ttl)))
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; @notice Stores new TTL in node record.
|
||||
;; @param node Set TTL of this node.
|
||||
;; @param new-resolver New TTL for this node.
|
||||
|
||||
(def 'set-ttl (node new-ttl)
|
||||
(sstore (+ node ttl) new-ttl))
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; @notice Checks that the caller is the node owner.
|
||||
;; @param node Check owner of this node.
|
||||
|
||||
(def 'only-node-owner (node)
|
||||
(when (!= (caller) (get-owner node))
|
||||
(jump invalid-location)))
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; INIT
|
||||
|
||||
;; Set the owner of the root node (0x00) to the deploying account.
|
||||
(set-owner 0x00 (caller))
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; CODE
|
||||
|
||||
(returnlll
|
||||
(seq
|
||||
|
||||
;; ----------------------------------------------------------------------
|
||||
;; @notice Returns the address of the resolver for the specified node.
|
||||
;; @dev Signature: resolver(bytes32)
|
||||
;; @param node Return this node's resolver.
|
||||
;; @return The associated resolver.
|
||||
|
||||
(def 'node (calldataload 0x04))
|
||||
|
||||
(function get-node-resolver
|
||||
(seq
|
||||
|
||||
;; Get the node's resolver and save it.
|
||||
(mstore call-result (get-resolver node))
|
||||
|
||||
;; Return result.
|
||||
(return call-result 32)))
|
||||
|
||||
;; ----------------------------------------------------------------------
|
||||
;; @notice Returns the address that owns the specified node.
|
||||
;; @dev Signature: owner(bytes32)
|
||||
;; @param node Return this node's owner.
|
||||
;; @return The associated address.
|
||||
|
||||
(def 'node (calldataload 0x04))
|
||||
|
||||
(function get-node-owner
|
||||
(seq
|
||||
|
||||
;; Get the node's owner and save it.
|
||||
(mstore call-result (get-owner node))
|
||||
|
||||
;; Return result.
|
||||
(return call-result 32)))
|
||||
|
||||
;; ----------------------------------------------------------------------
|
||||
;; @notice Returns the TTL of a node and any records associated with it.
|
||||
;; @dev Signature: ttl(bytes32)
|
||||
;; @param node Return this node's TTL.
|
||||
;; @return The node's TTL.
|
||||
|
||||
(def 'node (calldataload 0x04))
|
||||
|
||||
(function get-node-ttl
|
||||
(seq
|
||||
|
||||
;; Get the node's TTL and save it.
|
||||
(mstore call-result (get-ttl node))
|
||||
|
||||
;; Return result.
|
||||
(return call-result 32)))
|
||||
|
||||
;; ----------------------------------------------------------------------
|
||||
;; @notice Transfers ownership of a node to a new address. May only be
|
||||
;; called by the current owner of the node.
|
||||
;; @dev Signature: setOwner(bytes32,address)
|
||||
;; @param node The node to transfer ownership of.
|
||||
;; @param new-owner The address of the new owner.
|
||||
|
||||
(def 'node (calldataload 0x04))
|
||||
(def 'new-owner (calldataload 0x24))
|
||||
|
||||
(function set-node-owner
|
||||
(seq (only-node-owner node)
|
||||
|
||||
;; Transfer ownership by storing passed-in address.
|
||||
(set-owner node new-owner)
|
||||
|
||||
;; Emit an event about the transfer.
|
||||
;; Transfer(bytes32 indexed node, address owner);
|
||||
(mstore call-result new-owner)
|
||||
(log2 call-result 32
|
||||
(sha3 0x00 (lit 0x00 "Transfer(bytes32,address)")) node)
|
||||
|
||||
;; Nothing to return.
|
||||
(stop)))
|
||||
|
||||
;; ----------------------------------------------------------------------
|
||||
;; @notice Transfers ownership of a subnode to a new address. May only be
|
||||
;; called by the owner of the parent node.
|
||||
;; @dev Signature: setSubnodeOwner(bytes32,bytes32,address)
|
||||
;; @param node The parent node.
|
||||
;; @param label The hash of the label specifying the subnode.
|
||||
;; @param new-owner The address of the new owner.
|
||||
|
||||
(def 'node (calldataload 0x04))
|
||||
(def 'label (calldataload 0x24))
|
||||
(def 'new-owner (calldataload 0x44))
|
||||
|
||||
(function set-subnode-owner
|
||||
(seq (only-node-owner node)
|
||||
|
||||
;; Transfer ownership by storing passed-in address.
|
||||
(set-subowner node label new-owner)
|
||||
|
||||
;; Emit an event about the transfer.
|
||||
;; NewOwner(bytes32 indexed node, bytes32 indexed label, address owner);
|
||||
(mstore call-result new-owner)
|
||||
(log3 call-result 32
|
||||
(sha3 0x00 (lit 0x00 "NewOwner(bytes32,bytes32,address)"))
|
||||
node label)
|
||||
|
||||
;; Nothing to return.
|
||||
(stop)))
|
||||
|
||||
;; ----------------------------------------------------------------------
|
||||
;; @notice Sets the resolver address for the specified node.
|
||||
;; @dev Signature: setResolver(bytes32,address)
|
||||
;; @param node The node to update.
|
||||
;; @param new-resolver The address of the resolver.
|
||||
|
||||
(def 'node (calldataload 0x04))
|
||||
(def 'new-resolver (calldataload 0x24))
|
||||
|
||||
(function set-node-resolver
|
||||
(seq (only-node-owner node)
|
||||
|
||||
;; Transfer ownership by storing passed-in address.
|
||||
(set-resolver node new-resolver)
|
||||
|
||||
;; Emit an event about the change of resolver.
|
||||
;; NewResolver(bytes32 indexed node, address resolver);
|
||||
(mstore call-result new-resolver)
|
||||
(log2 call-result 32
|
||||
(sha3 0x00 (lit 0x00 "NewResolver(bytes32,address)")) node)
|
||||
|
||||
;; Nothing to return.
|
||||
(stop)))
|
||||
|
||||
;; ----------------------------------------------------------------------
|
||||
;; @notice Sets the TTL for the specified node.
|
||||
;; @dev Signature: setTTL(bytes32,uint64)
|
||||
;; @param node The node to update.
|
||||
;; @param ttl The TTL in seconds.
|
||||
|
||||
(def 'node (calldataload 0x04))
|
||||
(def 'new-ttl (calldataload 0x24))
|
||||
|
||||
(function set-node-ttl
|
||||
(seq (only-node-owner node)
|
||||
|
||||
;; Set new TTL by storing passed-in time.
|
||||
(set-ttl node new-ttl)
|
||||
|
||||
;; Emit an event about the change of TTL.
|
||||
;; NewTTL(bytes32 indexed node, uint64 ttl);
|
||||
(mstore call-result new-ttl)
|
||||
(log2 call-result 32
|
||||
(sha3 0x00 (lit 0x00 "NewTTL(bytes32,uint64)")) node)
|
||||
|
||||
;; Nothing to return.
|
||||
(stop)))
|
||||
|
||||
;; ----------------------------------------------------------------------
|
||||
;; @notice Fallback: No functions matched the function ID provided.
|
||||
|
||||
(jump invalid-location)))
|
||||
|
||||
)
|
||||
)DELIMITER";
|
||||
|
||||
static unique_ptr<bytes> s_compiledEns;
|
||||
|
||||
class LLLENSTestFramework: public LLLExecutionFramework
|
||||
{
|
||||
protected:
|
||||
void deployEns()
|
||||
{
|
||||
if (!s_compiledEns)
|
||||
{
|
||||
vector<string> errors;
|
||||
s_compiledEns.reset(new bytes(compileLLL(ensCode, solidity::test::Options::get().evmVersion(), solidity::test::Options::get().optimize, &errors)));
|
||||
BOOST_REQUIRE(errors.empty());
|
||||
}
|
||||
sendMessage(*s_compiledEns, true);
|
||||
BOOST_REQUIRE(m_transactionSuccessful);
|
||||
BOOST_REQUIRE(!m_output.empty());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// Test suite for the deployed ENS Registry implementation written in LLL
|
||||
BOOST_FIXTURE_TEST_SUITE(LLLENS, LLLENSTestFramework)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(creation)
|
||||
{
|
||||
deployEns();
|
||||
|
||||
// Root node 0x00 should initially be owned by the deploying account, account(0).
|
||||
BOOST_CHECK(callContractFunction("owner(bytes32)", 0x00) == encodeArgs(ACCOUNT(0)));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(transfer_ownership)
|
||||
{
|
||||
deployEns();
|
||||
|
||||
// Transfer ownership of root node from account(0) to account(1).
|
||||
BOOST_REQUIRE(callContractFunction("setOwner(bytes32,address)", 0x00, ACCOUNT(1)) == encodeArgs());
|
||||
|
||||
// Check that an event was raised and contents are correct.
|
||||
BOOST_REQUIRE(numLogs() == 1);
|
||||
BOOST_CHECK(logData(0) == encodeArgs(ACCOUNT(1)));
|
||||
BOOST_REQUIRE(numLogTopics(0) == 2);
|
||||
BOOST_CHECK(logTopic(0, 0) == keccak256(string("Transfer(bytes32,address)")));
|
||||
BOOST_CHECK(logTopic(0, 1) == u256(0x00));
|
||||
|
||||
// Verify that owner of 0x00 is now account(1).
|
||||
BOOST_CHECK(callContractFunction("owner(bytes32)", 0x00) == encodeArgs(ACCOUNT(1)));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(transfer_ownership_fail)
|
||||
{
|
||||
deployEns();
|
||||
|
||||
// Try to steal ownership of node 0x01
|
||||
BOOST_REQUIRE(callContractFunction("setOwner(bytes32,address)", 0x01, ACCOUNT(0)) == encodeArgs());
|
||||
|
||||
// Verify that owner of 0x01 remains the default zero address
|
||||
BOOST_CHECK(callContractFunction("owner(bytes32)", 0x01) == encodeArgs(0));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(set_resolver)
|
||||
{
|
||||
deployEns();
|
||||
|
||||
// Set resolver of root node to account(1).
|
||||
BOOST_REQUIRE(callContractFunction("setResolver(bytes32,address)", 0x00, ACCOUNT(1)) == encodeArgs());
|
||||
|
||||
// Check that an event was raised and contents are correct.
|
||||
BOOST_REQUIRE(numLogs() == 1);
|
||||
BOOST_CHECK(logData(0) == encodeArgs(ACCOUNT(1)));
|
||||
BOOST_REQUIRE(numLogTopics(0) == 2);
|
||||
BOOST_CHECK(logTopic(0, 0) == keccak256(string("NewResolver(bytes32,address)")));
|
||||
BOOST_CHECK(logTopic(0, 1) == u256(0x00));
|
||||
|
||||
// Verify that the resolver is changed to account(1).
|
||||
BOOST_CHECK(callContractFunction("resolver(bytes32)", 0x00) == encodeArgs(ACCOUNT(1)));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(set_resolver_fail)
|
||||
{
|
||||
deployEns();
|
||||
|
||||
// Try to set resolver of node 0x01, which is not owned by account(0).
|
||||
BOOST_REQUIRE(callContractFunction("setResolver(bytes32,address)", 0x01, ACCOUNT(0)) == encodeArgs());
|
||||
|
||||
// Verify that the resolver of 0x01 remains default zero address.
|
||||
BOOST_CHECK(callContractFunction("resolver(bytes32)", 0x01) == encodeArgs(0));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(set_ttl)
|
||||
{
|
||||
deployEns();
|
||||
|
||||
// Set ttl of root node to 3600.
|
||||
BOOST_REQUIRE(callContractFunction("setTTL(bytes32,uint64)", 0x00, 3600) == encodeArgs());
|
||||
|
||||
// Check that an event was raised and contents are correct.
|
||||
BOOST_REQUIRE(numLogs() == 1);
|
||||
BOOST_CHECK(logData(0) == encodeArgs(3600));
|
||||
BOOST_REQUIRE(numLogTopics(0) == 2);
|
||||
BOOST_CHECK(logTopic(0, 0) == keccak256(string("NewTTL(bytes32,uint64)")));
|
||||
BOOST_CHECK(logTopic(0, 1) == u256(0x00));
|
||||
|
||||
// Verify that the TTL has been set.
|
||||
BOOST_CHECK(callContractFunction("ttl(bytes32)", 0x00) == encodeArgs(3600));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(set_ttl_fail)
|
||||
{
|
||||
deployEns();
|
||||
|
||||
// Try to set TTL of node 0x01, which is not owned by account(0).
|
||||
BOOST_REQUIRE(callContractFunction("setTTL(bytes32,uint64)", 0x01, 3600) == encodeArgs());
|
||||
|
||||
// Verify that the TTL of node 0x01 has not changed from the default.
|
||||
BOOST_CHECK(callContractFunction("ttl(bytes32)", 0x01) == encodeArgs(0));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(create_subnode)
|
||||
{
|
||||
deployEns();
|
||||
|
||||
// Set ownership of "eth" sub-node to account(1)
|
||||
BOOST_REQUIRE(callContractFunction("setSubnodeOwner(bytes32,bytes32,address)", 0x00, keccak256(string("eth")), ACCOUNT(1)) == encodeArgs());
|
||||
|
||||
// Check that an event was raised and contents are correct.
|
||||
BOOST_REQUIRE(numLogs() == 1);
|
||||
BOOST_CHECK(logData(0) == encodeArgs(ACCOUNT(1)));
|
||||
BOOST_REQUIRE(numLogTopics(0) == 3);
|
||||
BOOST_CHECK(logTopic(0, 0) == keccak256(string("NewOwner(bytes32,bytes32,address)")));
|
||||
BOOST_CHECK(logTopic(0, 1) == u256(0x00));
|
||||
BOOST_CHECK(logTopic(0, 2) == keccak256(string("eth")));
|
||||
|
||||
// Verify that the sub-node owner is now account(1).
|
||||
u256 namehash = keccak256(h256(0x00).asBytes() + keccak256("eth").asBytes());
|
||||
BOOST_CHECK(callContractFunction("owner(bytes32)", namehash) == encodeArgs(ACCOUNT(1)));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(create_subnode_fail)
|
||||
{
|
||||
deployEns();
|
||||
|
||||
// Send account(1) some ether for gas.
|
||||
sendEther(account(1), 1000 * ether);
|
||||
BOOST_REQUIRE(balanceAt(account(1)) >= 1000 * ether);
|
||||
|
||||
// account(1) tries to set ownership of the "eth" sub-node.
|
||||
m_sender = account(1);
|
||||
BOOST_REQUIRE(callContractFunction("setSubnodeOwner(bytes32,bytes32,address)", 0x00, keccak256(string("eth")), ACCOUNT(1)) == encodeArgs());
|
||||
|
||||
// Verify that the sub-node owner remains at default zero address.
|
||||
u256 namehash = keccak256(h256(0x00).asBytes() + keccak256("eth").asBytes());
|
||||
BOOST_CHECK(callContractFunction("owner(bytes32)", namehash) == encodeArgs(0));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(fallback)
|
||||
{
|
||||
deployEns();
|
||||
|
||||
// Call fallback - should just abort via jump to invalid location.
|
||||
BOOST_CHECK(callFallback() == encodeArgs());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
} // end namespaces
|
||||
@@ -1,652 +0,0 @@
|
||||
/*
|
||||
This file is part of solidity.
|
||||
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Ben Edgington <ben@benjaminion.xyz>
|
||||
* @date 2017
|
||||
* Tests for an ERC20 token implementation written in LLL
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <test/liblll/ExecutionFramework.h>
|
||||
#include <liblll/Compiler.h>
|
||||
|
||||
#define TOKENSUPPLY 100000
|
||||
#define TOKENDECIMALS 2
|
||||
#define TOKENSYMBOL "BEN"
|
||||
#define TOKENNAME "Ben Token"
|
||||
#define ACCOUNT(n) h256(account(n), h256::AlignRight)
|
||||
#define SUCCESS encodeArgs(1)
|
||||
|
||||
using namespace std;
|
||||
using namespace solidity::lll;
|
||||
using namespace solidity::util;
|
||||
using namespace solidity::test;
|
||||
|
||||
namespace solidity::lll::test
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
static char const* erc20Code = R"DELIMITER(
|
||||
(seq
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; CONSTANTS
|
||||
|
||||
;; Token parameters.
|
||||
;; 0x40 is a "magic number" - the text of the string is placed here
|
||||
;; when returning the string to the caller. See return-string below.
|
||||
(def 'token-name-string (lit 0x40 "Ben Token"))
|
||||
(def 'token-symbol-string (lit 0x40 "BEN"))
|
||||
(def 'token-decimals 2)
|
||||
(def 'token-supply 100000) ; 1000.00 total tokens
|
||||
|
||||
;; Booleans
|
||||
(def 'false 0)
|
||||
(def 'true 1)
|
||||
|
||||
;; Memory layout.
|
||||
(def 'mem-ret 0x00) ; Fixed due to compiler macro for return.
|
||||
(def 'mem-func 0x00) ; No conflict with mem-ret, so re-use.
|
||||
(def 'mem-keccak 0x00) ; No conflict with mem-func or mem-ret, so re-use.
|
||||
(def 'scratch0 0x20)
|
||||
(def 'scratch1 0x40)
|
||||
|
||||
;; Precomputed function IDs.
|
||||
(def 'get-name 0x06fdde03) ; name()
|
||||
(def 'get-symbol 0x95d89b41) ; symbol()
|
||||
(def 'get-decimals 0x313ce567) ; decimals()
|
||||
(def 'get-total-supply 0x18160ddd) ; totalSupply()
|
||||
(def 'get-balance-of 0x70a08231) ; balanceOf(address)
|
||||
(def 'transfer 0xa9059cbb) ; transfer(address,uint256)
|
||||
(def 'transfer-from 0x23b872dd) ; transferFrom(address,address,uint256)
|
||||
(def 'approve 0x095ea7b3) ; approve(address,uint256)
|
||||
(def 'get-allowance 0xdd62ed3e) ; allowance(address,address)
|
||||
|
||||
;; Event IDs
|
||||
(def 'transfer-event-id ; Transfer(address,address,uint256)
|
||||
0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef)
|
||||
|
||||
(def 'approval-event-id ; Approval(address,address,uint256)
|
||||
0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925)
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; UTILITIES
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; The following define the key data-structures:
|
||||
;; - balance(addr) => value
|
||||
;; - allowance(addr,addr) => value
|
||||
|
||||
;; Balances are stored at s[owner_addr].
|
||||
(def 'balance (address) address)
|
||||
|
||||
;; Allowances are stored at s[owner_addr + keccak256(spender_addr)]
|
||||
;; We use a crypto function here to avoid any situation where
|
||||
;; approve(me, spender) can be abused to do approve(target, me).
|
||||
(def 'allowance (owner spender)
|
||||
(seq
|
||||
(mstore mem-keccak spender)
|
||||
(keccak256 mem-keccak 0x20)))
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; For convenience we have macros to refer to function arguments
|
||||
|
||||
(def 'arg1 (calldataload 0x04))
|
||||
(def 'arg2 (calldataload 0x24))
|
||||
(def 'arg3 (calldataload 0x44))
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; Revert is a soft return that does not consume the remaining gas.
|
||||
;; We use it when rejecting invalid user input.
|
||||
;;
|
||||
;; Note: The REVERT opcode will be implemented in Metropolis (EIP 140).
|
||||
;; Meanwhile it just causes an invalid instruction exception (similar
|
||||
;; to a "throw" in Solidity). When fully implemented, Revert could be
|
||||
;; use to return error codes, or even messages.
|
||||
|
||||
(def 'revert () (revert 0 0))
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; Macro for returning string names.
|
||||
;; Compliant with the ABI format for strings.
|
||||
|
||||
(def 'return-string (string-literal)
|
||||
(seq
|
||||
(mstore 0x00 0x20) ; Points to our string's memory location
|
||||
(mstore 0x20 string-literal) ; Length. String itself is copied to 0x40.
|
||||
(return 0x00 (& (+ (mload 0x20) 0x5f) (~ 0x1f)))))
|
||||
; Round return up to 32 byte boundary
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; Convenience macro for raising Events
|
||||
|
||||
(def 'event3 (id addr1 addr2 value)
|
||||
(seq
|
||||
(mstore scratch0 value)
|
||||
(log3 scratch0 0x20 id addr1 addr2)))
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; Determines whether the stored function ID matches a known
|
||||
;; function hash and executes <code-body> if so.
|
||||
;; @param function-hash The four-byte hash of a known function signature.
|
||||
;; @param code-body The code to run in the case of a match.
|
||||
|
||||
(def 'function (function-hash code-body)
|
||||
(when (= (mload mem-func) function-hash)
|
||||
code-body))
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; Gets the function ID and stores it in memory for reference.
|
||||
;; The function ID is in the leftmost four bytes of the call data.
|
||||
|
||||
(def 'uses-functions
|
||||
(mstore
|
||||
mem-func
|
||||
(shr (calldataload 0x00) 224)))
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; GUARDS
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; Checks that ensure that each function is called with the right
|
||||
;; number of arguments. For one thing this addresses the "ERC20
|
||||
;; short address attack". For another, it stops me making
|
||||
;; mistakes while testing. We use these only on the non-constant functions.
|
||||
|
||||
(def 'has-one-arg (unless (= 0x24 (calldatasize)) (revert)))
|
||||
(def 'has-two-args (unless (= 0x44 (calldatasize)) (revert)))
|
||||
(def 'has-three-args (unless (= 0x64 (calldatasize)) (revert)))
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; Check that addresses have only 160 bits and revert if not.
|
||||
;; We use these input type-checks on the non-constant functions.
|
||||
|
||||
(def 'is-address (addr)
|
||||
(when
|
||||
(shr addr 160)
|
||||
(revert)))
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; Check that transfer values are smaller than total supply and
|
||||
;; revert if not. This should effectively exclude negative values.
|
||||
|
||||
(def 'is-value (value)
|
||||
(when (> value token-supply) (revert)))
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; Will revert if sent any Ether. We use the macro immediately so as
|
||||
;; to abort if sent any Ether during contract deployment.
|
||||
|
||||
(def 'not-payable
|
||||
(when (callvalue) (revert)))
|
||||
|
||||
not-payable
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; INITIALISATION
|
||||
;;
|
||||
;; Assign all tokens initially to the owner of the contract.
|
||||
|
||||
(sstore (balance (caller)) token-supply)
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; CONTRACT CODE
|
||||
|
||||
(returnlll
|
||||
(seq not-payable uses-functions
|
||||
|
||||
;; ----------------------------------------------------------------------
|
||||
;; Getter for the name of the token.
|
||||
;; @abi name() constant returns (string)
|
||||
;; @return The token name as a string.
|
||||
|
||||
(function get-name
|
||||
(return-string token-name-string))
|
||||
|
||||
;; ----------------------------------------------------------------------
|
||||
;; Getter for the symbol of the token.
|
||||
;; @abi symbol() constant returns (string)
|
||||
;; @return The token symbol as a string.
|
||||
|
||||
(function get-symbol
|
||||
(return-string token-symbol-string))
|
||||
|
||||
;; ----------------------------------------------------------------------
|
||||
;; Getter for the number of decimals assigned to the token.
|
||||
;; @abi decimals() constant returns (uint256)
|
||||
;; @return The token decimals.
|
||||
|
||||
(function get-decimals
|
||||
(return token-decimals))
|
||||
|
||||
;; ----------------------------------------------------------------------
|
||||
;; Getter for the total token supply.
|
||||
;; @abi totalSupply() constant returns (uint256)
|
||||
;; @return The token supply.
|
||||
|
||||
(function get-total-supply
|
||||
(return token-supply))
|
||||
|
||||
;; ----------------------------------------------------------------------
|
||||
;; Returns the account balance of another account.
|
||||
;; @abi balanceOf(address) constant returns (uint256)
|
||||
;; @param owner The address of the account's owner.
|
||||
;; @return The account balance.
|
||||
|
||||
(function get-balance-of
|
||||
(seq
|
||||
|
||||
(def 'owner arg1)
|
||||
|
||||
(return (sload (balance owner)))))
|
||||
|
||||
;; ----------------------------------------------------------------------
|
||||
;; Transfers _value amount of tokens to address _to. The command
|
||||
;; should throw if the _from account balance has not enough
|
||||
;; tokens to spend.
|
||||
;; @abi transfer(address, uint256) returns (bool)
|
||||
;; @param to The account to receive the tokens.
|
||||
;; @param value The quantity of tokens to transfer.
|
||||
;; @return Success (true). Other outcomes result in a Revert.
|
||||
|
||||
(function transfer
|
||||
(seq has-two-args (is-address arg1) (is-value arg2)
|
||||
|
||||
(def 'to arg1)
|
||||
(def 'value arg2)
|
||||
|
||||
(when value ; value == 0 is a no-op
|
||||
(seq
|
||||
|
||||
;; The caller's balance. Save in memory for efficiency.
|
||||
(mstore scratch0 (sload (balance (caller))))
|
||||
|
||||
;; Revert if the caller's balance is not sufficient.
|
||||
(when (> value (mload scratch0))
|
||||
(revert))
|
||||
|
||||
;; Make the transfer
|
||||
;; It would be good to check invariants (sum of balances).
|
||||
(sstore (balance (caller)) (- (mload scratch0) value))
|
||||
(sstore (balance to) (+ (sload (balance to)) value))
|
||||
|
||||
;; Event - Transfer(address,address,uint256)
|
||||
(event3 transfer-event-id (caller) to value)))
|
||||
|
||||
(return true)))
|
||||
|
||||
;; ----------------------------------------------------------------------
|
||||
;; Send _value amount of tokens from address _from to address _to
|
||||
;; @abi transferFrom(address,address,uint256) returns (bool)
|
||||
;; @param from The account to send the tokens from.
|
||||
;; @param to The account to receive the tokens.
|
||||
;; @param value The quantity of tokens to transfer.
|
||||
;; @return Success (true). Other outcomes result in a Revert.
|
||||
|
||||
(function transfer-from
|
||||
(seq has-three-args (is-address arg1) (is-address arg2) (is-value arg3)
|
||||
|
||||
(def 'from arg1)
|
||||
(def 'to arg2)
|
||||
(def 'value arg3)
|
||||
|
||||
(when value ; value == 0 is a no-op
|
||||
|
||||
(seq
|
||||
|
||||
;; Save data to memory for efficiency.
|
||||
(mstore scratch0 (sload (balance from)))
|
||||
(mstore scratch1 (sload (allowance from (caller))))
|
||||
|
||||
;; Revert if not enough funds, or not enough approved.
|
||||
(when
|
||||
(||
|
||||
(> value (mload scratch0))
|
||||
(> value (mload scratch1)))
|
||||
(revert))
|
||||
|
||||
;; Make the transfer and update allowance.
|
||||
(sstore (balance from) (- (mload scratch0) value))
|
||||
(sstore (balance to) (+ (sload (balance to)) value))
|
||||
(sstore (allowance from (caller)) (- (mload scratch1) value))
|
||||
|
||||
;; Event - Transfer(address,address,uint256)
|
||||
(event3 transfer-event-id from to value)))
|
||||
|
||||
(return true)))
|
||||
|
||||
;; ----------------------------------------------------------------------
|
||||
;; Allows _spender to withdraw from your account multiple times,
|
||||
;; up to the _value amount. If this function is called again it
|
||||
;; overwrites the current allowance with _value.
|
||||
;; @abi approve(address,uint256) returns (bool)
|
||||
;; @param spender The withdrawing account having its limit set.
|
||||
;; @param value The maximum allowed amount.
|
||||
;; @return Success (true). Other outcomes result in a Revert.
|
||||
|
||||
(function approve
|
||||
(seq has-two-args (is-address arg1) (is-value arg2)
|
||||
|
||||
(def 'spender arg1)
|
||||
(def 'value arg2)
|
||||
|
||||
;; Force users set the allowance to 0 before setting it to
|
||||
;; another value for the same spender. Prevents this attack:
|
||||
;; https://docs.google.com/document/d/1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM
|
||||
(when
|
||||
(&& value (sload (allowance (caller) spender)))
|
||||
(revert))
|
||||
|
||||
(sstore (allowance (caller) spender) value)
|
||||
|
||||
;; Event - Approval(address,address,uint256)
|
||||
(event3 approval-event-id (caller) spender value)
|
||||
|
||||
(return true)))
|
||||
|
||||
;; ----------------------------------------------------------------------
|
||||
;; Returns the amount which _spender is still allowed to withdraw
|
||||
;; from _owner.
|
||||
;; @abi allowance(address,address) constant returns (uint256)
|
||||
;; @param owner The owning account.
|
||||
;; @param spender The withdrawing account.
|
||||
;; @return The allowed amount remaining.
|
||||
|
||||
(function get-allowance
|
||||
(seq
|
||||
|
||||
(def 'owner arg1)
|
||||
(def 'spender arg2)
|
||||
|
||||
(return (sload (allowance owner spender)))))
|
||||
|
||||
;; ----------------------------------------------------------------------
|
||||
;; Fallback: No functions matched the function ID provided.
|
||||
|
||||
(revert)))
|
||||
)
|
||||
)DELIMITER";
|
||||
|
||||
static unique_ptr<bytes> s_compiledErc20;
|
||||
|
||||
class LLLERC20TestFramework: public LLLExecutionFramework
|
||||
{
|
||||
protected:
|
||||
void deployErc20()
|
||||
{
|
||||
if (!s_compiledErc20)
|
||||
{
|
||||
vector<string> errors;
|
||||
s_compiledErc20.reset(new bytes(compileLLL(erc20Code, solidity::test::Options::get().evmVersion(), solidity::test::Options::get().optimize, &errors)));
|
||||
BOOST_REQUIRE(errors.empty());
|
||||
}
|
||||
sendMessage(*s_compiledErc20, true);
|
||||
BOOST_REQUIRE(m_transactionSuccessful);
|
||||
BOOST_REQUIRE(!m_output.empty());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// Test suite for an ERC20 contract written in LLL.
|
||||
BOOST_FIXTURE_TEST_SUITE(LLLERC20, LLLERC20TestFramework)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(creation)
|
||||
{
|
||||
deployErc20();
|
||||
|
||||
// All tokens are initially assigned to the contract creator.
|
||||
BOOST_CHECK(callContractFunction("balanceOf(address)", ACCOUNT(0)) == encodeArgs(TOKENSUPPLY));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(constants)
|
||||
{
|
||||
deployErc20();
|
||||
|
||||
BOOST_CHECK(callContractFunction("totalSupply()") == encodeArgs(TOKENSUPPLY));
|
||||
BOOST_CHECK(callContractFunction("decimals()") == encodeArgs(TOKENDECIMALS));
|
||||
BOOST_CHECK(callContractFunction("symbol()") == encodeDyn(string(TOKENSYMBOL)));
|
||||
BOOST_CHECK(callContractFunction("name()") == encodeDyn(string(TOKENNAME)));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(send_value)
|
||||
{
|
||||
deployErc20();
|
||||
|
||||
// Send value to the contract. Should always fail.
|
||||
m_sender = account(0);
|
||||
auto contractBalance = balanceAt(m_contractAddress);
|
||||
|
||||
// Fallback: check value is not transferred.
|
||||
BOOST_CHECK(callFallbackWithValue(42) != SUCCESS);
|
||||
BOOST_CHECK(balanceAt(m_contractAddress) == contractBalance);
|
||||
|
||||
// Transfer: check nothing happened.
|
||||
BOOST_CHECK(callContractFunctionWithValue("transfer(address,uint256)", ACCOUNT(1), 100, 42) != SUCCESS);
|
||||
BOOST_CHECK(balanceAt(m_contractAddress) == contractBalance);
|
||||
BOOST_CHECK(callContractFunction("balanceOf(address)", ACCOUNT(1)) == encodeArgs(0));
|
||||
BOOST_CHECK(callContractFunction("balanceOf(address)", ACCOUNT(0)) == encodeArgs(TOKENSUPPLY));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(transfer)
|
||||
{
|
||||
deployErc20();
|
||||
|
||||
// Transfer 100 tokens from account(0) to account(1).
|
||||
int transfer = 100;
|
||||
m_sender = account(0);
|
||||
BOOST_CHECK(callContractFunction("transfer(address,uint256)", ACCOUNT(1), u256(transfer)) == SUCCESS);
|
||||
BOOST_CHECK(callContractFunction("balanceOf(address)", ACCOUNT(0)) == encodeArgs(TOKENSUPPLY - transfer));
|
||||
BOOST_CHECK(callContractFunction("balanceOf(address)", ACCOUNT(1)) == encodeArgs(transfer));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(transfer_from)
|
||||
{
|
||||
deployErc20();
|
||||
|
||||
// Approve account(1) to transfer up to 1000 tokens from account(0).
|
||||
int allow = 1000;
|
||||
m_sender = account(0);
|
||||
BOOST_REQUIRE(callContractFunction("approve(address,uint256)", ACCOUNT(1), u256(allow)) == SUCCESS);
|
||||
BOOST_REQUIRE(callContractFunction("allowance(address,address)", ACCOUNT(0), ACCOUNT(1)) == encodeArgs(allow));
|
||||
|
||||
// Send account(1) some ether for gas.
|
||||
sendEther(account(1), 1000 * ether);
|
||||
BOOST_REQUIRE(balanceAt(account(1)) >= 1000 * ether);
|
||||
|
||||
// Transfer 300 tokens from account(0) to account(2); check that the allowance decreases.
|
||||
int transfer = 300;
|
||||
m_sender = account(1);
|
||||
BOOST_REQUIRE(callContractFunction("transferFrom(address,address,uint256)", ACCOUNT(0), ACCOUNT(2), u256(transfer)) == SUCCESS);
|
||||
BOOST_CHECK(callContractFunction("balanceOf(address)", ACCOUNT(2)) == encodeArgs(transfer));
|
||||
BOOST_CHECK(callContractFunction("balanceOf(address)", ACCOUNT(0)) == encodeArgs(TOKENSUPPLY - transfer));
|
||||
BOOST_CHECK(callContractFunction("allowance(address,address)", ACCOUNT(0), ACCOUNT(1)) == encodeArgs(allow - transfer));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(transfer_event)
|
||||
{
|
||||
deployErc20();
|
||||
|
||||
// Transfer 1000 tokens from account(0) to account(1).
|
||||
int transfer = 1000;
|
||||
m_sender = account(0);
|
||||
BOOST_REQUIRE(callContractFunction("transfer(address,uint256)", ACCOUNT(1), u256(transfer)) == SUCCESS);
|
||||
|
||||
// Check that a Transfer event was recorded and contents are correct.
|
||||
BOOST_REQUIRE(numLogs() == 1);
|
||||
BOOST_CHECK(logData(0) == encodeArgs(transfer));
|
||||
BOOST_REQUIRE(numLogTopics(0) == 3);
|
||||
BOOST_CHECK(logTopic(0, 0) == keccak256(string("Transfer(address,address,uint256)")));
|
||||
BOOST_CHECK(logTopic(0, 1) == ACCOUNT(0));
|
||||
BOOST_CHECK(logTopic(0, 2) == ACCOUNT(1));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(transfer_zero_no_event)
|
||||
{
|
||||
deployErc20();
|
||||
|
||||
// Transfer 0 tokens from account(0) to account(1). This is a no-op.
|
||||
int transfer = 0;
|
||||
m_sender = account(0);
|
||||
BOOST_REQUIRE(callContractFunction("transfer(address,uint256)", ACCOUNT(1), u256(transfer)) == SUCCESS);
|
||||
|
||||
// Check that no Event was recorded.
|
||||
BOOST_CHECK(numLogs() == 0);
|
||||
|
||||
// Check that balances have not changed.
|
||||
BOOST_CHECK(callContractFunction("balanceOf(address)", ACCOUNT(0)) == encodeArgs(TOKENSUPPLY - transfer));
|
||||
BOOST_CHECK(callContractFunction("balanceOf(address)", ACCOUNT(1)) == encodeArgs(transfer));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(approval_and_transfer_events)
|
||||
{
|
||||
deployErc20();
|
||||
|
||||
// Approve account(1) to transfer up to 10000 tokens from account(0).
|
||||
int allow = 10000;
|
||||
m_sender = account(0);
|
||||
BOOST_REQUIRE(callContractFunction("approve(address,uint256)", ACCOUNT(1), u256(allow)) == SUCCESS);
|
||||
|
||||
// Check that an Approval event was recorded and contents are correct.
|
||||
BOOST_REQUIRE(numLogs() == 1);
|
||||
BOOST_CHECK(logData(0) == encodeArgs(allow));
|
||||
BOOST_REQUIRE(numLogTopics(0) == 3);
|
||||
BOOST_CHECK(logTopic(0, 0) == keccak256(string("Approval(address,address,uint256)")));
|
||||
BOOST_CHECK(logTopic(0, 1) == ACCOUNT(0));
|
||||
BOOST_CHECK(logTopic(0, 2) == ACCOUNT(1));
|
||||
|
||||
// Send account(1) some ether for gas.
|
||||
sendEther(account(1), 1000 * ether);
|
||||
BOOST_REQUIRE(balanceAt(account(1)) >= 1000 * ether);
|
||||
|
||||
// Transfer 3000 tokens from account(0) to account(2); check that the allowance decreases.
|
||||
int transfer = 3000;
|
||||
m_sender = account(1);
|
||||
BOOST_REQUIRE(callContractFunction("transferFrom(address,address,uint256)", ACCOUNT(0), ACCOUNT(2), u256(transfer)) == SUCCESS);
|
||||
|
||||
// Check that a Transfer event was recorded and contents are correct.
|
||||
BOOST_REQUIRE(numLogs() == 1);
|
||||
BOOST_CHECK(logData(0) == encodeArgs(transfer));
|
||||
BOOST_REQUIRE(numLogTopics(0) == 3);
|
||||
BOOST_CHECK(logTopic(0, 0) == keccak256(string("Transfer(address,address,uint256)")));
|
||||
BOOST_CHECK(logTopic(0, 1) == ACCOUNT(0));
|
||||
BOOST_CHECK(logTopic(0, 2) == ACCOUNT(2));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(invalid_transfer_1)
|
||||
{
|
||||
deployErc20();
|
||||
|
||||
// Transfer more than the total supply; ensure nothing changes.
|
||||
int transfer = TOKENSUPPLY + 1;
|
||||
m_sender = account(0);
|
||||
BOOST_CHECK(callContractFunction("transfer(address,uint256)", ACCOUNT(1), u256(transfer)) != SUCCESS);
|
||||
BOOST_CHECK(callContractFunction("balanceOf(address)", ACCOUNT(0)) == encodeArgs(TOKENSUPPLY));
|
||||
BOOST_CHECK(callContractFunction("balanceOf(address)", ACCOUNT(1)) == encodeArgs(0));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(invalid_transfer_2)
|
||||
{
|
||||
deployErc20();
|
||||
|
||||
// Separate transfers that together exceed initial balance.
|
||||
int transfer = 1 + TOKENSUPPLY / 2;
|
||||
m_sender = account(0);
|
||||
|
||||
// First transfer should succeed.
|
||||
BOOST_REQUIRE(callContractFunction("transfer(address,uint256)", ACCOUNT(1), u256(transfer)) == SUCCESS);
|
||||
BOOST_REQUIRE(callContractFunction("balanceOf(address)", ACCOUNT(0)) == encodeArgs(TOKENSUPPLY - transfer));
|
||||
BOOST_REQUIRE(callContractFunction("balanceOf(address)", ACCOUNT(1)) == encodeArgs(transfer));
|
||||
|
||||
// Second transfer should fail.
|
||||
BOOST_CHECK(callContractFunction("transfer(address,uint256)", ACCOUNT(1), u256(transfer)) != SUCCESS);
|
||||
BOOST_CHECK(callContractFunction("balanceOf(address)", ACCOUNT(0)) == encodeArgs(TOKENSUPPLY - transfer));
|
||||
BOOST_CHECK(callContractFunction("balanceOf(address)", ACCOUNT(1)) == encodeArgs(transfer));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(invalid_transfer_from)
|
||||
{
|
||||
deployErc20();
|
||||
|
||||
// TransferFrom without approval.
|
||||
int transfer = 300;
|
||||
|
||||
// Send account(1) some ether for gas.
|
||||
m_sender = account(0);
|
||||
sendEther(account(1), 1000 * ether);
|
||||
BOOST_REQUIRE(balanceAt(account(1)) >= 1000 * ether);
|
||||
|
||||
// Try the transfer; ensure nothing changes.
|
||||
m_sender = account(1);
|
||||
BOOST_CHECK(callContractFunction("transferFrom(address,address,uint256)", ACCOUNT(0), ACCOUNT(2), u256(transfer)) != SUCCESS);
|
||||
BOOST_CHECK(callContractFunction("balanceOf(address)", ACCOUNT(2)) == encodeArgs(0));
|
||||
BOOST_CHECK(callContractFunction("balanceOf(address)", ACCOUNT(0)) == encodeArgs(TOKENSUPPLY));
|
||||
BOOST_CHECK(callContractFunction("allowance(address,address)", ACCOUNT(0), ACCOUNT(1)) == encodeArgs(0));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(invalid_reapprove)
|
||||
{
|
||||
deployErc20();
|
||||
|
||||
m_sender = account(0);
|
||||
|
||||
// Approve account(1) to transfer up to 1000 tokens from account(0).
|
||||
int allow1 = 1000;
|
||||
BOOST_REQUIRE(callContractFunction("approve(address,uint256)", ACCOUNT(1), u256(allow1)) == SUCCESS);
|
||||
BOOST_REQUIRE(callContractFunction("allowance(address,address)", ACCOUNT(0), ACCOUNT(1)) == encodeArgs(allow1));
|
||||
|
||||
// Now approve account(1) to transfer up to 500 tokens from account(0).
|
||||
// Should fail (we need to reset allowance to 0 first).
|
||||
int allow2 = 500;
|
||||
BOOST_CHECK(callContractFunction("approve(address,uint256)", ACCOUNT(1), u256(allow2)) != SUCCESS);
|
||||
BOOST_CHECK(callContractFunction("allowance(address,address)", ACCOUNT(0), ACCOUNT(1)) == encodeArgs(allow1));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(bad_data)
|
||||
{
|
||||
deployErc20();
|
||||
|
||||
m_sender = account(0);
|
||||
|
||||
// Correct data: transfer(address _to, 1).
|
||||
sendMessage((bytes)fromHex("a9059cbb") + (bytes)fromHex("000000000000000000000000123456789a123456789a123456789a123456789a") + encodeArgs(1), false, 0);
|
||||
BOOST_CHECK(m_transactionSuccessful);
|
||||
BOOST_CHECK(m_output == SUCCESS);
|
||||
|
||||
// Too little data (address is truncated by one byte).
|
||||
sendMessage((bytes)fromHex("a9059cbb") + (bytes)fromHex("000000000000000000000000123456789a123456789a123456789a12345678") + encodeArgs(1), false, 0);
|
||||
BOOST_CHECK(!m_transactionSuccessful);
|
||||
BOOST_CHECK(m_output != SUCCESS);
|
||||
|
||||
// Too much data (address is extended with a zero byte).
|
||||
sendMessage((bytes)fromHex("a9059cbb") + (bytes)fromHex("000000000000000000000000123456789a123456789a123456789a123456789a00") + encodeArgs(1), false, 0);
|
||||
BOOST_CHECK(!m_transactionSuccessful);
|
||||
BOOST_CHECK(m_output != SUCCESS);
|
||||
|
||||
// Invalid address (a bit above the 160th is set).
|
||||
sendMessage((bytes)fromHex("a9059cbb") + (bytes)fromHex("000000000000000000000100123456789a123456789a123456789a123456789a") + encodeArgs(1), false, 0);
|
||||
BOOST_CHECK(!m_transactionSuccessful);
|
||||
BOOST_CHECK(m_output != SUCCESS);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
} // end namespaces
|
||||
@@ -1,181 +0,0 @@
|
||||
/*
|
||||
This file is part of solidity.
|
||||
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Alex Beregszaszi
|
||||
* @date 2016
|
||||
* Unit tests for the LLL parser.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <liblll/Compiler.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace solidity::lll::test
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
bool successParse(std::string const& _source)
|
||||
{
|
||||
std::string ret = lll::parseLLL(_source);
|
||||
return ret.size() != 0;
|
||||
}
|
||||
|
||||
std::string parse(std::string const& _source)
|
||||
{
|
||||
return lll::parseLLL(_source);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(LLLParser)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(smoke_test)
|
||||
{
|
||||
char const* text = "1";
|
||||
BOOST_CHECK(successParse(text));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(string)
|
||||
{
|
||||
char const* text = "\"string\"";
|
||||
BOOST_CHECK(successParse(text));
|
||||
BOOST_CHECK_EQUAL(parse(text), R"("string")");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(symbol)
|
||||
{
|
||||
char const* text = "symbol";
|
||||
BOOST_CHECK(successParse(text));
|
||||
BOOST_CHECK_EQUAL(parse(text), R"(symbol)");
|
||||
|
||||
BOOST_CHECK(successParse("'symbol"));
|
||||
BOOST_CHECK_EQUAL(parse(text), R"(symbol)");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(decimals)
|
||||
{
|
||||
char const* text = "1234";
|
||||
BOOST_CHECK(successParse(text));
|
||||
BOOST_CHECK_EQUAL(parse(text), R"(1234)");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(hexadecimals)
|
||||
{
|
||||
char const* text = "0x1234";
|
||||
BOOST_CHECK(successParse(text));
|
||||
BOOST_CHECK_EQUAL(parse(text), R"(4660)");
|
||||
|
||||
BOOST_CHECK(!successParse("0x"));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(sequence)
|
||||
{
|
||||
char const* text = "{ 1234 }";
|
||||
BOOST_CHECK(successParse(text));
|
||||
BOOST_CHECK_EQUAL(parse(text), R"({ 1234 })");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(empty_sequence)
|
||||
{
|
||||
char const* text = "{}";
|
||||
BOOST_CHECK(successParse(text));
|
||||
BOOST_CHECK_EQUAL(parse(text), R"({ })");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(mload)
|
||||
{
|
||||
char const* text = "@0";
|
||||
BOOST_CHECK(successParse(text));
|
||||
BOOST_CHECK_EQUAL(parse(text), R"(@ 0)");
|
||||
|
||||
BOOST_CHECK(successParse("@0x0"));
|
||||
BOOST_CHECK(successParse("@symbol"));
|
||||
BOOST_CHECK(!successParse("@"));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(sload)
|
||||
{
|
||||
char const* text = "@@0";
|
||||
BOOST_CHECK(successParse(text));
|
||||
BOOST_CHECK_EQUAL(parse(text), R"(@@ 0)");
|
||||
|
||||
BOOST_CHECK(successParse("@@0x0"));
|
||||
BOOST_CHECK(successParse("@@symbol"));
|
||||
BOOST_CHECK(!successParse("@@"));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(mstore)
|
||||
{
|
||||
char const* text = "[0]:0";
|
||||
BOOST_CHECK(successParse(text));
|
||||
BOOST_CHECK_EQUAL(parse(text), R"([ 0 ] 0)");
|
||||
|
||||
BOOST_CHECK(successParse("[0] 0"));
|
||||
BOOST_CHECK(successParse("[0x0]:0x0"));
|
||||
BOOST_CHECK(successParse("[symbol]:symbol"));
|
||||
BOOST_CHECK(!successParse("[]"));
|
||||
BOOST_CHECK(!successParse("[0]"));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(sstore)
|
||||
{
|
||||
char const* text = "[[0]]:0";
|
||||
BOOST_CHECK(successParse(text));
|
||||
BOOST_CHECK_EQUAL(parse(text), R"([[ 0 ]] 0)");
|
||||
|
||||
BOOST_CHECK(successParse("[[0]] 0"));
|
||||
BOOST_CHECK(successParse("[[0x0]]:0x0"));
|
||||
BOOST_CHECK(successParse("[[symbol]]:symbol"));
|
||||
BOOST_CHECK(!successParse("[[]]"));
|
||||
BOOST_CHECK(!successParse("[[0x0]]"));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(calldataload)
|
||||
{
|
||||
char const* text = "$0";
|
||||
BOOST_CHECK(successParse(text));
|
||||
BOOST_CHECK_EQUAL(parse(text), R"($ 0)");
|
||||
|
||||
BOOST_CHECK(successParse("$0x0"));
|
||||
BOOST_CHECK(successParse("$symbol"));
|
||||
BOOST_CHECK(!successParse("$"));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(list)
|
||||
{
|
||||
char const* text = "( 1234 )";
|
||||
BOOST_CHECK(successParse(text));
|
||||
BOOST_CHECK_EQUAL(parse(text), R"(( 1234 ))");
|
||||
|
||||
BOOST_CHECK(successParse("( 1234 5467 )"));
|
||||
BOOST_CHECK(successParse("()"));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(macro_with_zero_args)
|
||||
{
|
||||
char const* text = "(def 'zeroargs () (asm INVALID))";
|
||||
BOOST_CHECK(successParse(text));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
} // end namespaces
|
||||
@@ -82,7 +82,7 @@ BOOST_AUTO_TEST_CASE(enums)
|
||||
}
|
||||
}
|
||||
)";
|
||||
bool newDecoder = solidity::test::Options::get().useABIEncoderV2;
|
||||
bool newDecoder = solidity::test::CommonOptions::get().useABIEncoderV2;
|
||||
BOTH_ENCODERS(
|
||||
compileAndRun(sourceCode);
|
||||
ABI_CHECK(callContractFunction("f(uint8)", 0), encodeArgs(u256(0)));
|
||||
@@ -104,7 +104,7 @@ BOOST_AUTO_TEST_CASE(cleanup)
|
||||
}
|
||||
}
|
||||
)";
|
||||
bool newDecoder = solidity::test::Options::get().useABIEncoderV2;
|
||||
bool newDecoder = solidity::test::CommonOptions::get().useABIEncoderV2;
|
||||
BOTH_ENCODERS(
|
||||
compileAndRun(sourceCode);
|
||||
ABI_CHECK(
|
||||
@@ -573,7 +573,7 @@ BOOST_AUTO_TEST_CASE(validation_function_type)
|
||||
function i(function () external[] calldata a) external pure returns (uint r) { a[0]; r = 4; }
|
||||
}
|
||||
)";
|
||||
bool newDecoder = solidity::test::Options::get().useABIEncoderV2;
|
||||
bool newDecoder = solidity::test::CommonOptions::get().useABIEncoderV2;
|
||||
string validFun{"01234567890123456789abcd"};
|
||||
string invalidFun{"01234567890123456789abcdX"};
|
||||
BOTH_ENCODERS(
|
||||
@@ -950,7 +950,7 @@ BOOST_AUTO_TEST_CASE(out_of_bounds_bool_value)
|
||||
function f(bool b) public pure returns (bool) { return b; }
|
||||
}
|
||||
)";
|
||||
bool newDecoder = solidity::test::Options::get().useABIEncoderV2;
|
||||
bool newDecoder = solidity::test::CommonOptions::get().useABIEncoderV2;
|
||||
BOTH_ENCODERS(
|
||||
compileAndRun(sourceCode);
|
||||
ABI_CHECK(callContractFunction("f(bool)", true), encodeArgs(true));
|
||||
|
||||
@@ -165,7 +165,7 @@ BOOST_AUTO_TEST_CASE(memory_array_one_dim)
|
||||
}
|
||||
)";
|
||||
|
||||
if (!solidity::test::Options::get().useABIEncoderV2)
|
||||
if (!solidity::test::CommonOptions::get().useABIEncoderV2)
|
||||
{
|
||||
compileAndRun(sourceCode);
|
||||
callContractFunction("f()");
|
||||
@@ -752,7 +752,7 @@ BOOST_AUTO_TEST_CASE(struct_in_constructor_indirect)
|
||||
}
|
||||
}
|
||||
)";
|
||||
if (solidity::test::Options::get().evmVersion().supportsReturndata())
|
||||
if (solidity::test::CommonOptions::get().evmVersion().supportsReturndata())
|
||||
{
|
||||
NEW_ENCODER(
|
||||
compileAndRun(sourceCode, 0, "D");
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
#include <test/libsolidity/ABIJsonTest.h>
|
||||
|
||||
#include <test/Options.h>
|
||||
#include <test/Common.h>
|
||||
|
||||
#include <libsolidity/interface/CompilerStack.h>
|
||||
#include <libsolutil/JSON.h>
|
||||
@@ -52,8 +52,8 @@ TestCase::TestResult ABIJsonTest::run(ostream& _stream, string const& _linePrefi
|
||||
CompilerStack compiler;
|
||||
|
||||
compiler.setSources({{"", "pragma solidity >=0.0;\n" + m_source}});
|
||||
compiler.setEVMVersion(solidity::test::Options::get().evmVersion());
|
||||
compiler.setOptimiserSettings(solidity::test::Options::get().optimize);
|
||||
compiler.setEVMVersion(solidity::test::CommonOptions::get().evmVersion());
|
||||
compiler.setOptimiserSettings(solidity::test::CommonOptions::get().optimize);
|
||||
if (!compiler.parseAndAnalyze())
|
||||
BOOST_THROW_EXCEPTION(runtime_error("Parsing contract failed"));
|
||||
|
||||
|
||||
@@ -282,7 +282,7 @@
|
||||
"name": "this",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 68,
|
||||
"referencedDeclaration": -28,
|
||||
"src": "217:4:1",
|
||||
"typeDescriptions":
|
||||
{
|
||||
|
||||
@@ -446,7 +446,7 @@
|
||||
[
|
||||
null
|
||||
],
|
||||
"referencedDeclaration": 68,
|
||||
"referencedDeclaration": -28,
|
||||
"type": "contract C",
|
||||
"value": "this"
|
||||
},
|
||||
|
||||
@@ -124,6 +124,7 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"evmVersion": %EVMVERSION%,
|
||||
"externalReferences": [],
|
||||
"id": 3,
|
||||
"nodeType": "InlineAssembly",
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"evmVersion": %EVMVERSION%,
|
||||
"externalReferences":
|
||||
[
|
||||
null
|
||||
|
||||
@@ -111,6 +111,7 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"evmVersion": %EVMVERSION%,
|
||||
"externalReferences": [],
|
||||
"id": 3,
|
||||
"nodeType": "InlineAssembly",
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"evmVersion": %EVMVERSION%,
|
||||
"externalReferences":
|
||||
[
|
||||
null
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"evmVersion": %EVMVERSION%,
|
||||
"externalReferences": [],
|
||||
"id": 3,
|
||||
"nodeType": "InlineAssembly",
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"evmVersion": %EVMVERSION%,
|
||||
"externalReferences":
|
||||
[
|
||||
null
|
||||
|
||||
@@ -124,6 +124,7 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"evmVersion": %EVMVERSION%,
|
||||
"externalReferences": [],
|
||||
"id": 3,
|
||||
"nodeType": "InlineAssembly",
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"evmVersion": %EVMVERSION%,
|
||||
"externalReferences":
|
||||
[
|
||||
null
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
{
|
||||
"absolutePath": "a",
|
||||
"exportedSymbols":
|
||||
{
|
||||
"C":
|
||||
[
|
||||
8
|
||||
]
|
||||
},
|
||||
"id": 9,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes":
|
||||
[
|
||||
{
|
||||
"abstract": false,
|
||||
"baseContracts": [],
|
||||
"contractDependencies": [],
|
||||
"contractKind": "contract",
|
||||
"documentation": null,
|
||||
"fullyImplemented": true,
|
||||
"id": 8,
|
||||
"linearizedBaseContracts":
|
||||
[
|
||||
8
|
||||
],
|
||||
"name": "C",
|
||||
"nodeType": "ContractDefinition",
|
||||
"nodes":
|
||||
[
|
||||
{
|
||||
"body":
|
||||
{
|
||||
"id": 6,
|
||||
"nodeType": "Block",
|
||||
"src": "57:97:1",
|
||||
"statements":
|
||||
[
|
||||
{
|
||||
"AST":
|
||||
{
|
||||
"nodeType": "YulBlock",
|
||||
"src": "72:78:1",
|
||||
"statements":
|
||||
[
|
||||
{
|
||||
"body":
|
||||
{
|
||||
"nodeType": "YulBlock",
|
||||
"src": "94:50:1",
|
||||
"statements":
|
||||
[
|
||||
{
|
||||
"body":
|
||||
{
|
||||
"nodeType": "YulBlock",
|
||||
"src": "118:3:1",
|
||||
"statements": []
|
||||
},
|
||||
"name": "f2",
|
||||
"nodeType": "YulFunctionDefinition",
|
||||
"src": "104:17:1"
|
||||
},
|
||||
{
|
||||
"nodeType": "YulAssignment",
|
||||
"src": "130:6:1",
|
||||
"value":
|
||||
{
|
||||
"kind": "number",
|
||||
"nodeType": "YulLiteral",
|
||||
"src": "135:1:1",
|
||||
"type": "",
|
||||
"value": "2"
|
||||
},
|
||||
"variableNames":
|
||||
[
|
||||
{
|
||||
"name": "x",
|
||||
"nodeType": "YulIdentifier",
|
||||
"src": "130:1:1"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"name": "f1",
|
||||
"nodeType": "YulFunctionDefinition",
|
||||
"src": "80:64:1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"evmVersion": %EVMVERSION%,
|
||||
"externalReferences": [],
|
||||
"id": 5,
|
||||
"nodeType": "InlineAssembly",
|
||||
"src": "63:87:1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"documentation": null,
|
||||
"functionSelector": "26121ff0",
|
||||
"id": 7,
|
||||
"implemented": true,
|
||||
"kind": "function",
|
||||
"modifiers": [],
|
||||
"name": "f",
|
||||
"nodeType": "FunctionDefinition",
|
||||
"overrides": null,
|
||||
"parameters":
|
||||
{
|
||||
"id": 1,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [],
|
||||
"src": "25:2:1"
|
||||
},
|
||||
"returnParameters":
|
||||
{
|
||||
"id": 4,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters":
|
||||
[
|
||||
{
|
||||
"constant": false,
|
||||
"id": 3,
|
||||
"name": "x",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"overrides": null,
|
||||
"scope": 7,
|
||||
"src": "49:6:1",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
},
|
||||
"typeName":
|
||||
{
|
||||
"id": 2,
|
||||
"name": "uint",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "49:4:1",
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
}
|
||||
},
|
||||
"value": null,
|
||||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"src": "48:8:1"
|
||||
},
|
||||
"scope": 8,
|
||||
"src": "15:139:1",
|
||||
"stateMutability": "pure",
|
||||
"virtual": false,
|
||||
"visibility": "public"
|
||||
}
|
||||
],
|
||||
"scope": 9,
|
||||
"src": "0:156:1"
|
||||
}
|
||||
],
|
||||
"src": "0:157:1"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
contract C {
|
||||
function f() public pure returns (uint x) {
|
||||
assembly {
|
||||
function f1() {
|
||||
function f2() { }
|
||||
x := 2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----
|
||||
@@ -0,0 +1,148 @@
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"absolutePath": "a",
|
||||
"exportedSymbols":
|
||||
{
|
||||
"C":
|
||||
[
|
||||
8
|
||||
]
|
||||
}
|
||||
},
|
||||
"children":
|
||||
[
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"abstract": false,
|
||||
"baseContracts":
|
||||
[
|
||||
null
|
||||
],
|
||||
"contractDependencies":
|
||||
[
|
||||
null
|
||||
],
|
||||
"contractKind": "contract",
|
||||
"documentation": null,
|
||||
"fullyImplemented": true,
|
||||
"linearizedBaseContracts":
|
||||
[
|
||||
8
|
||||
],
|
||||
"name": "C",
|
||||
"scope": 9
|
||||
},
|
||||
"children":
|
||||
[
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"documentation": null,
|
||||
"functionSelector": "26121ff0",
|
||||
"implemented": true,
|
||||
"isConstructor": false,
|
||||
"kind": "function",
|
||||
"modifiers":
|
||||
[
|
||||
null
|
||||
],
|
||||
"name": "f",
|
||||
"overrides": null,
|
||||
"scope": 8,
|
||||
"stateMutability": "pure",
|
||||
"virtual": false,
|
||||
"visibility": "public"
|
||||
},
|
||||
"children":
|
||||
[
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"parameters":
|
||||
[
|
||||
null
|
||||
]
|
||||
},
|
||||
"children": [],
|
||||
"id": 1,
|
||||
"name": "ParameterList",
|
||||
"src": "25:2:1"
|
||||
},
|
||||
{
|
||||
"children":
|
||||
[
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"constant": false,
|
||||
"name": "x",
|
||||
"overrides": null,
|
||||
"scope": 7,
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"type": "uint256",
|
||||
"value": null,
|
||||
"visibility": "internal"
|
||||
},
|
||||
"children":
|
||||
[
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"name": "uint",
|
||||
"type": "uint256"
|
||||
},
|
||||
"id": 2,
|
||||
"name": "ElementaryTypeName",
|
||||
"src": "49:4:1"
|
||||
}
|
||||
],
|
||||
"id": 3,
|
||||
"name": "VariableDeclaration",
|
||||
"src": "49:6:1"
|
||||
}
|
||||
],
|
||||
"id": 4,
|
||||
"name": "ParameterList",
|
||||
"src": "48:8:1"
|
||||
},
|
||||
{
|
||||
"children":
|
||||
[
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"evmVersion": %EVMVERSION%,
|
||||
"externalReferences":
|
||||
[
|
||||
null
|
||||
],
|
||||
"operations": "{\n function f1()\n {\n function f2()\n { }\n x := 2\n }\n}"
|
||||
},
|
||||
"children": [],
|
||||
"id": 5,
|
||||
"name": "InlineAssembly",
|
||||
"src": "63:87:1"
|
||||
}
|
||||
],
|
||||
"id": 6,
|
||||
"name": "Block",
|
||||
"src": "57:97:1"
|
||||
}
|
||||
],
|
||||
"id": 7,
|
||||
"name": "FunctionDefinition",
|
||||
"src": "15:139:1"
|
||||
}
|
||||
],
|
||||
"id": 8,
|
||||
"name": "ContractDefinition",
|
||||
"src": "0:156:1"
|
||||
}
|
||||
],
|
||||
"id": 9,
|
||||
"name": "SourceUnit",
|
||||
"src": "0:157:1"
|
||||
}
|
||||
@@ -176,6 +176,7 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"evmVersion": %EVMVERSION%,
|
||||
"externalReferences":
|
||||
[
|
||||
{
|
||||
|
||||
@@ -166,6 +166,7 @@
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"evmVersion": %EVMVERSION%,
|
||||
"externalReferences":
|
||||
[
|
||||
{
|
||||
|
||||
@@ -65,6 +65,7 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"evmVersion": %EVMVERSION%,
|
||||
"externalReferences": [],
|
||||
"id": 3,
|
||||
"nodeType": "InlineAssembly",
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"evmVersion": %EVMVERSION%,
|
||||
"externalReferences":
|
||||
[
|
||||
null
|
||||
|
||||
@@ -157,7 +157,24 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"externalReferences": [],
|
||||
"evmVersion": %EVMVERSION%,
|
||||
"externalReferences":
|
||||
[
|
||||
{
|
||||
"declaration": 5,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "141:1:1",
|
||||
"valueSize": 18446744073709551615
|
||||
},
|
||||
{
|
||||
"declaration": 5,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "172:1:1",
|
||||
"valueSize": 18446744073709551615
|
||||
}
|
||||
],
|
||||
"id": 3,
|
||||
"nodeType": "InlineAssembly",
|
||||
"src": "52:138:1"
|
||||
|
||||
@@ -89,9 +89,23 @@
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"evmVersion": %EVMVERSION%,
|
||||
"externalReferences":
|
||||
[
|
||||
null
|
||||
{
|
||||
"declaration": 5,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "141:1:1",
|
||||
"valueSize": 18446744073709551615
|
||||
},
|
||||
{
|
||||
"declaration": 5,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "172:1:1",
|
||||
"valueSize": 18446744073709551615
|
||||
}
|
||||
],
|
||||
"operations": "{\n let f := 0\n switch calldatasize()\n case 0 { f := 1 }\n default { f := 2 }\n}"
|
||||
},
|
||||
|
||||
@@ -107,6 +107,7 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"evmVersion": %EVMVERSION%,
|
||||
"externalReferences":
|
||||
[
|
||||
{
|
||||
|
||||
@@ -135,6 +135,7 @@
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"evmVersion": %EVMVERSION%,
|
||||
"externalReferences":
|
||||
[
|
||||
{
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
{
|
||||
"C":
|
||||
[
|
||||
1
|
||||
2
|
||||
]
|
||||
},
|
||||
"id": 2,
|
||||
"id": 3,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes":
|
||||
[
|
||||
@@ -16,17 +16,23 @@
|
||||
"baseContracts": [],
|
||||
"contractDependencies": [],
|
||||
"contractKind": "contract",
|
||||
"documentation": "This contract is empty",
|
||||
"documentation":
|
||||
{
|
||||
"id": 1,
|
||||
"nodeType": "StructuredDocumentation",
|
||||
"src": "0:27:1",
|
||||
"text": "This contract is empty"
|
||||
},
|
||||
"fullyImplemented": true,
|
||||
"id": 1,
|
||||
"id": 2,
|
||||
"linearizedBaseContracts":
|
||||
[
|
||||
1
|
||||
2
|
||||
],
|
||||
"name": "C",
|
||||
"nodeType": "ContractDefinition",
|
||||
"nodes": [],
|
||||
"scope": 2,
|
||||
"scope": 3,
|
||||
"src": "28:13:1"
|
||||
}
|
||||
],
|
||||
@@ -38,10 +44,10 @@
|
||||
{
|
||||
"C":
|
||||
[
|
||||
3
|
||||
5
|
||||
]
|
||||
},
|
||||
"id": 4,
|
||||
"id": 6,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes":
|
||||
[
|
||||
@@ -50,17 +56,23 @@
|
||||
"baseContracts": [],
|
||||
"contractDependencies": [],
|
||||
"contractKind": "contract",
|
||||
"documentation": "This contract is empty\nand has a line-breaking comment.",
|
||||
"documentation":
|
||||
{
|
||||
"id": 4,
|
||||
"nodeType": "StructuredDocumentation",
|
||||
"src": "0:61:2",
|
||||
"text": "This contract is empty\nand has a line-breaking comment."
|
||||
},
|
||||
"fullyImplemented": true,
|
||||
"id": 3,
|
||||
"id": 5,
|
||||
"linearizedBaseContracts":
|
||||
[
|
||||
3
|
||||
5
|
||||
],
|
||||
"name": "C",
|
||||
"nodeType": "ContractDefinition",
|
||||
"nodes": [],
|
||||
"scope": 4,
|
||||
"scope": 6,
|
||||
"src": "62:13:2"
|
||||
}
|
||||
],
|
||||
@@ -72,10 +84,10 @@
|
||||
{
|
||||
"C":
|
||||
[
|
||||
15
|
||||
20
|
||||
]
|
||||
},
|
||||
"id": 16,
|
||||
"id": 21,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes":
|
||||
[
|
||||
@@ -86,10 +98,10 @@
|
||||
"contractKind": "contract",
|
||||
"documentation": null,
|
||||
"fullyImplemented": true,
|
||||
"id": 15,
|
||||
"id": 20,
|
||||
"linearizedBaseContracts":
|
||||
[
|
||||
15
|
||||
20
|
||||
],
|
||||
"name": "C",
|
||||
"nodeType": "ContractDefinition",
|
||||
@@ -97,13 +109,19 @@
|
||||
[
|
||||
{
|
||||
"anonymous": false,
|
||||
"documentation": "Some comment on Evt.",
|
||||
"id": 6,
|
||||
"documentation":
|
||||
{
|
||||
"id": 7,
|
||||
"nodeType": "StructuredDocumentation",
|
||||
"src": "15:26:3",
|
||||
"text": "Some comment on Evt."
|
||||
},
|
||||
"id": 9,
|
||||
"name": "Evt",
|
||||
"nodeType": "EventDefinition",
|
||||
"parameters":
|
||||
{
|
||||
"id": 5,
|
||||
"id": 8,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [],
|
||||
"src": "51:2:3"
|
||||
@@ -113,26 +131,32 @@
|
||||
{
|
||||
"body":
|
||||
{
|
||||
"id": 9,
|
||||
"id": 13,
|
||||
"nodeType": "Block",
|
||||
"src": "99:6:3",
|
||||
"statements":
|
||||
[
|
||||
{
|
||||
"id": 8,
|
||||
"id": 12,
|
||||
"nodeType": "PlaceholderStatement",
|
||||
"src": "101:1:3"
|
||||
}
|
||||
]
|
||||
},
|
||||
"documentation": "Some comment on mod.",
|
||||
"id": 10,
|
||||
"documentation":
|
||||
{
|
||||
"id": 10,
|
||||
"nodeType": "StructuredDocumentation",
|
||||
"src": "57:26:3",
|
||||
"text": "Some comment on mod."
|
||||
},
|
||||
"id": 14,
|
||||
"name": "mod",
|
||||
"nodeType": "ModifierDefinition",
|
||||
"overrides": null,
|
||||
"parameters":
|
||||
{
|
||||
"id": 7,
|
||||
"id": 11,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [],
|
||||
"src": "96:2:3"
|
||||
@@ -144,14 +168,20 @@
|
||||
{
|
||||
"body":
|
||||
{
|
||||
"id": 13,
|
||||
"id": 18,
|
||||
"nodeType": "Block",
|
||||
"src": "155:2:3",
|
||||
"statements": []
|
||||
},
|
||||
"documentation": "Some comment on fn.",
|
||||
"documentation":
|
||||
{
|
||||
"id": 15,
|
||||
"nodeType": "StructuredDocumentation",
|
||||
"src": "108:25:3",
|
||||
"text": "Some comment on fn."
|
||||
},
|
||||
"functionSelector": "a4a2c40b",
|
||||
"id": 14,
|
||||
"id": 19,
|
||||
"implemented": true,
|
||||
"kind": "function",
|
||||
"modifiers": [],
|
||||
@@ -160,26 +190,26 @@
|
||||
"overrides": null,
|
||||
"parameters":
|
||||
{
|
||||
"id": 11,
|
||||
"id": 16,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [],
|
||||
"src": "145:2:3"
|
||||
},
|
||||
"returnParameters":
|
||||
{
|
||||
"id": 12,
|
||||
"id": 17,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [],
|
||||
"src": "155:0:3"
|
||||
},
|
||||
"scope": 15,
|
||||
"scope": 20,
|
||||
"src": "134:23:3",
|
||||
"stateMutability": "nonpayable",
|
||||
"virtual": false,
|
||||
"visibility": "public"
|
||||
}
|
||||
],
|
||||
"scope": 16,
|
||||
"scope": 21,
|
||||
"src": "0:159:3"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
{
|
||||
"C":
|
||||
[
|
||||
15
|
||||
20
|
||||
]
|
||||
}
|
||||
},
|
||||
@@ -29,10 +29,10 @@
|
||||
"fullyImplemented": true,
|
||||
"linearizedBaseContracts":
|
||||
[
|
||||
15
|
||||
20
|
||||
],
|
||||
"name": "C",
|
||||
"scope": 16
|
||||
"scope": 21
|
||||
},
|
||||
"children":
|
||||
[
|
||||
@@ -40,11 +40,19 @@
|
||||
"attributes":
|
||||
{
|
||||
"anonymous": false,
|
||||
"documentation": "Some comment on Evt.",
|
||||
"name": "Evt"
|
||||
},
|
||||
"children":
|
||||
[
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"text": "Some comment on Evt."
|
||||
},
|
||||
"id": 7,
|
||||
"name": "StructuredDocumentation",
|
||||
"src": "15:26:3"
|
||||
},
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
@@ -54,19 +62,18 @@
|
||||
]
|
||||
},
|
||||
"children": [],
|
||||
"id": 5,
|
||||
"id": 8,
|
||||
"name": "ParameterList",
|
||||
"src": "51:2:3"
|
||||
}
|
||||
],
|
||||
"id": 6,
|
||||
"id": 9,
|
||||
"name": "EventDefinition",
|
||||
"src": "42:12:3"
|
||||
},
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"documentation": "Some comment on mod.",
|
||||
"name": "mod",
|
||||
"overrides": null,
|
||||
"virtual": false,
|
||||
@@ -77,55 +84,12 @@
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"parameters":
|
||||
[
|
||||
null
|
||||
]
|
||||
"text": "Some comment on mod."
|
||||
},
|
||||
"children": [],
|
||||
"id": 7,
|
||||
"name": "ParameterList",
|
||||
"src": "96:2:3"
|
||||
"id": 10,
|
||||
"name": "StructuredDocumentation",
|
||||
"src": "57:26:3"
|
||||
},
|
||||
{
|
||||
"children":
|
||||
[
|
||||
{
|
||||
"id": 8,
|
||||
"name": "PlaceholderStatement",
|
||||
"src": "101:1:3"
|
||||
}
|
||||
],
|
||||
"id": 9,
|
||||
"name": "Block",
|
||||
"src": "99:6:3"
|
||||
}
|
||||
],
|
||||
"id": 10,
|
||||
"name": "ModifierDefinition",
|
||||
"src": "84:21:3"
|
||||
},
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"documentation": "Some comment on fn.",
|
||||
"functionSelector": "a4a2c40b",
|
||||
"implemented": true,
|
||||
"isConstructor": false,
|
||||
"kind": "function",
|
||||
"modifiers":
|
||||
[
|
||||
null
|
||||
],
|
||||
"name": "fn",
|
||||
"overrides": null,
|
||||
"scope": 15,
|
||||
"stateMutability": "nonpayable",
|
||||
"virtual": false,
|
||||
"visibility": "public"
|
||||
},
|
||||
"children":
|
||||
[
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
@@ -137,6 +101,66 @@
|
||||
"children": [],
|
||||
"id": 11,
|
||||
"name": "ParameterList",
|
||||
"src": "96:2:3"
|
||||
},
|
||||
{
|
||||
"children":
|
||||
[
|
||||
{
|
||||
"id": 12,
|
||||
"name": "PlaceholderStatement",
|
||||
"src": "101:1:3"
|
||||
}
|
||||
],
|
||||
"id": 13,
|
||||
"name": "Block",
|
||||
"src": "99:6:3"
|
||||
}
|
||||
],
|
||||
"id": 14,
|
||||
"name": "ModifierDefinition",
|
||||
"src": "84:21:3"
|
||||
},
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"functionSelector": "a4a2c40b",
|
||||
"implemented": true,
|
||||
"isConstructor": false,
|
||||
"kind": "function",
|
||||
"modifiers":
|
||||
[
|
||||
null
|
||||
],
|
||||
"name": "fn",
|
||||
"overrides": null,
|
||||
"scope": 20,
|
||||
"stateMutability": "nonpayable",
|
||||
"virtual": false,
|
||||
"visibility": "public"
|
||||
},
|
||||
"children":
|
||||
[
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"text": "Some comment on fn."
|
||||
},
|
||||
"id": 15,
|
||||
"name": "StructuredDocumentation",
|
||||
"src": "108:25:3"
|
||||
},
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"parameters":
|
||||
[
|
||||
null
|
||||
]
|
||||
},
|
||||
"children": [],
|
||||
"id": 16,
|
||||
"name": "ParameterList",
|
||||
"src": "145:2:3"
|
||||
},
|
||||
{
|
||||
@@ -148,7 +172,7 @@
|
||||
]
|
||||
},
|
||||
"children": [],
|
||||
"id": 12,
|
||||
"id": 17,
|
||||
"name": "ParameterList",
|
||||
"src": "155:0:3"
|
||||
},
|
||||
@@ -161,22 +185,22 @@
|
||||
]
|
||||
},
|
||||
"children": [],
|
||||
"id": 13,
|
||||
"id": 18,
|
||||
"name": "Block",
|
||||
"src": "155:2:3"
|
||||
}
|
||||
],
|
||||
"id": 14,
|
||||
"id": 19,
|
||||
"name": "FunctionDefinition",
|
||||
"src": "134:23:3"
|
||||
}
|
||||
],
|
||||
"id": 15,
|
||||
"id": 20,
|
||||
"name": "ContractDefinition",
|
||||
"src": "0:159:3"
|
||||
}
|
||||
],
|
||||
"id": 16,
|
||||
"id": 21,
|
||||
"name": "SourceUnit",
|
||||
"src": "0:160:3"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,227 @@
|
||||
{
|
||||
"absolutePath": "a",
|
||||
"exportedSymbols":
|
||||
{
|
||||
"C":
|
||||
[
|
||||
17
|
||||
]
|
||||
},
|
||||
"id": 18,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes":
|
||||
[
|
||||
{
|
||||
"abstract": false,
|
||||
"baseContracts": [],
|
||||
"contractDependencies": [],
|
||||
"contractKind": "contract",
|
||||
"documentation": null,
|
||||
"fullyImplemented": true,
|
||||
"id": 17,
|
||||
"linearizedBaseContracts":
|
||||
[
|
||||
17
|
||||
],
|
||||
"name": "C",
|
||||
"nodeType": "ContractDefinition",
|
||||
"nodes":
|
||||
[
|
||||
{
|
||||
"canonicalName": "C.E",
|
||||
"id": 4,
|
||||
"members":
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"name": "A",
|
||||
"nodeType": "EnumValue",
|
||||
"src": "26:1:1"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "B",
|
||||
"nodeType": "EnumValue",
|
||||
"src": "29:1:1"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "C",
|
||||
"nodeType": "EnumValue",
|
||||
"src": "32:1:1"
|
||||
}
|
||||
],
|
||||
"name": "E",
|
||||
"nodeType": "EnumDefinition",
|
||||
"src": "17:18:1"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"id": 8,
|
||||
"name": "a",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"overrides": null,
|
||||
"scope": 17,
|
||||
"src": "40:20:1",
|
||||
"stateVariable": true,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_mapping$_t_contract$_C_$17_$_t_bool_$",
|
||||
"typeString": "mapping(contract C => bool)"
|
||||
},
|
||||
"typeName":
|
||||
{
|
||||
"id": 7,
|
||||
"keyType":
|
||||
{
|
||||
"contractScope": null,
|
||||
"id": 5,
|
||||
"name": "C",
|
||||
"nodeType": "UserDefinedTypeName",
|
||||
"referencedDeclaration": 17,
|
||||
"src": "48:1:1",
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_contract$_C_$17",
|
||||
"typeString": "contract C"
|
||||
}
|
||||
},
|
||||
"nodeType": "Mapping",
|
||||
"src": "40:18:1",
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_mapping$_t_contract$_C_$17_$_t_bool_$",
|
||||
"typeString": "mapping(contract C => bool)"
|
||||
},
|
||||
"valueType":
|
||||
{
|
||||
"id": 6,
|
||||
"name": "bool",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "53:4:1",
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_bool",
|
||||
"typeString": "bool"
|
||||
}
|
||||
}
|
||||
},
|
||||
"value": null,
|
||||
"visibility": "internal"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"id": 12,
|
||||
"name": "b",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"overrides": null,
|
||||
"scope": 17,
|
||||
"src": "66:26:1",
|
||||
"stateVariable": true,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_mapping$_t_address_$_t_bool_$",
|
||||
"typeString": "mapping(address => bool)"
|
||||
},
|
||||
"typeName":
|
||||
{
|
||||
"id": 11,
|
||||
"keyType":
|
||||
{
|
||||
"id": 9,
|
||||
"name": "address",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "74:7:1",
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
}
|
||||
},
|
||||
"nodeType": "Mapping",
|
||||
"src": "66:24:1",
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_mapping$_t_address_$_t_bool_$",
|
||||
"typeString": "mapping(address => bool)"
|
||||
},
|
||||
"valueType":
|
||||
{
|
||||
"id": 10,
|
||||
"name": "bool",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "85:4:1",
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_bool",
|
||||
"typeString": "bool"
|
||||
}
|
||||
}
|
||||
},
|
||||
"value": null,
|
||||
"visibility": "internal"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"id": 16,
|
||||
"name": "c",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"overrides": null,
|
||||
"scope": 17,
|
||||
"src": "98:20:1",
|
||||
"stateVariable": true,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_mapping$_t_enum$_E_$4_$_t_bool_$",
|
||||
"typeString": "mapping(enum C.E => bool)"
|
||||
},
|
||||
"typeName":
|
||||
{
|
||||
"id": 15,
|
||||
"keyType":
|
||||
{
|
||||
"contractScope": null,
|
||||
"id": 13,
|
||||
"name": "E",
|
||||
"nodeType": "UserDefinedTypeName",
|
||||
"referencedDeclaration": 4,
|
||||
"src": "106:1:1",
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_enum$_E_$4",
|
||||
"typeString": "enum C.E"
|
||||
}
|
||||
},
|
||||
"nodeType": "Mapping",
|
||||
"src": "98:18:1",
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_mapping$_t_enum$_E_$4_$_t_bool_$",
|
||||
"typeString": "mapping(enum C.E => bool)"
|
||||
},
|
||||
"valueType":
|
||||
{
|
||||
"id": 14,
|
||||
"name": "bool",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "111:4:1",
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_bool",
|
||||
"typeString": "bool"
|
||||
}
|
||||
}
|
||||
},
|
||||
"value": null,
|
||||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"scope": 18,
|
||||
"src": "0:121:1"
|
||||
}
|
||||
],
|
||||
"src": "0:122:1"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
contract C {
|
||||
enum E { A, B, C }
|
||||
mapping(C => bool) a;
|
||||
mapping(address => bool) b;
|
||||
mapping(E => bool) c;
|
||||
}
|
||||
|
||||
// ----
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user