Skip to content

Commit

Permalink
feat: allow both variants
Browse files Browse the repository at this point in the history
  • Loading branch information
sakulstra committed Jan 19, 2025
1 parent 26e8148 commit bf06dcb
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 7 deletions.
64 changes: 60 additions & 4 deletions src/contracts/transparent-proxy/TransparentProxyFactoryBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,25 @@ import {ProxyAdmin} from './ProxyAdmin.sol';
abstract contract TransparentProxyFactoryBase is ITransparentProxyFactory {
/// @inheritdoc ITransparentProxyFactory
function create(address logic, ProxyAdmin admin, bytes calldata data) external returns (address) {
address proxy = address(new TransparentUpgradeableProxy(logic, admin, data));
return _create(logic, address(admin), data, true);
}

/// @inheritdoc ITransparentProxyFactory
function createAndDeployNewAdmin(
address logic,
address initialOwner,
bytes calldata data
) external returns (address) {
return _create(logic, initialOwner, data, false);
}

function _create(
address logic,
address admin,
bytes calldata data,
bool reuseAdmin
) internal returns (address) {
address proxy = address(new TransparentUpgradeableProxy(logic, admin, data, reuseAdmin));

emit ProxyCreated(proxy, logic, address(admin));
return proxy;
Expand All @@ -37,9 +55,31 @@ abstract contract TransparentProxyFactoryBase is ITransparentProxyFactory {
bytes calldata data,
bytes32 salt
) external returns (address) {
address proxy = address(new TransparentUpgradeableProxy{salt: salt}(logic, admin, data));
return _createDeterministic(logic, address(admin), data, true, salt);
}

/// @inheritdoc ITransparentProxyFactory
function createDeterministicAndDeployNewAdmin(
address logic,
address initialOwner,
bytes calldata data,
bytes32 salt
) external returns (address) {
return _createDeterministic(logic, initialOwner, data, false, salt);
}

emit ProxyDeterministicCreated(proxy, logic, address(admin), salt);
function _createDeterministic(
address logic,
address ownerOrAdmin,
bytes calldata data,
bool reuseAdmin,
bytes32 salt
) internal returns (address) {
address proxy = address(
new TransparentUpgradeableProxy{salt: salt}(logic, ownerOrAdmin, data, reuseAdmin)
);

emit ProxyDeterministicCreated(proxy, logic, address(ownerOrAdmin), salt);
return proxy;
}

Expand All @@ -66,7 +106,23 @@ abstract contract TransparentProxyFactoryBase is ITransparentProxyFactory {
address(this),
salt,
type(TransparentUpgradeableProxy).creationCode,
abi.encode(logic, address(admin), data)
abi.encode(logic, address(admin), data, true)
);
}

/// @inheritdoc ITransparentProxyFactory
function predictCreateDeterministicAndDeployNewAdmin(
address logic,
address initialOwner,
bytes calldata data,
bytes32 salt
) public view returns (address) {
return
_predictCreate2Address(
address(this),
salt,
type(TransparentUpgradeableProxy).creationCode,
abi.encode(logic, address(initialOwner), data, false)
);
}

Expand Down
11 changes: 8 additions & 3 deletions src/contracts/transparent-proxy/TransparentUpgradeableProxy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,15 @@ contract TransparentUpgradeableProxy is ERC1967Proxy {
*/
constructor(
address _logic,
ProxyAdmin initialOwner,
bytes memory _data
address ownerOrAdmin,
bytes memory _data,
bool useExistingAdmin
) payable ERC1967Proxy(_logic, _data) {
_admin = address(initialOwner);
if (useExistingAdmin) {
_admin = ownerOrAdmin;
} else {
_admin = address(new ProxyAdmin(ownerOrAdmin));
}
// Set the storage value and emit an event for ERC-1967 compatibility
ERC1967Utils.changeAdmin(_proxyAdmin());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,22 @@ interface ITransparentProxyFactory {
**/
function create(address logic, ProxyAdmin admin, bytes memory data) external returns (address);

/**
* @notice Creates a transparent proxy instance, doing the first initialization in construction
* @dev Version using CREATE
* @param logic The address of the implementation contract
* @param initialOwner The initial owner of the admin deployed by the proxy.
* @param data abi encoded call to the function with `initializer` (or `reinitializer`) modifier.
* E.g. `abi.encodeWithSelector(mockImpl.initialize.selector, 2)`
* for an `initialize` function being `function initialize(uint256 foo) external initializer;`
* @return address The address of the proxy deployed
**/
function createAndDeployNewAdmin(
address logic,
address initialOwner,
bytes memory data
) external returns (address);

/**
* @notice Creates a proxyAdmin instance, and transfers ownership to provided owner
* @dev Version using CREATE
Expand All @@ -56,6 +72,24 @@ interface ITransparentProxyFactory {
bytes32 salt
) external returns (address);

/**
* @notice Creates a transparent proxy instance, doing the first initialization in construction
* @dev Version using CREATE2, so deterministic
* @param logic The address of the implementation contract
* @param initialOwner The initial owner of the admin deployed by the proxy.
* @param data abi encoded call to the function with `initializer` (or `reinitializer`) modifier.
* E.g. `abi.encodeWithSelector(mockImpl.initialize.selector, 2)`
* for an `initialize` function being `function initialize(uint256 foo) external initializer;`
* @param salt Value to be used in the address calculation, to be chosen by the account calling this function
* @return address The address of the proxy deployed
**/
function createDeterministicAndDeployNewAdmin(
address logic,
address initialOwner,
bytes memory data,
bytes32 salt
) external returns (address);

/**
* @notice Deterministically create a proxy admin instance and transfers ownership to provided owner.
* @dev Version using CREATE2, so deterministic
Expand Down Expand Up @@ -85,6 +119,23 @@ interface ITransparentProxyFactory {
bytes32 salt
) external view returns (address);

/**
* @notice Pre-calculates and return the address on which `createDeterministic` will deploy a proxy
* @param logic The address of the implementation contract
* @param initialOwner The initial owner of the admin deployed by the proxy
* @param data abi encoded call to the function with `initializer` (or `reinitializer`) modifier.
* E.g. `abi.encodeWithSelector(mockImpl.initialize.selector, 2)`
* for an `initialize` function being `function initialize(uint256 foo) external initializer;`
* @param salt Value to be used in the address calculation, to be chosen by the account calling this function
* @return address The pre-calculated address
**/
function predictCreateDeterministicAndDeployNewAdmin(
address logic,
address initialOwner,
bytes calldata data,
bytes32 salt
) external view returns (address);

/**
* @notice Pre-calculates and return the address on which `createDeterministic` will deploy the proxyAdmin
* @param salt Value to be used in the address calculation, to be chosen by the account calling this function
Expand Down

0 comments on commit bf06dcb

Please sign in to comment.