@lukso/lsp23-contracts 0.15.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/artifacts/IPostDeploymentModule.json +34 -0
- package/artifacts/LSP23LinkedContractsFactory.json +544 -0
- package/contracts/ILSP23LinkedContractsFactory.sol +192 -0
- package/contracts/IPostDeploymentModule.sol +18 -0
- package/contracts/LSP23Errors.sol +24 -0
- package/contracts/LSP23LinkedContractsFactory.sol +396 -0
- package/contracts/modules/README.md +23 -0
- package/contracts/modules/UniversalProfileInitPostDeploymentModule.sol +65 -0
- package/contracts/modules/UniversalProfilePostDeploymentModule.sol +63 -0
- package/package.json +52 -0
- package/types/IPostDeploymentModule.ts +107 -0
- package/types/LSP23LinkedContractsFactory.ts +448 -0
- package/types/common.ts +131 -0
- package/types/contracts/IPostDeploymentModule.ts +107 -0
- package/types/contracts/LSP23LinkedContractsFactory.ts +448 -0
- package/types/index.ts +8 -0
@@ -0,0 +1,192 @@
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
2
|
+
pragma solidity ^0.8.4;
|
3
|
+
|
4
|
+
interface ILSP23LinkedContractsFactory {
|
5
|
+
/**
|
6
|
+
* @dev Emitted when a primary and secondary contract are deployed.
|
7
|
+
* @param primaryContract Address of the deployed primary contract.
|
8
|
+
* @param secondaryContract Address of the deployed secondary contract.
|
9
|
+
* @param primaryContractDeployment Parameters used for the primary contract deployment.
|
10
|
+
* @param secondaryContractDeployment Parameters used for the secondary contract deployment.
|
11
|
+
* @param postDeploymentModule Address of the post-deployment module.
|
12
|
+
* @param postDeploymentModuleCalldata Calldata passed to the post-deployment module.
|
13
|
+
*/
|
14
|
+
event DeployedContracts(
|
15
|
+
address indexed primaryContract,
|
16
|
+
address indexed secondaryContract,
|
17
|
+
PrimaryContractDeployment primaryContractDeployment,
|
18
|
+
SecondaryContractDeployment secondaryContractDeployment,
|
19
|
+
address postDeploymentModule,
|
20
|
+
bytes postDeploymentModuleCalldata
|
21
|
+
);
|
22
|
+
|
23
|
+
/**
|
24
|
+
* @dev Emitted when proxies of a primary and secondary contract are deployed.
|
25
|
+
* @param primaryContract Address of the deployed primary contract proxy.
|
26
|
+
* @param secondaryContract Address of the deployed secondary contract proxy.
|
27
|
+
* @param primaryContractDeploymentInit Parameters used for the primary contract proxy deployment.
|
28
|
+
* @param secondaryContractDeploymentInit Parameters used for the secondary contract proxy deployment.
|
29
|
+
* @param postDeploymentModule Address of the post-deployment module.
|
30
|
+
* @param postDeploymentModuleCalldata Calldata passed to the post-deployment module.
|
31
|
+
*/
|
32
|
+
event DeployedERC1167Proxies(
|
33
|
+
address indexed primaryContract,
|
34
|
+
address indexed secondaryContract,
|
35
|
+
PrimaryContractDeploymentInit primaryContractDeploymentInit,
|
36
|
+
SecondaryContractDeploymentInit secondaryContractDeploymentInit,
|
37
|
+
address postDeploymentModule,
|
38
|
+
bytes postDeploymentModuleCalldata
|
39
|
+
);
|
40
|
+
|
41
|
+
/**
|
42
|
+
* @param salt A unique value used to ensure each created proxies are unique (used for deterministic deployments).
|
43
|
+
* @param fundingAmount The value to be sent with the deployment transaction.
|
44
|
+
* @param creationBytecode The bytecode of the contract with the constructor params.
|
45
|
+
*/
|
46
|
+
struct PrimaryContractDeployment {
|
47
|
+
bytes32 salt;
|
48
|
+
uint256 fundingAmount;
|
49
|
+
bytes creationBytecode;
|
50
|
+
}
|
51
|
+
|
52
|
+
/**
|
53
|
+
* @param fundingAmount The value to be sent with the deployment transaction.
|
54
|
+
* @param creationBytecode The bytecode for contract creation, up to but not including the primary contract address (if it needs to be appended).
|
55
|
+
* @param addPrimaryContractAddress If set to `true`, this will append the primary contract's address + the `extraConstructorParams` to the `creationBytecode`.
|
56
|
+
* @param extraConstructorParams Params to be appended to the `creationBytecode` (after the primary contract address) if `addPrimaryContractAddress` is set to `true`.
|
57
|
+
*/
|
58
|
+
struct SecondaryContractDeployment {
|
59
|
+
uint256 fundingAmount;
|
60
|
+
bytes creationBytecode;
|
61
|
+
bool addPrimaryContractAddress;
|
62
|
+
bytes extraConstructorParams;
|
63
|
+
}
|
64
|
+
|
65
|
+
/**
|
66
|
+
* @param salt A unique value used to ensure each created proxies are unique. (Can be used to deploy the contract at a desired address.)
|
67
|
+
* @param fundingAmount The value to be sent with the deployment transaction.
|
68
|
+
* @param implementationContract The address of the contract that will be used as a base contract for the proxy.
|
69
|
+
* @param initializationCalldata The calldata used to initialize the contract.
|
70
|
+
*/
|
71
|
+
struct PrimaryContractDeploymentInit {
|
72
|
+
bytes32 salt;
|
73
|
+
uint256 fundingAmount;
|
74
|
+
address implementationContract;
|
75
|
+
bytes initializationCalldata;
|
76
|
+
}
|
77
|
+
|
78
|
+
/**
|
79
|
+
* @param fundingAmount The value to be sent with the deployment transaction.
|
80
|
+
* @param implementationContract The address of the contract that will be used as a base contract for the proxy.
|
81
|
+
* @param initializationCalldata Initialization calldata up to, but not including, the primary contract address (if it needs to be appended).
|
82
|
+
* @param addPrimaryContractAddress If set to `true`, this will append the primary contract's address + the `extraInitializationParams` to the `initializationCalldata`.
|
83
|
+
* @param extraInitializationParams Params to be appended to the `initializationCalldata` (after the primary contract address) if `addPrimaryContractAddress` is set to `true`
|
84
|
+
*/
|
85
|
+
struct SecondaryContractDeploymentInit {
|
86
|
+
uint256 fundingAmount;
|
87
|
+
address implementationContract;
|
88
|
+
bytes initializationCalldata;
|
89
|
+
bool addPrimaryContractAddress;
|
90
|
+
bytes extraInitializationParams;
|
91
|
+
}
|
92
|
+
|
93
|
+
/**
|
94
|
+
* @dev Deploys a primary and a secondary linked contract.
|
95
|
+
* @notice Contracts deployed. Contract Address: `primaryContractAddress`. Primary Contract Address: `primaryContractAddress`
|
96
|
+
*
|
97
|
+
* @param primaryContractDeployment Contains the needed parameter to deploy a contract. (`salt`, `fundingAmount`, `creationBytecode`)
|
98
|
+
* @param secondaryContractDeployment Contains the needed parameter to deploy the secondary contract. (`fundingAmount`, `creationBytecode`, `addPrimaryContractAddress`, `extraConstructorParams`)
|
99
|
+
* @param postDeploymentModule The optional module to be executed after deployment
|
100
|
+
* @param postDeploymentModuleCalldata The data to be passed to the post deployment module
|
101
|
+
*
|
102
|
+
* @return primaryContractAddress The address of the primary contract.
|
103
|
+
* @return secondaryContractAddress The address of the secondary contract.
|
104
|
+
*/
|
105
|
+
function deployContracts(
|
106
|
+
PrimaryContractDeployment calldata primaryContractDeployment,
|
107
|
+
SecondaryContractDeployment calldata secondaryContractDeployment,
|
108
|
+
address postDeploymentModule,
|
109
|
+
bytes calldata postDeploymentModuleCalldata
|
110
|
+
)
|
111
|
+
external
|
112
|
+
payable
|
113
|
+
returns (
|
114
|
+
address primaryContractAddress,
|
115
|
+
address secondaryContractAddress
|
116
|
+
);
|
117
|
+
|
118
|
+
/**
|
119
|
+
* @dev Deploys ERC1167 proxies of a primary contract and a secondary linked contract
|
120
|
+
* @notice Contract proxies deployed. Primary Proxy Address: `primaryContractAddress`. Secondary Contract Proxy Address: `secondaryContractAddress`
|
121
|
+
*
|
122
|
+
* @param primaryContractDeploymentInit Contains the needed parameters to deploy a proxy contract. (`salt`, `fundingAmount`, `implementationContract`, `initializationCalldata`)
|
123
|
+
* @param secondaryContractDeploymentInit Contains the needed parameters to deploy the secondary proxy contract. (`fundingAmount`, `implementationContract`, `initializationCalldata`, `addPrimaryContractAddress`, `extraInitializationParams`)
|
124
|
+
* @param postDeploymentModule The optional module to be executed after deployment.
|
125
|
+
* @param postDeploymentModuleCalldata The data to be passed to the post deployment module.
|
126
|
+
*
|
127
|
+
* @return primaryContractAddress The address of the deployed primary contract proxy
|
128
|
+
* @return secondaryContractAddress The address of the deployed secondary contract proxy
|
129
|
+
*/
|
130
|
+
function deployERC1167Proxies(
|
131
|
+
PrimaryContractDeploymentInit calldata primaryContractDeploymentInit,
|
132
|
+
SecondaryContractDeploymentInit
|
133
|
+
calldata secondaryContractDeploymentInit,
|
134
|
+
address postDeploymentModule,
|
135
|
+
bytes calldata postDeploymentModuleCalldata
|
136
|
+
)
|
137
|
+
external
|
138
|
+
payable
|
139
|
+
returns (
|
140
|
+
address primaryContractAddress,
|
141
|
+
address secondaryContractAddress
|
142
|
+
);
|
143
|
+
|
144
|
+
/**
|
145
|
+
* @dev Computes the addresses of a primary contract and a secondary linked contract
|
146
|
+
*
|
147
|
+
* @param primaryContractDeployment Contains the needed parameter to deploy the primary contract. (`salt`, `fundingAmount`, `creationBytecode`)
|
148
|
+
* @param secondaryContractDeployment Contains the needed parameter to deploy the secondary contract. (`fundingAmount`, `creationBytecode`, `addPrimaryContractAddress`, `extraConstructorParams`)
|
149
|
+
* @param postDeploymentModule The optional module to be executed after deployment
|
150
|
+
* @param postDeploymentModuleCalldata The data to be passed to the post deployment module
|
151
|
+
*
|
152
|
+
* @return primaryContractAddress The address of the deployed primary contract.
|
153
|
+
* @return secondaryContractAddress The address of the deployed secondary contract.
|
154
|
+
*/
|
155
|
+
function computeAddresses(
|
156
|
+
PrimaryContractDeployment calldata primaryContractDeployment,
|
157
|
+
SecondaryContractDeployment calldata secondaryContractDeployment,
|
158
|
+
address postDeploymentModule,
|
159
|
+
bytes calldata postDeploymentModuleCalldata
|
160
|
+
)
|
161
|
+
external
|
162
|
+
view
|
163
|
+
returns (
|
164
|
+
address primaryContractAddress,
|
165
|
+
address secondaryContractAddress
|
166
|
+
);
|
167
|
+
|
168
|
+
/**
|
169
|
+
* @dev Computes the addresses of a primary and a secondary linked contracts ERC1167 proxies to be created
|
170
|
+
*
|
171
|
+
* @param primaryContractDeploymentInit Contains the needed parameters to deploy a primary proxy contract. (`salt`, `fundingAmount`, `implementationContract`, `initializationCalldata`)
|
172
|
+
* @param secondaryContractDeploymentInit Contains the needed parameters to deploy the secondary proxy contract. (`fundingAmount`, `implementationContract`, `initializationCalldata`, `addPrimaryContractAddress`, `extraInitializationParams`)
|
173
|
+
* @param postDeploymentModule The optional module to be executed after deployment.
|
174
|
+
* @param postDeploymentModuleCalldata The data to be passed to the post deployment module.
|
175
|
+
*
|
176
|
+
* @return primaryContractAddress The address of the deployed primary contract proxy
|
177
|
+
* @return secondaryContractAddress The address of the deployed secondary contract proxy
|
178
|
+
*/
|
179
|
+
function computeERC1167Addresses(
|
180
|
+
PrimaryContractDeploymentInit calldata primaryContractDeploymentInit,
|
181
|
+
SecondaryContractDeploymentInit
|
182
|
+
calldata secondaryContractDeploymentInit,
|
183
|
+
address postDeploymentModule,
|
184
|
+
bytes calldata postDeploymentModuleCalldata
|
185
|
+
)
|
186
|
+
external
|
187
|
+
view
|
188
|
+
returns (
|
189
|
+
address primaryContractAddress,
|
190
|
+
address secondaryContractAddress
|
191
|
+
);
|
192
|
+
}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
2
|
+
pragma solidity ^0.8.4;
|
3
|
+
|
4
|
+
interface IPostDeploymentModule {
|
5
|
+
/**
|
6
|
+
* @dev Executes post-deployment logic for the primary and secondary contracts.
|
7
|
+
* @notice This function can be used to perform any additional setup or configuration after the primary and secondary contracts have been deployed.
|
8
|
+
*
|
9
|
+
* @param primaryContract The address of the deployed primary contract.
|
10
|
+
* @param secondaryContract The address of the deployed secondary contract.
|
11
|
+
* @param calldataToPostDeploymentModule Calldata to be passed for the post-deployment execution.
|
12
|
+
*/
|
13
|
+
function executePostDeployment(
|
14
|
+
address primaryContract,
|
15
|
+
address secondaryContract,
|
16
|
+
bytes calldata calldataToPostDeploymentModule
|
17
|
+
) external;
|
18
|
+
}
|
@@ -0,0 +1,24 @@
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
2
|
+
pragma solidity ^0.8.4;
|
3
|
+
|
4
|
+
/**
|
5
|
+
* @dev Reverts when the `msg.value` sent is not equal to the sum of value used for the deployment of the contract & its owner contract.
|
6
|
+
* @notice Invalid value sent.
|
7
|
+
*/
|
8
|
+
error InvalidValueSum();
|
9
|
+
|
10
|
+
/**
|
11
|
+
* @dev Reverts when the deployment & intialization of the contract has failed.
|
12
|
+
* @notice Failed to deploy & initialize the Primary Contract Proxy. Error: `errorData`.
|
13
|
+
*
|
14
|
+
* @param errorData Potentially information about why the deployment & intialization have failed.
|
15
|
+
*/
|
16
|
+
error PrimaryContractProxyInitFailureError(bytes errorData);
|
17
|
+
|
18
|
+
/**
|
19
|
+
* @dev Reverts when the deployment & intialization of the secondary contract has failed.
|
20
|
+
* @notice Failed to deploy & initialize the Secondary Contract Proxy. Error: `errorData`.
|
21
|
+
*
|
22
|
+
* @param errorData Potentially information about why the deployment & intialization have failed.
|
23
|
+
*/
|
24
|
+
error SecondaryContractProxyInitFailureError(bytes errorData);
|
@@ -0,0 +1,396 @@
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
2
|
+
pragma solidity ^0.8.4;
|
3
|
+
|
4
|
+
import {Create2} from "@openzeppelin/contracts/utils/Create2.sol";
|
5
|
+
import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol";
|
6
|
+
import {IPostDeploymentModule} from "./IPostDeploymentModule.sol";
|
7
|
+
import {ILSP23LinkedContractsFactory} from "./ILSP23LinkedContractsFactory.sol";
|
8
|
+
import {
|
9
|
+
InvalidValueSum,
|
10
|
+
PrimaryContractProxyInitFailureError,
|
11
|
+
SecondaryContractProxyInitFailureError
|
12
|
+
} from "./LSP23Errors.sol";
|
13
|
+
|
14
|
+
contract LSP23LinkedContractsFactory is ILSP23LinkedContractsFactory {
|
15
|
+
/**
|
16
|
+
* @inheritdoc ILSP23LinkedContractsFactory
|
17
|
+
*/
|
18
|
+
function deployContracts(
|
19
|
+
PrimaryContractDeployment calldata primaryContractDeployment,
|
20
|
+
SecondaryContractDeployment calldata secondaryContractDeployment,
|
21
|
+
address postDeploymentModule,
|
22
|
+
bytes calldata postDeploymentModuleCalldata
|
23
|
+
)
|
24
|
+
public
|
25
|
+
payable
|
26
|
+
override
|
27
|
+
returns (
|
28
|
+
address primaryContractAddress,
|
29
|
+
address secondaryContractAddress
|
30
|
+
)
|
31
|
+
{
|
32
|
+
/* check that the msg.value is equal to the sum of the values of the primary and secondary contracts */
|
33
|
+
if (
|
34
|
+
msg.value !=
|
35
|
+
primaryContractDeployment.fundingAmount +
|
36
|
+
secondaryContractDeployment.fundingAmount
|
37
|
+
) {
|
38
|
+
revert InvalidValueSum();
|
39
|
+
}
|
40
|
+
|
41
|
+
primaryContractAddress = _deployPrimaryContract(
|
42
|
+
primaryContractDeployment,
|
43
|
+
secondaryContractDeployment,
|
44
|
+
postDeploymentModule,
|
45
|
+
postDeploymentModuleCalldata
|
46
|
+
);
|
47
|
+
|
48
|
+
secondaryContractAddress = _deploySecondaryContract(
|
49
|
+
secondaryContractDeployment,
|
50
|
+
primaryContractAddress
|
51
|
+
);
|
52
|
+
|
53
|
+
emit DeployedContracts(
|
54
|
+
primaryContractAddress,
|
55
|
+
secondaryContractAddress,
|
56
|
+
primaryContractDeployment,
|
57
|
+
secondaryContractDeployment,
|
58
|
+
postDeploymentModule,
|
59
|
+
postDeploymentModuleCalldata
|
60
|
+
);
|
61
|
+
|
62
|
+
/* execute the post deployment logic in the postDeploymentModule if postDeploymentModule is not address(0) */
|
63
|
+
if (postDeploymentModule != address(0)) {
|
64
|
+
/* execute the post deployment module logic in the postDeploymentModule */
|
65
|
+
IPostDeploymentModule(postDeploymentModule).executePostDeployment(
|
66
|
+
primaryContractAddress,
|
67
|
+
secondaryContractAddress,
|
68
|
+
postDeploymentModuleCalldata
|
69
|
+
);
|
70
|
+
}
|
71
|
+
}
|
72
|
+
|
73
|
+
/**
|
74
|
+
* @inheritdoc ILSP23LinkedContractsFactory
|
75
|
+
*/
|
76
|
+
function deployERC1167Proxies(
|
77
|
+
PrimaryContractDeploymentInit calldata primaryContractDeploymentInit,
|
78
|
+
SecondaryContractDeploymentInit
|
79
|
+
calldata secondaryContractDeploymentInit,
|
80
|
+
address postDeploymentModule,
|
81
|
+
bytes calldata postDeploymentModuleCalldata
|
82
|
+
)
|
83
|
+
public
|
84
|
+
payable
|
85
|
+
override
|
86
|
+
returns (
|
87
|
+
address primaryContractAddress,
|
88
|
+
address secondaryContractAddress
|
89
|
+
)
|
90
|
+
{
|
91
|
+
/* check that the msg.value is equal to the sum of the values of the primary and secondary contracts */
|
92
|
+
if (
|
93
|
+
msg.value !=
|
94
|
+
primaryContractDeploymentInit.fundingAmount +
|
95
|
+
secondaryContractDeploymentInit.fundingAmount
|
96
|
+
) {
|
97
|
+
revert InvalidValueSum();
|
98
|
+
}
|
99
|
+
|
100
|
+
/* deploy the primary contract proxy with the primaryContractGeneratedSalt */
|
101
|
+
primaryContractAddress = _deployAndInitializePrimaryContractProxy(
|
102
|
+
primaryContractDeploymentInit,
|
103
|
+
secondaryContractDeploymentInit,
|
104
|
+
postDeploymentModule,
|
105
|
+
postDeploymentModuleCalldata
|
106
|
+
);
|
107
|
+
|
108
|
+
/* deploy the secondary contract proxy */
|
109
|
+
secondaryContractAddress = _deployAndInitializeSecondaryContractProxy(
|
110
|
+
secondaryContractDeploymentInit,
|
111
|
+
primaryContractAddress
|
112
|
+
);
|
113
|
+
|
114
|
+
emit DeployedERC1167Proxies(
|
115
|
+
primaryContractAddress,
|
116
|
+
secondaryContractAddress,
|
117
|
+
primaryContractDeploymentInit,
|
118
|
+
secondaryContractDeploymentInit,
|
119
|
+
postDeploymentModule,
|
120
|
+
postDeploymentModuleCalldata
|
121
|
+
);
|
122
|
+
|
123
|
+
/* execute the post deployment logic in the postDeploymentModule if postDeploymentModule is not address(0) */
|
124
|
+
if (postDeploymentModule != address(0)) {
|
125
|
+
/* execute the post deployment logic in the postDeploymentModule */
|
126
|
+
IPostDeploymentModule(postDeploymentModule).executePostDeployment(
|
127
|
+
primaryContractAddress,
|
128
|
+
secondaryContractAddress,
|
129
|
+
postDeploymentModuleCalldata
|
130
|
+
);
|
131
|
+
}
|
132
|
+
}
|
133
|
+
|
134
|
+
/**
|
135
|
+
* @inheritdoc ILSP23LinkedContractsFactory
|
136
|
+
*/
|
137
|
+
function computeAddresses(
|
138
|
+
PrimaryContractDeployment calldata primaryContractDeployment,
|
139
|
+
SecondaryContractDeployment calldata secondaryContractDeployment,
|
140
|
+
address postDeploymentModule,
|
141
|
+
bytes calldata postDeploymentModuleCalldata
|
142
|
+
)
|
143
|
+
public
|
144
|
+
view
|
145
|
+
override
|
146
|
+
returns (
|
147
|
+
address primaryContractAddress,
|
148
|
+
address secondaryContractAddress
|
149
|
+
)
|
150
|
+
{
|
151
|
+
bytes32 primaryContractGeneratedSalt = _generatePrimaryContractSalt(
|
152
|
+
primaryContractDeployment,
|
153
|
+
secondaryContractDeployment,
|
154
|
+
postDeploymentModule,
|
155
|
+
postDeploymentModuleCalldata
|
156
|
+
);
|
157
|
+
|
158
|
+
primaryContractAddress = Create2.computeAddress(
|
159
|
+
primaryContractGeneratedSalt,
|
160
|
+
keccak256(primaryContractDeployment.creationBytecode)
|
161
|
+
);
|
162
|
+
|
163
|
+
bytes memory secondaryContractByteCodeWithAllParams;
|
164
|
+
if (secondaryContractDeployment.addPrimaryContractAddress) {
|
165
|
+
secondaryContractByteCodeWithAllParams = abi.encodePacked(
|
166
|
+
secondaryContractDeployment.creationBytecode,
|
167
|
+
abi.encode(primaryContractAddress),
|
168
|
+
secondaryContractDeployment.extraConstructorParams
|
169
|
+
);
|
170
|
+
} else {
|
171
|
+
secondaryContractByteCodeWithAllParams = secondaryContractDeployment
|
172
|
+
.creationBytecode;
|
173
|
+
}
|
174
|
+
|
175
|
+
secondaryContractAddress = Create2.computeAddress(
|
176
|
+
keccak256(abi.encodePacked(primaryContractAddress)),
|
177
|
+
keccak256(secondaryContractByteCodeWithAllParams)
|
178
|
+
);
|
179
|
+
}
|
180
|
+
|
181
|
+
/**
|
182
|
+
* @inheritdoc ILSP23LinkedContractsFactory
|
183
|
+
*/
|
184
|
+
function computeERC1167Addresses(
|
185
|
+
PrimaryContractDeploymentInit calldata primaryContractDeploymentInit,
|
186
|
+
SecondaryContractDeploymentInit
|
187
|
+
calldata secondaryContractDeploymentInit,
|
188
|
+
address postDeploymentModule,
|
189
|
+
bytes calldata postDeploymentModuleCalldata
|
190
|
+
)
|
191
|
+
public
|
192
|
+
view
|
193
|
+
override
|
194
|
+
returns (
|
195
|
+
address primaryContractAddress,
|
196
|
+
address secondaryContractAddress
|
197
|
+
)
|
198
|
+
{
|
199
|
+
bytes32 primaryContractGeneratedSalt = _generatePrimaryContractProxySalt(
|
200
|
+
primaryContractDeploymentInit,
|
201
|
+
secondaryContractDeploymentInit,
|
202
|
+
postDeploymentModule,
|
203
|
+
postDeploymentModuleCalldata
|
204
|
+
);
|
205
|
+
|
206
|
+
primaryContractAddress = Clones.predictDeterministicAddress(
|
207
|
+
primaryContractDeploymentInit.implementationContract,
|
208
|
+
primaryContractGeneratedSalt
|
209
|
+
);
|
210
|
+
|
211
|
+
secondaryContractAddress = Clones.predictDeterministicAddress(
|
212
|
+
secondaryContractDeploymentInit.implementationContract,
|
213
|
+
keccak256(abi.encodePacked(primaryContractAddress))
|
214
|
+
);
|
215
|
+
}
|
216
|
+
|
217
|
+
function _deployPrimaryContract(
|
218
|
+
PrimaryContractDeployment calldata primaryContractDeployment,
|
219
|
+
SecondaryContractDeployment calldata secondaryContractDeployment,
|
220
|
+
address postDeploymentModule,
|
221
|
+
bytes calldata postDeploymentModuleCalldata
|
222
|
+
) internal returns (address primaryContractAddress) {
|
223
|
+
bytes32 primaryContractGeneratedSalt = _generatePrimaryContractSalt(
|
224
|
+
primaryContractDeployment,
|
225
|
+
secondaryContractDeployment,
|
226
|
+
postDeploymentModule,
|
227
|
+
postDeploymentModuleCalldata
|
228
|
+
);
|
229
|
+
|
230
|
+
/* deploy the primary contract */
|
231
|
+
primaryContractAddress = Create2.deploy(
|
232
|
+
primaryContractDeployment.fundingAmount,
|
233
|
+
primaryContractGeneratedSalt,
|
234
|
+
primaryContractDeployment.creationBytecode
|
235
|
+
);
|
236
|
+
}
|
237
|
+
|
238
|
+
function _deploySecondaryContract(
|
239
|
+
SecondaryContractDeployment calldata secondaryContractDeployment,
|
240
|
+
address primaryContractAddress
|
241
|
+
) internal returns (address secondaryContractAddress) {
|
242
|
+
/**
|
243
|
+
* If `addPrimaryContractAddress` is `true`, the following will be appended to the constructor params:
|
244
|
+
* - The primary contract address
|
245
|
+
* - `extraConstructorParams`
|
246
|
+
*/
|
247
|
+
bytes memory secondaryContractByteCode = secondaryContractDeployment
|
248
|
+
.creationBytecode;
|
249
|
+
|
250
|
+
if (secondaryContractDeployment.addPrimaryContractAddress) {
|
251
|
+
secondaryContractByteCode = abi.encodePacked(
|
252
|
+
secondaryContractByteCode,
|
253
|
+
abi.encode(primaryContractAddress),
|
254
|
+
secondaryContractDeployment.extraConstructorParams
|
255
|
+
);
|
256
|
+
}
|
257
|
+
|
258
|
+
secondaryContractAddress = Create2.deploy(
|
259
|
+
secondaryContractDeployment.fundingAmount,
|
260
|
+
keccak256(abi.encodePacked(primaryContractAddress)),
|
261
|
+
secondaryContractByteCode
|
262
|
+
);
|
263
|
+
}
|
264
|
+
|
265
|
+
function _deployAndInitializePrimaryContractProxy(
|
266
|
+
PrimaryContractDeploymentInit calldata primaryContractDeploymentInit,
|
267
|
+
SecondaryContractDeploymentInit
|
268
|
+
calldata secondaryContractDeploymentInit,
|
269
|
+
address postDeploymentModule,
|
270
|
+
bytes calldata postDeploymentModuleCalldata
|
271
|
+
) internal returns (address primaryContractAddress) {
|
272
|
+
bytes32 primaryContractGeneratedSalt = _generatePrimaryContractProxySalt(
|
273
|
+
primaryContractDeploymentInit,
|
274
|
+
secondaryContractDeploymentInit,
|
275
|
+
postDeploymentModule,
|
276
|
+
postDeploymentModuleCalldata
|
277
|
+
);
|
278
|
+
|
279
|
+
/* deploy the primary contract proxy with the primaryContractGeneratedSalt */
|
280
|
+
primaryContractAddress = Clones.cloneDeterministic(
|
281
|
+
primaryContractDeploymentInit.implementationContract,
|
282
|
+
primaryContractGeneratedSalt
|
283
|
+
);
|
284
|
+
|
285
|
+
/* initialize the primary contract proxy */
|
286
|
+
(bool success, bytes memory returnedData) = primaryContractAddress.call{
|
287
|
+
value: primaryContractDeploymentInit.fundingAmount
|
288
|
+
}(primaryContractDeploymentInit.initializationCalldata);
|
289
|
+
if (!success) {
|
290
|
+
revert PrimaryContractProxyInitFailureError(returnedData);
|
291
|
+
}
|
292
|
+
}
|
293
|
+
|
294
|
+
function _deployAndInitializeSecondaryContractProxy(
|
295
|
+
SecondaryContractDeploymentInit
|
296
|
+
calldata secondaryContractDeploymentInit,
|
297
|
+
address primaryContractAddress
|
298
|
+
) internal returns (address secondaryContractAddress) {
|
299
|
+
/* deploy the secondary contract proxy with the primaryContractGeneratedSalt */
|
300
|
+
secondaryContractAddress = Clones.cloneDeterministic(
|
301
|
+
secondaryContractDeploymentInit.implementationContract,
|
302
|
+
keccak256(abi.encodePacked(primaryContractAddress))
|
303
|
+
);
|
304
|
+
|
305
|
+
/**
|
306
|
+
* If `addPrimaryContractAddress` is `true`, the following will be appended to the `initializationCalldata`:
|
307
|
+
* - The primary contract address
|
308
|
+
* - `extraInitializationBytes`
|
309
|
+
*/
|
310
|
+
bytes
|
311
|
+
memory secondaryInitializationBytes = secondaryContractDeploymentInit
|
312
|
+
.initializationCalldata;
|
313
|
+
|
314
|
+
if (secondaryContractDeploymentInit.addPrimaryContractAddress) {
|
315
|
+
secondaryInitializationBytes = abi.encodePacked(
|
316
|
+
secondaryInitializationBytes,
|
317
|
+
abi.encode(primaryContractAddress),
|
318
|
+
secondaryContractDeploymentInit.extraInitializationParams
|
319
|
+
);
|
320
|
+
}
|
321
|
+
|
322
|
+
/* initialize the primary contract proxy */
|
323
|
+
(bool success, bytes memory returnedData) = secondaryContractAddress
|
324
|
+
.call{value: secondaryContractDeploymentInit.fundingAmount}(
|
325
|
+
secondaryInitializationBytes
|
326
|
+
);
|
327
|
+
if (!success) {
|
328
|
+
revert SecondaryContractProxyInitFailureError(returnedData);
|
329
|
+
}
|
330
|
+
}
|
331
|
+
|
332
|
+
function _generatePrimaryContractSalt(
|
333
|
+
PrimaryContractDeployment calldata primaryContractDeployment,
|
334
|
+
SecondaryContractDeployment calldata secondaryContractDeployment,
|
335
|
+
address postDeploymentModule,
|
336
|
+
bytes calldata postDeploymentModuleCalldata
|
337
|
+
) internal pure virtual returns (bytes32 primaryContractGeneratedSalt) {
|
338
|
+
/* generate salt for the primary contract
|
339
|
+
* the salt is generated by hashing the following elements:
|
340
|
+
* - the salt
|
341
|
+
* - the secondary contract bytecode
|
342
|
+
* - the secondary addPrimaryContractAddress boolean
|
343
|
+
* - the secondary extraConstructorParams
|
344
|
+
* - the postDeploymentModule address
|
345
|
+
* - the postDeploymentModuleCalldata
|
346
|
+
*
|
347
|
+
*/
|
348
|
+
primaryContractGeneratedSalt = keccak256(
|
349
|
+
abi.encode(
|
350
|
+
primaryContractDeployment.salt,
|
351
|
+
secondaryContractDeployment.creationBytecode,
|
352
|
+
secondaryContractDeployment.addPrimaryContractAddress,
|
353
|
+
secondaryContractDeployment.extraConstructorParams,
|
354
|
+
postDeploymentModule,
|
355
|
+
postDeploymentModuleCalldata
|
356
|
+
)
|
357
|
+
);
|
358
|
+
}
|
359
|
+
|
360
|
+
function _generatePrimaryContractProxySalt(
|
361
|
+
PrimaryContractDeploymentInit calldata primaryContractDeploymentInit,
|
362
|
+
SecondaryContractDeploymentInit
|
363
|
+
calldata secondaryContractDeploymentInit,
|
364
|
+
address postDeploymentModule,
|
365
|
+
bytes calldata postDeploymentModuleCalldata
|
366
|
+
)
|
367
|
+
internal
|
368
|
+
pure
|
369
|
+
virtual
|
370
|
+
returns (bytes32 primaryContractProxyGeneratedSalt)
|
371
|
+
{
|
372
|
+
/**
|
373
|
+
* Generate the salt for the primary contract
|
374
|
+
* The salt is generated by hashing the following elements:
|
375
|
+
* - the salt
|
376
|
+
* - the secondary implementation contract address
|
377
|
+
* - the secondary contract initialization calldata
|
378
|
+
* - the secondary contract addPrimaryContractAddress boolean
|
379
|
+
* - the secondary contract extra initialization params (if any)
|
380
|
+
* - the postDeploymentModule address
|
381
|
+
* - the callda to the post deployment module
|
382
|
+
*
|
383
|
+
*/
|
384
|
+
primaryContractProxyGeneratedSalt = keccak256(
|
385
|
+
abi.encode(
|
386
|
+
primaryContractDeploymentInit.salt,
|
387
|
+
secondaryContractDeploymentInit.implementationContract,
|
388
|
+
secondaryContractDeploymentInit.initializationCalldata,
|
389
|
+
secondaryContractDeploymentInit.addPrimaryContractAddress,
|
390
|
+
secondaryContractDeploymentInit.extraInitializationParams,
|
391
|
+
postDeploymentModule,
|
392
|
+
postDeploymentModuleCalldata
|
393
|
+
)
|
394
|
+
);
|
395
|
+
}
|
396
|
+
}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# LSP23 Linked Contracts Deployment Module
|
2
|
+
|
3
|
+
This folder contains modules related to the deployment of LSP23 Linked Contracts. The modules are essential for initializing and post-deploying actions for Universal Profiles.
|
4
|
+
|
5
|
+
## Modules
|
6
|
+
|
7
|
+
- **UniversalProfileInitPostDeploymentModule**: This module is responsible for the initial setup after the deployment of a Universal Profile Init contract.
|
8
|
+
|
9
|
+
- **Standardized Address**: `0x000000000066093407b6704B89793beFfD0D8F00`
|
10
|
+
- **Standardized Salt**: `0x12a6712f113536d8b01d99f72ce168c7e10901240d73e80eeb821d01aa4c2b1a`
|
11
|
+
- [More Details](./deployment-UP-init-module.md)
|
12
|
+
|
13
|
+
- **UniversalProfilePostDeploymentModule**: This module is responsible for the initial setup after the deployment of a Universal Profile contract.
|
14
|
+
- **Standardized Address**: `0x0000005aD606bcFEF9Ea6D0BbE5b79847054BcD7`
|
15
|
+
- **Standardized Salt**: `0x42ff55d7957589c62da54a4368b10a2bc549f2038bbb6880ec6b3e0ecae2ba58`
|
16
|
+
- [More Details](./deployment-UP-module.md)
|
17
|
+
|
18
|
+
## Setup
|
19
|
+
|
20
|
+
Before deploying any of these modules, make sure that the following contracts are already deployed on the same network:
|
21
|
+
|
22
|
+
- [Nick's Factory contract](https://github.com/Arachnid/deterministic-deployment-proxy/tree/master)
|
23
|
+
- [LSP23 Linked Contracts Factory](https://github.com/lukso-network/LIPs/blob/main/LSPs/LSP-23-LinkedContractsFactory.md#lsp23linkedcontractsfactory-deployment)
|