Skip to content

Commit 05541e5

Browse files
committed
Fixed internal error related to ecrecover and ABIEncoderV2.
1 parent 8607690 commit 05541e5

File tree

3 files changed

+26
-1
lines changed

3 files changed

+26
-1
lines changed

Changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Compiler Features:
99

1010
Bugfixes:
1111
* ABIEncoderV2: Fix internal error related to bare delegatecall.
12+
* ABIEncoderV2: Fix internal error related to ecrecover.
1213
* ABIEncoderV2: Fix internal error related to mappings as library parameters.
1314
* Yul: Properly detect name clashes with functions before their declaration.
1415

libsolidity/codegen/ExpressionCompiler.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1967,12 +1967,17 @@ void ExpressionCompiler::appendExternalFunctionCall(
19671967
// If the function takes arbitrary parameters or is a bare call, copy dynamic length data in place.
19681968
// Move arguments to memory, will not update the free memory pointer (but will update the memory
19691969
// pointer on the stack).
1970+
bool encodeInPlace = _functionType.takesArbitraryParameters() || _functionType.isBareCall();
1971+
if (_functionType.kind() == FunctionType::Kind::ECRecover)
1972+
// This would be the only combination of padding and in-place encoding,
1973+
// but all parameters of ecrecover are value types anyway.
1974+
encodeInPlace = false;
19701975
bool encodeForLibraryCall = funKind == FunctionType::Kind::DelegateCall;
19711976
utils().encodeToMemory(
19721977
argumentTypes,
19731978
parameterTypes,
19741979
_functionType.padArguments(),
1975-
_functionType.takesArbitraryParameters() || _functionType.isBareCall(),
1980+
encodeInPlace,
19761981
encodeForLibraryCall
19771982
);
19781983

test/libsolidity/SolidityEndToEndTest.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2633,6 +2633,25 @@ BOOST_AUTO_TEST_CASE(ecrecover)
26332633
ABI_CHECK(callContractFunction("a(bytes32,uint8,bytes32,bytes32)", h, v, r, s), encodeArgs(addr));
26342634
}
26352635

2636+
BOOST_AUTO_TEST_CASE(ecrecover_abiV2)
2637+
{
2638+
char const* sourceCode = R"(
2639+
pragma experimental ABIEncoderV2;
2640+
contract test {
2641+
function a(bytes32 h, uint8 v, bytes32 r, bytes32 s) public returns (address addr) {
2642+
return ecrecover(h, v, r, s);
2643+
}
2644+
}
2645+
)";
2646+
compileAndRun(sourceCode);
2647+
u256 h("0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c");
2648+
uint8_t v = 28;
2649+
u256 r("0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f");
2650+
u256 s("0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549");
2651+
u160 addr("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b");
2652+
ABI_CHECK(callContractFunction("a(bytes32,uint8,bytes32,bytes32)", h, v, r, s), encodeArgs(addr));
2653+
}
2654+
26362655
BOOST_AUTO_TEST_CASE(inter_contract_calls)
26372656
{
26382657
char const* sourceCode = R"(

0 commit comments

Comments
 (0)