Merge pull request #10686 from ethereum/libraryCallGuard

Library call guard.
This commit is contained in:
chriseth 2021-01-12 16:52:24 +01:00 committed by GitHub
commit d97b9ba865
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 351 additions and 223 deletions

View File

@ -80,6 +80,11 @@ string IRNames::implicitConstructor(ContractDefinition const& _contract)
return "constructor_" + _contract.name() + "_" + to_string(_contract.id()); return "constructor_" + _contract.name() + "_" + to_string(_contract.id());
} }
string IRNames::libraryAddressImmutable()
{
return "library_deploy_address";
}
string IRNames::constantValueFunction(VariableDeclaration const& _constant) string IRNames::constantValueFunction(VariableDeclaration const& _constant)
{ {
solAssert(_constant.isConstant(), ""); solAssert(_constant.isConstant(), "");

View File

@ -55,6 +55,7 @@ struct IRNames
static std::string runtimeObject(ContractDefinition const& _contract); static std::string runtimeObject(ContractDefinition const& _contract);
static std::string internalDispatch(YulArity const& _arity); static std::string internalDispatch(YulArity const& _arity);
static std::string implicitConstructor(ContractDefinition const& _contract); static std::string implicitConstructor(ContractDefinition const& _contract);
static std::string libraryAddressImmutable();
static std::string constantValueFunction(VariableDeclaration const& _constant); static std::string constantValueFunction(VariableDeclaration const& _constant);
static std::string localVariable(VariableDeclaration const& _declaration); static std::string localVariable(VariableDeclaration const& _declaration);
static std::string localVariable(Expression const& _expression); static std::string localVariable(Expression const& _expression);

View File

@ -94,16 +94,20 @@ string IRGenerator::generate(
code { code {
<memoryInitCreation> <memoryInitCreation>
<callValueCheck> <callValueCheck>
<?notLibrary> <?library>
<!library>
<?constructorHasParams> let <constructorParams> := <copyConstructorArguments>() </constructorHasParams> <?constructorHasParams> let <constructorParams> := <copyConstructorArguments>() </constructorHasParams>
<implicitConstructor>(<constructorParams>) <implicitConstructor>(<constructorParams>)
</notLibrary> </library>
<deploy> <deploy>
<functions> <functions>
} }
object "<RuntimeObject>" { object "<RuntimeObject>" {
code { code {
<memoryInitRuntime> <memoryInitRuntime>
<?library>
let called_via_delegatecall := iszero(eq(loadimmutable("<library_address>"), address()))
</library>
<dispatch> <dispatch>
<runtimeFunctions> <runtimeFunctions>
} }
@ -118,7 +122,7 @@ string IRGenerator::generate(
m_context.registerImmutableVariable(*var); m_context.registerImmutableVariable(*var);
t("CreationObject", IRNames::creationObject(_contract)); t("CreationObject", IRNames::creationObject(_contract));
t("notLibrary", !_contract.isLibrary()); t("library", _contract.isLibrary());
FunctionDefinition const* constructor = _contract.constructor(); FunctionDefinition const* constructor = _contract.constructor();
t("callValueCheck", !constructor || !constructor->isPayable() ? callValueCheck() : ""); t("callValueCheck", !constructor || !constructor->isPayable() ? callValueCheck() : "");
@ -156,6 +160,7 @@ string IRGenerator::generate(
// Do not register immutables to avoid assignment. // Do not register immutables to avoid assignment.
t("RuntimeObject", IRNames::runtimeObject(_contract)); t("RuntimeObject", IRNames::runtimeObject(_contract));
t("library_address", IRNames::libraryAddressImmutable());
t("dispatch", dispatchRoutine(_contract)); t("dispatch", dispatchRoutine(_contract));
generateQueuedFunctions(); generateQueuedFunctions();
generateInternalDispatchFunctions(); generateInternalDispatchFunctions();
@ -747,20 +752,30 @@ string IRGenerator::deployCode(ContractDefinition const& _contract)
vector<map<string, string>> loadImmutables; vector<map<string, string>> loadImmutables;
vector<map<string, string>> storeImmutables; vector<map<string, string>> storeImmutables;
for (VariableDeclaration const* immutable: ContractType(_contract).immutableVariables()) if (_contract.isLibrary())
{ {
solUnimplementedAssert(immutable->type()->isValueType(), ""); solAssert(ContractType(_contract).immutableVariables().empty(), "");
solUnimplementedAssert(immutable->type()->sizeOnStack() == 1, "");
string yulVar = m_context.newYulVariable();
loadImmutables.emplace_back(map<string, string>{
{"var"s, yulVar},
{"memoryOffset"s, to_string(m_context.immutableMemoryOffset(*immutable))}
});
storeImmutables.emplace_back(map<string, string>{ storeImmutables.emplace_back(map<string, string>{
{"var"s, yulVar}, {"var"s, "address()"},
{"immutableName"s, to_string(immutable->id())} {"immutableName"s, IRNames::libraryAddressImmutable()}
}); });
} }
else
for (VariableDeclaration const* immutable: ContractType(_contract).immutableVariables())
{
solUnimplementedAssert(immutable->type()->isValueType(), "");
solUnimplementedAssert(immutable->type()->sizeOnStack() == 1, "");
string yulVar = m_context.newYulVariable();
loadImmutables.emplace_back(map<string, string>{
{"var"s, yulVar},
{"memoryOffset"s, to_string(m_context.immutableMemoryOffset(*immutable))}
});
storeImmutables.emplace_back(map<string, string>{
{"var"s, yulVar},
{"immutableName"s, to_string(immutable->id())}
});
}
t("loadImmutables", std::move(loadImmutables)); t("loadImmutables", std::move(loadImmutables));
// reverse order to ease stack strain // reverse order to ease stack strain
reverse(storeImmutables.begin(), storeImmutables.end()); reverse(storeImmutables.begin(), storeImmutables.end());
@ -784,6 +799,7 @@ string IRGenerator::dispatchRoutine(ContractDefinition const& _contract)
case <functionSelector> case <functionSelector>
{ {
// <functionName> // <functionName>
<delegatecallCheck>
<callValueCheck> <callValueCheck>
<?+params>let <params> := </+params> <abiDecode>(4, calldatasize()) <?+params>let <params> := </+params> <abiDecode>(4, calldatasize())
<?+retParams>let <retParams> := </+retParams> <function>(<params>) <?+retParams>let <retParams> := </+retParams> <function>(<params>)
@ -806,7 +822,18 @@ string IRGenerator::dispatchRoutine(ContractDefinition const& _contract)
templ["functionSelector"] = "0x" + function.first.hex(); templ["functionSelector"] = "0x" + function.first.hex();
FunctionTypePointer const& type = function.second; FunctionTypePointer const& type = function.second;
templ["functionName"] = type->externalSignature(); templ["functionName"] = type->externalSignature();
templ["callValueCheck"] = type->isPayable() ? "" : callValueCheck(); string delegatecallCheck;
if (_contract.isLibrary())
{
solAssert(!type->isPayable(), "");
if (type->stateMutability() > StateMutability::View)
// If the function is not a view function and is called without DELEGATECALL,
// we revert.
// TODO add revert message.
delegatecallCheck = "if iszero(called_via_delegatecall) { revert(0, 0) }";
}
templ["delegatecallCheck"] = delegatecallCheck;
templ["callValueCheck"] = (type->isPayable() || _contract.isLibrary()) ? "" : callValueCheck();
unsigned paramVars = make_shared<TupleType>(type->parameterTypes())->sizeOnStack(); unsigned paramVars = make_shared<TupleType>(type->parameterTypes())->sizeOnStack();
unsigned retVars = make_shared<TupleType>(type->returnParameterTypes())->sizeOnStack(); unsigned retVars = make_shared<TupleType>(type->returnParameterTypes())->sizeOnStack();
@ -824,11 +851,19 @@ string IRGenerator::dispatchRoutine(ContractDefinition const& _contract)
solAssert(false, "Unexpected declaration for function!"); solAssert(false, "Unexpected declaration for function!");
templ["allocate"] = m_utils.allocationFunction(); templ["allocate"] = m_utils.allocationFunction();
templ["abiEncode"] = abiFunctions.tupleEncoder(type->returnParameterTypes(), type->returnParameterTypes(), false); templ["abiEncode"] = abiFunctions.tupleEncoder(type->returnParameterTypes(), type->returnParameterTypes(), _contract.isLibrary());
} }
t("cases", functions); t("cases", functions);
if (FunctionDefinition const* etherReceiver = _contract.receiveFunction())
{
solAssert(!_contract.isLibrary(), "");
t("receiveEther", m_context.enqueueFunctionForCodeGeneration(*etherReceiver) + "() stop()");
}
else
t("receiveEther", "");
if (FunctionDefinition const* fallback = _contract.fallbackFunction()) if (FunctionDefinition const* fallback = _contract.fallbackFunction())
{ {
solAssert(!_contract.isLibrary(), "");
string fallbackCode; string fallbackCode;
if (!fallback->isPayable()) if (!fallback->isPayable())
fallbackCode += callValueCheck() + "\n"; fallbackCode += callValueCheck() + "\n";
@ -846,10 +881,6 @@ string IRGenerator::dispatchRoutine(ContractDefinition const& _contract)
} }
else else
t("fallback", "revert(0, 0)"); t("fallback", "revert(0, 0)");
if (FunctionDefinition const* etherReceiver = _contract.receiveFunction())
t("receiveEther", m_context.enqueueFunctionForCodeGeneration(*etherReceiver) + "() stop()");
else
t("receiveEther", "");
return t.render(); return t.render();
} }

View File

@ -1664,7 +1664,10 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
FunctionType const& functionType = dynamic_cast<FunctionType const&>( FunctionType const& functionType = dynamic_cast<FunctionType const&>(
*_memberAccess.expression().annotation().type *_memberAccess.expression().annotation().type
); );
if (functionType.kind() == FunctionType::Kind::External) if (
functionType.kind() == FunctionType::Kind::External ||
functionType.kind() == FunctionType::Kind::DelegateCall
)
define(IRVariable{_memberAccess}, IRVariable(_memberAccess.expression()).part("functionSelector")); define(IRVariable{_memberAccess}, IRVariable(_memberAccess.expression()).part("functionSelector"));
else if (functionType.kind() == FunctionType::Kind::Declaration) else if (functionType.kind() == FunctionType::Kind::Declaration)
{ {
@ -1672,7 +1675,7 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
define(IRVariable{_memberAccess}) << formatNumber(functionType.externalIdentifier() << 224) << "\n"; define(IRVariable{_memberAccess}) << formatNumber(functionType.externalIdentifier() << 224) << "\n";
} }
else else
solAssert(false, "Invalid use of .selector"); solAssert(false, "Invalid use of .selector: " + functionType.toString(false));
} }
else if (member == "address") else if (member == "address")
{ {

View File

@ -35,6 +35,7 @@ object "C_81" {
case 0x70cb9605 case 0x70cb9605
{ {
// f(uint256,uint256,uint256,uint256) // f(uint256,uint256,uint256,uint256)
if callvalue() { revert(0, 0) } if callvalue() { revert(0, 0) }
let param_0, param_1, param_2, param_3 := abi_decode_tuple_t_uint256t_uint256t_uint256t_uint256(4, calldatasize()) let param_0, param_1, param_2, param_3 := abi_decode_tuple_t_uint256t_uint256t_uint256t_uint256(4, calldatasize())
let ret_0, ret_1, ret_2, ret_3 := fun_f_80(param_0, param_1, param_2, param_3) let ret_0, ret_1, ret_2, ret_3 := fun_f_80(param_0, param_1, param_2, param_3)

View File

@ -34,6 +34,7 @@ object \"C_7\" {
case 0x26121ff0 case 0x26121ff0
{ {
// f() // f()
if callvalue() { revert(0, 0) } if callvalue() { revert(0, 0) }
abi_decode_tuple_(4, calldatasize()) abi_decode_tuple_(4, calldatasize())
fun_f_6() fun_f_6()

View File

@ -85,6 +85,7 @@ object \"D_16\" {
case 0x26121ff0 case 0x26121ff0
{ {
// f() // f()
if callvalue() { revert(0, 0) } if callvalue() { revert(0, 0) }
abi_decode_tuple_(4, calldatasize()) abi_decode_tuple_(4, calldatasize())
fun_f_15() fun_f_15()

View File

@ -35,6 +35,7 @@ object "test_11" {
case 0x26121ff0 case 0x26121ff0
{ {
// f() // f()
if callvalue() { revert(0, 0) } if callvalue() { revert(0, 0) }
abi_decode_tuple_(4, calldatasize()) abi_decode_tuple_(4, calldatasize())
let ret_0 := fun_f_10() let ret_0 := fun_f_10()

View File

@ -34,6 +34,7 @@ object \"C_11\" {
case 0x26121ff0 case 0x26121ff0
{ {
// f() // f()
if callvalue() { revert(0, 0) } if callvalue() { revert(0, 0) }
abi_decode_tuple_(4, calldatasize()) abi_decode_tuple_(4, calldatasize())
let ret_0 := fun_f_10() let ret_0 := fun_f_10()

View File

@ -34,6 +34,7 @@ object \"C_11\" {
case 0x26121ff0 case 0x26121ff0
{ {
// f() // f()
if callvalue() { revert(0, 0) } if callvalue() { revert(0, 0) }
abi_decode_tuple_(4, calldatasize()) abi_decode_tuple_(4, calldatasize())
let ret_0 := fun_f_10() let ret_0 := fun_f_10()

View File

@ -34,6 +34,7 @@ object \"C_11\" {
case 0x26121ff0 case 0x26121ff0
{ {
// f() // f()
if callvalue() { revert(0, 0) } if callvalue() { revert(0, 0) }
abi_decode_tuple_(4, calldatasize()) abi_decode_tuple_(4, calldatasize())
let ret_0 := fun_f_10() let ret_0 := fun_f_10()

View File

@ -34,6 +34,7 @@ object \"C_11\" {
case 0x26121ff0 case 0x26121ff0
{ {
// f() // f()
if callvalue() { revert(0, 0) } if callvalue() { revert(0, 0) }
abi_decode_tuple_(4, calldatasize()) abi_decode_tuple_(4, calldatasize())
let ret_0 := fun_f_10() let ret_0 := fun_f_10()

View File

@ -34,6 +34,7 @@ object \"C_11\" {
case 0x26121ff0 case 0x26121ff0
{ {
// f() // f()
if callvalue() { revert(0, 0) } if callvalue() { revert(0, 0) }
abi_decode_tuple_(4, calldatasize()) abi_decode_tuple_(4, calldatasize())
let ret_0 := fun_f_10() let ret_0 := fun_f_10()

View File

@ -2239,10 +2239,13 @@ BOOST_AUTO_TEST_CASE(library_call_in_homestead)
} }
} }
)"; )";
compileAndRun(sourceCode, 0, "Lib"); ALSO_VIA_YUL(
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{"Lib", m_contractAddress}}); DISABLE_EWASM_TESTRUN()
ABI_CHECK(callContractFunction("f()"), encodeArgs()); compileAndRun(sourceCode, 0, "Lib");
ABI_CHECK(callContractFunction("sender()"), encodeArgs(m_sender)); compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{"Lib", m_contractAddress}});
ABI_CHECK(callContractFunction("f()"), encodeArgs());
ABI_CHECK(callContractFunction("sender()"), encodeArgs(m_sender));
)
} }
BOOST_AUTO_TEST_CASE(library_call_protection) BOOST_AUTO_TEST_CASE(library_call_protection)
@ -2266,16 +2269,19 @@ BOOST_AUTO_TEST_CASE(library_call_protection)
function pu() public pure returns (uint) { return Lib.pu(); } function pu() public pure returns (uint) { return Lib.pu(); }
} }
)"; )";
compileAndRun(sourceCode, 0, "Lib"); ALSO_VIA_YUL(
ABI_CHECK(callContractFunction("np(Lib.S storage)", 0), encodeArgs()); DISABLE_EWASM_TESTRUN()
ABI_CHECK(callContractFunction("v(Lib.S storage)", 0), encodeArgs(m_sender)); compileAndRun(sourceCode, 0, "Lib");
ABI_CHECK(callContractFunction("pu()"), encodeArgs(2)); ABI_CHECK(callContractFunction("np(Lib.S storage)", 0), encodeArgs());
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{"Lib", m_contractAddress}}); ABI_CHECK(callContractFunction("v(Lib.S storage)", 0), encodeArgs(m_sender));
ABI_CHECK(callContractFunction("s()"), encodeArgs(0)); ABI_CHECK(callContractFunction("pu()"), encodeArgs(2));
ABI_CHECK(callContractFunction("np()"), encodeArgs(m_sender)); compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{"Lib", m_contractAddress}});
ABI_CHECK(callContractFunction("s()"), encodeArgs(3)); ABI_CHECK(callContractFunction("s()"), encodeArgs(0));
ABI_CHECK(callContractFunction("v()"), encodeArgs(m_sender)); ABI_CHECK(callContractFunction("np()"), encodeArgs(m_sender));
ABI_CHECK(callContractFunction("pu()"), encodeArgs(2)); ABI_CHECK(callContractFunction("s()"), encodeArgs(3));
ABI_CHECK(callContractFunction("v()"), encodeArgs(m_sender));
ABI_CHECK(callContractFunction("pu()"), encodeArgs(2));
)
} }
BOOST_AUTO_TEST_CASE(library_staticcall_delegatecall) BOOST_AUTO_TEST_CASE(library_staticcall_delegatecall)
@ -2537,17 +2543,20 @@ BOOST_AUTO_TEST_CASE(struct_referencing)
function a2() public pure returns (uint) { L.S memory s; return L.a(s); } function a2() public pure returns (uint) { L.S memory s; return L.a(s); }
} }
)"; )";
compileAndRun(sourceCode, 0, "L"); ALSO_VIA_YUL(
ABI_CHECK(callContractFunction("f()"), encodeArgs(0, 3)); DISABLE_EWASM_TESTRUN()
ABI_CHECK(callContractFunction("g()"), encodeArgs(4)); compileAndRun(sourceCode, 0, "L");
compileAndRun(sourceCode, 0, "C", bytes(), map<string, h160>{ {"L", m_contractAddress}}); ABI_CHECK(callContractFunction("f()"), encodeArgs(0, 3));
ABI_CHECK(callContractFunction("f()"), encodeArgs(1)); ABI_CHECK(callContractFunction("g()"), encodeArgs(4));
ABI_CHECK(callContractFunction("g()"), encodeArgs(2)); compileAndRun(sourceCode, 0, "C", bytes(), map<string, h160>{ {"L", m_contractAddress}});
ABI_CHECK(callContractFunction("h()"), encodeArgs(0, 5)); ABI_CHECK(callContractFunction("f()"), encodeArgs(1));
ABI_CHECK(callContractFunction("x()"), encodeArgs(0, 3)); ABI_CHECK(callContractFunction("g()"), encodeArgs(2));
ABI_CHECK(callContractFunction("y()"), encodeArgs(4)); ABI_CHECK(callContractFunction("h()"), encodeArgs(0, 5));
ABI_CHECK(callContractFunction("a1()"), encodeArgs(1)); ABI_CHECK(callContractFunction("x()"), encodeArgs(0, 3));
ABI_CHECK(callContractFunction("a2()"), encodeArgs(2)); ABI_CHECK(callContractFunction("y()"), encodeArgs(4));
ABI_CHECK(callContractFunction("a1()"), encodeArgs(1));
ABI_CHECK(callContractFunction("a2()"), encodeArgs(2));
)
} }
BOOST_AUTO_TEST_CASE(enum_referencing) BOOST_AUTO_TEST_CASE(enum_referencing)
@ -2583,15 +2592,18 @@ BOOST_AUTO_TEST_CASE(enum_referencing)
} }
} }
)"; )";
compileAndRun(sourceCode, 0, "L"); ALSO_VIA_YUL(
ABI_CHECK(callContractFunction("f()"), encodeArgs(1)); DISABLE_EWASM_TESTRUN()
ABI_CHECK(callContractFunction("g()"), encodeArgs(3)); compileAndRun(sourceCode, 0, "L");
compileAndRun(sourceCode, 0, "C", bytes(), map<string, h160>{{"L", m_contractAddress}}); ABI_CHECK(callContractFunction("f()"), encodeArgs(1));
ABI_CHECK(callContractFunction("f()"), encodeArgs(3)); ABI_CHECK(callContractFunction("g()"), encodeArgs(3));
ABI_CHECK(callContractFunction("g()"), encodeArgs(3)); compileAndRun(sourceCode, 0, "C", bytes(), map<string, h160>{{"L", m_contractAddress}});
ABI_CHECK(callContractFunction("h()"), encodeArgs(1)); ABI_CHECK(callContractFunction("f()"), encodeArgs(3));
ABI_CHECK(callContractFunction("x()"), encodeArgs(1)); ABI_CHECK(callContractFunction("g()"), encodeArgs(3));
ABI_CHECK(callContractFunction("y()"), encodeArgs(3)); ABI_CHECK(callContractFunction("h()"), encodeArgs(1));
ABI_CHECK(callContractFunction("x()"), encodeArgs(1));
ABI_CHECK(callContractFunction("y()"), encodeArgs(3));
)
} }
BOOST_AUTO_TEST_CASE(bytes_in_arguments) BOOST_AUTO_TEST_CASE(bytes_in_arguments)
@ -3413,9 +3425,12 @@ BOOST_AUTO_TEST_CASE(library_call)
} }
} }
)"; )";
compileAndRun(sourceCode, 0, "Lib"); ALSO_VIA_YUL(
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{"Lib", m_contractAddress}}); DISABLE_EWASM_TESTRUN()
ABI_CHECK(callContractFunction("f(uint256)", u256(33)), encodeArgs(u256(33) * 9)); compileAndRun(sourceCode, 0, "Lib");
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{"Lib", m_contractAddress}});
ABI_CHECK(callContractFunction("f(uint256)", u256(33)), encodeArgs(u256(33) * 9));
)
} }
BOOST_AUTO_TEST_CASE(library_function_external) BOOST_AUTO_TEST_CASE(library_function_external)
@ -3428,9 +3443,12 @@ BOOST_AUTO_TEST_CASE(library_function_external)
} }
} }
)"; )";
compileAndRun(sourceCode, 0, "Lib"); ALSO_VIA_YUL(
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{"Lib", m_contractAddress}}); DISABLE_EWASM_TESTRUN()
ABI_CHECK(callContractFunction("f(bytes)", u256(0x20), u256(5), "abcde"), encodeArgs("c")); compileAndRun(sourceCode, 0, "Lib");
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{"Lib", m_contractAddress}});
ABI_CHECK(callContractFunction("f(bytes)", u256(0x20), u256(5), "abcde"), encodeArgs("c"));
)
} }
BOOST_AUTO_TEST_CASE(library_stray_values) BOOST_AUTO_TEST_CASE(library_stray_values)
@ -3445,9 +3463,12 @@ BOOST_AUTO_TEST_CASE(library_stray_values)
} }
} }
)"; )";
compileAndRun(sourceCode, 0, "Lib"); ALSO_VIA_YUL(
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{"Lib", m_contractAddress}}); DISABLE_EWASM_TESTRUN()
ABI_CHECK(callContractFunction("f(uint256)", u256(33)), encodeArgs(u256(42))); compileAndRun(sourceCode, 0, "Lib");
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{"Lib", m_contractAddress}});
ABI_CHECK(callContractFunction("f(uint256)", u256(33)), encodeArgs(u256(42)));
)
} }
BOOST_AUTO_TEST_CASE(internal_types_in_library) BOOST_AUTO_TEST_CASE(internal_types_in_library)
@ -3475,9 +3496,12 @@ BOOST_AUTO_TEST_CASE(internal_types_in_library)
} }
} }
)"; )";
compileAndRun(sourceCode, 0, "Lib"); ALSO_VIA_YUL(
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{"Lib", m_contractAddress}}); DISABLE_EWASM_TESTRUN()
ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(4), u256(17))); compileAndRun(sourceCode, 0, "Lib");
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{"Lib", m_contractAddress}});
ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(4), u256(17)));
)
} }
BOOST_AUTO_TEST_CASE(mapping_arguments_in_library) BOOST_AUTO_TEST_CASE(mapping_arguments_in_library)
@ -3506,22 +3530,25 @@ BOOST_AUTO_TEST_CASE(mapping_arguments_in_library)
} }
} }
)"; )";
compileAndRun(sourceCode, 0, "Lib"); ALSO_VIA_YUL(
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{"Lib", m_contractAddress}}); DISABLE_EWASM_TESTRUN()
ABI_CHECK(callContractFunction("set(uint256,uint256)", u256(1), u256(42)), encodeArgs(u256(0))); compileAndRun(sourceCode, 0, "Lib");
ABI_CHECK(callContractFunction("set(uint256,uint256)", u256(2), u256(84)), encodeArgs(u256(0))); compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{"Lib", m_contractAddress}});
ABI_CHECK(callContractFunction("set(uint256,uint256)", u256(21), u256(7)), encodeArgs(u256(0))); ABI_CHECK(callContractFunction("set(uint256,uint256)", u256(1), u256(42)), encodeArgs(u256(0)));
ABI_CHECK(callContractFunction("get(uint256)", u256(0)), encodeArgs(u256(0))); ABI_CHECK(callContractFunction("set(uint256,uint256)", u256(2), u256(84)), encodeArgs(u256(0)));
ABI_CHECK(callContractFunction("get(uint256)", u256(1)), encodeArgs(u256(42))); ABI_CHECK(callContractFunction("set(uint256,uint256)", u256(21), u256(7)), encodeArgs(u256(0)));
ABI_CHECK(callContractFunction("get(uint256)", u256(2)), encodeArgs(u256(84))); ABI_CHECK(callContractFunction("get(uint256)", u256(0)), encodeArgs(u256(0)));
ABI_CHECK(callContractFunction("get(uint256)", u256(21)), encodeArgs(u256(7))); ABI_CHECK(callContractFunction("get(uint256)", u256(1)), encodeArgs(u256(42)));
ABI_CHECK(callContractFunction("set(uint256,uint256)", u256(1), u256(21)), encodeArgs(u256(42))); ABI_CHECK(callContractFunction("get(uint256)", u256(2)), encodeArgs(u256(84)));
ABI_CHECK(callContractFunction("set(uint256,uint256)", u256(2), u256(42)), encodeArgs(u256(84))); ABI_CHECK(callContractFunction("get(uint256)", u256(21)), encodeArgs(u256(7)));
ABI_CHECK(callContractFunction("set(uint256,uint256)", u256(21), u256(14)), encodeArgs(u256(7))); ABI_CHECK(callContractFunction("set(uint256,uint256)", u256(1), u256(21)), encodeArgs(u256(42)));
ABI_CHECK(callContractFunction("get(uint256)", u256(0)), encodeArgs(u256(0))); ABI_CHECK(callContractFunction("set(uint256,uint256)", u256(2), u256(42)), encodeArgs(u256(84)));
ABI_CHECK(callContractFunction("get(uint256)", u256(1)), encodeArgs(u256(21))); ABI_CHECK(callContractFunction("set(uint256,uint256)", u256(21), u256(14)), encodeArgs(u256(7)));
ABI_CHECK(callContractFunction("get(uint256)", u256(2)), encodeArgs(u256(42))); ABI_CHECK(callContractFunction("get(uint256)", u256(0)), encodeArgs(u256(0)));
ABI_CHECK(callContractFunction("get(uint256)", u256(21)), encodeArgs(u256(14))); ABI_CHECK(callContractFunction("get(uint256)", u256(1)), encodeArgs(u256(21)));
ABI_CHECK(callContractFunction("get(uint256)", u256(2)), encodeArgs(u256(42)));
ABI_CHECK(callContractFunction("get(uint256)", u256(21)), encodeArgs(u256(14)));
)
} }
BOOST_AUTO_TEST_CASE(mapping_returns_in_library) BOOST_AUTO_TEST_CASE(mapping_returns_in_library)
@ -3554,52 +3581,55 @@ BOOST_AUTO_TEST_CASE(mapping_returns_in_library)
} }
} }
)"; )";
compileAndRun(sourceCode, 0, "Lib"); ALSO_VIA_YUL(
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{"Lib", m_contractAddress}}); DISABLE_EWASM_TESTRUN()
ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", true, u256(1), u256(42)), encodeArgs(u256(0))); compileAndRun(sourceCode, 0, "Lib");
ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", true, u256(2), u256(84)), encodeArgs(u256(0))); compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{"Lib", m_contractAddress}});
ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", true, u256(21), u256(7)), encodeArgs(u256(0))); ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", true, u256(1), u256(42)), encodeArgs(u256(0)));
ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", false, u256(1), u256(10)), encodeArgs(u256(0))); ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", true, u256(2), u256(84)), encodeArgs(u256(0)));
ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", false, u256(2), u256(11)), encodeArgs(u256(0))); ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", true, u256(21), u256(7)), encodeArgs(u256(0)));
ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", false, u256(21), u256(12)), encodeArgs(u256(0))); ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", false, u256(1), u256(10)), encodeArgs(u256(0)));
ABI_CHECK(callContractFunction("get(bool,uint256)", true, u256(0)), encodeArgs(u256(0))); ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", false, u256(2), u256(11)), encodeArgs(u256(0)));
ABI_CHECK(callContractFunction("get(bool,uint256)", true, u256(1)), encodeArgs(u256(42))); ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", false, u256(21), u256(12)), encodeArgs(u256(0)));
ABI_CHECK(callContractFunction("get(bool,uint256)", true, u256(2)), encodeArgs(u256(84))); ABI_CHECK(callContractFunction("get(bool,uint256)", true, u256(0)), encodeArgs(u256(0)));
ABI_CHECK(callContractFunction("get(bool,uint256)", true, u256(21)), encodeArgs(u256(7))); ABI_CHECK(callContractFunction("get(bool,uint256)", true, u256(1)), encodeArgs(u256(42)));
ABI_CHECK(callContractFunction("get_a(uint256)", u256(0)), encodeArgs(u256(0))); ABI_CHECK(callContractFunction("get(bool,uint256)", true, u256(2)), encodeArgs(u256(84)));
ABI_CHECK(callContractFunction("get_a(uint256)", u256(1)), encodeArgs(u256(42))); ABI_CHECK(callContractFunction("get(bool,uint256)", true, u256(21)), encodeArgs(u256(7)));
ABI_CHECK(callContractFunction("get_a(uint256)", u256(2)), encodeArgs(u256(84))); ABI_CHECK(callContractFunction("get_a(uint256)", u256(0)), encodeArgs(u256(0)));
ABI_CHECK(callContractFunction("get_a(uint256)", u256(21)), encodeArgs(u256(7))); ABI_CHECK(callContractFunction("get_a(uint256)", u256(1)), encodeArgs(u256(42)));
ABI_CHECK(callContractFunction("get(bool,uint256)", false, u256(0)), encodeArgs(u256(0))); ABI_CHECK(callContractFunction("get_a(uint256)", u256(2)), encodeArgs(u256(84)));
ABI_CHECK(callContractFunction("get(bool,uint256)", false, u256(1)), encodeArgs(u256(10))); ABI_CHECK(callContractFunction("get_a(uint256)", u256(21)), encodeArgs(u256(7)));
ABI_CHECK(callContractFunction("get(bool,uint256)", false, u256(2)), encodeArgs(u256(11))); ABI_CHECK(callContractFunction("get(bool,uint256)", false, u256(0)), encodeArgs(u256(0)));
ABI_CHECK(callContractFunction("get(bool,uint256)", false, u256(21)), encodeArgs(u256(12))); ABI_CHECK(callContractFunction("get(bool,uint256)", false, u256(1)), encodeArgs(u256(10)));
ABI_CHECK(callContractFunction("get_b(uint256)", u256(0)), encodeArgs(u256(0))); ABI_CHECK(callContractFunction("get(bool,uint256)", false, u256(2)), encodeArgs(u256(11)));
ABI_CHECK(callContractFunction("get_b(uint256)", u256(1)), encodeArgs(u256(10))); ABI_CHECK(callContractFunction("get(bool,uint256)", false, u256(21)), encodeArgs(u256(12)));
ABI_CHECK(callContractFunction("get_b(uint256)", u256(2)), encodeArgs(u256(11))); ABI_CHECK(callContractFunction("get_b(uint256)", u256(0)), encodeArgs(u256(0)));
ABI_CHECK(callContractFunction("get_b(uint256)", u256(21)), encodeArgs(u256(12))); ABI_CHECK(callContractFunction("get_b(uint256)", u256(1)), encodeArgs(u256(10)));
ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", true, u256(1), u256(21)), encodeArgs(u256(42))); ABI_CHECK(callContractFunction("get_b(uint256)", u256(2)), encodeArgs(u256(11)));
ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", true, u256(2), u256(42)), encodeArgs(u256(84))); ABI_CHECK(callContractFunction("get_b(uint256)", u256(21)), encodeArgs(u256(12)));
ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", true, u256(21), u256(14)), encodeArgs(u256(7))); ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", true, u256(1), u256(21)), encodeArgs(u256(42)));
ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", false, u256(1), u256(30)), encodeArgs(u256(10))); ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", true, u256(2), u256(42)), encodeArgs(u256(84)));
ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", false, u256(2), u256(31)), encodeArgs(u256(11))); ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", true, u256(21), u256(14)), encodeArgs(u256(7)));
ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", false, u256(21), u256(32)), encodeArgs(u256(12))); ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", false, u256(1), u256(30)), encodeArgs(u256(10)));
ABI_CHECK(callContractFunction("get_a(uint256)", u256(0)), encodeArgs(u256(0))); ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", false, u256(2), u256(31)), encodeArgs(u256(11)));
ABI_CHECK(callContractFunction("get_a(uint256)", u256(1)), encodeArgs(u256(21))); ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", false, u256(21), u256(32)), encodeArgs(u256(12)));
ABI_CHECK(callContractFunction("get_a(uint256)", u256(2)), encodeArgs(u256(42))); ABI_CHECK(callContractFunction("get_a(uint256)", u256(0)), encodeArgs(u256(0)));
ABI_CHECK(callContractFunction("get_a(uint256)", u256(21)), encodeArgs(u256(14))); ABI_CHECK(callContractFunction("get_a(uint256)", u256(1)), encodeArgs(u256(21)));
ABI_CHECK(callContractFunction("get(bool,uint256)", true, u256(0)), encodeArgs(u256(0))); ABI_CHECK(callContractFunction("get_a(uint256)", u256(2)), encodeArgs(u256(42)));
ABI_CHECK(callContractFunction("get(bool,uint256)", true, u256(1)), encodeArgs(u256(21))); ABI_CHECK(callContractFunction("get_a(uint256)", u256(21)), encodeArgs(u256(14)));
ABI_CHECK(callContractFunction("get(bool,uint256)", true, u256(2)), encodeArgs(u256(42))); ABI_CHECK(callContractFunction("get(bool,uint256)", true, u256(0)), encodeArgs(u256(0)));
ABI_CHECK(callContractFunction("get(bool,uint256)", true, u256(21)), encodeArgs(u256(14))); ABI_CHECK(callContractFunction("get(bool,uint256)", true, u256(1)), encodeArgs(u256(21)));
ABI_CHECK(callContractFunction("get_b(uint256)", u256(0)), encodeArgs(u256(0))); ABI_CHECK(callContractFunction("get(bool,uint256)", true, u256(2)), encodeArgs(u256(42)));
ABI_CHECK(callContractFunction("get_b(uint256)", u256(1)), encodeArgs(u256(30))); ABI_CHECK(callContractFunction("get(bool,uint256)", true, u256(21)), encodeArgs(u256(14)));
ABI_CHECK(callContractFunction("get_b(uint256)", u256(2)), encodeArgs(u256(31))); ABI_CHECK(callContractFunction("get_b(uint256)", u256(0)), encodeArgs(u256(0)));
ABI_CHECK(callContractFunction("get_b(uint256)", u256(21)), encodeArgs(u256(32))); ABI_CHECK(callContractFunction("get_b(uint256)", u256(1)), encodeArgs(u256(30)));
ABI_CHECK(callContractFunction("get(bool,uint256)", false, u256(0)), encodeArgs(u256(0))); ABI_CHECK(callContractFunction("get_b(uint256)", u256(2)), encodeArgs(u256(31)));
ABI_CHECK(callContractFunction("get(bool,uint256)", false, u256(1)), encodeArgs(u256(30))); ABI_CHECK(callContractFunction("get_b(uint256)", u256(21)), encodeArgs(u256(32)));
ABI_CHECK(callContractFunction("get(bool,uint256)", false, u256(2)), encodeArgs(u256(31))); ABI_CHECK(callContractFunction("get(bool,uint256)", false, u256(0)), encodeArgs(u256(0)));
ABI_CHECK(callContractFunction("get(bool,uint256)", false, u256(21)), encodeArgs(u256(32))); ABI_CHECK(callContractFunction("get(bool,uint256)", false, u256(1)), encodeArgs(u256(30)));
ABI_CHECK(callContractFunction("get(bool,uint256)", false, u256(2)), encodeArgs(u256(31)));
ABI_CHECK(callContractFunction("get(bool,uint256)", false, u256(21)), encodeArgs(u256(32)));
)
} }
BOOST_AUTO_TEST_CASE(mapping_returns_in_library_named) BOOST_AUTO_TEST_CASE(mapping_returns_in_library_named)
@ -3630,10 +3660,13 @@ BOOST_AUTO_TEST_CASE(mapping_returns_in_library_named)
} }
} }
)"; )";
compileAndRun(sourceCode, 0, "Lib"); ALSO_VIA_YUL(
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{"Lib", m_contractAddress}}); DISABLE_EWASM_TESTRUN()
ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(0), u256(42), u256(0), u256(0), u256(21), u256(84))); compileAndRun(sourceCode, 0, "Lib");
ABI_CHECK(callContractFunction("g()"), encodeArgs(u256(0), u256(42), u256(0), u256(0), u256(21), u256(17))); compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{"Lib", m_contractAddress}});
ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(0), u256(42), u256(0), u256(0), u256(21), u256(84)));
ABI_CHECK(callContractFunction("g()"), encodeArgs(u256(0), u256(42), u256(0), u256(0), u256(21), u256(17)));
)
} }
BOOST_AUTO_TEST_CASE(using_library_mappings_public) BOOST_AUTO_TEST_CASE(using_library_mappings_public)
@ -3658,9 +3691,12 @@ BOOST_AUTO_TEST_CASE(using_library_mappings_public)
} }
} }
)"; )";
compileAndRun(sourceCode, 0, "Lib"); ALSO_VIA_YUL(
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{"Lib", m_contractAddress}}); DISABLE_EWASM_TESTRUN()
ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(1), u256(0), u256(42), u256(23), u256(0), u256(99))); compileAndRun(sourceCode, 0, "Lib");
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{"Lib", m_contractAddress}});
ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(1), u256(0), u256(42), u256(23), u256(0), u256(99)));
)
} }
BOOST_AUTO_TEST_CASE(using_library_mappings_external) BOOST_AUTO_TEST_CASE(using_library_mappings_external)
@ -3719,9 +3755,12 @@ BOOST_AUTO_TEST_CASE(using_library_mappings_return)
} }
} }
)"; )";
compileAndRun(sourceCode, 0, "Lib"); ALSO_VIA_YUL(
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{"Lib", m_contractAddress}}); DISABLE_EWASM_TESTRUN()
ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(1), u256(0), u256(42), u256(23), u256(0), u256(99))); compileAndRun(sourceCode, 0, "Lib");
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{"Lib", m_contractAddress}});
ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(1), u256(0), u256(42), u256(23), u256(0), u256(99)));
)
} }
BOOST_AUTO_TEST_CASE(using_library_structs) BOOST_AUTO_TEST_CASE(using_library_structs)
@ -3747,9 +3786,12 @@ BOOST_AUTO_TEST_CASE(using_library_structs)
} }
} }
)"; )";
compileAndRun(sourceCode, 0, "Lib"); ALSO_VIA_YUL(
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{"Lib", m_contractAddress}}); DISABLE_EWASM_TESTRUN()
ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(7), u256(8))); compileAndRun(sourceCode, 0, "Lib");
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{"Lib", m_contractAddress}});
ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(7), u256(8)));
)
} }
BOOST_AUTO_TEST_CASE(short_strings) BOOST_AUTO_TEST_CASE(short_strings)
@ -3860,14 +3902,17 @@ BOOST_AUTO_TEST_CASE(short_strings)
} }
} }
)"; )";
compileAndRun(sourceCode, 0, "A"); ALSO_VIA_YUL(
ABI_CHECK(callContractFunction("data1()"), encodeDyn(string("123"))); DISABLE_EWASM_TESTRUN()
ABI_CHECK(callContractFunction("lengthChange()"), encodeArgs(u256(0))); compileAndRun(sourceCode, 0, "A");
BOOST_CHECK(storageEmpty(m_contractAddress)); ABI_CHECK(callContractFunction("data1()"), encodeDyn(string("123")));
ABI_CHECK(callContractFunction("deleteElements()"), encodeArgs(u256(0))); ABI_CHECK(callContractFunction("lengthChange()"), encodeArgs(u256(0)));
BOOST_CHECK(storageEmpty(m_contractAddress)); BOOST_CHECK(storageEmpty(m_contractAddress));
ABI_CHECK(callContractFunction("copy()"), encodeArgs(u256(0))); ABI_CHECK(callContractFunction("deleteElements()"), encodeArgs(u256(0)));
BOOST_CHECK(storageEmpty(m_contractAddress)); BOOST_CHECK(storageEmpty(m_contractAddress));
ABI_CHECK(callContractFunction("copy()"), encodeArgs(u256(0)));
BOOST_CHECK(storageEmpty(m_contractAddress));
)
} }
BOOST_AUTO_TEST_CASE(calldata_offset) BOOST_AUTO_TEST_CASE(calldata_offset)
@ -3901,17 +3946,20 @@ BOOST_AUTO_TEST_CASE(reject_ether_sent_to_library)
receive () external payable {} receive () external payable {}
} }
)"; )";
compileAndRun(sourceCode, 0, "lib"); ALSO_VIA_YUL(
Address libraryAddress = m_contractAddress; DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode, 10, "c"); compileAndRun(sourceCode, 0, "lib");
BOOST_CHECK_EQUAL(balanceAt(m_contractAddress), 10); Address libraryAddress = m_contractAddress;
BOOST_CHECK_EQUAL(balanceAt(libraryAddress), 0); compileAndRun(sourceCode, 10, "c");
ABI_CHECK(callContractFunction("f(address)", encodeArgs(libraryAddress)), encodeArgs(false)); BOOST_CHECK_EQUAL(balanceAt(m_contractAddress), 10);
BOOST_CHECK_EQUAL(balanceAt(m_contractAddress), 10); BOOST_CHECK_EQUAL(balanceAt(libraryAddress), 0);
BOOST_CHECK_EQUAL(balanceAt(libraryAddress), 0); ABI_CHECK(callContractFunction("f(address)", encodeArgs(libraryAddress)), encodeArgs(false));
ABI_CHECK(callContractFunction("f(address)", encodeArgs(m_contractAddress)), encodeArgs(true)); BOOST_CHECK_EQUAL(balanceAt(m_contractAddress), 10);
BOOST_CHECK_EQUAL(balanceAt(m_contractAddress), 10); BOOST_CHECK_EQUAL(balanceAt(libraryAddress), 0);
BOOST_CHECK_EQUAL(balanceAt(libraryAddress), 0); ABI_CHECK(callContractFunction("f(address)", encodeArgs(m_contractAddress)), encodeArgs(true));
BOOST_CHECK_EQUAL(balanceAt(m_contractAddress), 10);
BOOST_CHECK_EQUAL(balanceAt(libraryAddress), 0);
)
} }
BOOST_AUTO_TEST_CASE(create_memory_array_allocation_size) BOOST_AUTO_TEST_CASE(create_memory_array_allocation_size)
@ -3970,10 +4018,13 @@ BOOST_AUTO_TEST_CASE(using_for_function_on_struct)
} }
} }
)"; )";
compileAndRun(sourceCode, 0, "D"); ALSO_VIA_YUL(
compileAndRun(sourceCode, 0, "C", bytes(), map<string, h160>{{"D", m_contractAddress}}); DISABLE_EWASM_TESTRUN()
ABI_CHECK(callContractFunction("f(uint256)", u256(7)), encodeArgs(u256(3 * 7))); compileAndRun(sourceCode, 0, "D");
ABI_CHECK(callContractFunction("x()"), encodeArgs(u256(3 * 7))); compileAndRun(sourceCode, 0, "C", bytes(), map<string, h160>{{"D", m_contractAddress}});
ABI_CHECK(callContractFunction("f(uint256)", u256(7)), encodeArgs(u256(3 * 7)));
ABI_CHECK(callContractFunction("x()"), encodeArgs(u256(3 * 7)));
)
} }
BOOST_AUTO_TEST_CASE(using_for_overload) BOOST_AUTO_TEST_CASE(using_for_overload)
@ -3993,10 +4044,13 @@ BOOST_AUTO_TEST_CASE(using_for_overload)
} }
} }
)"; )";
compileAndRun(sourceCode, 0, "D"); ALSO_VIA_YUL(
compileAndRun(sourceCode, 0, "C", bytes(), map<string, h160>{{"D", m_contractAddress}}); DISABLE_EWASM_TESTRUN()
ABI_CHECK(callContractFunction("f(uint256)", u256(7)), encodeArgs(u256(6 * 7))); compileAndRun(sourceCode, 0, "D");
ABI_CHECK(callContractFunction("x()"), encodeArgs(u256(6 * 7))); compileAndRun(sourceCode, 0, "C", bytes(), map<string, h160>{{"D", m_contractAddress}});
ABI_CHECK(callContractFunction("f(uint256)", u256(7)), encodeArgs(u256(6 * 7)));
ABI_CHECK(callContractFunction("x()"), encodeArgs(u256(6 * 7)));
)
} }
BOOST_AUTO_TEST_CASE(using_for_by_name) BOOST_AUTO_TEST_CASE(using_for_by_name)
@ -4012,10 +4066,13 @@ BOOST_AUTO_TEST_CASE(using_for_by_name)
} }
} }
)"; )";
compileAndRun(sourceCode, 0, "D"); ALSO_VIA_YUL(
compileAndRun(sourceCode, 0, "C", bytes(), map<string, h160>{{"D", m_contractAddress}}); DISABLE_EWASM_TESTRUN()
ABI_CHECK(callContractFunction("f(uint256)", u256(7)), encodeArgs(u256(6 * 7))); compileAndRun(sourceCode, 0, "D");
ABI_CHECK(callContractFunction("x()"), encodeArgs(u256(6 * 7))); compileAndRun(sourceCode, 0, "C", bytes(), map<string, h160>{{"D", m_contractAddress}});
ABI_CHECK(callContractFunction("f(uint256)", u256(7)), encodeArgs(u256(6 * 7)));
ABI_CHECK(callContractFunction("x()"), encodeArgs(u256(6 * 7)));
)
} }
BOOST_AUTO_TEST_CASE(bound_function_in_function) BOOST_AUTO_TEST_CASE(bound_function_in_function)
@ -4032,9 +4089,12 @@ BOOST_AUTO_TEST_CASE(bound_function_in_function)
function t() public pure returns (uint) { return 7; } function t() public pure returns (uint) { return 7; }
} }
)"; )";
compileAndRun(sourceCode, 0, "L"); ALSO_VIA_YUL(
compileAndRun(sourceCode, 0, "C", bytes(), map<string, h160>{{"L", m_contractAddress}}); DISABLE_EWASM_TESTRUN()
ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(7))); compileAndRun(sourceCode, 0, "L");
compileAndRun(sourceCode, 0, "C", bytes(), map<string, h160>{{"L", m_contractAddress}});
ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(7)));
)
} }
BOOST_AUTO_TEST_CASE(bound_function_in_var) BOOST_AUTO_TEST_CASE(bound_function_in_var)
@ -4050,10 +4110,13 @@ BOOST_AUTO_TEST_CASE(bound_function_in_var)
} }
} }
)"; )";
compileAndRun(sourceCode, 0, "D"); ALSO_VIA_YUL(
compileAndRun(sourceCode, 0, "C", bytes(), map<string, h160>{{"D", m_contractAddress}}); DISABLE_EWASM_TESTRUN()
ABI_CHECK(callContractFunction("f(uint256)", u256(7)), encodeArgs(u256(6 * 7))); compileAndRun(sourceCode, 0, "D");
ABI_CHECK(callContractFunction("x()"), encodeArgs(u256(6 * 7))); compileAndRun(sourceCode, 0, "C", bytes(), map<string, h160>{{"D", m_contractAddress}});
ABI_CHECK(callContractFunction("f(uint256)", u256(7)), encodeArgs(u256(6 * 7)));
ABI_CHECK(callContractFunction("x()"), encodeArgs(u256(6 * 7)));
)
} }
BOOST_AUTO_TEST_CASE(bound_function_to_string) BOOST_AUTO_TEST_CASE(bound_function_to_string)
@ -4073,10 +4136,13 @@ BOOST_AUTO_TEST_CASE(bound_function_to_string)
} }
} }
)"; )";
compileAndRun(sourceCode, 0, "D"); ALSO_VIA_YUL(
compileAndRun(sourceCode, 0, "C", bytes(), map<string, h160>{{"D", m_contractAddress}}); DISABLE_EWASM_TESTRUN()
ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(3))); compileAndRun(sourceCode, 0, "D");
ABI_CHECK(callContractFunction("g()"), encodeArgs(u256(3))); compileAndRun(sourceCode, 0, "C", bytes(), map<string, h160>{{"D", m_contractAddress}});
ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(3)));
ABI_CHECK(callContractFunction("g()"), encodeArgs(u256(3)));
)
} }
BOOST_AUTO_TEST_CASE(inline_long_string_return) BOOST_AUTO_TEST_CASE(inline_long_string_return)
@ -4271,9 +4337,12 @@ BOOST_AUTO_TEST_CASE(payable_function_calls_library)
} }
} }
)"; )";
compileAndRun(sourceCode, 0, "L"); ALSO_VIA_YUL(
compileAndRun(sourceCode, 0, "C", bytes(), map<string, h160>{{"L", m_contractAddress}}); DISABLE_EWASM_TESTRUN()
ABI_CHECK(callContractFunctionWithValue("f()", 27), encodeArgs(u256(7))); compileAndRun(sourceCode, 0, "L");
compileAndRun(sourceCode, 0, "C", bytes(), map<string, h160>{{"L", m_contractAddress}});
ABI_CHECK(callContractFunctionWithValue("f()", 27), encodeArgs(u256(7)));
)
} }
BOOST_AUTO_TEST_CASE(non_payable_throw) BOOST_AUTO_TEST_CASE(non_payable_throw)
@ -4296,16 +4365,19 @@ BOOST_AUTO_TEST_CASE(non_payable_throw)
} }
)"; )";
compileAndRun(sourceCode, 0, "C"); ALSO_VIA_YUL(
ABI_CHECK(callContractFunctionWithValue("f()", 27), encodeArgs()); DISABLE_EWASM_TESTRUN()
BOOST_CHECK_EQUAL(balanceAt(m_contractAddress), 0); compileAndRun(sourceCode, 0, "C");
ABI_CHECK(callContractFunction(""), encodeArgs()); ABI_CHECK(callContractFunctionWithValue("f()", 27), encodeArgs());
ABI_CHECK(callContractFunction("a()"), encodeArgs(u256(1))); BOOST_CHECK_EQUAL(balanceAt(m_contractAddress), 0);
ABI_CHECK(callContractFunctionWithValue("", 27), encodeArgs()); ABI_CHECK(callContractFunction(""), encodeArgs());
BOOST_CHECK_EQUAL(balanceAt(m_contractAddress), 0); ABI_CHECK(callContractFunction("a()"), encodeArgs(u256(1)));
ABI_CHECK(callContractFunction("a()"), encodeArgs(u256(1))); ABI_CHECK(callContractFunctionWithValue("", 27), encodeArgs());
ABI_CHECK(callContractFunctionWithValue("a()", 27), encodeArgs()); BOOST_CHECK_EQUAL(balanceAt(m_contractAddress), 0);
BOOST_CHECK_EQUAL(balanceAt(m_contractAddress), 0); ABI_CHECK(callContractFunction("a()"), encodeArgs(u256(1)));
ABI_CHECK(callContractFunctionWithValue("a()", 27), encodeArgs());
BOOST_CHECK_EQUAL(balanceAt(m_contractAddress), 0);
)
} }
BOOST_AUTO_TEST_CASE(mem_resize_is_not_paid_at_call) BOOST_AUTO_TEST_CASE(mem_resize_is_not_paid_at_call)
@ -4340,11 +4412,14 @@ BOOST_AUTO_TEST_CASE(receive_external_function_type)
} }
)"; )";
compileAndRun(sourceCode, 0, "C"); ALSO_VIA_YUL(
ABI_CHECK(callContractFunction( DISABLE_EWASM_TESTRUN()
"f(function)", compileAndRun(sourceCode, 0, "C");
m_contractAddress.asBytes() + FixedHash<4>(util::keccak256("g()")).asBytes() + bytes(32 - 4 - 20, 0) ABI_CHECK(callContractFunction(
), encodeArgs(u256(7))); "f(function)",
m_contractAddress.asBytes() + FixedHash<4>(util::keccak256("g()")).asBytes() + bytes(32 - 4 - 20, 0)
), encodeArgs(u256(7)));
)
} }
BOOST_AUTO_TEST_CASE(return_external_function_type) BOOST_AUTO_TEST_CASE(return_external_function_type)
@ -5266,9 +5341,12 @@ BOOST_AUTO_TEST_CASE(event_signature_in_library)
} }
} }
)"; )";
compileAndRun(sourceCode, 0, "C"); ALSO_VIA_YUL(
BOOST_REQUIRE_EQUAL(numLogTopics(0), 2); DISABLE_EWASM_TESTRUN()
BOOST_CHECK_EQUAL(logTopic(0, 0), util::keccak256(string("E((uint8,int16),(uint8,int16))"))); compileAndRun(sourceCode, 0, "C");
BOOST_REQUIRE_EQUAL(numLogTopics(0), 2);
BOOST_CHECK_EQUAL(logTopic(0, 0), util::keccak256(string("E((uint8,int16),(uint8,int16))")));
)
} }
BOOST_AUTO_TEST_CASE(abi_encode_with_selector) BOOST_AUTO_TEST_CASE(abi_encode_with_selector)
@ -5556,14 +5634,17 @@ BOOST_AUTO_TEST_CASE(event_wrong_abi_name)
} }
} }
)"; )";
compileAndRun(sourceCode, 0, "ClientReceipt", bytes()); ALSO_VIA_YUL(
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{"ClientReceipt", m_contractAddress}}); DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode, 0, "ClientReceipt", bytes());
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{"ClientReceipt", m_contractAddress}});
callContractFunction("f()"); callContractFunction("f()");
BOOST_REQUIRE_EQUAL(numLogs(), 1); BOOST_REQUIRE_EQUAL(numLogs(), 1);
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress); BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
BOOST_REQUIRE_EQUAL(numLogTopics(0), 3); BOOST_REQUIRE_EQUAL(numLogTopics(0), 3);
BOOST_CHECK_EQUAL(logTopic(0, 0), util::keccak256(string("Deposit(address,bytes32,uint256)"))); BOOST_CHECK_EQUAL(logTopic(0, 0), util::keccak256(string("Deposit(address,bytes32,uint256)")));
)
} }
BOOST_AUTO_TEST_CASE(uninitialized_internal_storage_function) BOOST_AUTO_TEST_CASE(uninitialized_internal_storage_function)

View File

@ -15,6 +15,5 @@ contract C {
} }
// ==== // ====
// compileViaYul: also // compileViaYul: also
// compileToEwasm: also
// ---- // ----
// test() -> // test() ->

View File

@ -13,7 +13,6 @@ contract C {
} }
// ==== // ====
// compileViaYul: also // compileViaYul: also
// compileToEwasm: also
// ---- // ----
// foo(bool,bool): true, true -> false // foo(bool,bool): true, true -> false
// foo(bool,bool): true, false -> true // foo(bool,bool): true, false -> true

View File

@ -17,6 +17,5 @@ contract C {
// ==== // ====
// compileViaYul: also // compileViaYul: also
// compileToEwasm: also
// ---- // ----
// test() -> 42 // test() -> 42

View File

@ -17,6 +17,5 @@ contract C {
} }
// ==== // ====
// compileViaYul: also // compileViaYul: also
// compileToEwasm: also
// ---- // ----
// secondItem() -> 0x22 // secondItem() -> 0x22

View File

@ -13,6 +13,5 @@ contract C {
} }
// ==== // ====
// compileViaYul: also // compileViaYul: also
// compileToEwasm: also
// ---- // ----
// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122) // sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)

View File

@ -18,6 +18,5 @@ contract C {
// ==== // ====
// compileViaYul: also // compileViaYul: also
// compileToEwasm: also
// ---- // ----
// test(uint256): 5 -> 10 // test(uint256): 5 -> 10

View File

@ -13,6 +13,5 @@ contract C {
} }
// ==== // ====
// compileViaYul: also // compileViaYul: also
// compileToEwasm: also
// ---- // ----
// foo(uint256,uint256): 8, 42 -> 50 // foo(uint256,uint256): 8, 42 -> 50

View File

@ -18,6 +18,5 @@ contract C {
// ==== // ====
// compileViaYul: also // compileViaYul: also
// compileToEwasm: also
// ---- // ----
// test() -> 42 // test() -> 42

View File

@ -18,6 +18,5 @@ contract C {
// ==== // ====
// compileViaYul: also // compileViaYul: also
// compileToEwasm: also
// ---- // ----
// test(uint256): 5 -> 10 // test(uint256): 5 -> 10

View File

@ -14,6 +14,5 @@ contract C {
} }
// ==== // ====
// compileViaYul: also // compileViaYul: also
// compileToEwasm: also
// ---- // ----
// secondChar() -> 98 // secondChar() -> 98

View File

@ -35,6 +35,7 @@ contract C {
} }
} }
// ==== // ====
// compileViaYul: also
// EVMVersion: >=byzantium // EVMVersion: >=byzantium
// ---- // ----
// library: L // library: L

View File

@ -24,6 +24,7 @@ contract C {
} }
} }
// ==== // ====
// compileViaYul: also
// EVMVersion: >homestead // EVMVersion: >homestead
// ---- // ----
// library: L // library: L

View File

@ -24,6 +24,7 @@ contract C {
} }
} }
// ==== // ====
// compileViaYul: also
// EVMVersion: >homestead // EVMVersion: >homestead
// ---- // ----
// library: L // library: L

View File

@ -23,6 +23,7 @@ contract C {
} }
} }
// ==== // ====
// compileViaYul: also
// EVMVersion: >homestead // EVMVersion: >homestead
// ---- // ----
// library: L // library: L

View File

@ -23,6 +23,7 @@ contract C {
} }
} }
// ==== // ====
// compileViaYul: also
// EVMVersion: >homestead // EVMVersion: >homestead
// ---- // ----
// library: L // library: L

View File

@ -22,6 +22,7 @@ contract C {
} }
} }
// ==== // ====
// compileViaYul: also
// EVMVersion: >homestead // EVMVersion: >homestead
// ---- // ----
// library: L // library: L

View File

@ -20,6 +20,7 @@ contract C {
} }
} }
// ==== // ====
// compileViaYul: also
// EVMVersion: >homestead // EVMVersion: >homestead
// ---- // ----
// library: L // library: L

View File

@ -16,6 +16,8 @@ contract C {
assembly { slot := ptr.slot } assembly { slot := ptr.slot }
} }
} }
// ====
// compileViaYul: also
// ---- // ----
// library: Lib // library: Lib
// f() -> 123 // f() -> 123

View File

@ -23,6 +23,5 @@ contract C {
} }
// ==== // ====
// compileViaYul: also // compileViaYul: also
// compileToEwasm: also
// ---- // ----
// g() -> 7, 7 // g() -> 7, 7