@@ -4,37 +4,150 @@ pragma solidity ^0.8.10;
44
55import "forge-std/Script.sol " ;
66import {ATokenVaultFactory} from "../src/ATokenVaultFactory.sol " ;
7+ import {ICreateX} from "@pcaversaccio/createx/ICreateX.sol " ;
8+ import {ProxyAdmin as ProxyAdmin_v4_7} from "@openzeppelin/proxy/transparent/ProxyAdmin.sol " ;
9+ import {TransparentUpgradeableProxy as TransparentUpgradeableProxy_v5_3} from "@openzeppelin-v5/proxy/transparent/TransparentUpgradeableProxy.sol " ;
710
11+ /**
12+ * @title DeployFactory
13+ * @author Aave Labs
14+ * @notice Script to deploy the aTokenVaultFactory contract with deterministic address even when future versions change
15+ * @dev Run the script with the following command first:
16+ *
17+ * forge script script/DeployFactory.s.sol:DeployFactory -vvvv --rpc-url {$RPC_URL} --account ${ACCOUNT} --slow
18+ *
19+ * If succeeds, then add the --broadcast flag in order to send the transaction to the network.
20+ */
821contract DeployFactory is Script {
9- // DEPLOYMENT PARAMETERS - CHANGE THESE FOR YOUR FACTORY
10- // ===================================================
11- address constant PROXY_ADMIN_ADDRESS = address (0 ); // Address of the factory proxy admin
12- // ===================================================
13-
14- function getChainId () public view returns (uint256 ) {
15- uint256 chainId;
16- assembly {
17- chainId := chainid ()
18- }
19- return chainId;
20- }
22+ /////////////////// DEPLOYMENT PARAMETERS //////////////////////////
23+ /**
24+ * @notice Owner of the aTokenVaultFactory's Proxy Admin
25+ */
26+ address constant FACTORY_PROXY_ADMIN_OWNER = address (0 );
27+ ////////////////////////////////////////////////////////////////////
28+
29+ ////////////////// VERIFICATION PARAMETERS /////////////////////////
30+ /**
31+ * @notice Expected address for the deployed Renounced Proxy Admin, using CREATE3
32+ */
33+ address constant EXPECTED_RENOUNCED_PROXY_ADMIN_ADDRESS = address (0xd9734c69cCE8777514062e603aF211D429Ae328C );
34+ /**
35+ * @notice Expected address for deployed aTokenVaultFactory, using CREATE3
36+ */
37+ address constant EXPECTED_FACTORY_ADDRESS = address (0x7954d5c3ECaA0A8F3f373BBA88cE38f4Fa27616A );
38+ ////////////////////////////////////////////////////////////////////
39+
40+ address constant DEPLOYER_ADDRESS = address (0xFAC70d880Da5923673C502dbC8CeD1675c57e155 );
41+
42+ /**
43+ * @notice CREATE3 Salt for the Vault'sRenounced Ownership Proxy Admin deployment
44+ *
45+ * @dev Generated through following steps:
46+ *
47+ * Base Salt: keccak256("aave.aTokenVaultFactory.vault.renouncedProxyAdmin")
48+ * = 0x2bb59d5d1bfe60f97765faf35a14525d450d29788deb958f5afddb864ebc4929
49+ *
50+ * 0x 2bb59d5d1bfe60f97765faf35a14525d450d2978 8d eb958f5afddb864ebc4929
51+ *
52+ * Add deployer address (0xFAC70d880Da5923673C502dbC8CeD1675c57e155) at the beginning for protection:
53+ * 0x FAC70d880Da5923673C502dbC8CeD1675c57e155 8d eb958f5afddb864ebc4929
54+ *
55+ * Set the next byte to 0x00 in order to turn off the cross-chain protection:
56+ * 0x FAC70d880Da5923673C502dbC8CeD1675c57e155 00 eb958f5afddb864ebc4929
57+ *
58+ * Keep the final bytes from the base salt
59+ */
60+ bytes32 constant RENOUNCED_PROXY_ADMIN_SALT = 0xFAC70d880Da5923673C502dbC8CeD1675c57e15500eb958f5afddb864ebc4929 ;
61+
62+ /**
63+ * @notice CREATE3 Salt for the deterministic aTokenVaultFactory deployment
64+ *
65+ * @dev Generated through following steps:
66+ *
67+ * Base Salt: keccak256("aave.aTokenVaultFactory")
68+ * = 0x36275659667d979dfee1891a4bc3f4c14e3c2bb6a5b996d2f8dec69a6f19c4be
69+ *
70+ * 0x 36275659667d979dfee1891a4bc3f4c14e3c2bb6 a5 b996d2f8dec69a6f19c4be
71+ *
72+ * Add deployer address (0xFAC70d880Da5923673C502dbC8CeD1675c57e155) at the beginning for protection:
73+ * 0x FAC70d880Da5923673C502dbC8CeD1675c57e155 a5 b996d2f8dec69a6f19c4be
74+ *
75+ * Set the next byte to 0x00 in order to turn off the cross-chain protection:
76+ * 0x FAC70d880Da5923673C502dbC8CeD1675c57e155 00 b996d2f8dec69a6f19c4be
77+ *
78+ * Keep the final bytes from the base salt
79+ */
80+ bytes32 constant FACTORY_SALT = 0xFAC70d880Da5923673C502dbC8CeD1675c57e15500b996d2f8dec69a6f19c4be ;
81+
82+ /**
83+ * @notice @pcaversaccio/createx's address
84+ *
85+ * @dev Used as CREATE3 factory for deterministic deployments, not depending on the init code.
86+ */
87+ address constant CREATEX_ADDRESS = address (0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed );
88+
89+ ICreateX CREATE3_FACTORY = ICreateX (CREATEX_ADDRESS);
2190
2291 function run () external {
23- uint256 deployerPrivateKey = vm.envUint ("PRIVATE_KEY " );
2492
25- address deployerAddress = vm.addr (deployerPrivateKey);
26- console.log ("Deployer address: " , deployerAddress);
27- console.log ("Deployer balance: " , deployerAddress.balance);
93+ console.log ("Deployer balance: " , address (DEPLOYER_ADDRESS).balance);
94+
2895 console.log ("BlockNumber: " , block .number );
29- console.log ("ChainId: " , getChainId ());
30- console.log ("Proxy admin for deployed vaults: " , PROXY_ADMIN_ADDRESS);
31- console.log ("Deploying vault factory... " );
3296
33- vm.startBroadcast (deployerPrivateKey);
97+ console.log ("ChainId: " , block .chainid );
98+
99+ require (FACTORY_PROXY_ADMIN_OWNER != address (0 ), "FACTORY_PROXY_ADMIN_OWNER is not set " );
100+ console.log ("Proxy admin for deployed vaults: " , FACTORY_PROXY_ADMIN_OWNER);
101+
102+ require (EXPECTED_FACTORY_ADDRESS != address (0 ), "EXPECTED_FACTORY_ADDRESS is not set " );
103+ console.log ("Expected deployed factory address: " , EXPECTED_FACTORY_ADDRESS);
104+
105+
106+ vm.startBroadcast ();
107+
108+
109+ /////// Deploy Renounced ProxyAdmin (using OpenZeppelin v4.7)
110+
111+ console.log ("Deploying vault's renounced proxy admin - Expected at: " , address (EXPECTED_RENOUNCED_PROXY_ADMIN_ADDRESS));
112+
113+ address renouncedProxyAdmin = CREATE3_FACTORY.deployCreate3 ({
114+ salt: RENOUNCED_PROXY_ADMIN_SALT,
115+ initCode: abi.encodePacked (type (ProxyAdmin_v4_7).creationCode)
116+ });
117+
118+ console.log ("Renounced proxy admin deployed at: " , renouncedProxyAdmin);
119+
120+ require (renouncedProxyAdmin == EXPECTED_RENOUNCED_PROXY_ADMIN_ADDRESS, "Renounced proxy admin address mismatch " );
121+
122+ ProxyAdmin_v4_7 (renouncedProxyAdmin).renounceOwnership ();
123+
124+
125+ /////// Deploy aTokenVaultFactory Implementation (pass Renounced ProxyAdmin as argument)
126+
127+ console.log ("Deploying aTokenVaultFactory implementation... " );
128+
129+ ATokenVaultFactory factoryImplementation = new ATokenVaultFactory ({proxyAdmin: renouncedProxyAdmin});
130+
131+ console.log ("aTokenVaultFactory implementation deployed at: " , address (factoryImplementation));
132+
133+
134+
135+ /////// Deploy aTokenVaultFactory Proxy (using OpenZeppelin v5.3)
136+
137+ console.log ("Deploying aTokenVaultFactory proxy - Expected at: " , address (EXPECTED_FACTORY_ADDRESS));
138+
139+ address factoryProxy = CREATE3_FACTORY.deployCreate3 ({
140+ salt: FACTORY_SALT,
141+ initCode: abi.encodePacked (
142+ type (TransparentUpgradeableProxy_v5_3).creationCode,
143+ abi.encode (factoryImplementation, FACTORY_PROXY_ADMIN_OWNER, "" )
144+ )
145+ });
146+
147+ console.log ("aTokenVaultFactory proxy deployed at: " , factoryProxy);
148+
149+ require (address (factoryProxy) == EXPECTED_FACTORY_ADDRESS, "aTokenVaultFactory Proxy address mismatch " );
34150
35- // Deploy the implementation, which disables initializers on construction
36- ATokenVaultFactory factory = new ATokenVaultFactory ({proxyAdmin: PROXY_ADMIN_ADDRESS});
37- console.log ("Factory deployed at: " , address (factory));
38151
39152 vm.stopBroadcast ();
40153 }
0 commit comments