/* 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/structs/EnumerableSet.sol"; import "@openzeppelin/contracts/utils/introspection/ERC165.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "./interfaces/IVenueRegistar.sol"; import "./interfaces/IVenueFactory.sol"; import "./interfaces/IVenueSBT.sol"; contract VenueRegistar is IVenueRegistar, Initializable, UUPSUpgradeable, OwnableUpgradeable, ERC165 { using EnumerableSet for EnumerableSet.AddressSet; address private _venueFactory; address private _forwarder; address private _tokenReviewPaymaster; // address of GSN Paymaster address private _tokenReview; address public tokenCreator; //EOA which can mint on behalf of stripe credit card payment uint256 private _tokenReviewMinBalance; // min balance VenueRegistar should have to pay GSN reviews in ETH, MATIC uint256 public price; //in ETH, cost to deploy a venue when sender is not registar owner string private _versionVenueSBT; mapping(address => address) public splitterByVenue; EnumerableSet.AddressSet private _venues; EnumerableSet.AddressSet private _whitelistedPaymentTokens; function initialize( uint256 publicPrice, address tokenCreator_ ) public initializer { price = publicPrice; tokenCreator = tokenCreator_; __Ownable_init(); __UUPSUpgradeable_init(); } /// @inheritdoc IVenueRegistar function versionRegistar() external pure virtual override returns (string memory) { return "1.0.0-beta.0+fob.rsv.iVenueRegistar"; } /// @inheritdoc UUPSUpgradeable function _authorizeUpgrade(address newImplementation) internal override onlyOwner {} /// @inheritdoc IVenueRegistar function whitelistPaymentToken(address token, bool whitelist) external virtual override onlyOwner { if(whitelist) _whitelistedPaymentTokens.add(token); else _whitelistedPaymentTokens.remove(token); } /// @inheritdoc IVenueRegistar function setVenueFactory(address venueFactory) external virtual override onlyOwner { if(venueFactory == address(0)) revert RegistarWrongVenueFactory(); _venueFactory = venueFactory; } /// @inheritdoc IVenueRegistar function setTokenCreator(address newTokenCreator) external virtual override onlyOwner { tokenCreator = newTokenCreator; } /// @inheritdoc IVenueRegistar function setTokenReviewParams( address tokenReview, address tokenReviewPaymaster, uint256 minBalance ) external virtual override onlyOwner { _tokenReview = tokenReview; _tokenReviewPaymaster = tokenReviewPaymaster; _tokenReviewMinBalance = minBalance; } /// @inheritdoc IVenueRegistar function setPrice(uint256 publicPrice) external virtual override onlyOwner { price = publicPrice; } /// @inheritdoc IVenueRegistar function setForwarder(address forwarder) external virtual override onlyOwner { _forwarder = forwarder; } /// @inheritdoc IVenueRegistar function setVenueSBTVersion(string memory newVersion) external virtual override onlyOwner { _versionVenueSBT = newVersion; } /// @inheritdoc IVenueRegistar function deployVenue( string memory name, string memory symbol, string memory baseUri ) external payable virtual override { if(_venueFactory == address(0)) revert RegistarUndefinedVenueFactory(); if (msg.value != price) revert RegistarInvalidPrice(); _deployVenue(name, symbol, baseUri, _msgSender()); } /// @inheritdoc IVenueRegistar function ownerDeployVenue( string memory name, string memory symbol, string memory baseUri, address owner ) external virtual override onlyOwner { _deployVenue(name, symbol, baseUri, owner); } function _deployVenue( string memory name, string memory symbol, string memory baseUri, address owner ) private { (address venueAddress, address splitter) = IVenueFactory(_venueFactory).deployVenue( name, symbol, baseUri, owner ); _venues.add(venueAddress); splitterByVenue[venueAddress] = splitter; emit NewVenue(venueAddress, splitter, owner, block.number); } /// @inheritdoc IVenueRegistar function removeVenue(address venue) external virtual override onlyOwner { if (!_venues.contains(venue)) revert RegistarVenueNotFound(); _venues.remove(venue); } /// @inheritdoc IVenueRegistar function registerVenue(address venue) external virtual override onlyOwner { IVenueSBT venueSBT = IVenueSBT(venue); if ( keccak256(abi.encodePacked(venueSBT.versionVenueSBT())) != keccak256(abi.encodePacked(_versionVenueSBT)) ) revert RegistarSBTVersionNotSupported(); if (venueSBT.getVenueRegistar() != address(this)) revert RegistarWrongVenueRegistar(); if (_venues.contains(venue)) revert RegistarVenueAlreadyRegistered(); _venues.add(venue); } /// @inheritdoc IVenueRegistar function getWhitelistedPaymentTokens() external virtual view override returns(address[] memory) { return _whitelistedPaymentTokens.values(); } /// @inheritdoc IVenueRegistar function isPaymentTokenWhitelisted(address token) external virtual view override returns(bool) { return _whitelistedPaymentTokens.contains(token); } /// @inheritdoc IVenueRegistar function getVenues() external view virtual override returns (address[] memory) { return _venues.values(); } /// @inheritdoc IVenueRegistar function getTokenReviewParams() external view virtual override returns (address, address, uint256) { return (_tokenReview, _tokenReviewPaymaster, _tokenReviewMinBalance); } /// @inheritdoc IVenueRegistar function getMinBalance() external view virtual override returns(uint256) { return _tokenReviewMinBalance; } /// @inheritdoc IVenueRegistar function isVenue(address venue) external view virtual override returns (bool) { return _venues.contains((venue)); } /// @inheritdoc IVenueRegistar function isTrustedForwarder(address forwarder) public view virtual override returns (bool) { return forwarder == _forwarder; } /// @inheritdoc IVenueRegistar function getForwarder() external view virtual override returns (address) { return _forwarder; } /// @inheritdoc IVenueRegistar function getOwner() external virtual view override returns(address) { return owner(); } /// @inheritdoc IVenueRegistar function getVenueSBTVersion() external view virtual override returns (string memory) { return _versionVenueSBT; } /// @inheritdoc IVenueRegistar function withdrawToken(address token, address to) external virtual override onlyOwner { if (to == address(0)) revert RegistarInvalidReceiver(); IERC20 erc20 = IERC20(token); erc20.transfer(to, erc20.balanceOf(address(this))); } /// @inheritdoc IVenueRegistar function withdrawETH(address receiver) external virtual override onlyOwner { (bool success, ) = receiver.call{value: address(this).balance}(""); if (!success) revert RegistarUnableToWithdrawETH(); } function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IVenueRegistar).interfaceId || super.supportsInterface(interfaceId); } receive() external payable {} }