11// SPDX-License-Identifier: Apache-2.0
2- pragma solidity ^ 0.8.11 ;
2+ pragma solidity ^ 0.8.0 ;
33
44// ========== External imports ==========
55import "@openzeppelin/contracts/utils/Create2.sol " ;
66import "@openzeppelin/contracts/proxy/Clones.sol " ;
77import "@openzeppelin/contracts/utils/Address.sol " ;
8+ import "@openzeppelin/contracts/utils/Multicall.sol " ;
89import "@openzeppelin/contracts/access/AccessControlEnumerable.sol " ;
910import "@openzeppelin/contracts/metatx/ERC2771Context.sol " ;
1011
1112// ========== Internal imports ==========
12- import { IByocFactory } from "./interfaces/IByocFactory .sol " ;
13+ import { IContractDeployer } from "./interfaces/IContractDeployer .sol " ;
1314import { TWRegistry } from "./TWRegistry.sol " ;
14- import "./ThirdwebContract.sol " ;
15+ import { IContractMetadataRegistry } from "./interfaces/IContractMetadataRegistry.sol " ;
16+ import { ThirdwebContract } from "./ThirdwebContract.sol " ;
1517
16- contract ByocFactory is IByocFactory , ERC2771Context , AccessControlEnumerable , ThirdwebContract {
18+ contract ContractDeployer is IContractDeployer , ERC2771Context , Multicall , AccessControlEnumerable {
1719 /*///////////////////////////////////////////////////////////////
1820 State variables
1921 //////////////////////////////////////////////////////////////*/
2022
2123 /// @dev The main thirdweb registry.
2224 TWRegistry private immutable registry;
25+ /// @dev The contract metadta registry.
26+ IContractMetadataRegistry private immutable metadataRegistry;
27+ /// @dev contract address deployed through the factory => deployer
28+ mapping (address => address ) public getContractDeployer;
2329
2430 /// @dev Whether the registry is paused.
2531 bool public isPaused;
@@ -35,8 +41,13 @@ contract ByocFactory is IByocFactory, ERC2771Context, AccessControlEnumerable, T
3541 _;
3642 }
3743
38- constructor (address _twRegistry , address _trustedForwarder ) ERC2771Context (_trustedForwarder) {
44+ constructor (
45+ address _twRegistry ,
46+ address _metadataRegistry ,
47+ address _trustedForwarder
48+ ) ERC2771Context (_trustedForwarder) {
3949 registry = TWRegistry (_twRegistry);
50+ metadataRegistry = IContractMetadataRegistry (_metadataRegistry);
4051 _setupRole (DEFAULT_ADMIN_ROLE, _msgSender ());
4152 }
4253
@@ -51,25 +62,34 @@ contract ByocFactory is IByocFactory, ERC2771Context, AccessControlEnumerable, T
5162 bytes memory _constructorArgs ,
5263 bytes32 _salt ,
5364 uint256 _value ,
54- ThirdwebContract.ThirdwebInfo memory _thirdwebInfo
65+ string memory publishMetadataUri
5566 ) external onlyUnpausedOrAdmin returns (address deployedAddress ) {
56- require (bytes (_thirdwebInfo.publishMetadataUri).length > 0 , "No publish metadata " );
67+ require (bytes (publishMetadataUri).length > 0 , "No publish metadata " );
68+
69+ address caller = _msgSender ();
5770
5871 bytes memory contractBytecode = abi.encodePacked (_contractBytecode, _constructorArgs);
59- bytes32 salt = _salt == "" ? keccak256 (abi.encodePacked (_msgSender (), block .number )) : _salt;
72+ bytes32 salt = _salt == ""
73+ ? keccak256 (abi.encodePacked (caller, block .number , keccak256 (contractBytecode)))
74+ : keccak256 (abi.encodePacked (caller, _salt));
75+
76+ // compute the address of the clone and save it
77+ address computedContractAddress = Create2.computeAddress (salt, keccak256 (contractBytecode), address (this ));
78+ getContractDeployer[computedContractAddress] = caller;
6079
80+ // deploy the contract
6181 deployedAddress = Create2.deploy (_value, salt, contractBytecode);
6282
63- ThirdwebContract (deployedAddress).setThirdwebInfo (_thirdwebInfo);
64- require (
65- keccak256 (bytes (ThirdwebContract (deployedAddress).getPublishMetadataUri ())) ==
66- keccak256 (bytes (_thirdwebInfo.publishMetadataUri)),
67- "Not a thirdweb contract "
68- );
83+ // set the owner
84+ ThirdwebContract (deployedAddress).tw_initializeOwner (caller);
6985
70- registry.add (_publisher, deployedAddress);
86+ // register to metadata registry
87+ metadataRegistry.registerMetadata (deployedAddress, publishMetadataUri);
7188
72- emit ContractDeployed (_msgSender (), _publisher, deployedAddress);
89+ // register to TWRegistry
90+ registry.add (caller, deployedAddress);
91+
92+ emit ContractDeployed (caller, _publisher, deployedAddress);
7393 }
7494
7595 /// @notice Deploys a clone pointing to an implementation of a published contract.
@@ -79,26 +99,38 @@ contract ByocFactory is IByocFactory, ERC2771Context, AccessControlEnumerable, T
7999 bytes memory _initializeData ,
80100 bytes32 _salt ,
81101 uint256 _value ,
82- ThirdwebContract.ThirdwebInfo memory _thirdwebInfo
102+ string memory publishMetadataUri
83103 ) external onlyUnpausedOrAdmin returns (address deployedAddress ) {
84- bytes32 salt = _salt == "" ? keccak256 (abi.encodePacked (_msgSender (), block .number )) : _salt;
104+ require (bytes (publishMetadataUri).length > 0 , "No publish metadata " );
105+
106+ address caller = _msgSender ();
107+
108+ bytes32 salt = _salt == ""
109+ ? keccak256 (abi.encodePacked (caller, block .number , _implementation, _initializeData))
110+ : keccak256 (abi.encodePacked (caller, _salt));
111+
112+ // compute the address of the clone and save it
113+ address computedContractAddress = Clones.predictDeterministicAddress (_implementation, salt, address (this ));
114+ getContractDeployer[computedContractAddress] = caller;
115+
116+ // deploy the clone
85117 deployedAddress = Clones.cloneDeterministic (_implementation, salt);
86118
87- ThirdwebContract (deployedAddress).setThirdwebInfo (_thirdwebInfo);
88- require (
89- keccak256 (bytes (ThirdwebContract (deployedAddress).getPublishMetadataUri ())) ==
90- keccak256 (bytes (_thirdwebInfo.publishMetadataUri)),
91- "Not a thirdweb contract "
92- );
119+ // set the owner
120+ ThirdwebContract (deployedAddress).tw_initializeOwner (caller);
121+
122+ // register to metadata registry
123+ metadataRegistry.registerMetadata (deployedAddress, publishMetadataUri);
93124
94- registry.add (_publisher, deployedAddress);
125+ // register to TWRegistry
126+ registry.add (caller, deployedAddress);
95127
96128 if (_initializeData.length > 0 ) {
97129 // slither-disable-next-line unused-return
98130 Address.functionCallWithValue (deployedAddress, _initializeData, _value);
99131 }
100132
101- emit ContractDeployed (_msgSender () , _publisher, deployedAddress);
133+ emit ContractDeployed (caller , _publisher, deployedAddress);
102134 }
103135
104136 /*///////////////////////////////////////////////////////////////
0 commit comments