// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.20; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; import "@openzeppelin/contracts/access/AccessControl.sol"; import "./SellTixTicketContractFactory.sol"; import "../../factories/ITicketTypeContractFactory.sol"; import "../../interfaces/ITicketTypeContract.sol"; import "../TixSellEventLibrary.sol"; contract SellTixEventContract is Ownable,ReentrancyGuard,AccessControl { bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE"); // Mapping to store multiple events mapping(string => TixSellEventLibrary.Event) public events; // Mapping to store ticket contracts per event mapping(string => address) public eventTicketContracts; // Mapping to store ticket type contracts per event mapping(string => address) public eventTicketTypeContracts; // Track all event IDs string[] public eventIds; // Per event mappings mapping(string => mapping(uint256 => uint256)) public ticketTypesNbTicketMinted; mapping(string => mapping(uint256 => uint256[])) public listOfTicketForTicketType; address[] public admins; // Events event EventCreated(string eventId, string name); constructor(address[] memory _admins) Ownable(msg.sender) { for (uint256 i = 0; i < _admins.length; ++i) { _grantRole(ADMIN_ROLE, _admins[i]); _grantRole(DEFAULT_ADMIN_ROLE, _admins[i]); } admins = _admins; } modifier onlyAdmin() { bool isEventTicketContract = false; for(uint i = 0; i < eventIds.length; i++) { if(eventTicketContracts[eventIds[i]] == msg.sender) { isEventTicketContract = true; break; } } require(msg.sender == owner() || hasRole(ADMIN_ROLE, msg.sender) || isEventTicketContract, "Only admins can do that"); _; } function createEvent( string memory _eventId, address _organizerAddress, address _ticketFactoryAddress, address _ticketTypeFactoryAddress, TixSellEventLibrary.Event memory _eDta, address _tixSellpaymentSplitter, address _organizerEventPaymentSplitter, address _resellPaiementSplitter, address _dataFeedEURUSD, address _nftTemplateAddress, address _ticketReservationFactoryAddress ) external onlyAdmin { require(events[_eventId].eventDate == 0, "Event ID already exists"); require(_eDta.eventDate > block.timestamp, "Event is in the past"); require(_eDta.duration > 0, "Duration >0 expected"); events[_eventId] = _eDta; eventIds.push(_eventId); // deploy ticket SellTixTicketContractFactory ticketContractFactory = SellTixTicketContractFactory(_ticketFactoryAddress); eventTicketContracts[_eventId] = ticketContractFactory.deployTicketContractForEvent(admins,_eventId, _organizerAddress, _tixSellpaymentSplitter, _organizerEventPaymentSplitter, _resellPaiementSplitter, _dataFeedEURUSD, address(this),_eDta.name,_nftTemplateAddress,_ticketReservationFactoryAddress,_eDta.royalty); // Deploy ticket Type ITicketTypeContractFactory ticketTypeContractFactory = ITicketTypeContractFactory(_ticketTypeFactoryAddress); eventTicketTypeContracts[_eventId] = ticketTypeContractFactory.deployTicketTypeContractForEvent(admins,_organizerAddress,address(this)); emit EventCreated(_eventId,_eDta.name); } function createTicketType( string memory eventId,TixSellLibrary.TicketType memory _ticketTypeData) external onlyAdmin returns (uint256 _ticketTypeId) { require(events[eventId].eventDate != 0, "Event does not exist"); uint256 ticketTypeId = ITicketTypeContract(eventTicketTypeContracts[eventId]) .createTicketType(events[eventId].eventDate, events[eventId].openBookings, _ticketTypeData); ticketTypesNbTicketMinted[eventId][ticketTypeId] = 0; return ticketTypeId; } function bulkCreateTicketType(string memory eventId,TixSellLibrary.TicketType[] memory _ticketsType) external onlyAdmin { require(events[eventId].eventDate != 0, "Event does not exist"); for (uint256 i = 0; i < _ticketsType.length; i++) { uint256 ticketTypeId = ITicketTypeContract(eventTicketTypeContracts[eventId]) .createTicketType(events[eventId].eventDate, events[eventId].openBookings, _ticketsType[i]); ticketTypesNbTicketMinted[eventId][ticketTypeId] = 0; } } function getTicketTypeContract(string memory _eventId) external view returns(address){ return eventTicketTypeContracts[_eventId] ; } function getTicketTypesNbMinted(string memory _eventId,uint256 _ticketTypeId) external view returns (uint256){ return ticketTypesNbTicketMinted[_eventId][_ticketTypeId]; } function getListOfTicketForTicketType(string memory _eventId,uint256 _ticketTypeId) external view returns (uint256[] memory){ return listOfTicketForTicketType[_eventId][_ticketTypeId]; } function addTicketToListOfTicketType(string memory _eventId,uint256 _ticketTypeId,uint256 _tokenId) external onlyAdmin { listOfTicketForTicketType[_eventId][_ticketTypeId].push(_tokenId); } function addTicketTypesNbTicketMinted(string memory _eventId,uint256 _ticketTypeId,uint256 amount) external onlyAdmin { ticketTypesNbTicketMinted[_eventId][_ticketTypeId] = ticketTypesNbTicketMinted[_eventId][_ticketTypeId] + amount; } function getEvent(string memory _eventId) external view returns(TixSellEventLibrary.Event memory){ return events[_eventId]; } }