Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
This contract has been verified via Sourcify.
View contract in Sourcify repository
- Contract name:
- FactoryUpgradeGate
- Optimization enabled
- true
- Compiler version
- v0.8.17+commit.8df45f5f
- Optimization runs
- 5000
- EVM Version
- london
- Verified at
- 2026-02-06T12:50:29.559146Z
Constructor Arguments
000000000000000000000000db392f4391462d60b8b4413ef72018ab595af9d0
Arg [0] (address) : 0xdb392f4391462d60b8b4413ef72018ab595af9d0
src/FactoryUpgradeGate.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
import {IFactoryUpgradeGate} from "./interfaces/IFactoryUpgradeGate.sol";
import {Ownable2Step} from "./utils/ownable/Ownable2Step.sol";
/**
________ _____ ____ ______ ____
/\_____ \ /\ __`\/\ _`\ /\ _ \ /\ _`\
\/____//'/'\ \ \/\ \ \ \L\ \ \ \L\ \ \ \ \/\ \ _ __ ___ _____ ____
//'/' \ \ \ \ \ \ , /\ \ __ \ \ \ \ \ \/\`'__\/ __`\/\ '__`\ /',__\
//'/'___ \ \ \_\ \ \ \\ \\ \ \/\ \ \ \ \_\ \ \ \//\ \L\ \ \ \L\ \/\__, `\
/\_______\\ \_____\ \_\ \_\ \_\ \_\ \ \____/\ \_\\ \____/\ \ ,__/\/\____/
\/_______/ \/_____/\/_/\/ /\/_/\/_/ \/___/ \/_/ \/___/ \ \ \/ \/___/
\ \_\
\/_/
*/
/// @notice This contract handles gating allowed upgrades for Zora drops contracts
contract FactoryUpgradeGate is IFactoryUpgradeGate, Ownable2Step {
/// @notice Private mapping of valid upgrade paths
mapping(address => mapping(address => bool)) private _validUpgradePaths;
/// @notice Emitted when an upgrade path is added / registered
event UpgradePathRegistered(address newImpl, address oldImpl);
/// @notice Emitted when an upgrade path is removed
event UpgradePathRemoved(address newImpl, address oldImpl);
/// @notice Error for when not called from admin
error Access_OnlyOwner();
/// @notice Sets the owner and inits the contract
/// @param _initialOwner owner of the contract
constructor(address _initialOwner) Ownable2Step(_initialOwner) {}
/// @notice Ensures the given upgrade path is valid and does not overwrite existing storage slots
/// @param _newImpl The proposed implementation address
/// @param _currentImpl The current implementation address
function isValidUpgradePath(address _newImpl, address _currentImpl)
external
view
returns (bool)
{
return _validUpgradePaths[_newImpl][_currentImpl];
}
/// @notice Registers a new safe upgrade path for an implementation
/// @param _newImpl The new implementation
/// @param _supportedPrevImpls Safe implementations that can upgrade to this new implementation
function registerNewUpgradePath(
address _newImpl,
address[] calldata _supportedPrevImpls
) external onlyOwner {
for (uint256 i = 0; i < _supportedPrevImpls.length; i++) {
_validUpgradePaths[_newImpl][_supportedPrevImpls[i]] = true;
emit UpgradePathRegistered(_newImpl, _supportedPrevImpls[i]);
}
}
/// @notice Unregisters an upgrade path, in case of emergency
/// @param _newImpl the newer implementation
/// @param _prevImpl the older implementation
function unregisterUpgradePath(address _newImpl, address _prevImpl)
external
onlyOwner
{
_validUpgradePaths[_newImpl][_prevImpl] = false;
emit UpgradePathRemoved(_newImpl, _prevImpl);
}
}
/
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
interface IFactoryUpgradeGate {
function isValidUpgradePath(address _newImpl, address _currentImpl) external returns (bool);
function registerNewUpgradePath(address _newImpl, address[] calldata _supportedPrevImpls) external;
function unregisterUpgradePath(address _newImpl, address _prevImpl) external;
}
/
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;
/// @title IOwnable2Step
/// @author Rohan Kulkarni / Iain Nash
/// @notice The external Ownable events, errors, and functions
interface IOwnable2Step {
/// ///
/// EVENTS ///
/// ///
/// @notice Emitted when ownership has been updated
/// @param prevOwner The previous owner address
/// @param newOwner The new owner address
event OwnerUpdated(address indexed prevOwner, address indexed newOwner);
/// @notice Emitted when an ownership transfer is pending
/// @param owner The current owner address
/// @param pendingOwner The pending new owner address
event OwnerPending(address indexed owner, address indexed pendingOwner);
/// @notice Emitted when a pending ownership transfer has been canceled
/// @param owner The current owner address
/// @param canceledOwner The canceled owner address
event OwnerCanceled(address indexed owner, address indexed canceledOwner);
/// ///
/// ERRORS ///
/// ///
/// @dev Reverts if an unauthorized user calls an owner function
error ONLY_OWNER();
/// @dev Reverts if an unauthorized user calls a pending owner function
error ONLY_PENDING_OWNER();
/// @dev Owner cannot be the zero/burn address
error OWNER_CANNOT_BE_ZERO_ADDRESS();
/// ///
/// FUNCTIONS ///
/// ///
/// @notice The address of the owner
function owner() external view returns (address);
/// @notice The address of the pending owner
function pendingOwner() external view returns (address);
/// @notice Forces an ownership transfer
/// @param newOwner The new owner address
function transferOwnership(address newOwner) external;
/// @notice Initiates a two-step ownership transfer
/// @param newOwner The new owner address
function safeTransferOwnership(address newOwner) external;
/// @notice Accepts an ownership transfer
function acceptOwnership() external;
/// @notice Cancels a pending ownership transfer
function cancelOwnershipTransfer() external;
}
/
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;
import {IOwnable2Step} from "./IOwnable2Step.sol";
/// @title Ownable2Step
/// @author Iain Nash
/// @dev - Uses custom errors declared in IOwnable
/// @dev - Adds optional two-step ownership transfer (`safeTransferOwnership` + `acceptOwnership`)
abstract contract Ownable2Step is IOwnable2Step {
/// @dev The address of the owner
address internal _owner;
/// @dev The address of the pending owner
address internal _pendingOwner;
constructor(address _defaultOwner) {
_transferOwnership(_defaultOwner);
}
/// ///
/// STORAGE ///
/// ///
/// @dev Modifier to check if the address argument is the zero/burn address
modifier notZeroAddress(address check) {
if (check == address(0)) {
revert OWNER_CANNOT_BE_ZERO_ADDRESS();
}
_;
}
/// ///
/// MODIFIERS ///
/// ///
/// @dev Ensures the caller is the owner
modifier onlyOwner() {
if (msg.sender != _owner) {
revert ONLY_OWNER();
}
_;
}
/// @dev Ensures the caller is the pending owner
modifier onlyPendingOwner() {
if (msg.sender != _pendingOwner) {
revert ONLY_PENDING_OWNER();
}
_;
}
/// ///
/// FUNCTIONS ///
/// ///
/// @notice The address of the owner
function owner() public view virtual returns (address) {
return _owner;
}
/// @notice The address of the pending owner
function pendingOwner() public view returns (address) {
return _pendingOwner;
}
/// @notice Forces an ownership transfer from the last owner
/// @param _newOwner The new owner address
function transferOwnership(address _newOwner)
public
notZeroAddress(_newOwner)
onlyOwner
{
_transferOwnership(_newOwner);
}
/// @notice Forces an ownership transfer from any sender
/// @param _newOwner New owner to transfer contract to
/// @dev Ensure is called only from trusted internal code, no access control checks.
function _transferOwnership(address _newOwner) internal {
emit OwnerUpdated(_owner, _newOwner);
_owner = _newOwner;
if (_pendingOwner != address(0)) {
delete _pendingOwner;
}
}
/// @notice Initiates a two-step ownership transfer
/// @param _newOwner The new owner address
function safeTransferOwnership(address _newOwner)
public
notZeroAddress(_newOwner)
onlyOwner
{
_pendingOwner = _newOwner;
emit OwnerPending(_owner, _newOwner);
}
/// @notice Resign ownership of contract
/// @dev only callably by the owner, dangerous call.
function resignOwnership() public onlyOwner {
_transferOwnership(address(0));
}
/// @notice Accepts an ownership transfer
function acceptOwnership() public onlyPendingOwner {
emit OwnerUpdated(_owner, msg.sender);
_owner = _pendingOwner;
delete _pendingOwner;
}
/// @notice Cancels a pending ownership transfer
function cancelOwnershipTransfer() public onlyOwner {
emit OwnerCanceled(_owner, _pendingOwner);
delete _pendingOwner;
}
}
Compiler Settings
{"remappings":[":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",":ERC721A-Upgradeable/=lib/ERC721A-Upgradeable/contracts/",":base64/=lib/base64/",":ds-test/=lib/forge-std/lib/ds-test/src/",":erc721a-upgradeable/=lib/ERC721A-Upgradeable/contracts/",":forge-std/=lib/forge-std/src/",":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",":openzeppelin-contracts/=lib/openzeppelin-contracts/"],"optimizer":{"runs":5000,"enabled":true},"metadata":{"bytecodeHash":"ipfs"},"libraries":{},"evmVersion":"london","compilationTarget":{"src/FactoryUpgradeGate.sol":"FactoryUpgradeGate"}}
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_initialOwner","internalType":"address"}]},{"type":"error","name":"Access_OnlyOwner","inputs":[]},{"type":"error","name":"ONLY_OWNER","inputs":[]},{"type":"error","name":"ONLY_PENDING_OWNER","inputs":[]},{"type":"error","name":"OWNER_CANNOT_BE_ZERO_ADDRESS","inputs":[]},{"type":"event","name":"OwnerCanceled","inputs":[{"type":"address","name":"owner","internalType":"address","indexed":true},{"type":"address","name":"canceledOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"OwnerPending","inputs":[{"type":"address","name":"owner","internalType":"address","indexed":true},{"type":"address","name":"pendingOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"OwnerUpdated","inputs":[{"type":"address","name":"prevOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"UpgradePathRegistered","inputs":[{"type":"address","name":"newImpl","internalType":"address","indexed":false},{"type":"address","name":"oldImpl","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"UpgradePathRemoved","inputs":[{"type":"address","name":"newImpl","internalType":"address","indexed":false},{"type":"address","name":"oldImpl","internalType":"address","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"acceptOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"cancelOwnershipTransfer","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isValidUpgradePath","inputs":[{"type":"address","name":"_newImpl","internalType":"address"},{"type":"address","name":"_currentImpl","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"pendingOwner","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"registerNewUpgradePath","inputs":[{"type":"address","name":"_newImpl","internalType":"address"},{"type":"address[]","name":"_supportedPrevImpls","internalType":"address[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"resignOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"safeTransferOwnership","inputs":[{"type":"address","name":"_newOwner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"_newOwner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"unregisterUpgradePath","inputs":[{"type":"address","name":"_newImpl","internalType":"address"},{"type":"address","name":"_prevImpl","internalType":"address"}]}]
Contract Creation Code
0x608060405234801561001057600080fd5b50604051610a65380380610a6583398101604081905261002f916100b6565b8061003981610040565b50506100e6565b600080546040516001600160a01b03808516939216917f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d7691a3600080546001600160a01b0319166001600160a01b038381169190911790915560015416156100b357600180546001600160a01b03191690555b50565b6000602082840312156100c857600080fd5b81516001600160a01b03811681146100df57600080fd5b9392505050565b610970806100f56000396000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c80638942865411610076578063e30c39781161005b578063e30c397814610184578063ed0c709114610195578063f2fde38b1461019d57600080fd5b8063894286541461014c5780638da5cb5b1461015f57600080fd5b806373995833116100a757806373995833146100e057806379ba5097146101315780638466a71c1461013957600080fd5b806323452b9c146100c3578063395db2cd146100cd575b600080fd5b6100cb6101b0565b005b6100cb6100db3660046107d1565b61025b565b61011c6100ee3660046107f3565b6001600160a01b03918216600090815260026020908152604080832093909416825291909152205460ff1690565b60405190151581526020015b60405180910390f35b6100cb61034a565b6100cb6101473660046107f3565b610405565b6100cb61015a366004610826565b6104d2565b6000546001600160a01b03165b6040516001600160a01b039091168152602001610128565b6001546001600160a01b031661016c565b6100cb61062d565b6100cb6101ab3660046107d1565b61067d565b6000546001600160a01b031633146101f4576040517fd238ed5900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600154600080546040516001600160a01b0393841693909116917f682679deecef4dcd49674845cc1e3a075fea9073680aa445a8207d5a4bdea3da91a3600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b806001600160a01b03811661029c576040517f2c4ec43e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000546001600160a01b031633146102e0576040517fd238ed5900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0384811691821790925560008054604051929316917f4f2638f5949b9614ef8d5e268cb51348ad7f434a34812bf64b6e95014fbd357e9190a35050565b6001546001600160a01b0316331461038e576040517f065cd53100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805460405133926001600160a01b03909216917f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d7691a360018054600080547fffffffffffffffffffffffff00000000000000000000000000000000000000009081166001600160a01b03841617909155169055565b6000546001600160a01b03163314610449576040517fd238ed5900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0382811660008181526002602090815260408083209486168084529482529182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905581519283528201929092527fa3a0491075ec5f5949945a6f452fb9e0619a4dacc65a568ad2da3210cc91cdab910160405180910390a15050565b6000546001600160a01b03163314610516576040517fd238ed5900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610627576001600160a01b038416600090815260026020526040812060019185858581811061054e5761054e6108ac565b905060200201602081019061056391906107d1565b6001600160a01b03168152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169115159190911790557f7acfb66a4ce41040d432f980d35151e6d37f3279e6f8dbf383b0f5112271462f848484848181106105dd576105dd6108ac565b90506020020160208101906105f291906107d1565b604080516001600160a01b0393841681529290911660208301520160405180910390a18061061f816108db565b915050610519565b50505050565b6000546001600160a01b03163314610671576040517fd238ed5900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61067b600061070f565b565b806001600160a01b0381166106be576040517f2c4ec43e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000546001600160a01b03163314610702576040517fd238ed5900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61070b8261070f565b5050565b600080546040516001600160a01b03808516939216917f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d7691a3600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b038381169190911790915560015416156107b257600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001690555b50565b80356001600160a01b03811681146107cc57600080fd5b919050565b6000602082840312156107e357600080fd5b6107ec826107b5565b9392505050565b6000806040838503121561080657600080fd5b61080f836107b5565b915061081d602084016107b5565b90509250929050565b60008060006040848603121561083b57600080fd5b610844846107b5565b9250602084013567ffffffffffffffff8082111561086157600080fd5b818601915086601f83011261087557600080fd5b81358181111561088457600080fd5b8760208260051b850101111561089957600080fd5b6020830194508093505050509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610933577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea2646970667358221220a124600e6ac4e05308139e6bb7d6caf6b96bb8b5e46e779fdfa56c0fc940bc1664736f6c63430008110033000000000000000000000000db392f4391462d60b8b4413ef72018ab595af9d0
Deployed ByteCode
0x608060405234801561001057600080fd5b50600436106100be5760003560e01c80638942865411610076578063e30c39781161005b578063e30c397814610184578063ed0c709114610195578063f2fde38b1461019d57600080fd5b8063894286541461014c5780638da5cb5b1461015f57600080fd5b806373995833116100a757806373995833146100e057806379ba5097146101315780638466a71c1461013957600080fd5b806323452b9c146100c3578063395db2cd146100cd575b600080fd5b6100cb6101b0565b005b6100cb6100db3660046107d1565b61025b565b61011c6100ee3660046107f3565b6001600160a01b03918216600090815260026020908152604080832093909416825291909152205460ff1690565b60405190151581526020015b60405180910390f35b6100cb61034a565b6100cb6101473660046107f3565b610405565b6100cb61015a366004610826565b6104d2565b6000546001600160a01b03165b6040516001600160a01b039091168152602001610128565b6001546001600160a01b031661016c565b6100cb61062d565b6100cb6101ab3660046107d1565b61067d565b6000546001600160a01b031633146101f4576040517fd238ed5900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600154600080546040516001600160a01b0393841693909116917f682679deecef4dcd49674845cc1e3a075fea9073680aa445a8207d5a4bdea3da91a3600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b806001600160a01b03811661029c576040517f2c4ec43e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000546001600160a01b031633146102e0576040517fd238ed5900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0384811691821790925560008054604051929316917f4f2638f5949b9614ef8d5e268cb51348ad7f434a34812bf64b6e95014fbd357e9190a35050565b6001546001600160a01b0316331461038e576040517f065cd53100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805460405133926001600160a01b03909216917f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d7691a360018054600080547fffffffffffffffffffffffff00000000000000000000000000000000000000009081166001600160a01b03841617909155169055565b6000546001600160a01b03163314610449576040517fd238ed5900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0382811660008181526002602090815260408083209486168084529482529182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905581519283528201929092527fa3a0491075ec5f5949945a6f452fb9e0619a4dacc65a568ad2da3210cc91cdab910160405180910390a15050565b6000546001600160a01b03163314610516576040517fd238ed5900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610627576001600160a01b038416600090815260026020526040812060019185858581811061054e5761054e6108ac565b905060200201602081019061056391906107d1565b6001600160a01b03168152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169115159190911790557f7acfb66a4ce41040d432f980d35151e6d37f3279e6f8dbf383b0f5112271462f848484848181106105dd576105dd6108ac565b90506020020160208101906105f291906107d1565b604080516001600160a01b0393841681529290911660208301520160405180910390a18061061f816108db565b915050610519565b50505050565b6000546001600160a01b03163314610671576040517fd238ed5900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61067b600061070f565b565b806001600160a01b0381166106be576040517f2c4ec43e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000546001600160a01b03163314610702576040517fd238ed5900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61070b8261070f565b5050565b600080546040516001600160a01b03808516939216917f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d7691a3600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b038381169190911790915560015416156107b257600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001690555b50565b80356001600160a01b03811681146107cc57600080fd5b919050565b6000602082840312156107e357600080fd5b6107ec826107b5565b9392505050565b6000806040838503121561080657600080fd5b61080f836107b5565b915061081d602084016107b5565b90509250929050565b60008060006040848603121561083b57600080fd5b610844846107b5565b9250602084013567ffffffffffffffff8082111561086157600080fd5b818601915086601f83011261087557600080fd5b81358181111561088457600080fd5b8760208260051b850101111561089957600080fd5b6020830194508093505050509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610933577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea2646970667358221220a124600e6ac4e05308139e6bb7d6caf6b96bb8b5e46e779fdfa56c0fc940bc1664736f6c63430008110033