Skip to content

Commit

Permalink
Merge pull request #18 from base-org/amie/cleanup
Browse files Browse the repository at this point in the history
Final pre-audit nits
  • Loading branch information
amiecorso authored Feb 3, 2025
2 parents dd72de1 + c399a82 commit 9c0c9e6
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 14 deletions.
15 changes: 5 additions & 10 deletions src/EIP7702Proxy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ import {StorageSlot} from "openzeppelin-contracts/contracts/utils/StorageSlot.so

/// @title EIP7702Proxy
/// @notice Proxy contract designed for EIP-7702 smart accounts
/// @dev Implements ERC-1967 with an initial implementation and guarded initialization
/// @dev Implements ERC-1967 with an initial implementation address and guarded initializer function
/// @author Coinbase (https://github.com/base-org/eip-7702-proxy)
contract EIP7702Proxy is Proxy {
/// @notice ERC1271 interface constants
bytes4 internal constant ERC1271_MAGIC_VALUE = 0x1626ba7e;
bytes4 internal constant ERC1271_FAIL_VALUE = 0xffffffff;

/// @notice Address of this proxy contract (stored as immutable)
/// @notice Address of this proxy contract delegate
address immutable proxy;

/// @notice Initial implementation address set during construction
Expand All @@ -24,15 +24,12 @@ contract EIP7702Proxy is Proxy {
/// @notice Function selector on the implementation that is guarded from direct calls
bytes4 immutable guardedInitializer;

/// @dev Storage slot with the initialized flag, conforms to ERC-7201
/// @dev Storage slot with the initialized flag, calculated via ERC-7201
bytes32 internal constant INITIALIZED_SLOT =
keccak256(
abi.encode(uint256(keccak256("EIP7702Proxy.initialized")) - 1)
) & ~bytes32(uint256(0xff));

/// @notice Emitted when the implementation is upgraded
event Upgraded(address indexed implementation);

/// @notice Emitted when the initialization signature is invalid
error InvalidSignature();

Expand Down Expand Up @@ -76,9 +73,7 @@ contract EIP7702Proxy is Proxy {
// Construct hash without Ethereum signed message prefix to prevent phishing via standard wallet signing.
// Since this proxy is designed for EIP-7702 (where the proxy address is an EOA),
// using a raw hash ensures that initialization signatures cannot be obtained through normal
// wallet "Sign Message" prompts. This prevents malicious dapps from tricking users into
// initializing their account via standard wallet signing flows.
// Wallets must implement custom signing logic at a lower level to support initialization.
// wallet "Sign Message" prompts.
bytes32 hash = keccak256(abi.encode(proxy, args));
address recovered = ECDSA.recover(hash, signature);
if (recovered != address(this)) revert InvalidSignature();
Expand All @@ -93,7 +88,7 @@ contract EIP7702Proxy is Proxy {
);
}

/// @notice Handles ERC-1271 signature validation by enforcing a final ecrecover check if signatures fail `isValidSignature` check
/// @notice Handles ERC-1271 signature validation by enforcing a final `ecrecover` check if signatures fail `isValidSignature` check
///
/// @dev This ensures EOA signatures are considered valid regardless of the implementation's `isValidSignature` implementation
///
Expand Down
4 changes: 2 additions & 2 deletions test/EIP7702Proxy/initialize.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {EIP7702Proxy} from "../../src/EIP7702Proxy.sol";
import {MockImplementation, RevertingInitializerMockImplementation} from "../mocks/MockImplementation.sol";
import {ECDSA} from "openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol";
import {ERC1967Utils} from "openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Utils.sol";
import {IERC1967} from "openzeppelin-contracts/contracts/interfaces/IERC1967.sol";

contract InitializeTest is EIP7702ProxyBase {
function test_succeeds_withValidSignatureAndArgs(address newOwner) public {
Expand Down Expand Up @@ -44,9 +45,8 @@ contract InitializeTest is EIP7702ProxyBase {
function test_emitsUpgradedEvent() public {
bytes memory initArgs = _createInitArgs(_newOwner);
bytes memory signature = _signInitData(_EOA_PRIVATE_KEY, initArgs);

vm.expectEmit(true, false, false, false, address(_eoa));
emit EIP7702Proxy.Upgraded(address(_implementation));
emit IERC1967.Upgraded(address(_implementation));
EIP7702Proxy(_eoa).initialize(initArgs, signature);
}

Expand Down
5 changes: 3 additions & 2 deletions test/EIP7702Proxy/upgradeToAndCall.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pragma solidity ^0.8.23;
import {EIP7702ProxyBase} from "../base/EIP7702ProxyBase.sol";
import {EIP7702Proxy} from "../../src/EIP7702Proxy.sol";
import {MockImplementation} from "../mocks/MockImplementation.sol";
import {IERC1967} from "openzeppelin-contracts/contracts/interfaces/IERC1967.sol";

/**
* @title UpgradeToAndCallTest
Expand Down Expand Up @@ -31,7 +32,7 @@ contract UpgradeToAndCallTest is EIP7702ProxyBase {

// Expect the Upgraded event
vm.expectEmit(true, false, false, false, address(_eoa));
emit EIP7702Proxy.Upgraded(address(newImplementation));
emit IERC1967.Upgraded(address(newImplementation));

MockImplementation(payable(_eoa)).upgradeToAndCall(
address(newImplementation),
Expand All @@ -52,7 +53,7 @@ contract UpgradeToAndCallTest is EIP7702ProxyBase {
vm.prank(_newOwner);

vm.expectEmit(true, false, false, false, address(_eoa));
emit EIP7702Proxy.Upgraded(address(newImplementation));
emit IERC1967.Upgraded(address(newImplementation));

MockImplementation(payable(_eoa)).upgradeToAndCall(
address(newImplementation),
Expand Down

0 comments on commit 9c0c9e6

Please sign in to comment.