@@ -4,12 +4,13 @@ pragma solidity ^0.8.0;
44import {
55 TransparentUpgradeableProxy
66} from "@openzeppelin/contracts-v4/proxy/transparent/TransparentUpgradeableProxy.sol " ;
7+ import { ERC1967Utils } from "openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Utils.sol " ;
78import { ProxyAdmin } from "openzeppelin-contracts/contracts/proxy/transparent/ProxyAdmin.sol " ;
89import {
910 ITransparentUpgradeableProxy
1011} from "openzeppelin-contracts/contracts/proxy/transparent/TransparentUpgradeableProxy.sol " ;
1112
12- import { IPlugin } from "modular-account-libs/interfaces/IPlugin.sol " ;
13+ import { IPlugin, PluginMetadata } from "modular-account-libs/interfaces/IPlugin.sol " ;
1314
1415import { ACCOUNT_IMPL, ENTRYPOINT } from "webauthn-owner-plugin/../script/Factory.s.sol " ;
1516
@@ -52,7 +53,7 @@ contract Redeployer is BaseScript {
5253 ownerPlugin =
5354 IPlugin (_broadcastOrCreate3 ("node_modules/webauthn-owner-plugin/broadcast/Plugin " , "WebauthnOwnerPlugin " ));
5455 exaPlugin = IPlugin (_broadcastOrCreate3 ("broadcast/ExaPlugin " , "ExaPlugin " ));
55- factory = ExaAccountFactory ( payable (CREATE3_FACTORY. getDeployed (admin, keccak256 ( abi.encode ( " ExaAccountFactory " )))) );
56+ factory = _factory ( );
5657 auditor = IAuditor (_protocolOrStub ("Auditor " , "StubAuditor " ));
5758 marketUSDC = IMarket (_protocolOrStub ("MarketUSDC " , "StubMarketUSDC " ));
5859 marketWETH = IMarket (_protocolOrStub ("MarketWETH " , "StubMarketWETH " ));
@@ -196,18 +197,23 @@ contract Redeployer is BaseScript {
196197 /// @notice Upgrades a proxy to the cached ExaAccountFactory implementation.
197198 function deployExaFactory (address proxy ) external {
198199 if (address (factory).code.length == 0 ) revert NotPrepared ();
200+ if (address (uint160 (uint256 (vm.load (proxy, ERC1967Utils .IMPLEMENTATION_SLOT)))) == address (factory)) return ;
199201 vm.broadcast (acct ("admin " ));
200202 proxyAdmin.upgradeAndCall (ITransparentUpgradeableProxy (proxy), address (factory), "" );
201203 }
202204
203205 /// @notice Deploys ExaAccountFactory at a version-specific CREATE3 address.
204206 function deployExaFactory (string calldata version ) external returns (ExaAccountFactory f ) {
205- if (address (factory).code.length == 0 ) revert NotPrepared ();
207+ bytes32 salt = keccak256 (abi.encode ("Exa Plugin " , version));
208+ f = ExaAccountFactory (payable (CREATE3_FACTORY.getDeployed (acct ("admin " ), salt)));
209+ if (address (f).code.length != 0 ) return f;
210+ if (address (ownerPlugin).code.length == 0 || address (exaPlugin).code.length == 0 ) revert NotPrepared ();
211+
206212 address admin = acct ("admin " );
207213 vm.startBroadcast (admin);
208214 f = ExaAccountFactory (
209215 payable (CREATE3_FACTORY.deploy (
210- keccak256 ( abi.encode ( " Exa Plugin " , version)) ,
216+ salt ,
211217 abi.encodePacked (
212218 vm.getCode ("ExaAccountFactory.sol:ExaAccountFactory " ),
213219 abi.encode (admin, ownerPlugin, exaPlugin, ACCOUNT_IMPL, ENTRYPOINT)
@@ -247,6 +253,16 @@ contract Redeployer is BaseScript {
247253 if (addr == address (0 )) addr = CREATE3_FACTORY.getDeployed (acct ("admin " ), keccak256 (abi.encode (salt)));
248254 }
249255
256+ function _factory () internal returns (ExaAccountFactory) {
257+ if (address (exaPlugin).code.length != 0 ) {
258+ PluginMetadata memory metadata = exaPlugin.pluginMetadata ();
259+ address f = CREATE3_FACTORY.getDeployed (acct ("admin " ), keccak256 (abi.encode (metadata.name, metadata.version)));
260+ if (f.code.length != 0 ) return ExaAccountFactory (payable (f));
261+ }
262+ return
263+ ExaAccountFactory (payable (CREATE3_FACTORY.getDeployed (acct ("admin " ), keccak256 (abi.encode ("ExaAccountFactory " )))));
264+ }
265+
250266 function _protocolOrStub (string memory name , string memory stub ) internal returns (address addr ) {
251267 addr = protocol (name, false );
252268 if (addr == address (0 )) addr = CREATE3_FACTORY.getDeployed (acct ("admin " ), keccak256 (abi.encode (stub)));
0 commit comments