Skip to content

Commit b2da844

Browse files
authored
Merge pull request #10 from base-org/amie/review-first-pass
Address review comments (first pass)
2 parents 2523cb7 + 5f7aea9 commit b2da844

File tree

1 file changed

+29
-26
lines changed

1 file changed

+29
-26
lines changed

src/EIP7702Proxy.sol

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9,35 +9,48 @@ import {Address} from "openzeppelin-contracts/contracts/utils/Address.sol";
99
/// @title EIP7702Proxy
1010
/// @notice Proxy contract designed for EIP-7702 smart accounts
1111
/// @dev Implements ERC-1967 with an initial implementation and guarded initialization
12+
/// @author Coinbase (https://github.com/base-org/eip-7702-proxy)
1213
contract EIP7702Proxy is Proxy {
13-
// ERC1271 interface constants
14+
/// @notice ERC1271 interface constants
1415
bytes4 internal constant ERC1271_MAGIC_VALUE = 0x1626ba7e;
15-
bytes4 internal constant ERC1271_ISVALIDSIGNATURE_SELECTOR = 0x1626ba7e;
1616
bytes4 internal constant ERC1271_FAIL_VALUE = 0xffffffff;
1717

1818
/// @notice Address of this proxy contract (stored as immutable)
1919
address immutable proxy;
20+
2021
/// @notice Initial implementation address set during construction
2122
address immutable initialImplementation;
23+
2224
/// @notice Function selector on the implementation that is guarded from direct calls
2325
bytes4 immutable guardedInitializer;
2426

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

30+
/// @notice Emitted when the initialization signature is invalid
2731
error InvalidSignature();
32+
33+
/// @notice Emitted when the `guardedInitializer` is called
2834
error InvalidInitializer();
35+
36+
/// @notice Emitted when initialization is attempted on a non-initial implementation
2937
error InvalidImplementation();
3038

39+
/// @notice Initializes the proxy with an initial implementation and guarded initializer
40+
/// @param implementation The initial implementation address
41+
/// @param initializer The selector of the `guardedInitializer` function
3142
constructor(address implementation, bytes4 initializer) {
3243
proxy = address(this);
3344
initialImplementation = implementation;
3445
guardedInitializer = initializer;
3546
}
3647

3748
/// @notice Initializes the proxy and implementation with a signed payload
49+
///
50+
/// @dev Signature must be from this contract's address
51+
///
3852
/// @param args The initialization arguments for the implementation
3953
/// @param signature The signature authorizing initialization
40-
/// @dev Signature must be from this contract's address
4154
function initialize(
4255
bytes calldata args,
4356
bytes calldata signature
@@ -52,22 +65,21 @@ contract EIP7702Proxy is Proxy {
5265
if (implementation != initialImplementation)
5366
revert InvalidImplementation();
5467

55-
// Set the ERC-1967 implementation slot and emit Upgraded event
56-
ERC1967Utils.upgradeToAndCall(initialImplementation, "");
57-
58-
Address.functionDelegateCall(
68+
// Set the ERC-1967 implementation slot, emit Upgraded event, call the initializer on the initial implementation
69+
ERC1967Utils.upgradeToAndCall(
5970
initialImplementation,
6071
abi.encodePacked(guardedInitializer, args)
6172
);
6273
}
6374

64-
/**
65-
* @notice Handles ERC-1271 signature validation by enforcing a final ecrecover check if signatures fail `isValidSignature` check
66-
* @dev This ensures EOA signatures are considered valid regardless of the implementation's `isValidSignature` implementation
67-
* @param hash The hash of the message being signed
68-
* @param signature The signature of the message
69-
* @return The result of the `isValidSignature` check
70-
*/
75+
/// @notice Handles ERC-1271 signature validation by enforcing a final ecrecover check if signatures fail `isValidSignature` check
76+
///
77+
/// @dev This ensures EOA signatures are considered valid regardless of the implementation's `isValidSignature` implementation
78+
///
79+
/// @param hash The hash of the message being signed
80+
/// @param signature The signature of the message
81+
///
82+
/// @return The result of the `isValidSignature` check
7183
function isValidSignature(
7284
bytes32 hash,
7385
bytes calldata signature
@@ -83,28 +95,19 @@ contract EIP7702Proxy is Proxy {
8395
result.length == 32 &&
8496
abi.decode(result, (bytes4)) == ERC1271_MAGIC_VALUE
8597
) {
86-
assembly {
87-
mstore(0, ERC1271_MAGIC_VALUE)
88-
return(0, 32)
89-
}
98+
return ERC1271_MAGIC_VALUE;
9099
}
91100

92101
// Only try ECDSA if signature is the right length (65 bytes)
93102
if (signature.length == 65) {
94103
address recovered = ECDSA.recover(hash, signature);
95104
if (recovered == address(this)) {
96-
assembly {
97-
mstore(0, ERC1271_MAGIC_VALUE)
98-
return(0, 32)
99-
}
105+
return ERC1271_MAGIC_VALUE;
100106
}
101107
}
102108

103109
// If all checks fail, return failure value
104-
assembly {
105-
mstore(0, ERC1271_FAIL_VALUE)
106-
return(0, 32)
107-
}
110+
return ERC1271_FAIL_VALUE;
108111
}
109112

110113
/// @inheritdoc Proxy

0 commit comments

Comments
 (0)