Skip to content

Commit

Permalink
Split ERC-7821 executor into its own contract
Browse files Browse the repository at this point in the history
  • Loading branch information
ernestognw committed Jan 7, 2025
1 parent bbc0c77 commit 175575f
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 10 deletions.
11 changes: 8 additions & 3 deletions contracts/account/Account.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,21 @@ import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Hol
import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";
import {ERC7739Signer} from "../utils/cryptography/ERC7739Signer.sol";
import {AccountCore} from "./AccountCore.sol";
import {AccountERC7821} from "./extensions/AccountERC7821.sol";
import {ERC7821} from "./extensions/ERC7821.sol";

/**
* @dev Extension of {AccountCore} with recommended feature that most account abstraction implementation will want:
*
* * {AccountERC7821} for performing external calls in batches.
* * {ERC7821} for performing external calls in batches.
* * {ERC721Holder} and {ERC1155Holder} to accept ERC-712 and ERC-1155 token transfers transfers.
* * {ERC7739Signer} for ERC-1271 signature support with ERC-7739 replay protection
*
* NOTE: To use this contract, the {ERC7739Signer-_rawSignatureValidation} function must be
* implemented using a specific signature verification algorithm. See {SignerECDSA}, {SignerP256} or {SignerRSA}.
*/
abstract contract Account is AccountCore, AccountERC7821, ERC721Holder, ERC1155Holder, ERC7739Signer {}
abstract contract Account is AccountCore, ERC7821, ERC721Holder, ERC1155Holder, ERC7739Signer {
/// @inheritdoc ERC7821
function execute(bytes32 mode, bytes calldata executionData) public payable virtual override onlyEntryPointOrSelf {
super.execute(mode, executionData);
}
}
9 changes: 7 additions & 2 deletions contracts/account/README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@
[.readme-notice]
NOTE: This document is better viewed at https://docs.openzeppelin.com/community-contracts/api/account

This directory includes contracts to build accounts for ERC-4337.
This directory includes contracts to build accounts for ERC-4337. These include:

* {AccountCore}: An ERC-4337 smart account implementation that includes the core logic to process user operations.
* {Account}: An extension of `AccountCore` that implements the recommended features for ERC-4337 smart accounts.
* {AccountSignerERC7702}: An account implementation with low-level signature validation performed by an EOA.
* {ERC7821}: Minimal batch executor implementation whose contracts can delegate to. Useful to enable easy batch execution for smart contracts.

== Core

Expand All @@ -14,4 +19,4 @@ This directory includes contracts to build accounts for ERC-4337.

{{AccountSignerERC7702}}

{{AccountERC7821}}
{{ERC7821}}
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,25 @@ pragma solidity ^0.8.20;

import {ERC7579Utils, Mode, CallType, ExecType, ModeSelector} from "@openzeppelin/contracts/account/utils/draft-ERC7579Utils.sol";
import {IERC7821} from "../../interfaces/IERC7821.sol";
import {AccountCore} from "../AccountCore.sol";

/**
* @dev Minimal batch executor following ERC7821. Only supports basic mode (no optional "opData").
* @dev Minimal batch executor following ERC-7821. Only supports basic mode (no optional "opData").
*/
abstract contract AccountERC7821 is AccountCore, IERC7821 {
abstract contract ERC7821 is IERC7821 {
using ERC7579Utils for *;

error UnsupportedExecutionMode();

/// @inheritdoc IERC7821
function execute(bytes32 mode, bytes calldata executionData) public payable virtual onlyEntryPointOrSelf {
/**
* @dev Executes the calls in `executionData` with no optional `opData` support.
*
* NOTE: When using with an {Account}, make sure to use wrap this function with
* an authorization check that ensures the caller is the account itself or
* the entrypoint.
*
* Reverts and bubbles up error if any call fails.
*/
function execute(bytes32 mode, bytes calldata executionData) public payable virtual {
if (!supportsExecutionMode(mode)) revert UnsupportedExecutionMode();
executionData.execBatch(ERC7579Utils.EXECTYPE_DEFAULT);
}
Expand All @@ -28,4 +35,12 @@ abstract contract AccountERC7821 is AccountCore, IERC7821 {
execType == ERC7579Utils.EXECTYPE_DEFAULT &&
modeSelector == ModeSelector.wrap(0x00000000);
}

// slither-disable-next-line write-after-write
function _emptyCalldataBytes() private pure returns (bytes calldata result) {
assembly ("memory-safe") {
result.offset := 0
result.length := 0
}
}
}

0 comments on commit 175575f

Please sign in to comment.