diff --git a/contracts/Scarb.lock b/contracts/Scarb.lock index 66547a8..6d36761 100644 --- a/contracts/Scarb.lock +++ b/contracts/Scarb.lock @@ -1,15 +1,24 @@ # Code generated by scarb DO NOT EDIT. version = 1 +[[package]] +name = "achievement" +version = "0.0.0" +dependencies = [ + "dojo", +] + [[package]] name = "arcade" version = "0.0.0" dependencies = [ + "achievement", "controller", "dojo", "dojo_cairo_test", "provider", "registry", + "society", ] [[package]] @@ -53,3 +62,11 @@ version = "0.0.0" dependencies = [ "dojo", ] + +[[package]] +name = "society" +version = "0.0.0" +dependencies = [ + "dojo", + "registry", +] diff --git a/contracts/Scarb.toml b/contracts/Scarb.toml index 740ef08..a842750 100644 --- a/contracts/Scarb.toml +++ b/contracts/Scarb.toml @@ -11,9 +11,11 @@ dev = "sozo clean && sozo build --typescript && sozo migrate plan && sozo migrat [dependencies] dojo = { git = "https://github.com/dojoengine/dojo", tag = "v1.0.1" } +achievement = { path = ".." } controller = { path = ".." } provider = { path = ".." } registry = { path = ".." } +society = { path = ".." } starknet = "2.8.4" cairo_test = "2.8.4" @@ -23,16 +25,21 @@ dojo_cairo_test = { git = "https://github.com/dojoengine/dojo", tag = "v1.0.1" } [[target.starknet-contract]] build-external-contracts = [ "dojo::world::world_contract::world", + "achievement::events::index::e_TrophyPinning", "controller::models::index::m_Account", "controller::models::index::m_Controller", - "controller::models::index::m_Member", "controller::models::index::m_Signer", - "controller::models::index::m_Team", "provider::models::index::m_Deployment", "provider::models::index::m_Factory", + "provider::models::index::m_Team", + "provider::models::index::m_Teammate", "registry::models::index::m_Access", "registry::models::index::m_Achievement", "registry::models::index::m_Game", + "society::models::index::m_Alliance", + "society::models::index::m_Guild", + "society::models::index::m_Member", + "society::events::index::e_Follow", ] [profile.slot] diff --git a/contracts/src/lib.cairo b/contracts/src/lib.cairo index b490fef..fccb26b 100644 --- a/contracts/src/lib.cairo +++ b/contracts/src/lib.cairo @@ -1,7 +1,9 @@ mod constants; mod systems { + mod achievement; mod controller; mod registry; mod slot; + mod society; } diff --git a/contracts/src/systems/achievement.cairo b/contracts/src/systems/achievement.cairo new file mode 100644 index 0000000..286817d --- /dev/null +++ b/contracts/src/systems/achievement.cairo @@ -0,0 +1,74 @@ +// Interfaces + +#[starknet::interface] +trait IAchievement { + fn pin(self: @TContractState, achievement_id: felt252); + fn unpin(self: @TContractState, achievement_id: felt252); +} + +// Contracts + +#[dojo::contract] +mod Achievement { + // Dojo imports + + use dojo::world::WorldStorage; + + // Component imports + + use achievement::components::pinnable::PinnableComponent; + + // Internal imports + + use arcade::constants::NAMESPACE; + + // Local imports + + use super::IAchievement; + + // Components + + component!(path: PinnableComponent, storage: pinnable, event: PinnableEvent); + impl PinnableInternalImpl = PinnableComponent::InternalImpl; + + // Storage + + #[storage] + struct Storage { + #[substorage(v0)] + pinnable: PinnableComponent::Storage, + } + + // Events + + #[event] + #[derive(Drop, starknet::Event)] + enum Event { + #[flat] + PinnableEvent: PinnableComponent::Event, + } + + // Implementations + + #[abi(embed_v0)] + impl AchievementImpl of IAchievement { + fn pin(self: @ContractState, achievement_id: felt252) { + let world: WorldStorage = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.pinnable.pin(world, caller, achievement_id); + } + + fn unpin(self: @ContractState, achievement_id: felt252) { + let world: WorldStorage = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.pinnable.unpin(world, caller, achievement_id); + } + } + + #[generate_trait] + impl Private of PrivateTrait { + fn world_storage(self: @ContractState) -> WorldStorage { + self.world(@NAMESPACE()) + } + } +} diff --git a/contracts/src/systems/registry.cairo b/contracts/src/systems/registry.cairo index ae091ea..51b7dcb 100644 --- a/contracts/src/systems/registry.cairo +++ b/contracts/src/systems/registry.cairo @@ -151,10 +151,13 @@ mod Registry { youtube: Option, website: Option, ) { + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); self .registerable .register( - self.world_storage(), + world, + caller, world_address, namespace, project, @@ -186,10 +189,13 @@ mod Registry { youtube: Option, website: Option, ) { + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); self .registerable .update( - self.world_storage(), + world, + caller, world_address, namespace, color, @@ -206,23 +212,33 @@ mod Registry { } fn publish_game(self: @ContractState, world_address: felt252, namespace: felt252) { - self.registerable.publish(self.world_storage(), world_address, namespace); + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.registerable.publish(world, caller, world_address, namespace); } fn hide_game(self: @ContractState, world_address: felt252, namespace: felt252) { - self.registerable.hide(self.world_storage(), world_address, namespace); + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.registerable.hide(world, caller, world_address, namespace); } fn whitelist_game(self: @ContractState, world_address: felt252, namespace: felt252) { - self.registerable.whitelist(self.world_storage(), world_address, namespace); + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.registerable.whitelist(world, caller, world_address, namespace); } fn blacklist_game(self: @ContractState, world_address: felt252, namespace: felt252) { - self.registerable.blacklist(self.world_storage(), world_address, namespace); + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.registerable.blacklist(world, caller, world_address, namespace); } fn remove_game(self: @ContractState, world_address: felt252, namespace: felt252) { - self.registerable.remove(self.world_storage(), world_address, namespace); + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.registerable.remove(world, caller, world_address, namespace); } fn register_achievement( @@ -232,9 +248,9 @@ mod Registry { identifier: felt252, karma: u16, ) { - self - .trackable - .register(self.world_storage(), world_address, namespace, identifier, karma) + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.trackable.register(world, caller, world_address, namespace, identifier, karma) } fn update_achievement( @@ -244,37 +260,49 @@ mod Registry { identifier: felt252, karma: u16, ) { - self.trackable.update(self.world_storage(), world_address, namespace, identifier, karma) + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.trackable.update(world, caller, world_address, namespace, identifier, karma) } fn publish_achievement( self: @ContractState, world_address: felt252, namespace: felt252, identifier: felt252 ) { - self.trackable.publish(self.world_storage(), world_address, namespace, identifier); + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.trackable.publish(world, caller, world_address, namespace, identifier); } fn hide_achievement( self: @ContractState, world_address: felt252, namespace: felt252, identifier: felt252 ) { - self.trackable.hide(self.world_storage(), world_address, namespace, identifier); + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.trackable.hide(world, caller, world_address, namespace, identifier); } fn whitelist_achievement( self: @ContractState, world_address: felt252, namespace: felt252, identifier: felt252 ) { - self.trackable.whitelist(self.world_storage(), world_address, namespace, identifier); + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.trackable.whitelist(world, caller, world_address, namespace, identifier); } fn blacklist_achievement( self: @ContractState, world_address: felt252, namespace: felt252, identifier: felt252 ) { - self.trackable.blacklist(self.world_storage(), world_address, namespace, identifier); + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.trackable.blacklist(world, caller, world_address, namespace, identifier); } fn remove_achievement( self: @ContractState, world_address: felt252, namespace: felt252, identifier: felt252 ) { - self.trackable.remove(self.world_storage(), world_address, namespace, identifier); + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.trackable.remove(world, caller, world_address, namespace, identifier); } } diff --git a/contracts/src/systems/slot.cairo b/contracts/src/systems/slot.cairo index 7a28021..dcac7b6 100644 --- a/contracts/src/systems/slot.cairo +++ b/contracts/src/systems/slot.cairo @@ -56,12 +56,14 @@ mod Slot { impl SlotImpl of ISlot { fn deploy(self: @ContractState, service: u8, project: felt252, tier: u8,) { let world = self.world_storage(); - self.deployable.deploy(world, service.into(), project, tier.into()) + let caller: felt252 = starknet::get_caller_address().into(); + self.deployable.deploy(world, caller, service.into(), project, tier.into()) } fn remove(self: @ContractState, service: u8, project: felt252,) { let world = self.world_storage(); - self.deployable.remove(world, service.into(), project); + let caller: felt252 = starknet::get_caller_address().into(); + self.deployable.remove(world, caller, service.into(), project); } } diff --git a/contracts/src/systems/society.cairo b/contracts/src/systems/society.cairo new file mode 100644 index 0000000..f665e2d --- /dev/null +++ b/contracts/src/systems/society.cairo @@ -0,0 +1,310 @@ +// Interfaces + +#[starknet::interface] +trait ISociety { + fn follow(self: @TContractState, target: felt252,); + fn unfollow(self: @TContractState, target: felt252,); + fn create_alliance( + self: @TContractState, + color: Option, + name: Option, + description: Option, + image: Option, + banner: Option, + discord: Option, + telegram: Option, + twitter: Option, + youtube: Option, + website: Option + ); + fn open_alliance(self: @TContractState, free: bool); + fn close_alliance(self: @TContractState); + fn crown_guild(self: @TContractState, guild_id: u32); + fn hire_guild(self: @TContractState, guild_id: u32); + fn fire_guild(self: @TContractState, guild_id: u32); + fn request_alliance(self: @TContractState, alliance_id: u32); + fn cancel_alliance(self: @TContractState); + fn leave_alliance(self: @TContractState); + fn create_guild( + self: @TContractState, + color: Option, + name: Option, + description: Option, + image: Option, + banner: Option, + discord: Option, + telegram: Option, + twitter: Option, + youtube: Option, + website: Option + ); + fn open_guild(self: @TContractState, free: bool); + fn close_guild(self: @TContractState); + fn crown_member(self: @TContractState, member_id: felt252); + fn promote_member(self: @TContractState, member_id: felt252); + fn demote_member(self: @TContractState, member_id: felt252); + fn hire_member(self: @TContractState, member_id: felt252); + fn fire_member(self: @TContractState, member_id: felt252); + fn request_guild(self: @TContractState, guild_id: u32); + fn cancel_guild(self: @TContractState); + fn leave_guild(self: @TContractState); +} + +// Contracts + +#[dojo::contract] +mod Society { + // Dojo imports + + use dojo::world::WorldStorage; + + // Component imports + + use society::components::allianceable::AllianceableComponent; + use society::components::followable::FollowableComponent; + use society::components::guildable::GuildableComponent; + + // Internal imports + + use arcade::constants::NAMESPACE; + + // Local imports + + use super::ISociety; + + // Components + + component!(path: AllianceableComponent, storage: allianceable, event: AllianceableEvent); + impl AllianceableImpl = AllianceableComponent::InternalImpl; + component!(path: FollowableComponent, storage: followable, event: FollowableEvent); + impl FollowableImpl = FollowableComponent::InternalImpl; + component!(path: GuildableComponent, storage: guildable, event: GuildableEvent); + impl GuildableImpl = GuildableComponent::InternalImpl; + + // Storage + + #[storage] + struct Storage { + #[substorage(v0)] + allianceable: AllianceableComponent::Storage, + #[substorage(v0)] + followable: FollowableComponent::Storage, + #[substorage(v0)] + guildable: GuildableComponent::Storage, + } + + // Events + + #[event] + #[derive(Drop, starknet::Event)] + enum Event { + #[flat] + AllianceableEvent: AllianceableComponent::Event, + #[flat] + FollowableEvent: FollowableComponent::Event, + #[flat] + GuildableEvent: GuildableComponent::Event, + } + + // Implementations + + #[abi(embed_v0)] + impl SocietyImpl of ISociety { + fn follow(self: @ContractState, target: felt252) { + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.followable.follow(world, caller, target); + } + + fn unfollow(self: @ContractState, target: felt252) { + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.followable.unfollow(world, caller, target); + } + + // Alliance + + fn create_alliance( + self: @ContractState, + color: Option, + name: Option, + description: Option, + image: Option, + banner: Option, + discord: Option, + telegram: Option, + twitter: Option, + youtube: Option, + website: Option, + ) { + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self + .allianceable + .create( + world, + caller, + color, + name, + description, + image, + banner, + discord, + telegram, + twitter, + youtube, + website + ); + } + + fn open_alliance(self: @ContractState, free: bool) { + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.allianceable.open(world, caller, free); + } + + fn close_alliance(self: @ContractState) { + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.allianceable.close(world, caller); + } + + fn crown_guild(self: @ContractState, guild_id: u32) { + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.allianceable.crown(world, caller, guild_id); + } + + fn hire_guild(self: @ContractState, guild_id: u32) { + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.allianceable.hire(world, caller, guild_id); + } + + fn fire_guild(self: @ContractState, guild_id: u32) { + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.allianceable.fire(world, caller, guild_id); + } + + fn request_alliance(self: @ContractState, alliance_id: u32) { + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.allianceable.request(world, caller, alliance_id); + } + + fn cancel_alliance(self: @ContractState) { + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.allianceable.cancel(world, caller); + } + + fn leave_alliance(self: @ContractState) { + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.allianceable.leave(world, caller); + } + + // Guild + + fn create_guild( + self: @ContractState, + color: Option, + name: Option, + description: Option, + image: Option, + banner: Option, + discord: Option, + telegram: Option, + twitter: Option, + youtube: Option, + website: Option, + ) { + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self + .guildable + .create( + world, + caller, + color, + name, + description, + image, + banner, + discord, + telegram, + twitter, + youtube, + website + ); + } + + fn open_guild(self: @ContractState, free: bool) { + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.guildable.open(world, caller, free); + } + + fn close_guild(self: @ContractState) { + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.guildable.close(world, caller); + } + + fn crown_member(self: @ContractState, member_id: felt252) { + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.guildable.crown(world, caller, member_id); + } + + fn promote_member(self: @ContractState, member_id: felt252) { + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.guildable.promote(world, caller, member_id); + } + + fn demote_member(self: @ContractState, member_id: felt252) { + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.guildable.demote(world, caller, member_id); + } + + fn hire_member(self: @ContractState, member_id: felt252) { + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.guildable.hire(world, caller, member_id); + } + + fn fire_member(self: @ContractState, member_id: felt252) { + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.guildable.fire(world, caller, member_id); + } + + fn request_guild(self: @ContractState, guild_id: u32) { + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.guildable.request(world, caller, guild_id); + } + + fn cancel_guild(self: @ContractState) { + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.guildable.cancel(world, caller); + } + + fn leave_guild(self: @ContractState) { + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.guildable.leave(world, caller); + } + } + + #[generate_trait] + impl Private of PrivateTrait { + fn world_storage(self: @ContractState) -> WorldStorage { + self.world(@NAMESPACE()) + } + } +} diff --git a/packages/controller/src/models/account.cairo b/packages/controller/src/models/account.cairo index 0029ae7..683fc54 100644 --- a/packages/controller/src/models/account.cairo +++ b/packages/controller/src/models/account.cairo @@ -67,7 +67,7 @@ mod tests { const USERNAME: felt252 = 'USERNAME'; #[test] - fn test_deployment_new() { + fn test_account_new() { let account = AccountTrait::new(IDENTIFIER, 0, 'NAME', USERNAME, "{}"); assert_eq!(account.id, IDENTIFIER); assert_eq!(account.controllers, 0); @@ -78,14 +78,14 @@ mod tests { } #[test] - fn test_deployment_assert_does_exist() { + fn test_account_assert_does_exist() { let account = AccountTrait::new(IDENTIFIER, 0, 'NAME', USERNAME, "{}"); account.assert_does_exist(); } #[test] #[should_panic(expected: 'Account: already exists')] - fn test_deployment_revert_already_exists() { + fn test_account_revert_already_exists() { let account = AccountTrait::new(IDENTIFIER, 0, 'NAME', USERNAME, "{}"); account.assert_does_not_exist(); } diff --git a/packages/controller/src/models/controller.cairo b/packages/controller/src/models/controller.cairo index e47bf02..590759c 100644 --- a/packages/controller/src/models/controller.cairo +++ b/packages/controller/src/models/controller.cairo @@ -96,7 +96,7 @@ mod tests { const NETWORK: felt252 = 'NETWORK'; #[test] - fn test_deployment_new() { + fn test_controller_new() { let controller = ControllerTrait::new( ACCOUNT_ID, IDENTIFIER, SIGNERS, ADDRESS, NETWORK, "" ); @@ -109,7 +109,7 @@ mod tests { } #[test] - fn test_deployment_assert_does_exist() { + fn test_controller_assert_does_exist() { let controller = ControllerTrait::new( ACCOUNT_ID, IDENTIFIER, SIGNERS, ADDRESS, NETWORK, "" ); @@ -118,7 +118,7 @@ mod tests { #[test] #[should_panic(expected: 'Controller: already exists')] - fn test_deployment_revert_already_exists() { + fn test_controller_revert_already_exists() { let controller = ControllerTrait::new( ACCOUNT_ID, IDENTIFIER, SIGNERS, ADDRESS, NETWORK, "" ); @@ -127,31 +127,31 @@ mod tests { #[test] #[should_panic(expected: 'Controller: invalid account id')] - fn test_deployment_revert_invalid_account_id() { + fn test_controller_revert_invalid_account_id() { ControllerTrait::new(0, IDENTIFIER, SIGNERS, ADDRESS, NETWORK, ""); } #[test] #[should_panic(expected: 'Controller: invalid identifier')] - fn test_deployment_revert_invalid_identifier() { + fn test_controller_revert_invalid_identifier() { ControllerTrait::new(ACCOUNT_ID, 0, SIGNERS, ADDRESS, NETWORK, ""); } #[test] #[should_panic(expected: 'Controller: invalid signers')] - fn test_deployment_revert_invalid_signers() { + fn test_controller_revert_invalid_signers() { ControllerTrait::new(ACCOUNT_ID, IDENTIFIER, 0, ADDRESS, NETWORK, ""); } #[test] #[should_panic(expected: 'Controller: invalid address')] - fn test_deployment_revert_invalid_address() { + fn test_controller_revert_invalid_address() { ControllerTrait::new(ACCOUNT_ID, IDENTIFIER, SIGNERS, 0, NETWORK, ""); } #[test] #[should_panic(expected: 'Controller: invalid network')] - fn test_deployment_revert_invalid_network() { + fn test_controller_revert_invalid_network() { ControllerTrait::new(ACCOUNT_ID, IDENTIFIER, SIGNERS, ADDRESS, 0, ""); } } diff --git a/packages/controller/src/models/signer.cairo b/packages/controller/src/models/signer.cairo index 59b7802..a6c213c 100644 --- a/packages/controller/src/models/signer.cairo +++ b/packages/controller/src/models/signer.cairo @@ -77,7 +77,7 @@ mod tests { const METHOD: Method = Method::StarknetAccount; #[test] - fn test_deployment_new() { + fn test_signer_new() { let signer = SignerTrait::new(ACCOUNT_ID, CONTROLLER_ID, METHOD, ""); assert_eq!(signer.account_id, ACCOUNT_ID); assert_eq!(signer.controller_id, CONTROLLER_ID); @@ -86,33 +86,33 @@ mod tests { } #[test] - fn test_deployment_assert_does_exist() { + fn test_signer_assert_does_exist() { let signer = SignerTrait::new(ACCOUNT_ID, CONTROLLER_ID, METHOD, ""); signer.assert_does_exist(); } #[test] #[should_panic(expected: 'Signer: already exists')] - fn test_deployment_revert_already_exists() { + fn test_signer_revert_already_exists() { let signer = SignerTrait::new(ACCOUNT_ID, CONTROLLER_ID, METHOD, ""); signer.assert_does_not_exist(); } #[test] #[should_panic(expected: 'Signer: invalid account id')] - fn test_deployment_revert_invalid_account_id() { + fn test_signer_revert_invalid_account_id() { SignerTrait::new(0, CONTROLLER_ID, METHOD, ""); } #[test] #[should_panic(expected: 'Signer: invalid controller id')] - fn test_deployment_revert_invalid_controller_id() { + fn test_signer_revert_invalid_controller_id() { SignerTrait::new(ACCOUNT_ID, 0, METHOD, ""); } #[test] #[should_panic(expected: 'Signer: invalid method')] - fn test_deployment_revert_invalid_method() { + fn test_signer_revert_invalid_method() { SignerTrait::new(ACCOUNT_ID, CONTROLLER_ID, Method::None, ""); } } diff --git a/packages/provider/src/components/deployable.cairo b/packages/provider/src/components/deployable.cairo index de04cdd..4cd0d47 100644 --- a/packages/provider/src/components/deployable.cairo +++ b/packages/provider/src/components/deployable.cairo @@ -48,6 +48,7 @@ mod DeployableComponent { fn deploy( self: @ComponentState, world: WorldStorage, + caller_id: felt252, service: Service, project: felt252, tier: Tier, @@ -64,11 +65,10 @@ mod DeployableComponent { deployment.assert_does_not_exist(); // [Check] Caller permission - let account_id: felt252 = starknet::get_caller_address().into(); let mut team = store.get_team(project); if team.exists() { // [Check] Caller is at least an admin - let teammate = store.get_teammate(project, team.time, account_id); + let teammate = store.get_teammate(project, team.time, caller_id); teammate.assert_is_allowed(Role::Admin); // [Effect] Increment deployment count team.deploy(); @@ -80,7 +80,7 @@ mod DeployableComponent { team.deploy(); store.set_team(@team); // [Effect] Create teammate - let teammate = TeammateTrait::new(project, time, account_id, Role::Owner); + let teammate = TeammateTrait::new(project, time, caller_id, Role::Owner); store.set_teammate(@teammate); } @@ -94,6 +94,7 @@ mod DeployableComponent { fn remove( self: @ComponentState, world: WorldStorage, + caller_id: felt252, service: Service, project: felt252, ) { @@ -113,8 +114,7 @@ mod DeployableComponent { team.assert_does_exist(); // [Check] Caller is at least admin - let account_id: felt252 = starknet::get_caller_address().into(); - let teammate = store.get_teammate(project, team.time, account_id); + let teammate = store.get_teammate(project, team.time, caller_id); teammate.assert_is_allowed(Role::Admin); // [Effect] Delete deployment diff --git a/packages/provider/src/components/groupable.cairo b/packages/provider/src/components/groupable.cairo index ccda4bd..d7af41b 100644 --- a/packages/provider/src/components/groupable.cairo +++ b/packages/provider/src/components/groupable.cairo @@ -29,6 +29,7 @@ mod GroupableComponent { fn add( self: @ComponentState, world: WorldStorage, + caller_id: felt252, name: felt252, account_id: felt252, role: Role, @@ -41,7 +42,6 @@ mod GroupableComponent { team.assert_does_exist(); // [Check] Caller is at least admin - let caller_id: felt252 = starknet::get_caller_address().into(); let callermate = store.get_teammate(name, team.time, caller_id); callermate.assert_is_allowed(Role::Admin); @@ -57,6 +57,7 @@ mod GroupableComponent { fn remove( self: @ComponentState, world: WorldStorage, + caller_id: felt252, name: felt252, account_id: felt252, ) { @@ -68,7 +69,6 @@ mod GroupableComponent { team.assert_does_exist(); // [Check] Caller is at least admin - let caller_id: felt252 = starknet::get_caller_address().into(); let callermate = store.get_teammate(name, team.time, caller_id); callermate.assert_is_allowed(Role::Admin); diff --git a/packages/provider/src/models/team.cairo b/packages/provider/src/models/team.cairo index 211f4a6..07c0d18 100644 --- a/packages/provider/src/models/team.cairo +++ b/packages/provider/src/models/team.cairo @@ -88,7 +88,7 @@ mod tests { const TIME: u64 = 1; #[test] - fn test_deployment_new() { + fn test_team_new() { let team = TeamTrait::new(IDENTIFIER, TIME, NAME, ""); assert_eq!(team.id, IDENTIFIER); assert_eq!(team.time, TIME); @@ -97,14 +97,14 @@ mod tests { } #[test] - fn test_deployment_assert_does_exist() { + fn test_team_assert_does_exist() { let team = TeamTrait::new(IDENTIFIER, TIME, NAME, ""); team.assert_does_exist(); } #[test] #[should_panic(expected: 'Team: already exists')] - fn test_deployment_revert_already_exists() { + fn test_team_revert_already_exists() { let team = TeamTrait::new(IDENTIFIER, TIME, NAME, ""); team.assert_does_not_exist(); } diff --git a/packages/provider/src/models/teammate.cairo b/packages/provider/src/models/teammate.cairo index ac06f91..9716acf 100644 --- a/packages/provider/src/models/teammate.cairo +++ b/packages/provider/src/models/teammate.cairo @@ -92,7 +92,7 @@ mod tests { const ROLE: Role = Role::Admin; #[test] - fn test_deployment_new() { + fn test_teammate_new() { let member = TeammateTrait::new(TEAM_ID, TIME, ACCOUNT_ID, ROLE); assert_eq!(member.account_id, ACCOUNT_ID); assert_eq!(member.team_id, TEAM_ID); @@ -100,21 +100,21 @@ mod tests { } #[test] - fn test_deployment_assert_does_exist() { + fn test_teammate_assert_does_exist() { let member = TeammateTrait::new(TEAM_ID, TIME, ACCOUNT_ID, ROLE); member.assert_does_exist(); } #[test] #[should_panic(expected: 'Teammate: already exists')] - fn test_deployment_revert_already_exists() { + fn test_teammate_revert_already_exists() { let member = TeammateTrait::new(TEAM_ID, TIME, ACCOUNT_ID, ROLE); member.assert_does_not_exist(); } #[test] #[should_panic(expected: 'Teammate: invalid role')] - fn test_deployment_revert_invalid_role() { + fn test_teammate_revert_invalid_role() { TeammateTrait::new(TEAM_ID, TIME, ACCOUNT_ID, Role::None); } } diff --git a/packages/registry/src/components/registerable.cairo b/packages/registry/src/components/registerable.cairo index 56ed296..89e9521 100644 --- a/packages/registry/src/components/registerable.cairo +++ b/packages/registry/src/components/registerable.cairo @@ -31,6 +31,7 @@ mod RegisterableComponent { fn register( self: @ComponentState, world: WorldStorage, + caller_id: felt252, world_address: felt252, namespace: felt252, project: felt252, @@ -55,8 +56,9 @@ mod RegisterableComponent { // [Effect] Create game let metadata = MetadataTrait::new(color, name, description, image, banner); let socials = SocialsTrait::new(discord, telegram, twitter, youtube, website); - let owner: felt252 = starknet::get_caller_address().into(); - let game = GameTrait::new(world_address, namespace, project, metadata, socials, owner); + let game = GameTrait::new( + world_address, namespace, project, metadata, socials, caller_id + ); // [Effect] Store game store.set_game(@game); @@ -65,6 +67,7 @@ mod RegisterableComponent { fn update( self: @ComponentState, world: WorldStorage, + caller_id: felt252, world_address: felt252, namespace: felt252, color: Option, @@ -86,7 +89,7 @@ mod RegisterableComponent { game.assert_does_exist(); // [Check] Caller is owner - game.assert_is_owner(starknet::get_caller_address().into()); + game.assert_is_owner(caller_id); // [Effect] Update game let metadata = MetadataTrait::new(color, name, description, image, banner); @@ -100,6 +103,7 @@ mod RegisterableComponent { fn publish( self: @ComponentState, world: WorldStorage, + caller_id: felt252, world_address: felt252, namespace: felt252, ) { @@ -111,7 +115,7 @@ mod RegisterableComponent { game.assert_does_exist(); // [Check] Caller is owner - game.assert_is_owner(starknet::get_caller_address().into()); + game.assert_is_owner(caller_id); // [Effect] Publish game game.publish(); @@ -123,6 +127,7 @@ mod RegisterableComponent { fn hide( self: @ComponentState, world: WorldStorage, + caller_id: felt252, world_address: felt252, namespace: felt252, ) { @@ -134,7 +139,7 @@ mod RegisterableComponent { game.assert_does_exist(); // [Check] Caller is owner - game.assert_is_owner(starknet::get_caller_address().into()); + game.assert_is_owner(caller_id); // [Effect] Hide game game.hide(); @@ -146,6 +151,7 @@ mod RegisterableComponent { fn whitelist( self: @ComponentState, world: WorldStorage, + caller_id: felt252, world_address: felt252, namespace: felt252, ) { @@ -153,8 +159,7 @@ mod RegisterableComponent { let mut store: Store = StoreTrait::new(world); // [Check] Caller is allowed - let caller = starknet::get_caller_address().into(); - let access = store.get_access(caller); + let access = store.get_access(caller_id); access.assert_is_allowed(Role::Admin); // [Check] Game exists @@ -171,6 +176,7 @@ mod RegisterableComponent { fn blacklist( self: @ComponentState, world: WorldStorage, + caller_id: felt252, world_address: felt252, namespace: felt252, ) { @@ -178,8 +184,7 @@ mod RegisterableComponent { let mut store: Store = StoreTrait::new(world); // [Check] Caller is allowed - let caller = starknet::get_caller_address().into(); - let access = store.get_access(caller); + let access = store.get_access(caller_id); access.assert_is_allowed(Role::Admin); // [Check] Game exists @@ -196,6 +201,7 @@ mod RegisterableComponent { fn remove( self: @ComponentState, world: WorldStorage, + caller_id: felt252, world_address: felt252, namespace: felt252, ) { @@ -206,6 +212,9 @@ mod RegisterableComponent { let mut game = store.get_game(world_address, namespace); game.assert_does_exist(); + // [Check] Caller is owner + game.assert_is_owner(caller_id); + // [Effect] Remove game game.nullify(); diff --git a/packages/registry/src/components/trackable.cairo b/packages/registry/src/components/trackable.cairo index 3bb1ddd..65ddbc8 100644 --- a/packages/registry/src/components/trackable.cairo +++ b/packages/registry/src/components/trackable.cairo @@ -30,6 +30,7 @@ mod TrackableComponent { fn register( self: @ComponentState, world: WorldStorage, + caller_id: felt252, world_address: felt252, namespace: felt252, identifier: felt252, @@ -43,7 +44,7 @@ mod TrackableComponent { game.assert_does_exist(); // [Check] Caller is owner - game.assert_is_owner(starknet::get_caller_address().into()); + game.assert_is_owner(caller_id); // [Check] Achievement does not exist let achievement = store.get_achievement(world_address, namespace, identifier); @@ -63,6 +64,7 @@ mod TrackableComponent { fn update( self: @ComponentState, world: WorldStorage, + caller_id: felt252, world_address: felt252, namespace: felt252, identifier: felt252, @@ -76,7 +78,7 @@ mod TrackableComponent { game.assert_does_exist(); // [Check] Caller is owner - game.assert_is_owner(starknet::get_caller_address().into()); + game.assert_is_owner(caller_id); // [Check] Achievement exists let mut achievement = store.get_achievement(world_address, namespace, identifier); @@ -95,6 +97,7 @@ mod TrackableComponent { fn publish( self: @ComponentState, world: WorldStorage, + caller_id: felt252, world_address: felt252, namespace: felt252, identifier: felt252, @@ -107,7 +110,7 @@ mod TrackableComponent { game.assert_does_exist(); // [Check] Caller is owner - game.assert_is_owner(starknet::get_caller_address().into()); + game.assert_is_owner(caller_id); // [Check] Achievement exists let mut achievement = store.get_achievement(world_address, namespace, identifier); @@ -123,6 +126,7 @@ mod TrackableComponent { fn hide( self: @ComponentState, world: WorldStorage, + caller_id: felt252, world_address: felt252, namespace: felt252, identifier: felt252, @@ -135,7 +139,7 @@ mod TrackableComponent { game.assert_does_exist(); // [Check] Caller is owner - game.assert_is_owner(starknet::get_caller_address().into()); + game.assert_is_owner(caller_id); // [Check] Achievement exists let mut achievement = store.get_achievement(world_address, namespace, identifier); @@ -151,6 +155,7 @@ mod TrackableComponent { fn whitelist( self: @ComponentState, world: WorldStorage, + caller_id: felt252, world_address: felt252, namespace: felt252, identifier: felt252, @@ -159,8 +164,7 @@ mod TrackableComponent { let mut store: Store = StoreTrait::new(world); // [Check] Caller is allowed - let caller = starknet::get_caller_address().into(); - let access = store.get_access(caller); + let access = store.get_access(caller_id); access.assert_is_allowed(Role::Admin); // [Check] Game exists @@ -181,6 +185,7 @@ mod TrackableComponent { fn blacklist( self: @ComponentState, world: WorldStorage, + caller_id: felt252, world_address: felt252, namespace: felt252, identifier: felt252, @@ -189,8 +194,7 @@ mod TrackableComponent { let mut store: Store = StoreTrait::new(world); // [Check] Caller is allowed - let caller = starknet::get_caller_address().into(); - let access = store.get_access(caller); + let access = store.get_access(caller_id); access.assert_is_allowed(Role::Admin); // [Check] Game exists @@ -211,6 +215,7 @@ mod TrackableComponent { fn remove( self: @ComponentState, world: WorldStorage, + caller_id: felt252, world_address: felt252, namespace: felt252, identifier: felt252, @@ -222,6 +227,9 @@ mod TrackableComponent { let mut game = store.get_game(world_address, namespace); game.assert_does_exist(); + // [Check] Caller is owner + game.assert_is_owner(caller_id); + // [Check] Achievement exists let mut achievement = store.get_achievement(world_address, namespace, identifier); achievement.assert_does_exist(); diff --git a/packages/registry/src/tests/mocks/register.cairo b/packages/registry/src/tests/mocks/register.cairo index 32722fa..2dd246c 100644 --- a/packages/registry/src/tests/mocks/register.cairo +++ b/packages/registry/src/tests/mocks/register.cairo @@ -103,10 +103,13 @@ pub mod Register { youtube: Option, website: Option, ) { + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); self .registerable .register( - self.world_storage(), + world, + caller, world_address, namespace, project, @@ -119,7 +122,7 @@ pub mod Register { telegram, twitter, youtube, - website, + website ); } @@ -138,10 +141,13 @@ pub mod Register { youtube: Option, website: Option, ) { + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); self .registerable .update( - self.world_storage(), + world, + caller, world_address, namespace, color, @@ -158,19 +164,27 @@ pub mod Register { } fn publish(self: @ContractState, world_address: felt252, namespace: felt252) { - self.registerable.publish(self.world_storage(), world_address, namespace); + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.registerable.publish(world, caller, world_address, namespace); } fn hide(self: @ContractState, world_address: felt252, namespace: felt252) { - self.registerable.hide(self.world_storage(), world_address, namespace); + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.registerable.hide(world, caller, world_address, namespace); } fn whitelist(self: @ContractState, world_address: felt252, namespace: felt252) { - self.registerable.whitelist(self.world_storage(), world_address, namespace); + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.registerable.whitelist(world, caller, world_address, namespace); } fn blacklist(self: @ContractState, world_address: felt252, namespace: felt252) { - self.registerable.blacklist(self.world_storage(), world_address, namespace); + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.registerable.blacklist(world, caller, world_address, namespace); } } diff --git a/packages/registry/src/tests/mocks/tracker.cairo b/packages/registry/src/tests/mocks/tracker.cairo index cc6a57c..cc6c875 100644 --- a/packages/registry/src/tests/mocks/tracker.cairo +++ b/packages/registry/src/tests/mocks/tracker.cairo @@ -83,9 +83,9 @@ pub mod Tracker { identifier: felt252, karma: u16, ) { - self - .trackable - .register(self.world_storage(), world_address, namespace, identifier, karma); + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.trackable.register(world, caller, world_address, namespace, identifier, karma); } fn update( @@ -95,33 +95,41 @@ pub mod Tracker { identifier: felt252, karma: u16, ) { - self - .trackable - .update(self.world_storage(), world_address, namespace, identifier, karma); + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.trackable.update(world, caller, world_address, namespace, identifier, karma); } fn publish( self: @ContractState, world_address: felt252, namespace: felt252, identifier: felt252 ) { - self.trackable.publish(self.world_storage(), world_address, namespace, identifier); + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.trackable.publish(world, caller, world_address, namespace, identifier); } fn hide( self: @ContractState, world_address: felt252, namespace: felt252, identifier: felt252 ) { - self.trackable.hide(self.world_storage(), world_address, namespace, identifier); + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.trackable.hide(world, caller, world_address, namespace, identifier); } fn whitelist( self: @ContractState, world_address: felt252, namespace: felt252, identifier: felt252 ) { - self.trackable.whitelist(self.world_storage(), world_address, namespace, identifier); + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.trackable.whitelist(world, caller, world_address, namespace, identifier); } fn blacklist( self: @ContractState, world_address: felt252, namespace: felt252, identifier: felt252 ) { - self.trackable.blacklist(self.world_storage(), world_address, namespace, identifier); + let world = self.world_storage(); + let caller: felt252 = starknet::get_caller_address().into(); + self.trackable.blacklist(world, caller, world_address, namespace, identifier); } }