@@ -66,15 +66,7 @@ contract ZoraFactoryImpl is
6666 zoraHookRegistry = zoraHookRegistry_;
6767 }
6868
69- /// @notice Creates a new creator coin contract
70- /// @param payoutRecipient The recipient of creator reward payouts; this can be updated by an owner
71- /// @param owners The list of addresses that will be able to manage the coin's payout address and metadata uri
72- /// @param uri The coin metadata uri
73- /// @param name The name of the coin
74- /// @param symbol The symbol of the coin
75- /// @param poolConfig The config parameters for the coin's pool
76- /// @param platformReferrer The address of the platform referrer
77- /// @param coinSalt The salt used to deploy the coin
69+ /// @inheritdoc IZoraFactory
7870 function deployCreatorCoin (
7971 address payoutRecipient ,
8072 address [] memory owners ,
@@ -86,39 +78,24 @@ contract ZoraFactoryImpl is
8678 bytes32 coinSalt
8779 ) public nonReentrant returns (address ) {
8880 bytes32 salt = _buildSalt (msg .sender , name, symbol, poolConfig, platformReferrer, coinSalt);
81+ return address (_createAndInitializeCreatorCoin (payoutRecipient, owners, uri, name, symbol, poolConfig, platformReferrer, salt));
82+ }
8983
90- uint8 version = CoinConfigurationVersions.getVersion (poolConfig);
91-
92- require (version == CoinConfigurationVersions.DOPPLER_MULTICURVE_UNI_V4_POOL_VERSION, InvalidConfig ());
93-
94- address creatorCoin = Clones.cloneDeterministic (creatorCoinImpl, salt);
95-
96- _setVersionForDeployedCoin (address (creatorCoin), version);
97-
98- (, address currency , uint160 sqrtPriceX96 , bool isCoinToken0 , PoolConfiguration memory poolConfiguration ) = CoinSetup.generatePoolConfig (
99- address (creatorCoin),
100- poolConfig
101- );
102-
103- PoolKey memory poolKey = CoinSetup.buildPoolKey (address (creatorCoin), currency, isCoinToken0, IHooks (hook));
104-
105- ICreatorCoin (creatorCoin).initialize (payoutRecipient, owners, uri, name, symbol, platformReferrer, currency, poolKey, sqrtPriceX96, poolConfiguration);
106-
107- emit CreatorCoinCreated (
108- msg .sender ,
109- payoutRecipient,
110- platformReferrer,
111- currency,
112- uri,
113- name,
114- symbol,
115- address (creatorCoin),
116- poolKey,
117- CoinCommon.hashPoolKey (poolKey),
118- IVersionedContract (address (creatorCoin)).contractVersion ()
119- );
120-
121- return creatorCoin;
84+ /// @inheritdoc IZoraFactory
85+ function deployCreatorCoin (
86+ address payoutRecipient ,
87+ address [] memory owners ,
88+ string memory uri ,
89+ string memory name ,
90+ string memory symbol ,
91+ bytes memory poolConfig ,
92+ address platformReferrer ,
93+ address postDeployHook ,
94+ bytes calldata postDeployHookData ,
95+ bytes32 coinSalt
96+ ) external payable nonReentrant returns (address coin , bytes memory postDeployHookDataOut ) {
97+ bytes32 salt = _buildSalt (msg .sender , name, symbol, poolConfig, platformReferrer, coinSalt);
98+ return _deployCreatorCoinWithHook (payoutRecipient, owners, uri, name, symbol, poolConfig, platformReferrer, postDeployHook, postDeployHookData, salt);
12299 }
123100
124101 /// @inheritdoc IZoraFactory
@@ -151,6 +128,18 @@ contract ZoraFactoryImpl is
151128 return Clones.predictDeterministicAddress (getCoinImpl (CoinConfigurationVersions.getVersion (poolConfig)), salt, address (this ));
152129 }
153130
131+ function _executePostDeployHook (address coin , address deployHook , bytes calldata hookData ) internal returns (bytes memory hookDataOut ) {
132+ if (deployHook != address (0 )) {
133+ if (! IERC165 (deployHook).supportsInterface (type (IHasAfterCoinDeploy).interfaceId)) {
134+ revert InvalidHook ();
135+ }
136+ hookDataOut = IHasAfterCoinDeploy (deployHook).afterCoinDeploy {value: msg .value }(msg .sender , ICoin (coin), hookData);
137+ } else if (msg .value > 0 ) {
138+ // cannot send eth without a hook
139+ revert EthTransferInvalid ();
140+ }
141+ }
142+
154143 /// @dev Internal function to deploy a coin with a hook
155144 function _deployWithHook (
156145 address payoutRecipient ,
@@ -165,16 +154,24 @@ contract ZoraFactoryImpl is
165154 bytes32 salt
166155 ) internal returns (address coin , bytes memory hookDataOut ) {
167156 coin = address (_createAndInitializeCoin (payoutRecipient, owners, uri, name, symbol, poolConfig, platformReferrer, salt));
157+ hookDataOut = _executePostDeployHook (coin, deployHook, hookData);
158+ }
168159
169- if (deployHook != address (0 )) {
170- if (! IERC165 (deployHook).supportsInterface (type (IHasAfterCoinDeploy).interfaceId)) {
171- revert InvalidHook ();
172- }
173- hookDataOut = IHasAfterCoinDeploy (deployHook).afterCoinDeploy {value: msg .value }(msg .sender , ICoin (coin), hookData);
174- } else if (msg .value > 0 ) {
175- // cannot send eth without a hook
176- revert EthTransferInvalid ();
177- }
160+ /// @dev Internal function to deploy a creator coin with a hook
161+ function _deployCreatorCoinWithHook (
162+ address payoutRecipient ,
163+ address [] memory owners ,
164+ string memory uri ,
165+ string memory name ,
166+ string memory symbol ,
167+ bytes memory poolConfig ,
168+ address platformReferrer ,
169+ address deployHook ,
170+ bytes calldata hookData ,
171+ bytes32 salt
172+ ) internal returns (address coin , bytes memory hookDataOut ) {
173+ coin = address (_createAndInitializeCreatorCoin (payoutRecipient, owners, uri, name, symbol, poolConfig, platformReferrer, salt));
174+ hookDataOut = _executePostDeployHook (coin, deployHook, hookData);
178175 }
179176
180177 /**
@@ -251,41 +248,69 @@ contract ZoraFactoryImpl is
251248 revert ICoin.InvalidPoolVersion ();
252249 }
253250
254- function _createCoin (uint8 version , bytes32 salt ) internal returns (address payable ) {
255- return payable (Clones.cloneDeterministic (getCoinImpl (version), salt));
251+ function _createCoinWithPoolConfig (
252+ address _implementation ,
253+ bytes memory poolConfig ,
254+ bytes32 coinSalt ,
255+ address payoutRecipient ,
256+ address [] memory owners ,
257+ string memory uri ,
258+ string memory name ,
259+ string memory symbol ,
260+ address platformReferrer
261+ ) internal returns (address coin , uint8 version , PoolKey memory poolKey , address currency ) {
262+ version = CoinConfigurationVersions.getVersion (poolConfig);
263+ coin = Clones.cloneDeterministic (_implementation, coinSalt);
264+ _setVersionForDeployedCoin (coin, version);
265+
266+ uint160 sqrtPriceX96;
267+ bool isCoinToken0;
268+ PoolConfiguration memory poolConfiguration;
269+ (, currency, sqrtPriceX96, isCoinToken0, poolConfiguration) = CoinSetup.generatePoolConfig (coin, poolConfig);
270+
271+ poolKey = CoinSetup.buildPoolKey (coin, currency, isCoinToken0, IHooks (hook));
272+ ICoin (coin).initialize (payoutRecipient, owners, uri, name, symbol, platformReferrer, currency, poolKey, sqrtPriceX96, poolConfiguration);
256273 }
257274
258- function _setupV4Coin (
259- ICoin coin ,
260- address currency ,
261- bool isCoinToken0 ,
262- uint160 sqrtPriceX96 ,
263- PoolConfiguration memory poolConfiguration ,
275+ function _createAndInitializeCreatorCoin (
264276 address payoutRecipient ,
265277 address [] memory owners ,
266278 string memory uri ,
267279 string memory name ,
268280 string memory symbol ,
269- address platformReferrer
270- ) internal {
271- PoolKey memory poolKey = CoinSetup.buildPoolKey (address (coin), currency, isCoinToken0, IHooks (hook));
281+ bytes memory poolConfig ,
282+ address platformReferrer ,
283+ bytes32 coinSalt
284+ ) internal returns (ICreatorCoin) {
285+ (address creatorCoin , uint8 version , PoolKey memory poolKey , address currency ) = _createCoinWithPoolConfig (
286+ creatorCoinImpl,
287+ poolConfig,
288+ coinSalt,
289+ payoutRecipient,
290+ owners,
291+ uri,
292+ name,
293+ symbol,
294+ platformReferrer
295+ );
272296
273- // Initialize coin with pre-configured pool
274- coin.initialize (payoutRecipient, owners, uri, name, symbol, platformReferrer, currency, poolKey, sqrtPriceX96, poolConfiguration);
297+ require (version == CoinConfigurationVersions.DOPPLER_MULTICURVE_UNI_V4_POOL_VERSION, InvalidConfig ());
275298
276- emit CoinCreatedV4 (
299+ emit CreatorCoinCreated (
277300 msg .sender ,
278301 payoutRecipient,
279302 platformReferrer,
280303 currency,
281304 uri,
282305 name,
283306 symbol,
284- address (coin) ,
307+ creatorCoin ,
285308 poolKey,
286309 CoinCommon.hashPoolKey (poolKey),
287- IVersionedContract (address (coin) ).contractVersion ()
310+ IVersionedContract (creatorCoin ).contractVersion ()
288311 );
312+
313+ return ICreatorCoin (creatorCoin);
289314 }
290315
291316 function _createAndInitializeCoin (
@@ -298,26 +323,34 @@ contract ZoraFactoryImpl is
298323 address platformReferrer ,
299324 bytes32 coinSalt
300325 ) internal returns (ICoin) {
301- uint8 version = CoinConfigurationVersions.getVersion (poolConfig);
302-
303- address payable coin = _createCoin (version, coinSalt);
326+ (address coin , uint8 version , PoolKey memory poolKey , address currency ) = _createCoinWithPoolConfig (
327+ coinV4Impl,
328+ poolConfig,
329+ coinSalt,
330+ payoutRecipient,
331+ owners,
332+ uri,
333+ name,
334+ symbol,
335+ platformReferrer
336+ );
304337
305- _setVersionForDeployedCoin ( address (coin), version );
338+ require (version == CoinConfigurationVersions.DOPPLER_MULTICURVE_UNI_V4_POOL_VERSION, ICoin. InvalidPoolVersion () );
306339
307- (, address currency , uint160 sqrtPriceX96 , bool isCoinToken0 , PoolConfiguration memory poolConfiguration ) = CoinSetup.generatePoolConfig (
308- address (coin),
309- poolConfig
340+ emit CoinCreatedV4 (
341+ msg .sender ,
342+ payoutRecipient,
343+ platformReferrer,
344+ currency,
345+ uri,
346+ name,
347+ symbol,
348+ coin,
349+ poolKey,
350+ CoinCommon.hashPoolKey (poolKey),
351+ IVersionedContract (coin).contractVersion ()
310352 );
311353
312- if (CoinConfigurationVersions.isV3 (version)) {
313- // V3 is no longer supported
314- revert ICoin.InvalidPoolVersion ();
315- } else if (CoinConfigurationVersions.isV4 (version)) {
316- _setupV4Coin (ICoin (coin), currency, isCoinToken0, sqrtPriceX96, poolConfiguration, payoutRecipient, owners, uri, name, symbol, platformReferrer);
317- } else {
318- revert ICoin.InvalidPoolVersion ();
319- }
320-
321354 return ICoin (coin);
322355 }
323356
0 commit comments