// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IDeploy } from '../interfaces/IDeploy.sol'; import { ContractAddress } from '../libs/ContractAddress.sol'; import { CreateDeploy } from './CreateDeploy.sol'; import { Create3Address } from './Create3Address.sol'; /** * @title Create3 contract * @notice This contract can be used to deploy a contract with a deterministic address that depends only on * the deployer address and deployment salt, not the contract bytecode and constructor parameters. */ contract Create3 is Create3Address, IDeploy { using ContractAddress for address; /** * @notice Deploys a new contract using the `CREATE3` method. * @dev This function first deploys the CreateDeploy contract using * the `CREATE2` opcode and then utilizes the CreateDeploy to deploy the * new contract with the `CREATE` opcode. * @param bytecode The bytecode of the contract to be deployed * @param deploySalt A salt to influence the contract address * @return deployed The address of the deployed contract */ function _create3(bytes memory bytecode, bytes32 deploySalt) internal returns (address deployed) { deployed = _create3Address(deploySalt); if (bytecode.length == 0) revert EmptyBytecode(); if (deployed.isContract()) revert AlreadyDeployed(); // Deploy using create2 CreateDeploy create = new CreateDeploy{ salt: deploySalt }(); if (address(create) == address(0)) revert DeployFailed(); // Deploy using create create.deploy(bytecode); } }