@@ -5,6 +5,7 @@ import {Proxy} from "openzeppelin-contracts/contracts/proxy/Proxy.sol";
55import {ERC1967Utils } from "openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Utils.sol " ;
66import {ECDSA} from "openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol " ;
77import {StorageSlot} from "openzeppelin-contracts/contracts/utils/StorageSlot.sol " ;
8+ import {IERC1271 } from "openzeppelin-contracts/contracts/interfaces/IERC1271.sol " ;
89
910/// @title EIP7702Proxy
1011/// @notice Proxy contract designed for EIP-7702 smart accounts
@@ -164,11 +165,11 @@ contract EIP7702Proxy is Proxy {
164165 receive () external payable {}
165166
166167 /**
167- * @notice Resets the ERC-1967 implementation slot after signature verification
168- * @dev Uses raw hash (no Ethereum signed message prefix) to prevent phishing
168+ * @notice Resets the ERC-1967 implementation slot after signature verification from any valid owner
169+ * @dev Uses the implementation's isValidSignature to verify owner signatures
169170 * @param newImplementation The implementation address to set
170- * @param nonce The nonce for this operation (verified against NonceTracker)
171- * @param signature The EOA signature authorizing this change
171+ * @param nonce The nonce for this operation
172+ * @param signature The SignatureWrapper from any valid owner
172173 */
173174 function resetImplementation (
174175 address newImplementation ,
@@ -182,22 +183,43 @@ contract EIP7702Proxy is Proxy {
182183 revert NonceAlreadyUsed ();
183184 }
184185
185- // Raw hash without Ethereum signed message prefix
186+ // Hash includes newImplementation and nonce
186187 bytes32 hash = keccak256 (abi.encode (newImplementation, nonce));
187188
188- // Verify signature is from this address (the EOA)
189- address recovered = ECDSA.recover (hash, signature);
190- if (recovered != address (this )) {
191- revert InvalidSignature ();
189+ // First try validating against new implementation's isValidSignature
190+ (bool success , bytes memory result ) = newImplementation.call (
191+ abi.encodeWithSelector (
192+ IERC1271 .isValidSignature.selector ,
193+ hash,
194+ signature
195+ )
196+ );
197+
198+ // Check if implementation validation succeeded
199+ if (
200+ success &&
201+ result.length == 32 &&
202+ abi.decode (result, (bytes4 )) == ERC1271_MAGIC_VALUE
203+ ) {
204+ // Valid owner signature, proceed with reset
205+ ERC1967Utils .upgradeToAndCall (newImplementation, "" );
206+ emit ImplementationReset (newImplementation);
207+ return ;
192208 }
193209
194- // Reset the implementation slot
195- ERC1967Utils .upgradeToAndCall (
196- newImplementation,
197- "" // No initialization needed
198- );
210+ // If implementation check failed, try direct EOA signature
211+ if (signature.length == 65 ) {
212+ address recovered = ECDSA.recover (hash, signature);
213+ if (recovered == address (this )) {
214+ // Valid EOA signature, proceed with reset
215+ ERC1967Utils .upgradeToAndCall (newImplementation, "" );
216+ emit ImplementationReset (newImplementation);
217+ return ;
218+ }
219+ }
199220
200- emit ImplementationReset (newImplementation);
221+ // If both checks fail, revert
222+ revert InvalidSignature ();
201223 }
202224}
203225
0 commit comments