/* Crafted with love by Fueled on Bacon https://fueledonbacon.com */ //SPDX-License-Identifier: MIT pragma solidity ^0.8.15; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import "@openzeppelin/contracts/utils/introspection/ERC165.sol"; import "./interfaces/IVenueRegistar.sol"; import "./interfaces/IReservForwarder.sol"; import "./interfaces/IERC721FactoryWide.sol"; contract ReservForwarder is IReservForwarder, Initializable, UUPSUpgradeable, OwnableUpgradeable, ERC165 { address private _venueRegistar; uint256 public factoriesCount; //will start from 1 //factories by typeOf mapping(uint256 => address) private _factories; //factory by position mapping(address => uint256) private _positions; mapping(address => bool) public deprecated; function initialize(address venueRegistar) public initializer { _venueRegistar = venueRegistar; __Ownable_init(); __UUPSUpgradeable_init(); } /// @inheritdoc UUPSUpgradeable function _authorizeUpgrade(address newImplementation) internal override onlyOwner {} /// @inheritdoc IReservForwarder function versionForwarder() external pure virtual override returns (string memory) { return "1.0.0-beta.0+fob.rsv.iReservForwarder"; } /// @inheritdoc IReservForwarder /// @notice factories count starts from 1 function addfactory(address factory) external virtual override onlyOwner { if(factory == address(0)) revert ForwarderFactoryAddressZero(); if(_positions[factory] > 0) revert ForwarderFactoryAlreadyAdded(); bytes4 factoryWideInterfaceId = type(IERC721FactoryWide).interfaceId; (bool success, bytes memory data) = factory.call( abi.encodeWithSignature( "supportsInterface(bytes4)", factoryWideInterfaceId ) ); if(!success) revert ForwarderUnableToRetrieveFactryInterface(); bool isSupported = abi.decode(data, (bool)); if(!isSupported) revert ForwarderNotSupportedInterface(); factoriesCount += 1; _factories[factoriesCount] = factory; _positions[factory] = factoriesCount; emit NewFactory(factoriesCount, factory); } /// @inheritdoc IReservForwarder function deprecateFactory(address factory, bool deprecate) external virtual override onlyOwner { if(factory == address(0)) revert ForwarderFactoryAddressZero(); uint256 pos = _positions[factory]; if(pos == 0 || pos > factoriesCount) revert ForwarderUnexistentFactory(); if(deprecate && deprecated[factory]) revert ForwarderDeprecatedFactory(); else if(!deprecate && !deprecated[factory]) revert ForwarderNotDeprecatedFactory(); deprecated[factory] = deprecate; emit DeprecateFactory(factory, deprecate); } /// @inheritdoc IReservForwarder function deploy( uint256 typeOf, string memory name, string memory symbol, bytes memory mainData ) external virtual override returns (address) { address venue = _msgSender(); IVenueRegistar venueRegistar = IVenueRegistar(_venueRegistar); if(!venueRegistar.isVenue(venue)) revert ForwarderUnknownVenue(); address factory = _factories[typeOf]; if(factory == address(0)) revert ForwarderUnexistentFactory(); if(deprecated[factory]) revert ForwarderDeprecatedFactory(); (bool success, bytes memory data) = factory.call( abi.encodeWithSignature( "deploy(string,string,address,bytes)", name, symbol, venue, mainData ) ); if(!success) revert ForwarderErrorDeploying(); address deployed = abi.decode(data, (address)); emit Deployment(venue, factory, deployed); return deployed; } /// @inheritdoc IReservForwarder function removeEvent(address _event, uint256 typeOf) external virtual override { address venue = _msgSender(); IVenueRegistar venueRegistar = IVenueRegistar(_venueRegistar); if(!venueRegistar.isVenue(venue)) revert ForwarderUnknownVenue(); address factory = _factories[typeOf]; if(factory == address(0)) revert ForwarderUnexistentFactory(); (bool success, ) = factory.call( abi.encodeWithSignature("removeEvent(address,address)", venue, _event) ); if(!success) revert ForwarderErrorRemoving(); emit Removed(venue, factory, _event); } /// @inheritdoc IReservForwarder function getFactoryAt(uint256 position) external virtual override view returns(address) { return _factories[position]; } /// @inheritdoc IReservForwarder function getFactoryPosition(address factory) external virtual override view returns(uint256) { return _positions[factory]; } function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IReservForwarder).interfaceId || super.supportsInterface(interfaceId); } }