mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Fix combination of delegatecall and ABIEncoderV2.
We can set the flag to false for bare delegatecall, because we always send a memory string and never a storage reference.
This commit is contained in:
parent
55c4131a03
commit
d5791fef41
@ -8,6 +8,7 @@ Compiler Features:
|
||||
|
||||
|
||||
Bugfixes:
|
||||
* ABIEncoderV2: Fix internal error related to bare delegatecall.
|
||||
* ABIEncoderV2: Fix internal error related to mappings as library parameters.
|
||||
* Yul: Properly detect name clashes with functions before their declaration.
|
||||
|
||||
|
@ -1967,12 +1967,13 @@ void ExpressionCompiler::appendExternalFunctionCall(
|
||||
// If the function takes arbitrary parameters or is a bare call, copy dynamic length data in place.
|
||||
// Move arguments to memory, will not update the free memory pointer (but will update the memory
|
||||
// pointer on the stack).
|
||||
bool encodeForLibraryCall = funKind == FunctionType::Kind::DelegateCall;
|
||||
utils().encodeToMemory(
|
||||
argumentTypes,
|
||||
parameterTypes,
|
||||
_functionType.padArguments(),
|
||||
_functionType.takesArbitraryParameters() || _functionType.isBareCall(),
|
||||
isDelegateCall
|
||||
encodeForLibraryCall
|
||||
);
|
||||
|
||||
// Stack now:
|
||||
|
@ -4440,23 +4440,29 @@ BOOST_AUTO_TEST_CASE(generic_delegatecall)
|
||||
}
|
||||
}
|
||||
)**";
|
||||
compileAndRun(sourceCode, 0, "Receiver");
|
||||
u160 const c_receiverAddress = m_contractAddress;
|
||||
compileAndRun(sourceCode, 50, "Sender");
|
||||
u160 const c_senderAddress = m_contractAddress;
|
||||
BOOST_CHECK(m_sender != c_senderAddress); // just for sanity
|
||||
ABI_CHECK(callContractFunctionWithValue("doSend(address)", 11, c_receiverAddress), encodeArgs());
|
||||
ABI_CHECK(callContractFunction("received()"), encodeArgs(u256(23)));
|
||||
ABI_CHECK(callContractFunction("sender()"), encodeArgs(u160(m_sender)));
|
||||
ABI_CHECK(callContractFunction("value()"), encodeArgs(u256(11)));
|
||||
m_contractAddress = c_receiverAddress;
|
||||
ABI_CHECK(callContractFunction("received()"), encodeArgs(u256(0)));
|
||||
ABI_CHECK(callContractFunction("sender()"), encodeArgs(u256(0)));
|
||||
ABI_CHECK(callContractFunction("value()"), encodeArgs(u256(0)));
|
||||
BOOST_CHECK(storageEmpty(c_receiverAddress));
|
||||
BOOST_CHECK(!storageEmpty(c_senderAddress));
|
||||
BOOST_CHECK_EQUAL(balanceAt(c_receiverAddress), 0);
|
||||
BOOST_CHECK_EQUAL(balanceAt(c_senderAddress), 50 + 11);
|
||||
|
||||
for (auto v2: {false, true})
|
||||
{
|
||||
string source = (v2 ? "pragma experimental ABIEncoderV2;\n" : "") + string(sourceCode);
|
||||
|
||||
compileAndRun(source, 0, "Receiver");
|
||||
u160 const c_receiverAddress = m_contractAddress;
|
||||
compileAndRun(source, 50, "Sender");
|
||||
u160 const c_senderAddress = m_contractAddress;
|
||||
BOOST_CHECK(m_sender != c_senderAddress); // just for sanity
|
||||
ABI_CHECK(callContractFunctionWithValue("doSend(address)", 11, c_receiverAddress), encodeArgs());
|
||||
ABI_CHECK(callContractFunction("received()"), encodeArgs(u256(23)));
|
||||
ABI_CHECK(callContractFunction("sender()"), encodeArgs(u160(m_sender)));
|
||||
ABI_CHECK(callContractFunction("value()"), encodeArgs(u256(11)));
|
||||
m_contractAddress = c_receiverAddress;
|
||||
ABI_CHECK(callContractFunction("received()"), encodeArgs(u256(0)));
|
||||
ABI_CHECK(callContractFunction("sender()"), encodeArgs(u256(0)));
|
||||
ABI_CHECK(callContractFunction("value()"), encodeArgs(u256(0)));
|
||||
BOOST_CHECK(storageEmpty(c_receiverAddress));
|
||||
BOOST_CHECK(!storageEmpty(c_senderAddress));
|
||||
BOOST_CHECK_EQUAL(balanceAt(c_receiverAddress), 0);
|
||||
BOOST_CHECK_EQUAL(balanceAt(c_senderAddress), 50 + 11);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(generic_staticcall)
|
||||
|
Loading…
Reference in New Issue
Block a user