@@ -15,86 +15,64 @@ interface ICreateX {
1515 ) external view returns (address computedAddress );
1616}
1717
18- bytes11 constant EMPTY_CONTRACT_SALT = bytes11 (uint88 (0xffffffffffffffffffffff ));
19-
2018library CrosschainDeployLib {
2119 using CrosschainDeployLib for * ;
2220
2321 /// -----------------------------------------------------------------------
2422 /// Write
2523 /// -----------------------------------------------------------------------
2624
27- /**
25+ /*
2826 * @notice Deploys a crosschain empty contract.
2927 * @dev The empty contract MUST stay consistent across all chains/deployments.
3028 * @dev The empty contract MUST always be deployed with the same salt.
3129 */
32- function deployEmptyContract (address deployer ) internal returns (address ) {
30+ function deployEmptyContract (
31+ address deployer
32+ ) internal returns (address ) {
3333 address computedAddress =
34- computeCrosschainAddress (deployer, keccak256 (type (EmptyContract).creationCode), EMPTY_CONTRACT_SALT );
34+ computeCrosschainAddress (deployer, keccak256 (type (EmptyContract).creationCode), type (EmptyContract).name );
3535 if (computedAddress.code.length != 0 ) return computedAddress;
36- return type (EmptyContract).creationCode. deployCrosschain (deployer, EMPTY_CONTRACT_SALT );
36+ return _deployCrosschain (deployer, type (EmptyContract).creationCode, type (EmptyContract).name );
3737 }
3838
3939 /*
40- * @notice Deploys a crosschain contract with CreateX.
40+ * @notice Deploys a crosschain `TransparentUpgradeableProxy` using CreateX.
41+ * @dev The initial admin is the deployer.
42+ * @dev The implementation MUST also be deterministic to ensure the contract can be deployed on all chains.
43+ * @dev The salt MUST be unique for each proxy deployment sharing the same implementation otherwise address collisions WILL occur.
44+ * @dev The `admin` is also assumed to be the deployer.
4145 *
4246 * @dev Example usage:
4347 * ```solidity
44- * type(EmptyContract).creationCode.deployCrosschain(EMPTY_CONTRACT_SALT)
48+ * bytes11 salt = bytes11(uint88(0xffffffffffffffffffffff));
49+ * address emptyContract = type(EmptyContract).creationCode.deployCrosschain(deployer);
50+ * address proxy = emptyContract.deployCrosschainProxy(deployer, salt);
51+ * ITransparentUpgradeableProxy(address(proxy)).upgradeTo(address(implementation));
52+ * ITransparentUpgradeableProxy(address(proxy)).changeAdmin(address(admin));
4553 * ```
4654 */
47- function deployCrosschain (bytes memory initCode , address deployer , bytes11 salt ) internal returns (address ) {
48- return createx.deployCreate2 (computeProtectedSalt (deployer, salt), initCode);
55+ function deployCrosschainProxy (
56+ address adminAndDeployer ,
57+ address implementation ,
58+ string memory name
59+ ) internal returns (ITransparentUpgradeableProxy) {
60+ return ITransparentUpgradeableProxy (
61+ _deployCrosschain (adminAndDeployer, computeUpgradeableProxyInitCode (implementation, adminAndDeployer), name)
62+ );
4963 }
5064
51- // /*
52- // * @notice Deploys a crosschain contract using CreateX with the `DEFAULT_SALT`.
53- // *
54- // * @dev Example usage:
55- // * ```solidity
56- // * address emptyContract = type(EmptyContract).creationCode.deployCrosschain();
57- // * ```
58- // */
59- // function deployCrosschain(
60- // bytes memory initCode
61- // ) internal returns (address) {
62- // return deployCrosschain(initCode, EMPTY_CONTRACT_SALT);
63- // }
64-
6565 /*
66- * @notice Deploys a crosschain `TransparentUpgradeableProxy` using CreateX.
67- * @dev The initial admin is msg.sender.
68- * @dev The implementation MUST also be deterministic to ensure the contract can be deployed on all chains.
69- * @dev The salt MUST be unique for each proxy deployment sharing the same implementation otherwise address collisions WILL occur.
66+ * @notice Deploys a crosschain contract with CreateX.
7067 *
7168 * @dev Example usage:
7269 * ```solidity
73- * bytes11 salt = bytes11(uint88(0xffffffffffffffffffffff));
74- * address emptyContract = type(EmptyContract).creationCode.deployCrosschain();
75- * address proxy = emptyContract.deployCrosschainProxy(salt);
76- * ITransparentUpgradeableProxy(address(proxy)).upgradeTo(address(implementation));
77- * ITransparentUpgradeableProxy(address(proxy)).changeAdmin(address(admin));
70+ * type(EmptyContract).creationCode.deployCrosschain(deployer, EMPTY_CONTRACT_SALT)
7871 * ```
7972 */
80- // function deployCrosschainProxy(
81- // address implementation,
82- // bytes11 salt
83- // ) internal returns (ITransparentUpgradeableProxy) {
84- // return ITransparentUpgradeableProxy(
85- // deployCrosschain(computeUpgradeableProxyInitCode(implementation, msg.sender), salt)
86- // );
87- // }
88-
89- // /**
90- // * @notice Deploys a crosschain name salted `TransparentUpgradeableProxy` using CreateX.
91- // */
92- // function deployCrosschainProxy(
93- // address implementation,
94- // string memory name
95- // ) internal returns (ITransparentUpgradeableProxy) {
96- // return deployCrosschainProxy(implementation, bytes11(keccak256(bytes(name))));
97- // }
73+ function _deployCrosschain (address deployer , bytes memory initCode , string memory name ) private returns (address ) {
74+ return createx.deployCreate2 (computeProtectedSalt (deployer, name), initCode);
75+ }
9876
9977 /// -----------------------------------------------------------------------
10078 /// Helpers
@@ -110,12 +88,17 @@ library CrosschainDeployLib {
11088 return bytes32 (
11189 bytes .concat (
11290 bytes20 (deployer),
113- bytes1 (uint8 (1 )), // Cross-chain deployments are allowed (0: false, 1: true)
91+ bytes1 (uint8 (0 )), // Cross-chain redeploy protection disabled (0: false, 1: true)
11492 bytes11 (salt)
11593 )
11694 );
11795 }
11896
97+ /// @dev Helper to compute the protected salt for a given name.
98+ function computeProtectedSalt (address deployer , string memory name ) internal pure returns (bytes32 ) {
99+ return computeProtectedSalt (deployer, bytes11 (keccak256 (bytes (name))));
100+ }
101+
119102 /*
120103 * @notice Returns the initialization code for a transparent upgradeable proxy.
121104 * @dev The returned init code does not include metadata typically appended by the compiler.
@@ -127,25 +110,24 @@ library CrosschainDeployLib {
127110 return abi.encodePacked (type (TransparentUpgradeableProxy).creationCode, abi.encode (implementation, admin, "" ));
128111 }
129112
130- /*
131- * @notice Returns the predicted address of a contract deployed with CreateX.
132- */
133113 function computeCrosschainAddress (
134114 address deployer ,
135115 bytes32 initCodeHash ,
136- bytes11 salt
116+ string memory name
137117 ) internal view returns (address ) {
138- return createx.computeCreate2Address (computeProtectedSalt (deployer, salt ), initCodeHash);
118+ return createx.computeCreate2Address (computeProtectedSalt (deployer, name ), initCodeHash);
139119 }
140120
141121 /*
142122 * @notice Returns the predicted address of a `TransparentUpgradeableProxy` deployed with CreateX.
143123 */
144124 function computeCrosschainUpgradeableProxyAddress (
125+ address adminAndDeployer ,
145126 address implementation ,
146- address admin ,
147- bytes11 salt
127+ string memory name
148128 ) internal view returns (address ) {
149- return computeCrosschainAddress (admin, keccak256 (computeUpgradeableProxyInitCode (implementation, admin)), salt);
129+ return computeCrosschainAddress (
130+ adminAndDeployer, keccak256 (computeUpgradeableProxyInitCode (implementation, adminAndDeployer)), name
131+ );
150132 }
151133}
0 commit comments