Skip to content

Commit 8be4fac

Browse files
feat: DeployFactory script uses keystore & CREATE3 deterministic addresses
1 parent 2eb4ef0 commit 8be4fac

File tree

1 file changed

+136
-23
lines changed

1 file changed

+136
-23
lines changed

script/DeployFactory.s.sol

Lines changed: 136 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,37 +4,150 @@ pragma solidity ^0.8.10;
44

55
import "forge-std/Script.sol";
66
import {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+
*/
821
contract 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

Comments
 (0)