Skip to content

Commit

Permalink
feat: add interfce and clean up
Browse files Browse the repository at this point in the history
  • Loading branch information
ChefMist committed Oct 11, 2024
1 parent aec0db5 commit f878298
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 10 deletions.
14 changes: 7 additions & 7 deletions src/Create2Factory.sol
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.26;

import {ICreate2Factory} from "./interfaces/ICreate2Factory.sol";
import {Ownable2Step, Ownable} from "@openzeppelin/contracts/access/Ownable2Step.sol";
import {Create2} from "@openzeppelin/contracts/utils/Create2.sol";
import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";

/// @notice Deploy contracts in a deterministic way using CREATE2
/// @dev ensure this contract is deployed on multiple chain with the same address
contract Create2Factory is Ownable2Step, ReentrancyGuard {
contract Create2Factory is ICreate2Factory, Ownable2Step, ReentrancyGuard {
event SetWhitelist(address indexed user, bool isWhitelist);

// Only whitelisted user can interact with create2Factory
Expand All @@ -22,8 +23,7 @@ contract Create2Factory is Ownable2Step, ReentrancyGuard {
isUserWhitelisted[msg.sender] = true;
}

/// @notice create2 deploy a contract
/// @dev So long the same salt, creationCode is used, the contract will be deployed at the same address on other chain
/// @inheritdoc ICreate2Factory
function deploy(bytes32 salt, bytes memory creationCode)
external
payable
Expand All @@ -33,18 +33,18 @@ contract Create2Factory is Ownable2Step, ReentrancyGuard {
deployed = Create2.deploy(msg.value, salt, creationCode);
}

function getDeployed(bytes32 salt, bytes32 bytecodeHash) public view returns (address addr) {
/// @inheritdoc ICreate2Factory
function computeAddress(bytes32 salt, bytes32 bytecodeHash) public view returns (address) {
return Create2.computeAddress(salt, bytecodeHash);
}

/// @notice execute a call on a deployed contract
/// @dev used in scenario where contract owner is create2Factory and we need to transfer ownership
/// @inheritdoc ICreate2Factory
function execute(address target, bytes calldata data) external payable onlyWhitelisted nonReentrant {
(bool success,) = target.call{value: msg.value}(data);
require(success, "Create2Factory: failed execute call");
}

/// @notice set user as whitelisted
/// @inheritdoc ICreate2Factory
function setWhitelistUser(address user, bool isWhiteList) external onlyOwner {
isUserWhitelisted[user] = isWhiteList;

Expand Down
18 changes: 18 additions & 0 deletions src/interfaces/ICreate2Factory.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface ICreate2Factory {
/// @notice create2 deploy a contract
/// @dev So long the same salt, creationCode is used, the contract will be deployed at the same address on other chain
function deploy(bytes32 salt, bytes memory creationCode) external payable returns (address deployed);

/// @notice compute the create2 address based on salt, bytecodeHash
function computeAddress(bytes32 salt, bytes32 bytecodeHash) external view returns (address);

/// @notice execute a call on a deployed contract
/// @dev used in scenario where contract owner is create2Factory and we need to transfer ownership
function execute(address target, bytes calldata data) external payable;

/// @notice set user as whitelisted
function setWhitelistUser(address user, bool isWhiteList) external;
}
6 changes: 3 additions & 3 deletions test/Create2Factory.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ contract Create2FactoryTest is Test, GasSnapshot {
snapLastCall("Create2FactoryTest#test_Deploy_ContractWithArgs");

// verify
address expectedDeployed = create2Factory.getDeployed(salt, keccak256(creationCode));
address expectedDeployed = create2Factory.computeAddress(salt, keccak256(creationCode));
assertEq(deployed, expectedDeployed);

MockWithConstructorArgs deployedContract = MockWithConstructorArgs(deployed);
Expand All @@ -46,7 +46,7 @@ contract Create2FactoryTest is Test, GasSnapshot {
address deployed = create2Factory.deploy(salt, creationCode);

// verify
address expectedDeployed = create2Factory.getDeployed(salt, keccak256(creationCode));
address expectedDeployed = create2Factory.computeAddress(salt, keccak256(creationCode));
assertEq(deployed, expectedDeployed);
}

Expand All @@ -62,7 +62,7 @@ contract Create2FactoryTest is Test, GasSnapshot {
address deployed = create2Factory.deploy(salt, creationCode);

// verify
address expectedDeployed = create2Factory.getDeployed(salt, keccak256(creationCode));
address expectedDeployed = create2Factory.computeAddress(salt, keccak256(creationCode));
assertEq(deployed, expectedDeployed);
}

Expand Down

0 comments on commit f878298

Please sign in to comment.