Skip to content

Commit

Permalink
Merge pull request #12 from erc6900/adam/istandardexecutor-update
Browse files Browse the repository at this point in the history
Rename Execution to Call, and update IStandardExecutor
  • Loading branch information
adam-alchemy authored Nov 29, 2023
2 parents 98bc1d7 + 0e4b0ab commit b4755df
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 75 deletions.
38 changes: 12 additions & 26 deletions src/account/UpgradeableModularAccount.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,9 @@ import {BaseAccount} from "@eth-infinitism/account-abstraction/core/BaseAccount.
import {BaseModularAccount} from "./BaseModularAccount.sol";
import {BaseModularAccountLoupe} from "./BaseModularAccountLoupe.sol";
import {IPlugin, PluginManifest} from "../interfaces/IPlugin.sol";
import {IStandardExecutor} from "../interfaces/IStandardExecutor.sol";
import {IStandardExecutor, Call} from "../interfaces/IStandardExecutor.sol";
import {IPluginExecutor} from "../interfaces/IPluginExecutor.sol";
import {AccountStorage, getAccountStorage, getPermittedCallKey} from "../libraries/AccountStorage.sol";
import {Execution} from "../libraries/ERC6900TypeUtils.sol";
import {FunctionReference, FunctionReferenceLib} from "../libraries/FunctionReferenceLib.sol";
import {AccountStorageInitializable} from "./AccountStorageInitializable.sol";
import {IPluginManager} from "../interfaces/IPluginManager.sol";
Expand Down Expand Up @@ -137,46 +136,38 @@ contract UpgradeableModularAccount is
return execReturnData;
}

/// @notice Executes a transaction from the account
/// @param execution The execution to perform
/// @return result The result of the execution
function execute(Execution calldata execution)
/// @inheritdoc IStandardExecutor
function execute(address target, uint256 value, bytes calldata data)
external
payable
override
wrapNativeFunction
returns (bytes memory result)
{
result = _exec(execution.target, execution.value, execution.data);
result = _exec(target, value, data);
}

/// @notice Executes a batch of transactions from the account
/// @dev If any of the transactions revert, the entire batch reverts
/// @param executions The executions to perform
/// @return results The results of the executions
function executeBatch(Execution[] calldata executions)
/// @inheritdoc IStandardExecutor
function executeBatch(Call[] calldata calls)
external
payable
override
wrapNativeFunction
returns (bytes[] memory results)
{
uint256 executionsLength = executions.length;
results = new bytes[](executionsLength);
uint256 callsLength = calls.length;
results = new bytes[](callsLength);

for (uint256 i = 0; i < executionsLength;) {
results[i] = _exec(executions[i].target, executions[i].value, executions[i].data);
for (uint256 i = 0; i < callsLength;) {
results[i] = _exec(calls[i].target, calls[i].value, calls[i].data);

unchecked {
++i;
}
}
}

/// @notice Executes a call from a plugin to another plugin
/// @dev Permissions must be granted to the calling plugin for the call to go through
/// @param data calldata to send to the plugin
/// @return The result of the call
/// @inheritdoc IPluginExecutor
function executeFromPlugin(bytes calldata data) external payable override returns (bytes memory) {
bytes4 selector = bytes4(data[:4]);
address callingPlugin = msg.sender;
Expand Down Expand Up @@ -213,12 +204,7 @@ contract UpgradeableModularAccount is
return returnData;
}

/// @notice Executes a call from a plugin to a non-plugin address
/// @dev Permissions must be granted to the calling plugin for the call to go through
/// @param target address of the target to call
/// @param value value to send with the call
/// @param data calldata to send to the target
/// @return The result of the call
/// @inheritdoc IPluginExecutor
function executeFromPluginExternal(address target, uint256 value, bytes calldata data)
external
payable
Expand Down
18 changes: 10 additions & 8 deletions src/interfaces/IPluginExecutor.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,18 @@
pragma solidity ^0.8.19;

interface IPluginExecutor {
/// @notice Method from calls made from plugins.
/// @param data The call data for the call.
/// @return The return data from the call.
/// @notice Executes a call from a plugin to another plugin.
/// @dev Permissions must be granted to the calling plugin for the call to go through.
/// @param data calldata to send to the plugin
/// @return The result of the call
function executeFromPlugin(bytes calldata data) external payable returns (bytes memory);

/// @notice Method from calls made from plugins.
/// @dev If the target is a plugin, the call SHOULD revert.
/// @param target The target of the external contract to be called.
/// @param value The value to pass.
/// @param data The data to pass.
/// @notice Executes a call from a plugin to a non-plugin address.
/// @dev Permissions must be granted to the calling plugin for the call to go through.
/// @param target address of the target to call
/// @param value value to send with the call
/// @param data calldata to send to the target
/// @return The result of the call
function executeFromPluginExternal(address target, uint256 value, bytes calldata data)
external
payable
Expand Down
23 changes: 17 additions & 6 deletions src/interfaces/IStandardExecutor.sol
Original file line number Diff line number Diff line change
@@ -1,18 +1,29 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.19;

import {Execution} from "../libraries/ERC6900TypeUtils.sol";
struct Call {
// The target address for account to call.
address target;
// The value sent with the call.
uint256 value;
// The call data for the call.
bytes data;
}

/// @title Standard Executor Interface
interface IStandardExecutor {
/// @notice Standard execute method.
/// @dev If the target is a plugin, the call SHOULD revert.
/// @param execution The execution information.
/// @param target The target address for account to call.
/// @param value The value sent with the call.
/// @param data The call data for the call.
/// @return The return data from the call.
function execute(Execution calldata execution) external payable returns (bytes memory);
function execute(address target, uint256 value, bytes calldata data) external payable returns (bytes memory);

/// @notice Standard executeBatch method.
/// @dev If the target is a plugin, the call SHOULD revert.
/// @param executions The array of executions.
/// @dev If the target is a plugin, the call SHOULD revert. If any of the transactions revert, the entire batch
/// reverts.
/// @param calls The array of calls.
/// @return An array containing the return data from the calls.
function executeBatch(Execution[] calldata executions) external payable returns (bytes[] memory);
function executeBatch(Call[] calldata calls) external payable returns (bytes[] memory);
}
11 changes: 0 additions & 11 deletions src/libraries/ERC6900TypeUtils.sol

This file was deleted.

13 changes: 6 additions & 7 deletions test/account/AccountReturnData.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {IPluginManager} from "../../src/interfaces/IPluginManager.sol";
import {UpgradeableModularAccount} from "../../src/account/UpgradeableModularAccount.sol";
import {SingleOwnerPlugin} from "../../src/plugins/owner/SingleOwnerPlugin.sol";
import {FunctionReference} from "../../src/libraries/FunctionReferenceLib.sol";
import {Execution} from "../../src/libraries/ERC6900TypeUtils.sol";
import {Call} from "../../src/interfaces/IStandardExecutor.sol";

import {
RegularResultContract,
Expand Down Expand Up @@ -72,9 +72,8 @@ contract AccountReturnDataTest is Test {

// Tests the ability to read the results of contracts called via IStandardExecutor.execute
function test_returnData_singular_execute() public {
bytes memory returnData = account.execute(
Execution(address(regularResultContract), 0, abi.encodeCall(RegularResultContract.foo, ()))
);
bytes memory returnData =
account.execute(address(regularResultContract), 0, abi.encodeCall(RegularResultContract.foo, ()));

bytes32 result = abi.decode(returnData, (bytes32));

Expand All @@ -83,13 +82,13 @@ contract AccountReturnDataTest is Test {

// Tests the ability to read the results of multiple contract calls via IStandardExecutor.executeBatch
function test_returnData_executeBatch() public {
Execution[] memory calls = new Execution[](2);
calls[0] = Execution({
Call[] memory calls = new Call[](2);
calls[0] = Call({
target: address(regularResultContract),
value: 0,
data: abi.encodeCall(RegularResultContract.foo, ())
});
calls[1] = Execution({
calls[1] = Call({
target: address(regularResultContract),
value: 0,
data: abi.encodeCall(RegularResultContract.bar, ())
Expand Down
26 changes: 9 additions & 17 deletions test/account/UpgradeableModularAccount.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {PluginManifest} from "../../src/interfaces/IPlugin.sol";
import {IPluginLoupe} from "../../src/interfaces/IPluginLoupe.sol";
import {IPluginManager} from "../../src/interfaces/IPluginManager.sol";
import {IPluginExecutor} from "../../src/interfaces/IPluginExecutor.sol";
import {Execution} from "../../src/libraries/ERC6900TypeUtils.sol";
import {Call} from "../../src/interfaces/IStandardExecutor.sol";
import {FunctionReference} from "../../src/libraries/FunctionReferenceLib.sol";
import {IPlugin, PluginManifest} from "../../src/interfaces/IPlugin.sol";

Expand Down Expand Up @@ -122,9 +122,7 @@ contract UpgradeableModularAccountTest is Test {
sender: address(account1),
nonce: 0,
initCode: abi.encodePacked(address(factory), abi.encodeCall(factory.createAccount, (owner1, 0))),
callData: abi.encodeCall(
UpgradeableModularAccount(payable(account1)).execute, Execution(recipient, 1 wei, "")
),
callData: abi.encodeCall(UpgradeableModularAccount.execute, (recipient, 1 wei, "")),
callGasLimit: CALL_GAS_LIMIT,
verificationGasLimit: VERIFICATION_GAS_LIMIT,
preVerificationGas: 0,
Expand Down Expand Up @@ -152,9 +150,7 @@ contract UpgradeableModularAccountTest is Test {
sender: address(account2),
nonce: 0,
initCode: "",
callData: abi.encodeCall(
UpgradeableModularAccount(payable(account2)).execute, Execution(ethRecipient, 1 wei, "")
),
callData: abi.encodeCall(UpgradeableModularAccount.execute, (ethRecipient, 1 wei, "")),
callGasLimit: CALL_GAS_LIMIT,
verificationGasLimit: VERIFICATION_GAS_LIMIT,
preVerificationGas: 0,
Expand Down Expand Up @@ -182,9 +178,7 @@ contract UpgradeableModularAccountTest is Test {
sender: address(account2),
nonce: 0,
initCode: "",
callData: abi.encodeCall(
UpgradeableModularAccount(payable(account2)).execute, Execution(ethRecipient, 1 wei, "")
),
callData: abi.encodeCall(UpgradeableModularAccount.execute, (ethRecipient, 1 wei, "")),
callGasLimit: CALL_GAS_LIMIT,
verificationGasLimit: VERIFICATION_GAS_LIMIT,
preVerificationGas: 0,
Expand Down Expand Up @@ -213,8 +207,7 @@ contract UpgradeableModularAccountTest is Test {
nonce: 0,
initCode: "",
callData: abi.encodeCall(
UpgradeableModularAccount(payable(account2)).execute,
Execution(address(counter), 0, abi.encodeCall(counter.increment, ()))
UpgradeableModularAccount.execute, (address(counter), 0, abi.encodeCall(counter.increment, ()))
),
callGasLimit: CALL_GAS_LIMIT,
verificationGasLimit: VERIFICATION_GAS_LIMIT,
Expand All @@ -240,16 +233,15 @@ contract UpgradeableModularAccountTest is Test {

function test_batchExecute() public {
// Performs both an eth send and a contract interaction with counter
Execution[] memory executions = new Execution[](2);
executions[0] = Execution({target: ethRecipient, value: 1 wei, data: ""});
executions[1] =
Execution({target: address(counter), value: 0, data: abi.encodeCall(counter.increment, ())});
Call[] memory calls = new Call[](2);
calls[0] = Call({target: ethRecipient, value: 1 wei, data: ""});
calls[1] = Call({target: address(counter), value: 0, data: abi.encodeCall(counter.increment, ())});

UserOperation memory userOp = UserOperation({
sender: address(account2),
nonce: 0,
initCode: "",
callData: abi.encodeCall(UpgradeableModularAccount(payable(account2)).executeBatch, (executions)),
callData: abi.encodeCall(UpgradeableModularAccount.executeBatch, (calls)),
callGasLimit: CALL_GAS_LIMIT,
verificationGasLimit: VERIFICATION_GAS_LIMIT,
preVerificationGas: 0,
Expand Down

0 comments on commit b4755df

Please sign in to comment.