diff --git a/src/account/UpgradeableModularAccount.sol b/src/account/UpgradeableModularAccount.sol index be4dc126..312c1d46 100644 --- a/src/account/UpgradeableModularAccount.sol +++ b/src/account/UpgradeableModularAccount.sol @@ -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"; @@ -137,35 +136,30 @@ 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; @@ -173,10 +167,7 @@ contract UpgradeableModularAccount is } } - /// @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; @@ -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 diff --git a/src/interfaces/IPluginExecutor.sol b/src/interfaces/IPluginExecutor.sol index c5e3b7e7..31269e00 100644 --- a/src/interfaces/IPluginExecutor.sol +++ b/src/interfaces/IPluginExecutor.sol @@ -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 diff --git a/src/interfaces/IStandardExecutor.sol b/src/interfaces/IStandardExecutor.sol index 15f84872..5c3c52b3 100644 --- a/src/interfaces/IStandardExecutor.sol +++ b/src/interfaces/IStandardExecutor.sol @@ -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); } diff --git a/src/libraries/ERC6900TypeUtils.sol b/src/libraries/ERC6900TypeUtils.sol deleted file mode 100644 index 9e088121..00000000 --- a/src/libraries/ERC6900TypeUtils.sol +++ /dev/null @@ -1,11 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.8.19; - -struct Execution { - // The target contract for account to execute. - address target; - // The value for the execution. - uint256 value; - // The call data for the execution. - bytes data; -} diff --git a/test/account/AccountReturnData.t.sol b/test/account/AccountReturnData.t.sol index d969c2c8..dc5c350f 100644 --- a/test/account/AccountReturnData.t.sol +++ b/test/account/AccountReturnData.t.sol @@ -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, @@ -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)); @@ -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, ()) diff --git a/test/account/UpgradeableModularAccount.t.sol b/test/account/UpgradeableModularAccount.t.sol index 0da80e81..3b584181 100644 --- a/test/account/UpgradeableModularAccount.t.sol +++ b/test/account/UpgradeableModularAccount.t.sol @@ -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"; @@ -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, @@ -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, @@ -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, @@ -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, @@ -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,