Skip to content

Commit 4f3009e

Browse files
committed
remove space
1 parent c306de8 commit 4f3009e

File tree

3 files changed

+46
-9
lines changed

3 files changed

+46
-9
lines changed

src/EIP7702Proxy.sol

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
// SPDX-License-Identifier: UNLICENSED
22
pragma solidity ^0.8.0;
33

4-
import {Proxy} from "@openzeppelin/contracts/proxy/Proxy.sol";
5-
import {ERC1967Utils} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Utils.sol";
6-
import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
7-
import {Address} from "@openzeppelin/contracts/utils/Address.sol";
4+
import {Proxy} from "openzeppelin-contracts/contracts/proxy/Proxy.sol";
5+
import {ERC1967Utils} from "openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Utils.sol";
6+
import {ECDSA} from "openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol";
7+
import {Address} from "openzeppelin-contracts/contracts/utils/Address.sol";
88

99
/// @notice Proxy contract designed for EIP-7702 smart accounts.
1010
///
@@ -15,6 +15,8 @@ contract EIP7702Proxy is Proxy {
1515
address immutable initialImplementation;
1616
bytes4 immutable guardedInitializer;
1717

18+
event Upgraded(address indexed implementation);
19+
1820
error InvalidSignature();
1921
error InvalidInitializer();
2022
error InvalidImplementation();
@@ -39,6 +41,9 @@ contract EIP7702Proxy is Proxy {
3941
if (implementation != initialImplementation)
4042
revert InvalidImplementation();
4143

44+
// Set the ERC-1967 implementation slot and emit Upgraded event
45+
ERC1967Utils.upgradeToAndCall(initialImplementation, "");
46+
4247
Address.functionDelegateCall(
4348
initialImplementation,
4449
abi.encodePacked(guardedInitializer, args)

test/EIP7702Proxy/initialize.t.sol

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ import {EIP7702ProxyBase} from "../base/EIP7702ProxyBase.sol";
55
import {EIP7702Proxy} from "../../src/EIP7702Proxy.sol";
66
import {CoinbaseSmartWallet} from "../../lib/smart-wallet/src/CoinbaseSmartWallet.sol";
77
import {ECDSA} from "openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol";
8+
import {ERC1967Utils} from "openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Utils.sol";
89

910
contract InitializeTest is EIP7702ProxyBase {
1011
function testSucceedsWithValidSignature() public {
1112
bytes memory initArgs = _createInitArgs(_newOwner);
1213
bytes memory signature = _signInitData(_EOA_PRIVATE_KEY, initArgs);
1314

14-
vm.prank(_eoa);
1515
EIP7702Proxy(_eoa).initialize(initArgs, signature);
1616

1717
// Verify initialization through implementation at the EOA's address
@@ -26,7 +26,6 @@ contract InitializeTest is EIP7702ProxyBase {
2626
bytes memory initArgs = _createInitArgs(_newOwner);
2727
bytes memory signature = hex"deadbeef"; // Invalid signature
2828

29-
vm.prank(_eoa);
3029
vm.expectRevert(); // Should revert with signature verification error
3130
EIP7702Proxy(_eoa).initialize(initArgs, signature);
3231
}
@@ -40,7 +39,6 @@ contract InitializeTest is EIP7702ProxyBase {
4039
(uint8 v, bytes32 r, bytes32 s) = vm.sign(wrongPk, initHash);
4140
bytes memory signature = abi.encodePacked(r, s, v);
4241

43-
vm.prank(_eoa);
4442
vm.expectRevert(); // Should revert with signature verification error
4543
EIP7702Proxy(_eoa).initialize(initArgs, signature);
4644
}
@@ -49,12 +47,33 @@ contract InitializeTest is EIP7702ProxyBase {
4947
bytes memory initArgs = _createInitArgs(_newOwner);
5048
bytes memory signature = _signInitData(_EOA_PRIVATE_KEY, initArgs);
5149

52-
vm.prank(_eoa);
5350
EIP7702Proxy(_eoa).initialize(initArgs, signature);
5451

5552
// Try to initialize again
56-
vm.prank(_eoa);
5753
vm.expectRevert(CoinbaseSmartWallet.Initialized.selector);
5854
EIP7702Proxy(_eoa).initialize(initArgs, signature);
5955
}
56+
57+
function testSetsERC1967ImplementationSlot() public {
58+
bytes memory initArgs = _createInitArgs(_newOwner);
59+
bytes memory signature = _signInitData(_EOA_PRIVATE_KEY, initArgs);
60+
61+
EIP7702Proxy(_eoa).initialize(initArgs, signature);
62+
63+
address storedImpl = _getERC1967Implementation(address(_eoa));
64+
assertEq(
65+
storedImpl,
66+
address(_implementation),
67+
"ERC1967 implementation slot should store implementation address"
68+
);
69+
}
70+
71+
function testEmitsUpgradedEvent() public {
72+
bytes memory initArgs = _createInitArgs(_newOwner);
73+
bytes memory signature = _signInitData(_EOA_PRIVATE_KEY, initArgs);
74+
75+
vm.expectEmit(true, false, false, false, address(_eoa));
76+
emit EIP7702Proxy.Upgraded(address(_implementation));
77+
EIP7702Proxy(_eoa).initialize(initArgs, signature);
78+
}
6079
}

test/base/EIP7702ProxyBase.sol

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ import {ECDSA} from "openzeppelin-contracts/contracts/utils/cryptography/ECDSA.s
1212
* This contract should not contain any actual tests.
1313
*/
1414
abstract contract EIP7702ProxyBase is Test {
15+
// Add ERC1967 implementation slot constant
16+
bytes32 internal constant IMPLEMENTATION_SLOT =
17+
0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
18+
1519
// Test accounts
1620
uint256 internal constant _EOA_PRIVATE_KEY = 0xA11CE;
1721
address payable internal _eoa;
@@ -77,4 +81,13 @@ abstract contract EIP7702ProxyBase is Test {
7781
owners[0] = abi.encode(owner);
7882
return abi.encode(owners);
7983
}
84+
85+
/**
86+
* @dev Helper to read the implementation address from ERC1967 storage slot
87+
* @param proxy Address of the proxy contract to read from
88+
* @return The implementation address stored in the ERC1967 slot
89+
*/
90+
function _getERC1967Implementation(address proxy) internal view returns (address) {
91+
return address(uint160(uint256(vm.load(proxy, IMPLEMENTATION_SLOT))));
92+
}
8093
}

0 commit comments

Comments
 (0)