diff --git a/src/event_factory/event_factory.cairo b/src/event_factory/event_factory.cairo index c1deff2..460dcd9 100644 --- a/src/event_factory/event_factory.cairo +++ b/src/event_factory/event_factory.cairo @@ -4,7 +4,7 @@ pub mod EventFactory { //*////////////////////////////////////////////////////////////////////////// // IMPORTS //////////////////////////////////////////////////////////////////////////*// - use core::{num::traits::zero::Zero, pedersen::PedersenTrait, hash::HashStateTrait,}; + use core::{num::traits::zero::Zero, pedersen::PedersenTrait, hash::HashStateTrait}; use starknet::{ ContractAddress, SyscallResultTrait, class_hash::ClassHash, get_block_timestamp, get_caller_address, get_contract_address, get_tx_info, syscalls::deploy_syscall, @@ -183,9 +183,9 @@ pub mod EventFactory { total_tickets: u256, ticket_price: u256, ) -> EventData { - let event_hash = self._gen_event_hash(event_id); - // assert caller has role - self.accesscontrol.assert_only_role(event_hash); + let main_organizer_role = self._gen_main_organizer_role(event_id); + // assert caller has main organizer role + self.accesscontrol.assert_only_role(main_organizer_role); let event = self ._update_event( @@ -205,12 +205,9 @@ pub mod EventFactory { } fn cancel_event(ref self: ContractState, event_id: u256) -> bool { - // assert if event has been created - let event_count = self.event_count.read(); - assert(event_id <= event_count, Errors::EVENT_NOT_CREATED); - - // assert caller has event role - self.accesscontrol.assert_only_role(self._gen_event_hash(event_id)); + let main_organizer_role = self._gen_main_organizer_role(event_id); + // assert caller has main organizer role + self.accesscontrol.assert_only_role(main_organizer_role); let event_canceled = self._cancel_event(event_id); @@ -218,13 +215,17 @@ pub mod EventFactory { } fn add_organizer(ref self: ContractState, event_id: u256, organizer: ContractAddress) { + let main_organizer_role = self._gen_main_organizer_role(event_id); + // assert caller has main organizer role + self.accesscontrol.assert_only_role(main_organizer_role); let event_hash = self._gen_event_hash(event_id); - self.accesscontrol.assert_only_role(event_hash); self._add_organizer(event_hash, organizer); } fn remove_organizer(ref self: ContractState, event_id: u256, organizer: ContractAddress) { + let main_organizer_role = self._gen_main_organizer_role(event_id); + // assert caller has main organizer role + self.accesscontrol.assert_only_role(main_organizer_role); let event_hash = self._gen_event_hash(event_id); - self.accesscontrol.assert_only_role(event_hash); self._remove_organizer(event_hash, organizer); } @@ -291,6 +292,13 @@ pub mod EventFactory { .finalize() } + fn _gen_main_organizer_role(self: @ContractState, event_id: u256) -> felt252 { + PedersenTrait::new(0) + .update('MAIN_ORGANIZER') + .update(self._gen_event_hash(event_id)) + .finalize() + } + fn _create_event( ref self: ContractState, name: ByteArray, @@ -309,8 +317,11 @@ pub mod EventFactory { // create event role let event_hash = self._gen_event_hash(event_count); - // grant caller event role - self.accesscontrol._grant_role(event_hash, caller); + let main_organizer_role = self._gen_main_organizer_role(event_count); + // grant caller main organizer role + self.accesscontrol._grant_role(main_organizer_role, caller); + // set main organizer role as the admin role for this event role + self.accesscontrol.set_role_admin(event_hash, main_organizer_role); // deploy ticket721 contract let event_ticket = deploy_syscall( @@ -393,6 +404,10 @@ pub mod EventFactory { } fn _cancel_event(ref self: ContractState, event_id: u256) -> bool { + // assert event has been created + let event_count = self.event_count.read(); + assert(event_id <= event_count, Errors::EVENT_NOT_CREATED); + let mut event_instance = self.events.entry(event_id).read(); // assert caller is the main event organizer assert(get_caller_address() == event_instance.organizer, Errors::NOT_EVENT_ORGANIZER); @@ -412,14 +427,14 @@ pub mod EventFactory { ref self: ContractState, event_hash: felt252, organizer: ContractAddress ) { // grant role to caller - self.accesscontrol._grant_role(event_hash, organizer); + self.accesscontrol.grant_role(event_hash, organizer); } fn _remove_organizer( ref self: ContractState, event_hash: felt252, organizer: ContractAddress ) { // revoke role from caller - self.accesscontrol._revoke_role(event_hash, organizer); + self.accesscontrol.revoke_role(event_hash, organizer); } fn _purchase_ticket(ref self: ContractState, event_id: u256) -> ContractAddress { @@ -496,33 +511,4 @@ pub mod EventFactory { tba_address } } - // #[generate_trait] -// pub impl MultiCallImpl of IMultiCallTrait { -// // Internal function to execute multiple calls -// fn _multicalls(ref self: ContractState, mut calls: Array) -> Array> { -// let mut result: Array> = ArrayTrait::new(); -// let mut calls = calls; -// let mut index = 0; - - // loop { -// match calls.pop_front() { -// Option::Some(call) => { -// match call_contract_syscall(call.to, call.selector, call.calldata) { -// Result::Ok(mut retdata) => { -// result.append(retdata); -// index += 1; -// }, -// Result::Err(err) => { -// let mut data = array!['multicall-failed', index]; -// data.append_all(err.span()); -// panic(data); -// } -// } -// }, -// Option::None(_) => { break (); } -// }; -// }; -// result -// } -// } } diff --git a/tests/test_event_factory.cairo b/tests/test_event_factory.cairo index 689036d..ed0d480 100644 --- a/tests/test_event_factory.cairo +++ b/tests/test_event_factory.cairo @@ -4,6 +4,7 @@ use snforge_std::{ declare, ContractClassTrait, DeclareResultTrait, start_cheat_caller_address, stop_cheat_caller_address }; +use core::{pedersen::PedersenTrait, hash::HashStateTrait}; use crowd_pass::{ interfaces::{ i_event_factory::{EventData, IEventFactoryDispatcher, IEventFactoryDispatcherTrait}, @@ -28,22 +29,20 @@ fn deploy_contract(name: ByteArray) -> ContractAddress { contract_address } -fn deploy_event_factory() -> ContractAddress { - let contract = declare("EventFactory").unwrap().contract_class(); - let calldata = array![ - ACCOUNT, - STRK_TOKEN_ADDR, - TICKET_NFT_CLASS_HASH, - TBA_REGISTRY_CLASS_HASH, - TBA_ACCOUNTV3_CLASS_HASH - ]; - let (event_factory_address, _) = contract.deploy(@calldata).unwrap(); +fn gen_event_hash(event_id: u256) -> felt252 { + PedersenTrait::new(0).update('CROWD_PASS_EVENT').update(event_id.try_into().unwrap()).finalize() +} - event_factory_address +fn gen_main_organizer_role(event_id: u256) -> felt252 { + PedersenTrait::new(0).update('MAIN_ORGANIZER').update(gen_event_hash(event_id)).finalize() } fn create_event() -> (ContractAddress, EventData, ITicket721Dispatcher,) { - let event_factory_address = deploy_event_factory(); + let event_factory_contract = declare("EventFactory").unwrap().contract_class(); + let calldata = array![ + ACCOUNT, TICKET_NFT_CLASS_HASH, TBA_REGISTRY_CLASS_HASH, TBA_ACCOUNTV3_CLASS_HASH + ]; + let (event_factory_address, _) = event_factory_contract.deploy(@calldata).unwrap(); let event_factory = IEventFactoryDispatcher { contract_address: event_factory_address }; start_cheat_caller_address(event_factory_address, ACCOUNT.try_into().unwrap()); @@ -102,18 +101,26 @@ fn test_cancel_event() { #[test] #[fork("SEPOLIA_LATEST")] -#[should_panic(expected: 'Caller not main organizer')] -fn test_not_main_organizer_cancel_event() { +#[should_panic(expected: 'Caller is missing role')] +fn test_fail_not_main_organizer_cancel_event() { let (event_factory_address, _, _) = create_event(); let event_factory = IEventFactoryDispatcher { contract_address: event_factory_address }; - event_factory.add_organizer(1, ACCOUNT1.try_into().unwrap()); stop_cheat_caller_address(event_factory_address); start_cheat_caller_address(event_factory_address, ACCOUNT1.try_into().unwrap()); event_factory.cancel_event(1); } + +#[test] +#[fork("SEPOLIA_LATEST")] +fn test_remove_organizer() { + let (event_factory_address, _, _) = create_event(); + let event_factory = IEventFactoryDispatcher { contract_address: event_factory_address }; + + event_factory.add_organizer(1, ACCOUNT1.try_into().unwrap()); +} // #[test] // fn test_increase_balance() { // let contract_address = deploy_contract("EventFactory");