Skip to content

Commit 90b7bf4

Browse files
authored
♻️ Remove need to return results from ERC7821 execute (#1220)
1 parent d76c059 commit 90b7bf4

File tree

4 files changed

+24
-74
lines changed

4 files changed

+24
-74
lines changed

src/accounts/ERC7821.sol

Lines changed: 16 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@ contract ERC7821 is Receiver {
2828
/* EXECUTION OPERATIONS */
2929
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
3030

31-
/// @dev Executes the `calls` in `executionData` and returns the results.
32-
/// The `results` are the returned data from each call.
31+
/// @dev Executes the calls in `executionData`.
3332
/// Reverts and bubbles up error if any call fails.
3433
///
3534
/// `executionData` encoding:
@@ -49,12 +48,7 @@ contract ERC7821 is Receiver {
4948
///
5049
/// `opData` may be used to store additional data for authentication,
5150
/// paymaster data, gas limits, etc.
52-
function execute(bytes32 mode, bytes calldata executionData)
53-
public
54-
payable
55-
virtual
56-
returns (bytes[] memory)
57-
{
51+
function execute(bytes32 mode, bytes calldata executionData) public payable virtual {
5852
uint256 id = _executionModeId(mode);
5953
Call[] calldata calls;
6054
bytes calldata opData;
@@ -64,7 +58,7 @@ contract ERC7821 is Receiver {
6458
mstore(0x00, 0x7f181275) // `UnsupportedExecutionMode()`.
6559
revert(0x1c, 0x04)
6660
}
67-
// Use inline assembly to extract the `calls` and optional `opData` efficiently.
61+
// Use inline assembly to extract the calls and optional `opData` efficiently.
6862
opData.length := 0
6963
let o := add(executionData.offset, calldataload(executionData.offset))
7064
calls.offset := add(o, 0x20)
@@ -76,7 +70,7 @@ contract ERC7821 is Receiver {
7670
opData.length := calldataload(q)
7771
}
7872
}
79-
return _execute(mode, executionData, calls, opData);
73+
_execute(mode, executionData, calls, opData);
8074
}
8175

8276
/// @dev Provided for execution mode support detection.
@@ -105,15 +99,15 @@ contract ERC7821 is Receiver {
10599
}
106100
}
107101

108-
/// @dev Executes the `calls` and returns the results.
102+
/// @dev Executes the calls.
109103
/// Reverts and bubbles up error if any call fails.
110104
/// The `mode` and `executionData` are passed along in case there's a need to use them.
111105
function _execute(
112106
bytes32 mode,
113107
bytes calldata executionData,
114108
Call[] calldata calls,
115109
bytes calldata opData
116-
) internal virtual returns (bytes[] memory) {
110+
) internal virtual {
117111
// Silence compiler warning on unused variables.
118112
mode = mode;
119113
executionData = executionData;
@@ -127,20 +121,10 @@ contract ERC7821 is Receiver {
127121
revert(); // In your override, replace this with logic to operate on `opData`.
128122
}
129123

130-
/// @dev Executes the `calls` and returns the results.
124+
/// @dev Executes the calls.
131125
/// Reverts and bubbles up error if any call fails.
132126
/// `extraData` can be any supplementary data (e.g. a memory pointer, some hash).
133-
function _execute(Call[] calldata calls, bytes32 extraData)
134-
internal
135-
virtual
136-
returns (bytes[] memory results)
137-
{
138-
/// @solidity memory-safe-assembly
139-
assembly {
140-
results := mload(0x40) // Grab the free memory pointer.
141-
mstore(results, calls.length) // Store the length of results.
142-
mstore(0x40, add(add(results, 0x20), shl(5, calls.length))) // Allocate memory.
143-
}
127+
function _execute(Call[] calldata calls, bytes32 extraData) internal virtual {
144128
uint256 n = calls.length << 5;
145129
for (uint256 j; j != n;) {
146130
address target;
@@ -158,36 +142,27 @@ contract ERC7821 is Receiver {
158142
data.length := calldataload(o)
159143
j := add(j, 0x20)
160144
}
161-
bytes memory r = _execute(target, value, data, extraData);
162-
/// @solidity memory-safe-assembly
163-
assembly {
164-
mstore(add(results, j), r) // Set `results[i]` to `r`.
165-
}
145+
_execute(target, value, data, extraData);
166146
}
167147
}
168148

169-
/// @dev Executes the `calls` and returns the result.
149+
/// @dev Executes the call.
170150
/// Reverts and bubbles up error if any call fails.
171151
/// `extraData` can be any supplementary data (e.g. a memory pointer, some hash).
172152
function _execute(address target, uint256 value, bytes calldata data, bytes32 extraData)
173153
internal
174154
virtual
175-
returns (bytes memory result)
176155
{
177156
/// @solidity memory-safe-assembly
178157
assembly {
179-
result := mload(0x40) // Grab the free memory pointer.
180-
calldatacopy(result, data.offset, data.length)
181-
if iszero(call(gas(), target, value, result, data.length, codesize(), 0x00)) {
158+
extraData := extraData // Silence unused variable compiler warning.
159+
let m := mload(0x40) // Grab the free memory pointer.
160+
calldatacopy(m, data.offset, data.length)
161+
if iszero(call(gas(), target, value, m, data.length, codesize(), 0x00)) {
182162
// Bubble up the revert if the call reverts.
183-
returndatacopy(result, 0x00, returndatasize())
184-
revert(result, returndatasize())
163+
returndatacopy(m, 0x00, returndatasize())
164+
revert(m, returndatasize())
185165
}
186-
mstore(result, returndatasize()) // Store the length.
187-
let o := add(result, 0x20)
188-
returndatacopy(o, 0x00, returndatasize()) // Copy the returndata.
189-
mstore(0x40, add(o, returndatasize())) // Allocate the memory.
190-
extraData := extraData // Silence unused variable compiler warning.
191166
}
192167
}
193168
}

src/accounts/Timelock.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ contract Timelock is ERC7821, EnumerableRoles {
305305
bytes calldata executionData,
306306
Call[] calldata calls,
307307
bytes calldata opData
308-
) internal virtual override(ERC7821) returns (bytes[] memory results) {
308+
) internal virtual override(ERC7821) {
309309
if (!_hasRole(OPEN_ROLE_HOLDER, EXECUTOR_ROLE)) _checkRole(EXECUTOR_ROLE);
310310
bytes32 id;
311311
uint256 s;
@@ -332,7 +332,7 @@ contract Timelock is ERC7821, EnumerableRoles {
332332
}
333333
}
334334
}
335-
results = _execute(calls, id);
335+
_execute(calls, id);
336336
/// @solidity memory-safe-assembly
337337
assembly {
338338
// Recheck the operation after the calls, in case of reentrancy.

test/ERC7821.t.sol

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,7 @@ contract ERC7821Test is SoladyTest {
4848
bytes memory data = abi.encode(calls);
4949
vm.resumeGasMetering();
5050

51-
bytes[] memory results = mbe.execute{value: _totalValue(calls)}(_SUPPORTED_MODE, data);
52-
53-
vm.pauseGasMetering();
54-
55-
assertEq(results.length, 2);
56-
assertEq(abi.decode(results[0], (bytes)), "hehe");
57-
assertEq(abi.decode(results[1], (bytes32)), keccak256("lol"));
58-
vm.resumeGasMetering();
51+
mbe.execute{value: _totalValue(calls)}(_SUPPORTED_MODE, data);
5952
}
6053

6154
function testERC7821(bytes memory opData) public {
@@ -71,14 +64,9 @@ contract ERC7821Test is SoladyTest {
7164
calls[1].value = 789;
7265
calls[1].data = abi.encodeWithSignature("returnsHash(bytes)", "lol");
7366

74-
bytes[] memory results =
75-
mbe.execute{value: _totalValue(calls)}(_SUPPORTED_MODE, _encode(calls, opData));
67+
mbe.execute{value: _totalValue(calls)}(_SUPPORTED_MODE, _encode(calls, opData));
7668

7769
assertEq(mbe.lastOpData(), opData);
78-
79-
assertEq(results.length, 2);
80-
assertEq(abi.decode(results[0], (bytes)), "hehe");
81-
assertEq(abi.decode(results[1], (bytes32)), keccak256("lol"));
8270
}
8371

8472
function testERC7821ForRevert() public {
@@ -124,14 +112,7 @@ contract ERC7821Test is SoladyTest {
124112
}
125113
}
126114

127-
bytes[] memory results = mbe.executeDirect{value: _totalValue(calls)}(calls);
128-
for (uint256 i; i < calls.length; ++i) {
129-
if (payloads[i].mode == 0) {
130-
assertEq(abi.decode(results[i], (bytes)), payloads[i].data);
131-
} else {
132-
assertEq(abi.decode(results[i], (bytes32)), keccak256(payloads[i].data));
133-
}
134-
}
115+
mbe.executeDirect{value: _totalValue(calls)}(calls);
135116

136117
if (calls.length != 0 && _randomChance(32)) {
137118
calls[_randomUniform() % calls.length].data =

test/utils/mocks/MockERC7821.sol

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,15 @@ contract MockERC7821 is ERC7821, Brutalizer {
1313
internal
1414
virtual
1515
override
16-
returns (bytes[] memory)
1716
{
1817
lastOpData = opData;
19-
return _execute(calls, bytes32(0));
18+
_execute(calls, bytes32(0));
2019
}
2120

22-
function executeDirect(Call[] calldata calls)
23-
public
24-
payable
25-
virtual
26-
returns (bytes[] memory results)
27-
{
21+
function executeDirect(Call[] calldata calls) public payable virtual {
2822
_misalignFreeMemoryPointer();
2923
_brutalizeMemory();
30-
results = _execute(calls, bytes32(0));
24+
_execute(calls, bytes32(0));
3125
_checkMemory();
3226
}
3327
}

0 commit comments

Comments
 (0)