mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #10686 from ethereum/libraryCallGuard
Library call guard.
This commit is contained in:
commit
d97b9ba865
@ -80,6 +80,11 @@ string IRNames::implicitConstructor(ContractDefinition const& _contract)
|
||||
return "constructor_" + _contract.name() + "_" + to_string(_contract.id());
|
||||
}
|
||||
|
||||
string IRNames::libraryAddressImmutable()
|
||||
{
|
||||
return "library_deploy_address";
|
||||
}
|
||||
|
||||
string IRNames::constantValueFunction(VariableDeclaration const& _constant)
|
||||
{
|
||||
solAssert(_constant.isConstant(), "");
|
||||
|
@ -55,6 +55,7 @@ struct IRNames
|
||||
static std::string runtimeObject(ContractDefinition const& _contract);
|
||||
static std::string internalDispatch(YulArity const& _arity);
|
||||
static std::string implicitConstructor(ContractDefinition const& _contract);
|
||||
static std::string libraryAddressImmutable();
|
||||
static std::string constantValueFunction(VariableDeclaration const& _constant);
|
||||
static std::string localVariable(VariableDeclaration const& _declaration);
|
||||
static std::string localVariable(Expression const& _expression);
|
||||
|
@ -94,16 +94,20 @@ string IRGenerator::generate(
|
||||
code {
|
||||
<memoryInitCreation>
|
||||
<callValueCheck>
|
||||
<?notLibrary>
|
||||
<?library>
|
||||
<!library>
|
||||
<?constructorHasParams> let <constructorParams> := <copyConstructorArguments>() </constructorHasParams>
|
||||
<implicitConstructor>(<constructorParams>)
|
||||
</notLibrary>
|
||||
</library>
|
||||
<deploy>
|
||||
<functions>
|
||||
}
|
||||
object "<RuntimeObject>" {
|
||||
code {
|
||||
<memoryInitRuntime>
|
||||
<?library>
|
||||
let called_via_delegatecall := iszero(eq(loadimmutable("<library_address>"), address()))
|
||||
</library>
|
||||
<dispatch>
|
||||
<runtimeFunctions>
|
||||
}
|
||||
@ -118,7 +122,7 @@ string IRGenerator::generate(
|
||||
m_context.registerImmutableVariable(*var);
|
||||
|
||||
t("CreationObject", IRNames::creationObject(_contract));
|
||||
t("notLibrary", !_contract.isLibrary());
|
||||
t("library", _contract.isLibrary());
|
||||
|
||||
FunctionDefinition const* constructor = _contract.constructor();
|
||||
t("callValueCheck", !constructor || !constructor->isPayable() ? callValueCheck() : "");
|
||||
@ -156,6 +160,7 @@ string IRGenerator::generate(
|
||||
|
||||
// Do not register immutables to avoid assignment.
|
||||
t("RuntimeObject", IRNames::runtimeObject(_contract));
|
||||
t("library_address", IRNames::libraryAddressImmutable());
|
||||
t("dispatch", dispatchRoutine(_contract));
|
||||
generateQueuedFunctions();
|
||||
generateInternalDispatchFunctions();
|
||||
@ -747,6 +752,16 @@ string IRGenerator::deployCode(ContractDefinition const& _contract)
|
||||
vector<map<string, string>> loadImmutables;
|
||||
vector<map<string, string>> storeImmutables;
|
||||
|
||||
if (_contract.isLibrary())
|
||||
{
|
||||
solAssert(ContractType(_contract).immutableVariables().empty(), "");
|
||||
storeImmutables.emplace_back(map<string, string>{
|
||||
{"var"s, "address()"},
|
||||
{"immutableName"s, IRNames::libraryAddressImmutable()}
|
||||
});
|
||||
|
||||
}
|
||||
else
|
||||
for (VariableDeclaration const* immutable: ContractType(_contract).immutableVariables())
|
||||
{
|
||||
solUnimplementedAssert(immutable->type()->isValueType(), "");
|
||||
@ -784,6 +799,7 @@ string IRGenerator::dispatchRoutine(ContractDefinition const& _contract)
|
||||
case <functionSelector>
|
||||
{
|
||||
// <functionName>
|
||||
<delegatecallCheck>
|
||||
<callValueCheck>
|
||||
<?+params>let <params> := </+params> <abiDecode>(4, calldatasize())
|
||||
<?+retParams>let <retParams> := </+retParams> <function>(<params>)
|
||||
@ -806,7 +822,18 @@ string IRGenerator::dispatchRoutine(ContractDefinition const& _contract)
|
||||
templ["functionSelector"] = "0x" + function.first.hex();
|
||||
FunctionTypePointer const& type = function.second;
|
||||
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 retVars = make_shared<TupleType>(type->returnParameterTypes())->sizeOnStack();
|
||||
@ -824,11 +851,19 @@ string IRGenerator::dispatchRoutine(ContractDefinition const& _contract)
|
||||
solAssert(false, "Unexpected declaration for function!");
|
||||
|
||||
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);
|
||||
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())
|
||||
{
|
||||
solAssert(!_contract.isLibrary(), "");
|
||||
string fallbackCode;
|
||||
if (!fallback->isPayable())
|
||||
fallbackCode += callValueCheck() + "\n";
|
||||
@ -846,10 +881,6 @@ string IRGenerator::dispatchRoutine(ContractDefinition const& _contract)
|
||||
}
|
||||
else
|
||||
t("fallback", "revert(0, 0)");
|
||||
if (FunctionDefinition const* etherReceiver = _contract.receiveFunction())
|
||||
t("receiveEther", m_context.enqueueFunctionForCodeGeneration(*etherReceiver) + "() stop()");
|
||||
else
|
||||
t("receiveEther", "");
|
||||
return t.render();
|
||||
}
|
||||
|
||||
|
@ -1664,7 +1664,10 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
|
||||
FunctionType const& functionType = dynamic_cast<FunctionType const&>(
|
||||
*_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"));
|
||||
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";
|
||||
}
|
||||
else
|
||||
solAssert(false, "Invalid use of .selector");
|
||||
solAssert(false, "Invalid use of .selector: " + functionType.toString(false));
|
||||
}
|
||||
else if (member == "address")
|
||||
{
|
||||
|
@ -35,6 +35,7 @@ object "C_81" {
|
||||
case 0x70cb9605
|
||||
{
|
||||
// f(uint256,uint256,uint256,uint256)
|
||||
|
||||
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 ret_0, ret_1, ret_2, ret_3 := fun_f_80(param_0, param_1, param_2, param_3)
|
||||
|
@ -34,6 +34,7 @@ object \"C_7\" {
|
||||
case 0x26121ff0
|
||||
{
|
||||
// f()
|
||||
|
||||
if callvalue() { revert(0, 0) }
|
||||
abi_decode_tuple_(4, calldatasize())
|
||||
fun_f_6()
|
||||
|
@ -85,6 +85,7 @@ object \"D_16\" {
|
||||
case 0x26121ff0
|
||||
{
|
||||
// f()
|
||||
|
||||
if callvalue() { revert(0, 0) }
|
||||
abi_decode_tuple_(4, calldatasize())
|
||||
fun_f_15()
|
||||
|
@ -35,6 +35,7 @@ object "test_11" {
|
||||
case 0x26121ff0
|
||||
{
|
||||
// f()
|
||||
|
||||
if callvalue() { revert(0, 0) }
|
||||
abi_decode_tuple_(4, calldatasize())
|
||||
let ret_0 := fun_f_10()
|
||||
|
@ -34,6 +34,7 @@ object \"C_11\" {
|
||||
case 0x26121ff0
|
||||
{
|
||||
// f()
|
||||
|
||||
if callvalue() { revert(0, 0) }
|
||||
abi_decode_tuple_(4, calldatasize())
|
||||
let ret_0 := fun_f_10()
|
||||
|
@ -34,6 +34,7 @@ object \"C_11\" {
|
||||
case 0x26121ff0
|
||||
{
|
||||
// f()
|
||||
|
||||
if callvalue() { revert(0, 0) }
|
||||
abi_decode_tuple_(4, calldatasize())
|
||||
let ret_0 := fun_f_10()
|
||||
|
@ -34,6 +34,7 @@ object \"C_11\" {
|
||||
case 0x26121ff0
|
||||
{
|
||||
// f()
|
||||
|
||||
if callvalue() { revert(0, 0) }
|
||||
abi_decode_tuple_(4, calldatasize())
|
||||
let ret_0 := fun_f_10()
|
||||
|
@ -34,6 +34,7 @@ object \"C_11\" {
|
||||
case 0x26121ff0
|
||||
{
|
||||
// f()
|
||||
|
||||
if callvalue() { revert(0, 0) }
|
||||
abi_decode_tuple_(4, calldatasize())
|
||||
let ret_0 := fun_f_10()
|
||||
|
@ -34,6 +34,7 @@ object \"C_11\" {
|
||||
case 0x26121ff0
|
||||
{
|
||||
// f()
|
||||
|
||||
if callvalue() { revert(0, 0) }
|
||||
abi_decode_tuple_(4, calldatasize())
|
||||
let ret_0 := fun_f_10()
|
||||
|
@ -2239,10 +2239,13 @@ BOOST_AUTO_TEST_CASE(library_call_in_homestead)
|
||||
}
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
compileAndRun(sourceCode, 0, "Lib");
|
||||
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)
|
||||
@ -2266,6 +2269,8 @@ BOOST_AUTO_TEST_CASE(library_call_protection)
|
||||
function pu() public pure returns (uint) { return Lib.pu(); }
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
compileAndRun(sourceCode, 0, "Lib");
|
||||
ABI_CHECK(callContractFunction("np(Lib.S storage)", 0), encodeArgs());
|
||||
ABI_CHECK(callContractFunction("v(Lib.S storage)", 0), encodeArgs(m_sender));
|
||||
@ -2276,6 +2281,7 @@ BOOST_AUTO_TEST_CASE(library_call_protection)
|
||||
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)
|
||||
@ -2537,6 +2543,8 @@ BOOST_AUTO_TEST_CASE(struct_referencing)
|
||||
function a2() public pure returns (uint) { L.S memory s; return L.a(s); }
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
compileAndRun(sourceCode, 0, "L");
|
||||
ABI_CHECK(callContractFunction("f()"), encodeArgs(0, 3));
|
||||
ABI_CHECK(callContractFunction("g()"), encodeArgs(4));
|
||||
@ -2548,6 +2556,7 @@ BOOST_AUTO_TEST_CASE(struct_referencing)
|
||||
ABI_CHECK(callContractFunction("y()"), encodeArgs(4));
|
||||
ABI_CHECK(callContractFunction("a1()"), encodeArgs(1));
|
||||
ABI_CHECK(callContractFunction("a2()"), encodeArgs(2));
|
||||
)
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(enum_referencing)
|
||||
@ -2583,6 +2592,8 @@ BOOST_AUTO_TEST_CASE(enum_referencing)
|
||||
}
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
compileAndRun(sourceCode, 0, "L");
|
||||
ABI_CHECK(callContractFunction("f()"), encodeArgs(1));
|
||||
ABI_CHECK(callContractFunction("g()"), encodeArgs(3));
|
||||
@ -2592,6 +2603,7 @@ BOOST_AUTO_TEST_CASE(enum_referencing)
|
||||
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)
|
||||
@ -3413,9 +3425,12 @@ BOOST_AUTO_TEST_CASE(library_call)
|
||||
}
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
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)
|
||||
@ -3428,9 +3443,12 @@ BOOST_AUTO_TEST_CASE(library_function_external)
|
||||
}
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
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)
|
||||
@ -3445,9 +3463,12 @@ BOOST_AUTO_TEST_CASE(library_stray_values)
|
||||
}
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
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)
|
||||
@ -3475,9 +3496,12 @@ BOOST_AUTO_TEST_CASE(internal_types_in_library)
|
||||
}
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
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)
|
||||
@ -3506,6 +3530,8 @@ BOOST_AUTO_TEST_CASE(mapping_arguments_in_library)
|
||||
}
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
compileAndRun(sourceCode, 0, "Lib");
|
||||
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{"Lib", m_contractAddress}});
|
||||
ABI_CHECK(callContractFunction("set(uint256,uint256)", u256(1), u256(42)), encodeArgs(u256(0)));
|
||||
@ -3522,6 +3548,7 @@ BOOST_AUTO_TEST_CASE(mapping_arguments_in_library)
|
||||
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)
|
||||
@ -3554,6 +3581,8 @@ BOOST_AUTO_TEST_CASE(mapping_returns_in_library)
|
||||
}
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
compileAndRun(sourceCode, 0, "Lib");
|
||||
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{"Lib", m_contractAddress}});
|
||||
ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", true, u256(1), u256(42)), encodeArgs(u256(0)));
|
||||
@ -3600,6 +3629,7 @@ BOOST_AUTO_TEST_CASE(mapping_returns_in_library)
|
||||
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)
|
||||
@ -3630,10 +3660,13 @@ BOOST_AUTO_TEST_CASE(mapping_returns_in_library_named)
|
||||
}
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
compileAndRun(sourceCode, 0, "Lib");
|
||||
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)
|
||||
@ -3658,9 +3691,12 @@ BOOST_AUTO_TEST_CASE(using_library_mappings_public)
|
||||
}
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
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)
|
||||
@ -3719,9 +3755,12 @@ BOOST_AUTO_TEST_CASE(using_library_mappings_return)
|
||||
}
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
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)
|
||||
@ -3747,9 +3786,12 @@ BOOST_AUTO_TEST_CASE(using_library_structs)
|
||||
}
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
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)
|
||||
@ -3860,6 +3902,8 @@ BOOST_AUTO_TEST_CASE(short_strings)
|
||||
}
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
compileAndRun(sourceCode, 0, "A");
|
||||
ABI_CHECK(callContractFunction("data1()"), encodeDyn(string("123")));
|
||||
ABI_CHECK(callContractFunction("lengthChange()"), encodeArgs(u256(0)));
|
||||
@ -3868,6 +3912,7 @@ BOOST_AUTO_TEST_CASE(short_strings)
|
||||
BOOST_CHECK(storageEmpty(m_contractAddress));
|
||||
ABI_CHECK(callContractFunction("copy()"), encodeArgs(u256(0)));
|
||||
BOOST_CHECK(storageEmpty(m_contractAddress));
|
||||
)
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(calldata_offset)
|
||||
@ -3901,6 +3946,8 @@ BOOST_AUTO_TEST_CASE(reject_ether_sent_to_library)
|
||||
receive () external payable {}
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
compileAndRun(sourceCode, 0, "lib");
|
||||
Address libraryAddress = m_contractAddress;
|
||||
compileAndRun(sourceCode, 10, "c");
|
||||
@ -3912,6 +3959,7 @@ BOOST_AUTO_TEST_CASE(reject_ether_sent_to_library)
|
||||
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)
|
||||
@ -3970,10 +4018,13 @@ BOOST_AUTO_TEST_CASE(using_for_function_on_struct)
|
||||
}
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
compileAndRun(sourceCode, 0, "D");
|
||||
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)
|
||||
@ -3993,10 +4044,13 @@ BOOST_AUTO_TEST_CASE(using_for_overload)
|
||||
}
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
compileAndRun(sourceCode, 0, "D");
|
||||
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)
|
||||
@ -4012,10 +4066,13 @@ BOOST_AUTO_TEST_CASE(using_for_by_name)
|
||||
}
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
compileAndRun(sourceCode, 0, "D");
|
||||
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)
|
||||
@ -4032,9 +4089,12 @@ BOOST_AUTO_TEST_CASE(bound_function_in_function)
|
||||
function t() public pure returns (uint) { return 7; }
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
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)
|
||||
@ -4050,10 +4110,13 @@ BOOST_AUTO_TEST_CASE(bound_function_in_var)
|
||||
}
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
compileAndRun(sourceCode, 0, "D");
|
||||
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)
|
||||
@ -4073,10 +4136,13 @@ BOOST_AUTO_TEST_CASE(bound_function_to_string)
|
||||
}
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
compileAndRun(sourceCode, 0, "D");
|
||||
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)
|
||||
@ -4271,9 +4337,12 @@ BOOST_AUTO_TEST_CASE(payable_function_calls_library)
|
||||
}
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
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)
|
||||
@ -4296,6 +4365,8 @@ BOOST_AUTO_TEST_CASE(non_payable_throw)
|
||||
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
compileAndRun(sourceCode, 0, "C");
|
||||
ABI_CHECK(callContractFunctionWithValue("f()", 27), encodeArgs());
|
||||
BOOST_CHECK_EQUAL(balanceAt(m_contractAddress), 0);
|
||||
@ -4306,6 +4377,7 @@ BOOST_AUTO_TEST_CASE(non_payable_throw)
|
||||
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)
|
||||
@ -4340,11 +4412,14 @@ BOOST_AUTO_TEST_CASE(receive_external_function_type)
|
||||
}
|
||||
)";
|
||||
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
compileAndRun(sourceCode, 0, "C");
|
||||
ABI_CHECK(callContractFunction(
|
||||
"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)
|
||||
@ -5266,9 +5341,12 @@ BOOST_AUTO_TEST_CASE(event_signature_in_library)
|
||||
}
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
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)
|
||||
@ -5556,6 +5634,8 @@ BOOST_AUTO_TEST_CASE(event_wrong_abi_name)
|
||||
}
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
compileAndRun(sourceCode, 0, "ClientReceipt", bytes());
|
||||
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{"ClientReceipt", m_contractAddress}});
|
||||
|
||||
@ -5564,6 +5644,7 @@ BOOST_AUTO_TEST_CASE(event_wrong_abi_name)
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 3);
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 0), util::keccak256(string("Deposit(address,bytes32,uint256)")));
|
||||
)
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(uninitialized_internal_storage_function)
|
||||
|
@ -15,6 +15,5 @@ contract C {
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// compileToEwasm: also
|
||||
// ----
|
||||
// test() ->
|
||||
|
@ -13,7 +13,6 @@ contract C {
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// compileToEwasm: also
|
||||
// ----
|
||||
// foo(bool,bool): true, true -> false
|
||||
// foo(bool,bool): true, false -> true
|
||||
|
@ -17,6 +17,5 @@ contract C {
|
||||
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// compileToEwasm: also
|
||||
// ----
|
||||
// test() -> 42
|
||||
|
@ -17,6 +17,5 @@ contract C {
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// compileToEwasm: also
|
||||
// ----
|
||||
// secondItem() -> 0x22
|
||||
|
@ -13,6 +13,5 @@ contract C {
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// compileToEwasm: also
|
||||
// ----
|
||||
// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)
|
||||
|
@ -18,6 +18,5 @@ contract C {
|
||||
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// compileToEwasm: also
|
||||
// ----
|
||||
// test(uint256): 5 -> 10
|
||||
|
@ -13,6 +13,5 @@ contract C {
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// compileToEwasm: also
|
||||
// ----
|
||||
// foo(uint256,uint256): 8, 42 -> 50
|
||||
|
@ -18,6 +18,5 @@ contract C {
|
||||
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// compileToEwasm: also
|
||||
// ----
|
||||
// test() -> 42
|
||||
|
@ -18,6 +18,5 @@ contract C {
|
||||
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// compileToEwasm: also
|
||||
// ----
|
||||
// test(uint256): 5 -> 10
|
||||
|
@ -14,6 +14,5 @@ contract C {
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// compileToEwasm: also
|
||||
// ----
|
||||
// secondChar() -> 98
|
||||
|
@ -35,6 +35,7 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// EVMVersion: >=byzantium
|
||||
// ----
|
||||
// library: L
|
||||
|
@ -24,6 +24,7 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// EVMVersion: >homestead
|
||||
// ----
|
||||
// library: L
|
||||
|
@ -24,6 +24,7 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// EVMVersion: >homestead
|
||||
// ----
|
||||
// library: L
|
||||
|
@ -23,6 +23,7 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// EVMVersion: >homestead
|
||||
// ----
|
||||
// library: L
|
||||
|
@ -23,6 +23,7 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// EVMVersion: >homestead
|
||||
// ----
|
||||
// library: L
|
||||
|
@ -22,6 +22,7 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// EVMVersion: >homestead
|
||||
// ----
|
||||
// library: L
|
||||
|
@ -20,6 +20,7 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// EVMVersion: >homestead
|
||||
// ----
|
||||
// library: L
|
||||
|
@ -16,6 +16,8 @@ contract C {
|
||||
assembly { slot := ptr.slot }
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// library: Lib
|
||||
// f() -> 123
|
||||
|
@ -23,6 +23,5 @@ contract C {
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// compileToEwasm: also
|
||||
// ----
|
||||
// g() -> 7, 7
|
||||
|
Loading…
Reference in New Issue
Block a user