Skip to content

Commit 2780b74

Browse files
committed
fix: view and pure functions revert when paid
1 parent 7194e1a commit 2780b74

File tree

4 files changed

+23
-14
lines changed

4 files changed

+23
-14
lines changed

libevm/precompilegen/precompile.go.tmpl

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,11 @@ func (p precompile) run(env vm.PrecompileEnvironment, input []byte) ([]byte, err
7171
return p.impl.Fallback(env, input)
7272
}
7373

74+
payable := false
7475
switch m := methods[selector]; m.StateMutability {
75-
case "nonpayable":
76-
if !env.Value().IsZero() {
77-
return []byte(revertBufferWhenNonPayableReceivesValue), vm.ErrExecutionReverted
78-
}
7976
case "payable":
77+
payable = true
78+
case "nonpayable":
8079
case "pure":
8180
env = env.AsPure()
8281
case "view":
@@ -87,6 +86,9 @@ func (p precompile) run(env vm.PrecompileEnvironment, input []byte) ([]byte, err
8786
data := fmt.Sprintf("unsupported state mutability %q on method %s", m.StateMutability, m.Sig)
8887
return []byte(data), vm.ErrExecutionReverted
8988
}
89+
if !payable && !env.Value().IsZero() {
90+
return []byte(revertBufferWhenNonPayableReceivesValue), vm.ErrExecutionReverted
91+
}
9092

9193
ret, err := dispatchers[selector](p.impl, env, input)
9294
switch err := err.(type) {

libevm/precompilegen/testprecompile/TestSuite.sol

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,18 +93,23 @@ contract TestSuite {
9393
uint256 value = precompile.Payable{value: 42}();
9494
assert(value == 42);
9595

96-
callNonPayable(0, "");
97-
callNonPayable(1, abi.encodePacked(_expectedNonPayableErrorMsg));
96+
bytes4 nonPayable = IPrecompile.NonPayable.selector;
97+
callNonPayable(nonPayable, 0, "");
98+
99+
bytes memory err = abi.encodePacked(_expectedNonPayableErrorMsg);
100+
callNonPayable(nonPayable, 1, err);
101+
callNonPayable(IPrecompile.View.selector, 1, err);
102+
callNonPayable(IPrecompile.Pure.selector, 1, err);
98103

99104
emit Called("Transfer()");
100105
}
101106

102-
function callNonPayable(uint256 value, bytes memory expectRevertWith) internal {
107+
function callNonPayable(bytes4 selector, uint256 value, bytes memory expectRevertWith) internal {
103108
// We can't use just call `precompile.NonPayable()` directly because
104109
// (a) it's a precompile and (b) it doesn't return values, which means
105110
// that Solidity will perform an EXTCODESIZE check first and revert.
106-
bytes memory selector = abi.encodeWithSelector(IPrecompile.NonPayable.selector);
107-
(bool ok, bytes memory ret) = address(precompile).call{value: value}(selector);
111+
bytes memory data = abi.encodeWithSelector(selector);
112+
(bool ok, bytes memory ret) = address(precompile).call{value: value}(data);
108113

109114
if (expectRevertWith.length == 0) {
110115
assert(ok);

libevm/precompilegen/testprecompile/generated.go

Lines changed: 6 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)