diff --git a/Scarb.lock b/Scarb.lock index 1e856d6..dbde4a1 100644 --- a/Scarb.lock +++ b/Scarb.lock @@ -58,6 +58,7 @@ dependencies = [ "openzeppelin_access", "openzeppelin_introspection", "openzeppelin_token", + "openzeppelin_upgrades", "snforge_std", "token_bound_accounts", ] @@ -109,6 +110,12 @@ dependencies = [ "openzeppelin_introspection", ] +[[package]] +name = "openzeppelin_upgrades" +version = "0.17.0" +source = "registry+https://scarbs.xyz/" +checksum = "sha256:a0fa5934f2924e1e85ec8f8c5b7dcd95c25295c029d3a745ba87b3191146004d" + [[package]] name = "openzeppelin_utils" version = "0.17.0" diff --git a/Scarb.toml b/Scarb.toml index ce4ab40..3dad14e 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -16,6 +16,7 @@ alexandria_bytes = { git = "https://github.com/keep-starknet-strange/alexandria. openzeppelin_token = "0.17.0" openzeppelin_introspection = "0.17.0" openzeppelin_access = "0.17.0" +openzeppelin_upgrades = "0.17.0" [dev-dependencies] snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry", tag = "v0.31.0" } diff --git a/src/coloniznft/coloniznft.cairo b/src/coloniznft/coloniznft.cairo index 705c6f0..0ee18d9 100644 --- a/src/coloniznft/coloniznft.cairo +++ b/src/coloniznft/coloniznft.cairo @@ -4,7 +4,7 @@ pub mod ColonizNFT { // IMPORTS // ************************************************************************* use starknet::{ - ContractAddress, get_block_timestamp, get_caller_address, + ContractAddress, ClassHash, get_block_timestamp, get_caller_address, storage::{ StoragePointerWriteAccess, StoragePointerReadAccess, Map, StorageMapReadAccess, StorageMapWriteAccess @@ -20,9 +20,12 @@ pub mod ColonizNFT { use openzeppelin_access::ownable::OwnableComponent; use openzeppelin_token::erc721::{ERC721Component, ERC721HooksEmptyImpl}; use openzeppelin_introspection::{src5::SRC5Component}; + use openzeppelin_upgrades::UpgradeableComponent; + component!(path: OwnableComponent, storage: ownable, event: OwnableEvent); component!(path: SRC5Component, storage: src5, event: SRC5Event); component!(path: ERC721Component, storage: erc721, event: ERC721Event); + component!(path: UpgradeableComponent, storage: upgradeable, event: UpgradeableEvent); // allow to check what interface is supported #[abi(embed_v0)] @@ -41,6 +44,8 @@ pub mod ColonizNFT { impl OwnableImpl = OwnableComponent::OwnableImpl; impl OwnableInternalImpl = OwnableComponent::InternalImpl; + impl UpgradeableInternalImpl = UpgradeableComponent::InternalImpl; + // ************************************************************************* // STORAGE @@ -53,6 +58,8 @@ pub mod ColonizNFT { src5: SRC5Component::Storage, #[substorage(v0)] ownable: OwnableComponent::Storage, + #[substorage(v0)] + upgradeable: UpgradeableComponent::Storage, admin: ContractAddress, last_minted_id: u256, mint_timestamp: Map, @@ -73,14 +80,17 @@ pub mod ColonizNFT { SRC5Event: SRC5Component::Event, #[flat] OwnableEvent: OwnableComponent::Event, + #[flat] + UpgradeableEvent: UpgradeableComponent::Event } // ************************************************************************* // CONSTRUCTOR // ************************************************************************* #[constructor] - fn constructor(ref self: ContractState, admin: ContractAddress,) { + fn constructor(ref self: ContractState, admin: ContractAddress) { self.admin.write(admin); + self.ownable.initializer(admin); self.erc721.initializer("Coloniz Profile", "CLZ:PROFILE", ""); } @@ -107,12 +117,23 @@ pub mod ColonizNFT { self.profile_variants.write(token_id, profile_variant); } + /// @notice sets token base uri + /// @param base_uri base uri to set fn set_base_uri(ref self: ContractState, base_uri: ByteArray) { let admin = self.admin.read(); assert(get_caller_address() == admin, UNAUTHORIZED); self.base_uri.write(base_uri); } + /// @notice upgrades the nft contract + /// @param new_class_hash classhash to upgrade to + fn upgrade(ref self: ContractState, new_class_hash: ClassHash) { + self.ownable.assert_only_owner(); + + // Replace the class hash upgrading the contract + self.upgradeable.upgrade(new_class_hash); + } + // ************************************************************************* // GETTERS // ************************************************************************* diff --git a/src/community/community.cairo b/src/community/community.cairo index b65a414..b2dffed 100644 --- a/src/community/community.cairo +++ b/src/community/community.cairo @@ -165,7 +165,10 @@ pub mod CommunityComponent { // deploy community nft - use community_id as salt since its unique let community_nft_address = self ._deploy_community_nft( - community_id, community_nft_classhash, get_block_timestamp().try_into().unwrap() + community_id, + community_owner, + community_nft_classhash, + get_block_timestamp().try_into().unwrap() ); // create community nft @@ -895,11 +898,12 @@ pub mod CommunityComponent { fn _deploy_community_nft( ref self: ComponentState, community_id: u256, + community_owner: ContractAddress, community_nft_impl_class_hash: ClassHash, salt: felt252 ) -> ContractAddress { let mut constructor_calldata: Array = array![ - community_id.low.into(), community_id.high.into() + community_id.low.into(), community_id.high.into(), community_owner.into() ]; let (account_address, _) = deploy_syscall( diff --git a/src/community/communitynft.cairo b/src/community/communitynft.cairo index d141ef7..9d15b7b 100644 --- a/src/community/communitynft.cairo +++ b/src/community/communitynft.cairo @@ -3,13 +3,14 @@ pub mod CommunityNFT { // ************************************************************************* // IMPORTS // ************************************************************************* - use starknet::{ContractAddress, get_block_timestamp}; + use starknet::{ContractAddress, ClassHash, get_block_timestamp}; use core::num::traits::zero::Zero; use openzeppelin_introspection::src5::SRC5Component; use openzeppelin_token::erc721::{ERC721Component, ERC721HooksEmptyImpl}; + use openzeppelin_access::ownable::OwnableComponent; + use openzeppelin_upgrades::UpgradeableComponent; use coloniz::interfaces::ICustomNFT::ICustomNFT; - use coloniz::base::{ constants::errors::Errors::{ALREADY_MINTED, NOT_TOKEN_OWNER, TOKEN_DOES_NOT_EXIST}, utils::base64_extended::convert_into_byteArray, @@ -23,13 +24,22 @@ pub mod CommunityNFT { // ************************************************************************* // COMPONENTS // ************************************************************************* + component!(path: OwnableComponent, storage: ownable, event: OwnableEvent); component!(path: ERC721Component, storage: erc721, event: ERC721Event); component!(path: SRC5Component, storage: src5, event: SRC5Event); + component!(path: UpgradeableComponent, storage: upgradeable, event: UpgradeableEvent); // ERC721 Mixin impl ERC721MixinImpl = ERC721Component::ERC721MixinImpl; impl ERC721InternalImpl = ERC721Component::InternalImpl; + // add an owner + #[abi(embed_v0)] + impl OwnableImpl = OwnableComponent::OwnableImpl; + impl OwnableInternalImpl = OwnableComponent::InternalImpl; + + impl UpgradeableInternalImpl = UpgradeableComponent::InternalImpl; + // ************************************************************************* // STORAGE // ************************************************************************* @@ -39,6 +49,10 @@ pub mod CommunityNFT { erc721: ERC721Component::Storage, #[substorage(v0)] src5: SRC5Component::Storage, + #[substorage(v0)] + ownable: OwnableComponent::Storage, + #[substorage(v0)] + upgradeable: UpgradeableComponent::Storage, last_minted_id: u256, mint_timestamp: Map, user_token_id: Map, @@ -54,14 +68,19 @@ pub mod CommunityNFT { #[flat] ERC721Event: ERC721Component::Event, #[flat] - SRC5Event: SRC5Component::Event + SRC5Event: SRC5Component::Event, + #[flat] + OwnableEvent: OwnableComponent::Event, + #[flat] + UpgradeableEvent: UpgradeableComponent::Event } // ************************************************************************* // CONSTRUCTOR // ************************************************************************* #[constructor] - fn constructor(ref self: ContractState, community_id: u256) { + fn constructor(ref self: ContractState, community_id: u256, admin: ContractAddress) { + self.ownable.initializer(admin); self.community_id.write(community_id); } @@ -98,6 +117,15 @@ pub mod CommunityNFT { self.user_token_id.write(user_address, 0); } + /// @notice upgrades the nft contract + /// @param new_class_hash classhash to upgrade to + fn upgrade(ref self: ContractState, new_class_hash: ClassHash) { + self.ownable.assert_only_owner(); + + // Replace the class hash upgrading the contract + self.upgradeable.upgrade(new_class_hash); + } + // ************************************************************************* // GETTERS // ************************************************************************* diff --git a/src/follownft/follownft.cairo b/src/follownft/follownft.cairo index 67efe23..71ca823 100644 --- a/src/follownft/follownft.cairo +++ b/src/follownft/follownft.cairo @@ -4,7 +4,7 @@ pub mod Follow { // IMPORT // ************************************************************************* use starknet::{ - ContractAddress, get_block_timestamp, + ContractAddress, ClassHash, get_block_timestamp, storage::{ StoragePointerWriteAccess, StoragePointerReadAccess, Map, StorageMapReadAccess, StorageMapWriteAccess @@ -16,13 +16,15 @@ pub mod Follow { constants::{errors::Errors, types::FollowData}, utils::hubrestricted::HubRestricted::hub_only, token_uris::follow_token_uri::FollowTokenUri, }; - use openzeppelin_access::ownable::OwnableComponent; + use openzeppelin_access::ownable::OwnableComponent; use openzeppelin_token::erc721::{ERC721Component, ERC721HooksEmptyImpl}; use openzeppelin_introspection::{src5::SRC5Component}; + use openzeppelin_upgrades::UpgradeableComponent; component!(path: OwnableComponent, storage: ownable, event: OwnableEvent); component!(path: SRC5Component, storage: src5, event: SRC5Event); component!(path: ERC721Component, storage: erc721, event: ERC721Event); + component!(path: UpgradeableComponent, storage: upgradeable, event: UpgradeableEvent); // allow to check what interface is supported #[abi(embed_v0)] @@ -40,6 +42,8 @@ pub mod Follow { impl OwnableImpl = OwnableComponent::OwnableImpl; impl OwnableInternalImpl = OwnableComponent::InternalImpl; + impl UpgradeableInternalImpl = UpgradeableComponent::InternalImpl; + // ************************************************************************* // STORAGE // ************************************************************************* @@ -51,6 +55,8 @@ pub mod Follow { src5: SRC5Component::Storage, #[substorage(v0)] ownable: OwnableComponent::Storage, + #[substorage(v0)] + upgradeable: UpgradeableComponent::Storage, admin: ContractAddress, followed_profile_address: ContractAddress, token_id: u256, @@ -72,6 +78,8 @@ pub mod Follow { SRC5Event: SRC5Component::Event, #[flat] OwnableEvent: OwnableComponent::Event, + #[flat] + UpgradeableEvent: UpgradeableComponent::Event, Followed: Followed, Unfollowed: Unfollowed, FollowerBlocked: FollowerBlocked, @@ -122,6 +130,7 @@ pub mod Follow { admin: ContractAddress ) { self.admin.write(admin); + self.ownable.initializer(admin); self.token_id.write(token_id); self.coloniz_hub.write(hub); self.followed_profile_address.write(profile_address); @@ -228,6 +237,15 @@ pub mod Follow { return true; } + /// @notice upgrades the nft contract + /// @param new_class_hash classhash to upgrade to + fn upgrade(ref self: ContractState, new_class_hash: ClassHash) { + self.ownable.assert_only_owner(); + + // Replace the class hash upgrading the contract + self.upgradeable.upgrade(new_class_hash); + } + // ************************************************************************* // GETTERS // ************************************************************************* diff --git a/src/hub/hub.cairo b/src/hub/hub.cairo index fc3339d..2ff8d35 100644 --- a/src/hub/hub.cairo +++ b/src/hub/hub.cairo @@ -1,4 +1,4 @@ -use starknet::ContractAddress; +use starknet::{ContractAddress, ClassHash}; #[starknet::interface] trait IColonizHub { @@ -17,18 +17,18 @@ trait IColonizHub { ) -> bool; fn get_handle_id(self: @TState, profile_address: ContractAddress) -> u256; fn get_handle(self: @TState, handle_id: u256) -> ByteArray; + fn upgrade(ref self: TState, new_class_hash: ClassHash); } #[starknet::contract] pub mod ColonizHub { use core::array::SpanTrait; use starknet::{ - ContractAddress, get_caller_address, get_contract_address, + ContractAddress, ClassHash, get_caller_address, get_contract_address, storage::{StoragePointerWriteAccess, StoragePointerReadAccess} }; use coloniz::profile::profile::ProfileComponent; use coloniz::publication::publication::PublicationComponent; - use openzeppelin_access::ownable::OwnableComponent; use coloniz::community::community::CommunityComponent; use coloniz::channel::channel::ChannelComponent; use coloniz::jolt::jolt::JoltComponent; @@ -41,6 +41,9 @@ pub mod ColonizHub { BLOCKED_STATUS, INVALID_PROFILE_ADDRESS, SELF_FOLLOWING }; + use openzeppelin_access::ownable::OwnableComponent; + use openzeppelin_upgrades::UpgradeableComponent; + // ************************************************************************* // COMPONENTS // ************************************************************************* @@ -50,27 +53,29 @@ pub mod ColonizHub { component!(path: JoltComponent, storage: jolt, event: JoltEvent); component!(path: ChannelComponent, storage: channel, event: ChannelEvent); component!(path: CommunityComponent, storage: community, event: CommunityEvent); + component!(path: UpgradeableComponent, storage: upgradeable, event: UpgradeableEvent); #[abi(embed_v0)] impl ProfileImpl = ProfileComponent::colonizProfile; #[abi(embed_v0)] impl PublicationImpl = PublicationComponent::colonizPublication; - impl PublicationPrivateImpl = PublicationComponent::InternalImpl; - - impl ProfilePrivateImpl = ProfileComponent::Private; - - #[abi(embed_v0)] impl communityImpl = CommunityComponent::colonizCommunity; - impl communityPrivateImpl = CommunityComponent::Private; - #[abi(embed_v0)] impl channelImpl = ChannelComponent::colonizChannel; - impl channelPrivateImpl = ChannelComponent::InternalImpl; - #[abi(embed_v0)] impl joltImpl = JoltComponent::Jolt; + #[abi(embed_v0)] + impl OwnableMixinImpl = OwnableComponent::OwnableMixinImpl; + + impl OwnableInternalImpl = OwnableComponent::InternalImpl; impl joltPrivateImpl = JoltComponent::Private; + impl PublicationPrivateImpl = PublicationComponent::InternalImpl; + impl ProfilePrivateImpl = ProfileComponent::Private; + impl channelPrivateImpl = ChannelComponent::InternalImpl; + impl communityPrivateImpl = CommunityComponent::Private; + impl UpgradeableInternalImpl = UpgradeableComponent::InternalImpl; + // ************************************************************************* // STORAGE // ************************************************************************* @@ -88,6 +93,8 @@ pub mod ColonizHub { community: CommunityComponent::Storage, #[substorage(v0)] channel: ChannelComponent::Storage, + #[substorage(v0)] + upgradeable: UpgradeableComponent::Storage, handle_contract_address: ContractAddress, handle_registry_contract_address: ContractAddress } @@ -108,6 +115,8 @@ pub mod ColonizHub { CommunityEvent: CommunityComponent::Event, #[flat] ChannelEvent: ChannelComponent::Event, + #[flat] + UpgradeableEvent: UpgradeableComponent::Event } // ************************************************************************* @@ -135,6 +144,7 @@ pub mod ColonizHub { self.publication._initializer(collect_nft_classhash); self.community._initializer(community_nft_classhash); self.jolt._initializer(owner); + self.ownable.initializer(owner); } #[abi(embed_v0)] @@ -191,6 +201,15 @@ pub mod ColonizHub { } } + /// @notice upgrades the hub contract + /// @param new_class_hash classhash to upgrade to + fn upgrade(ref self: ContractState, new_class_hash: ClassHash) { + self.ownable.assert_only_owner(); + + // Replace the class hash upgrading the contract + self.upgradeable.upgrade(new_class_hash); + } + // ************************************************************************* // GETTERS // ************************************************************************* diff --git a/src/interfaces.cairo b/src/interfaces.cairo index 2528461..0db2a7e 100644 --- a/src/interfaces.cairo +++ b/src/interfaces.cairo @@ -12,5 +12,4 @@ pub mod ICommunity; pub mod ICollectNFT; pub mod ICustomNFT; pub mod IJolt; -pub mod IUpgradeable; pub mod IChannel; diff --git a/src/interfaces/IColonizNFT.cairo b/src/interfaces/IColonizNFT.cairo index c26617c..ab1b7ca 100644 --- a/src/interfaces/IColonizNFT.cairo +++ b/src/interfaces/IColonizNFT.cairo @@ -1,4 +1,4 @@ -use starknet::ContractAddress; +use starknet::{ContractAddress, ClassHash}; use coloniz::base::constants::types::ProfileVariants; // ************************************************************************* // INTERFACE of coloniz NFT @@ -12,6 +12,7 @@ pub trait IColonizNFT { ref self: TState, address: ContractAddress, profile_variant: ProfileVariants ); fn set_base_uri(ref self: TState, base_uri: ByteArray); + fn upgrade(ref self: TState, new_class_hash: ClassHash); // ************************************************************************* // GETTERS // ************************************************************************* diff --git a/src/interfaces/ICustomNFT.cairo b/src/interfaces/ICustomNFT.cairo index de66023..92f2525 100644 --- a/src/interfaces/ICustomNFT.cairo +++ b/src/interfaces/ICustomNFT.cairo @@ -1,27 +1,27 @@ -use starknet::ContractAddress; +use starknet::{ContractAddress, ClassHash}; // ************************************************************************* // INTERFACE of ICommunity NFT // ************************************************************************* #[starknet::interface] -pub trait ICustomNFT { +pub trait ICustomNFT { // ************************************************************************* // EXTERNALS // ************************************************************************* - fn mint_nft(ref self: TContractState, user_address: ContractAddress) -> u256; - fn burn_nft(ref self: TContractState, user_address: ContractAddress, token_id: u256); + fn mint_nft(ref self: TState, user_address: ContractAddress) -> u256; + fn burn_nft(ref self: TState, user_address: ContractAddress, token_id: u256); + fn upgrade(ref self: TState, new_class_hash: ClassHash); // ************************************************************************* // GETTERS // ************************************************************************* - fn get_user_token_id(self: @TContractState, user_address: ContractAddress) -> u256; - + fn get_user_token_id(self: @TState, user_address: ContractAddress) -> u256; // ************************************************************************* // METADATA // ************************************************************************* - fn name(self: @TContractState) -> ByteArray; - fn symbol(self: @TContractState) -> ByteArray; - fn token_uri(self: @TContractState, token_id: u256) -> ByteArray; + fn name(self: @TState) -> ByteArray; + fn symbol(self: @TState) -> ByteArray; + fn token_uri(self: @TState, token_id: u256) -> ByteArray; } diff --git a/src/interfaces/IFollowNFT.cairo b/src/interfaces/IFollowNFT.cairo index 83d98fc..84b0ff1 100644 --- a/src/interfaces/IFollowNFT.cairo +++ b/src/interfaces/IFollowNFT.cairo @@ -1,4 +1,4 @@ -use starknet::ContractAddress; +use starknet::{ContractAddress, ClassHash}; use coloniz::base::constants::types::FollowData; // ************************************************************************* @@ -13,6 +13,7 @@ pub trait IFollowNFT { fn unfollow(ref self: TState, unfollower_profile_address: ContractAddress); fn process_block(ref self: TState, follower_profile_address: ContractAddress) -> bool; fn process_unblock(ref self: TState, follower_profile_address: ContractAddress) -> bool; + fn upgrade(ref self: TState, new_class_hash: ClassHash); // ************************************************************************* // GETTERS // ************************************************************************* diff --git a/src/interfaces/IHandle.cairo b/src/interfaces/IHandle.cairo index c61c442..b5b71ba 100644 --- a/src/interfaces/IHandle.cairo +++ b/src/interfaces/IHandle.cairo @@ -1,7 +1,7 @@ // ************************************************************************* // INTERFACE of HANDLE NFT // ************************************************************************* -use starknet::ContractAddress; +use starknet::{ContractAddress, ClassHash}; #[starknet::interface] pub trait IHandle { @@ -10,6 +10,7 @@ pub trait IHandle { // ************************************************************************* fn mint_handle(ref self: TState, local_name: felt252, profile: ContractAddress) -> u256; fn burn_handle(ref self: TState, token_id: u256); + fn upgrade(ref self: TState, new_class_hash: ClassHash); // ************************************************************************* // GETTERS // ************************************************************************* diff --git a/src/interfaces/IHandleRegistry.cairo b/src/interfaces/IHandleRegistry.cairo index 7397c8f..7332589 100644 --- a/src/interfaces/IHandleRegistry.cairo +++ b/src/interfaces/IHandleRegistry.cairo @@ -1,4 +1,4 @@ -use starknet::ContractAddress; +use starknet::{ContractAddress, ClassHash}; // ************************************************************************* // INTERFACE OF HANDLE REGISTRY // ************************************************************************* @@ -9,6 +9,7 @@ pub trait IHandleRegistry { // ************************************************************************* fn link(ref self: TState, handle_id: u256, profile_address: ContractAddress); fn unlink(ref self: TState, handle_id: u256, profile_address: ContractAddress); + fn upgrade(ref self: TState, new_class_hash: ClassHash); // ************************************************************************* // GETTERS // ************************************************************************* diff --git a/src/interfaces/IHub.cairo b/src/interfaces/IHub.cairo index fbd8521..7b7a4cc 100644 --- a/src/interfaces/IHub.cairo +++ b/src/interfaces/IHub.cairo @@ -1,4 +1,4 @@ -use starknet::ContractAddress; +use starknet::{ContractAddress, ClassHash}; use coloniz::base::constants::types::{ Profile, PostParams, RepostParams, CommentParams, PublicationType, Publication }; @@ -73,4 +73,9 @@ pub trait IHub { // ************************************************************************* fn get_handle_id(self: @TState, profile_address: ContractAddress) -> u256; fn get_handle(self: @TState, handle_id: u256) -> ByteArray; + + // ************************************************************************* + // UPGRADEABILITY + // ************************************************************************* + fn upgrade(ref self: TState, new_class_hash: ClassHash); } diff --git a/src/interfaces/IUpgradeable.cairo b/src/interfaces/IUpgradeable.cairo deleted file mode 100644 index e96214b..0000000 --- a/src/interfaces/IUpgradeable.cairo +++ /dev/null @@ -1,9 +0,0 @@ -// ************************************************************************* -// UPGRADEABLE INTERFACE -// ************************************************************************* -use starknet::ClassHash; - -#[starknet::interface] -pub trait IUpgradeable { - fn upgrade(ref self: TContractState, new_class_hash: ClassHash); -} diff --git a/src/namespaces/handle_registry.cairo b/src/namespaces/handle_registry.cairo index 2717ad8..a25c027 100644 --- a/src/namespaces/handle_registry.cairo +++ b/src/namespaces/handle_registry.cairo @@ -5,7 +5,7 @@ pub mod HandleRegistry { // ************************************************************************* use core::num::traits::zero::Zero; use starknet::{ - ContractAddress, get_caller_address, get_block_timestamp, contract_address_const, + ContractAddress, ClassHash, get_caller_address, get_block_timestamp, contract_address_const, storage::{ StoragePointerWriteAccess, StoragePointerReadAccess, Map, StorageMapReadAccess, StorageMapWriteAccess @@ -16,11 +16,27 @@ pub mod HandleRegistry { use coloniz::base::{constants::errors::Errors}; use coloniz::interfaces::IHandle::{IHandleDispatcher, IHandleDispatcherTrait}; + use openzeppelin_access::ownable::OwnableComponent; + use openzeppelin_upgrades::UpgradeableComponent; + + component!(path: UpgradeableComponent, storage: upgradeable, event: UpgradeableEvent); + component!(path: OwnableComponent, storage: ownable, event: OwnableEvent); + + #[abi(embed_v0)] + impl OwnableMixinImpl = OwnableComponent::OwnableMixinImpl; + + impl OwnableInternalImpl = OwnableComponent::InternalImpl; + impl UpgradeableInternalImpl = UpgradeableComponent::InternalImpl; + // ************************************************************************* // STORAGE // ************************************************************************* #[storage] pub struct Storage { + #[substorage(v0)] + ownable: OwnableComponent::Storage, + #[substorage(v0)] + upgradeable: UpgradeableComponent::Storage, handle_address: ContractAddress, handle_to_profile_address: Map::, profile_address_to_handle: Map::, @@ -32,6 +48,10 @@ pub mod HandleRegistry { #[event] #[derive(Drop, starknet::Event)] pub enum Event { + #[flat] + OwnableEvent: OwnableComponent::Event, + #[flat] + UpgradeableEvent: UpgradeableComponent::Event, Linked: HandleLinked, Unlinked: HandleUnlinked, } @@ -56,8 +76,11 @@ pub mod HandleRegistry { // CONSTRUCTOR // ************************************************************************* #[constructor] - fn constructor(ref self: ContractState, handle_address: ContractAddress) { + fn constructor( + ref self: ContractState, handle_address: ContractAddress, owner: ContractAddress + ) { self.handle_address.write(handle_address); + self.ownable.initializer(owner); } // ************************************************************************* @@ -80,6 +103,15 @@ pub mod HandleRegistry { self._unlink(handle_id, profile_address, caller); } + /// @notice upgrades the hub contract + /// @param new_class_hash classhash to upgrade to + fn upgrade(ref self: ContractState, new_class_hash: ClassHash) { + self.ownable.assert_only_owner(); + + // Replace the class hash upgrading the contract + self.upgradeable.upgrade(new_class_hash); + } + // ************************************************************************* // GETTERS // ************************************************************************* diff --git a/src/namespaces/handles.cairo b/src/namespaces/handles.cairo index 487f860..3f24d1d 100644 --- a/src/namespaces/handles.cairo +++ b/src/namespaces/handles.cairo @@ -8,15 +8,17 @@ pub mod Handles { use core::poseidon::PoseidonTrait; use core::hash::{HashStateTrait, HashStateExTrait}; use starknet::{ - ContractAddress, get_caller_address, get_block_timestamp, + ContractAddress, ClassHash, get_caller_address, get_block_timestamp, storage::{ StoragePointerWriteAccess, StoragePointerReadAccess, Map, StorageMapReadAccess, StorageMapWriteAccess } }; - use openzeppelin_access::ownable::OwnableComponent; + use openzeppelin_access::ownable::OwnableComponent; use openzeppelin_token::erc721::{ERC721Component, ERC721HooksEmptyImpl}; use openzeppelin_introspection::{src5::SRC5Component}; + use openzeppelin_upgrades::UpgradeableComponent; + use coloniz::base::{ constants::errors::Errors, utils::byte_array_extra::FeltTryIntoByteArray, token_uris::handle_token_uri::HandleTokenUri, @@ -26,6 +28,7 @@ pub mod Handles { component!(path: OwnableComponent, storage: ownable, event: OwnableEvent); component!(path: SRC5Component, storage: src5, event: SRC5Event); component!(path: ERC721Component, storage: erc721, event: ERC721Event); + component!(path: UpgradeableComponent, storage: upgradeable, event: UpgradeableEvent); // allow to check what interface is supported #[abi(embed_v0)] @@ -43,6 +46,8 @@ pub mod Handles { impl OwnableImpl = OwnableComponent::OwnableImpl; impl OwnableInternalImpl = OwnableComponent::InternalImpl; + impl UpgradeableInternalImpl = UpgradeableComponent::InternalImpl; + // ************************************************************************* // STORAGE // ************************************************************************* @@ -54,6 +59,8 @@ pub mod Handles { src5: SRC5Component::Storage, #[substorage(v0)] ownable: OwnableComponent::Storage, + #[substorage(v0)] + upgradeable: UpgradeableComponent::Storage, admin: ContractAddress, total_supply: u256, local_names: Map::, @@ -82,6 +89,8 @@ pub mod Handles { SRC5Event: SRC5Component::Event, #[flat] OwnableEvent: OwnableComponent::Event, + #[flat] + UpgradeableEvent: UpgradeableComponent::Event, HandleMinted: HandleMinted, HandleBurnt: HandleBurnt, } @@ -108,6 +117,7 @@ pub mod Handles { #[constructor] fn constructor(ref self: ContractState, admin: ContractAddress) { self.admin.write(admin); + self.ownable.initializer(admin); self.erc721.initializer("Coloniz Handles", "CLZ:HANDLES", ""); } @@ -147,6 +157,15 @@ pub mod Handles { ); } + /// @notice upgrades the nft contract + /// @param new_class_hash classhash to upgrade to + fn upgrade(ref self: ContractState, new_class_hash: ClassHash) { + self.ownable.assert_only_owner(); + + // Replace the class hash upgrading the contract + self.upgradeable.upgrade(new_class_hash); + } + // ************************************************************************* // GETTERS // ************************************************************************* diff --git a/src/profile/profile.cairo b/src/profile/profile.cairo index 1bf52b3..048b719 100644 --- a/src/profile/profile.cairo +++ b/src/profile/profile.cairo @@ -73,9 +73,7 @@ pub mod ProfileComponent { let coloniz_nft_address = self.coloniz_nft_address.read(); // mint coloniz nft let recipient = get_caller_address(); - let owns_coloniznft = IERC721Dispatcher { - contract_address: coloniz_nft_address - } + let owns_coloniznft = IERC721Dispatcher { contract_address: coloniz_nft_address } .balance_of(recipient); if owns_coloniznft == 0 { IColonizNFTDispatcher { contract_address: coloniz_nft_address } @@ -89,9 +87,7 @@ pub mod ProfileComponent { let profile_address = IRegistryDispatcher { contract_address: registry_contract_address } - .create_account( - implementation_hash, coloniz_nft_address, token_id, salt, chain_id - ); + .create_account(implementation_hash, coloniz_nft_address, token_id, salt, chain_id); // deploy follow nft contract let mut constructor_calldata: Array = array![ diff --git a/src/publication/collectnft.cairo b/src/publication/collectnft.cairo index 23dda85..b931564 100644 --- a/src/publication/collectnft.cairo +++ b/src/publication/collectnft.cairo @@ -19,7 +19,7 @@ pub mod CollectNFT { Map, StoragePointerWriteAccess, StoragePointerReadAccess, StorageMapReadAccess, StorageMapWriteAccess }; - use openzeppelin_access::ownable::OwnableComponent; + use openzeppelin_access::ownable::OwnableComponent; use openzeppelin_token::erc721::{ERC721Component, ERC721HooksEmptyImpl}; use openzeppelin_introspection::{src5::SRC5Component}; diff --git a/tests/test_handle_registry.cairo b/tests/test_handle_registry.cairo index 102e5ea..00f49a2 100644 --- a/tests/test_handle_registry.cairo +++ b/tests/test_handle_registry.cairo @@ -36,7 +36,7 @@ fn __setup__() -> (ContractAddress, ContractAddress) { // deploy handle registry contract let handle_registry_class_hash = declare("HandleRegistry").unwrap().contract_class(); - let mut calldata: Array = array![handle_contract_address.into()]; + let mut calldata: Array = array![handle_contract_address.into(), ADMIN_ADDRESS]; let (handle_registry_contract_address, _) = handle_registry_class_hash .deploy(@calldata) .unwrap_syscall(); diff --git a/tests/test_hub.cairo b/tests/test_hub.cairo index 7874cc5..d673cba 100644 --- a/tests/test_hub.cairo +++ b/tests/test_hub.cairo @@ -44,16 +44,14 @@ fn __setup__() -> (ContractAddress, ContractAddress, ContractAddress, ContractAd // deploy handle registry contract let handle_registry_class_hash = declare("HandleRegistry").unwrap().contract_class(); - let mut calldata: Array = array![handle_contract_address.into()]; + let mut calldata: Array = array![handle_contract_address.into(), ADMIN]; let (handle_registry_contract_address, _) = handle_registry_class_hash .deploy(@calldata) .unwrap_syscall(); // deploy tokenbound registry let registry_class_hash = declare("Registry").unwrap().contract_class(); - let (registry_contract_address, _) = registry_class_hash - .deploy(@array![]) - .unwrap_syscall(); + let (registry_contract_address, _) = registry_class_hash.deploy(@array![]).unwrap_syscall(); // declare tokenbound account let account_class_hash = declare("AccountV3").unwrap().contract_class(); @@ -71,7 +69,7 @@ fn __setup__() -> (ContractAddress, ContractAddress, ContractAddress, ContractAd let hub_class_hash = declare("ColonizHub").unwrap().contract_class(); let mut calldata: Array = array![ nft_contract_address.into(), - handle_contract_address.into(), + handle_contract_address.into(), handle_registry_contract_address.into(), (*follow_nft_classhash.class_hash).into(), (*community_nft_classhash.class_hash).into(), diff --git a/tests/test_profile.cairo b/tests/test_profile.cairo index f61d6b2..f72ba4d 100644 --- a/tests/test_profile.cairo +++ b/tests/test_profile.cairo @@ -64,7 +64,10 @@ fn __setup__() -> (ContractAddress, ContractAddress, felt252, ContractAddress) { #[test] fn test_profile_creation() { let ( - nft_contract_address, registry_contract_address, account_class_hash, profile_contract_address + nft_contract_address, + registry_contract_address, + account_class_hash, + profile_contract_address ) = __setup__(); let colonizNFTDispatcher = IColonizNFTDispatcher { contract_address: nft_contract_address }; @@ -82,9 +85,7 @@ fn test_profile_creation() { start_cheat_caller_address(profile_contract_address, USER.try_into().unwrap()); start_cheat_caller_address(nft_contract_address, USER.try_into().unwrap()); let profile_address = profileDispatcher - .create_profile( - registry_contract_address, account_class_hash, 2456, profile_variant - ); + .create_profile(registry_contract_address, account_class_hash, 2456, profile_variant); // test a new coloniz nft is minted let last_minted_id = colonizNFTDispatcher.get_last_minted_id(); @@ -107,7 +108,10 @@ fn test_profile_creation() { #[test] fn test_profile_metadata() { let ( - nft_contract_address, registry_contract_address, account_class_hash, profile_contract_address + nft_contract_address, + registry_contract_address, + account_class_hash, + profile_contract_address ) = __setup__(); let profileDispatcher = IProfileDispatcher { contract_address: profile_contract_address }; @@ -124,9 +128,7 @@ fn test_profile_metadata() { start_cheat_caller_address(profile_contract_address, USER.try_into().unwrap()); start_cheat_caller_address(nft_contract_address, USER.try_into().unwrap()); let profile_address = profileDispatcher - .create_profile( - registry_contract_address, account_class_hash, 2456, profile_variant - ); + .create_profile(registry_contract_address, account_class_hash, 2456, profile_variant); profileDispatcher .set_profile_metadata_uri( @@ -148,7 +150,10 @@ fn test_profile_metadata() { #[test] fn test_profile_creation_event() { let ( - nft_contract_address, registry_contract_address, account_class_hash, profile_contract_address + nft_contract_address, + registry_contract_address, + account_class_hash, + profile_contract_address ) = __setup__(); let colonizNFTDispatcher = IColonizNFTDispatcher { contract_address: nft_contract_address }; @@ -169,9 +174,7 @@ fn test_profile_creation_event() { start_cheat_caller_address(nft_contract_address, USER.try_into().unwrap()); let profile_address = profileDispatcher - .create_profile( - registry_contract_address, account_class_hash, 2456, profile_variant - ); + .create_profile(registry_contract_address, account_class_hash, 2456, profile_variant); let token_id = colonizNFTDispatcher.get_user_token_id(USER.try_into().unwrap()); diff --git a/tests/test_publication.cairo b/tests/test_publication.cairo index 61da1e6..055eda8 100644 --- a/tests/test_publication.cairo +++ b/tests/test_publication.cairo @@ -39,12 +39,7 @@ const ADMIN: felt252 = 'ADMIN'; // SETUP // ************************************************************************* fn __setup__() -> ( - ContractAddress, - ContractAddress, - felt252, - felt252, - ContractAddress, - ProfileVariants + ContractAddress, ContractAddress, felt252, felt252, ContractAddress, ProfileVariants ) { // deploy NFT let nft_contract = declare("ColonizNFT").unwrap().contract_class(); @@ -131,9 +126,7 @@ fn test_post_community_post() { start_cheat_caller_address(publication_contract_address, USER_ONE.try_into().unwrap()); // Create profile let user_one_profile_address = publication_dispatcher - .create_profile( - registry_contract_address, account_class_hash, 2478, profile_variant - ); + .create_profile(registry_contract_address, account_class_hash, 2478, profile_variant); // Check if community is created let community_id = community_dispatcher.create_community(); // Check if community is created @@ -175,9 +168,7 @@ fn test_if_is_community_post() { start_cheat_caller_address(publication_contract_address, USER_ONE.try_into().unwrap()); // Create profile let user_one_profile_address = publication_dispatcher - .create_profile( - registry_contract_address, account_class_hash, 2478, profile_variant - ); + .create_profile(registry_contract_address, account_class_hash, 2478, profile_variant); // Check if community is created let community_id = community_dispatcher.create_community(); // Check if community is created @@ -227,9 +218,7 @@ fn test_community_censorship_post_status_tobe_true() { start_cheat_caller_address(publication_contract_address, USER_ONE.try_into().unwrap()); // Create profile let user_one_profile_address = publication_dispatcher - .create_profile( - registry_contract_address, account_class_hash, 2478, profile_variant - ); + .create_profile(registry_contract_address, account_class_hash, 2478, profile_variant); // Check if community is created let community_id = community_dispatcher.create_community(); // Check if community is created @@ -275,9 +264,7 @@ fn test_community_censorship_post_status_tobe_false() { start_cheat_caller_address(publication_contract_address, USER_ONE.try_into().unwrap()); // Create profile let user_one_profile_address = publication_dispatcher - .create_profile( - registry_contract_address, account_class_hash, 2478, profile_variant - ); + .create_profile(registry_contract_address, account_class_hash, 2478, profile_variant); // Check if community is created let community_id = community_dispatcher.create_community(); community_dispatcher.set_community_censorship_status(community_id, true); @@ -324,9 +311,7 @@ fn test_channel_censorship_post_status_tobe_true() { start_cheat_caller_address(publication_contract_address, USER_ONE.try_into().unwrap()); // Create profile let user_one_profile_address = publication_dispatcher - .create_profile( - registry_contract_address, account_class_hash, 2478, profile_variant - ); + .create_profile(registry_contract_address, account_class_hash, 2478, profile_variant); // Check if community is created let community_id = community_dispatcher.create_community(); // Check if community is created @@ -371,9 +356,7 @@ fn test_channel_censorship_post_status_tobe_false() { start_cheat_caller_address(publication_contract_address, USER_ONE.try_into().unwrap()); // Create profile let user_one_profile_address = publication_dispatcher - .create_profile( - registry_contract_address, account_class_hash, 2478, profile_variant - ); + .create_profile(registry_contract_address, account_class_hash, 2478, profile_variant); // Check if community is created let community_id = community_dispatcher.create_community(); @@ -422,9 +405,7 @@ fn test_if_is_channel_post() { start_cheat_caller_address(publication_contract_address, USER_ONE.try_into().unwrap()); // Create profile let user_one_profile_address = publication_dispatcher - .create_profile( - registry_contract_address, account_class_hash, 2478, profile_variant - ); + .create_profile(registry_contract_address, account_class_hash, 2478, profile_variant); // Check if community is created let community_id = community_dispatcher.create_community(); // Check if community is created @@ -476,9 +457,7 @@ fn test_should_fail_if_user_is_not_a_community_member() { start_cheat_caller_address(publication_contract_address, USER_ONE.try_into().unwrap()); // Create profile let user_one_profile_address = publication_dispatcher - .create_profile( - registry_contract_address, account_class_hash, 2478, profile_variant - ); + .create_profile(registry_contract_address, account_class_hash, 2478, profile_variant); // Check if community is created let community_id = community_dispatcher.create_community(); // Check if channel is created @@ -499,9 +478,7 @@ fn test_should_fail_if_user_is_not_a_community_member() { let content_URI: ByteArray = "ipfs://helloworld"; // Create profile let user_one_profile_address = publication_dispatcher - .create_profile( - registry_contract_address, account_class_hash, 2478, profile_variant - ); + .create_profile(registry_contract_address, account_class_hash, 2478, profile_variant); // Attempt to post let _pub_assigned_id = publication_dispatcher .post( @@ -539,9 +516,7 @@ fn test_should_fail_if_user_is_not_a_channel_member() { start_cheat_caller_address(publication_contract_address, USER_ONE.try_into().unwrap()); // Create profile let user_one_profile_address = publication_dispatcher - .create_profile( - registry_contract_address, account_class_hash, 2478, profile_variant - ); + .create_profile(registry_contract_address, account_class_hash, 2478, profile_variant); // Check if community is created let community_id = community_dispatcher.create_community(); // Check if channel is created @@ -562,9 +537,7 @@ fn test_should_fail_if_user_is_not_a_channel_member() { let content_URI: ByteArray = "ipfs://helloworld"; // Create profile let user_two_profile_address = publication_dispatcher - .create_profile( - registry_contract_address, account_class_hash, 2478, profile_variant - ); + .create_profile(registry_contract_address, account_class_hash, 2478, profile_variant); // Attempt to post community_dispatcher.join_community(community_id); channel_dispatcher.join_channel(channel_id); @@ -584,9 +557,7 @@ fn test_should_fail_if_user_is_not_a_channel_member() { let content_URI: ByteArray = "ipfs://helloworld"; // Create profile let user_three_profile_address = publication_dispatcher - .create_profile( - registry_contract_address, account_class_hash, 2478, profile_variant - ); + .create_profile(registry_contract_address, account_class_hash, 2478, profile_variant); // Attempt to post community_dispatcher.join_community(community_id); let _pub_assigned_id = publication_dispatcher @@ -624,9 +595,7 @@ fn test_post_channel_post() { start_cheat_caller_address(publication_contract_address, USER_ONE.try_into().unwrap()); // Create profile let user_one_profile_address = publication_dispatcher - .create_profile( - registry_contract_address, account_class_hash, 2478, profile_variant - ); + .create_profile(registry_contract_address, account_class_hash, 2478, profile_variant); // Check if community is created let community_id = community_dispatcher.create_community(); // Check if community is created @@ -667,9 +636,7 @@ fn test_upvote() { start_cheat_caller_address(publication_contract_address, USER_TWO.try_into().unwrap()); let user_two_profile_address = publication_dispatcher - .create_profile( - registry_contract_address, account_class_hash, 2478, profile_variant - ); + .create_profile(registry_contract_address, account_class_hash, 2478, profile_variant); let community_id = community_dispatcher.create_community(); let channel_id = channel_dispatcher.create_channel(community_id); let pub_assigned_id = publication_dispatcher @@ -711,9 +678,7 @@ fn test_downvote() { start_cheat_caller_address(publication_contract_address, USER_TWO.try_into().unwrap()); let user_two_profile_address = publication_dispatcher - .create_profile( - registry_contract_address, account_class_hash, 2478, profile_variant - ); + .create_profile(registry_contract_address, account_class_hash, 2478, profile_variant); let community_id = community_dispatcher.create_community(); let channel_id = channel_dispatcher.create_channel(community_id); let pub_assigned_id = publication_dispatcher @@ -757,9 +722,7 @@ fn test_upvote_event_emission() { let content_URI: ByteArray = "ipfs://helloworld"; start_cheat_caller_address(publication_contract_address, USER_ONE.try_into().unwrap()); let user_one_profile_address = publication_dispatcher - .create_profile( - registry_contract_address, account_class_hash, 2478, profile_variant - ); + .create_profile(registry_contract_address, account_class_hash, 2478, profile_variant); let community_id = community_dispatcher.create_community(); let channel_id = channel_dispatcher.create_channel(community_id); @@ -814,9 +777,7 @@ fn test_downvote_event_emission() { let content_URI: ByteArray = "ipfs://helloworld"; start_cheat_caller_address(publication_contract_address, USER_ONE.try_into().unwrap()); let user_one_profile_address = publication_dispatcher - .create_profile( - registry_contract_address, account_class_hash, 2478, profile_variant - ); + .create_profile(registry_contract_address, account_class_hash, 2478, profile_variant); let community_id = community_dispatcher.create_community(); let channel_id = channel_dispatcher.create_channel(community_id); @@ -870,9 +831,7 @@ fn test_upvote_should_fail_if_user_already_upvoted() { start_cheat_caller_address(publication_contract_address, USER_TWO.try_into().unwrap()); let user_two_profile_address = publication_dispatcher - .create_profile( - registry_contract_address, account_class_hash, 2478, profile_variant - ); + .create_profile(registry_contract_address, account_class_hash, 2478, profile_variant); let community_id = community_dispatcher.create_community(); let channel_id = channel_dispatcher.create_channel(community_id); let pub_assigned_id = publication_dispatcher @@ -914,9 +873,7 @@ fn test_downvote_should_fail_if_user_already_downvoted() { start_cheat_caller_address(publication_contract_address, USER_TWO.try_into().unwrap()); let user_two_profile_address = publication_dispatcher - .create_profile( - registry_contract_address, account_class_hash, 2478, profile_variant - ); + .create_profile(registry_contract_address, account_class_hash, 2478, profile_variant); let community_id = community_dispatcher.create_community(); let channel_id = channel_dispatcher.create_channel(community_id); let pub_assigned_id = publication_dispatcher @@ -959,9 +916,7 @@ fn test_post_event_emission() { let content_URI: ByteArray = "ipfs://helloworld"; start_cheat_caller_address(publication_contract_address, USER_ONE.try_into().unwrap()); let user_one_profile_address = publication_dispatcher - .create_profile( - registry_contract_address, account_class_hash, 2478, profile_variant - ); + .create_profile(registry_contract_address, account_class_hash, 2478, profile_variant); let community_id = community_dispatcher.create_community(); let channel_id = channel_dispatcher.create_channel(community_id); @@ -1015,9 +970,7 @@ fn test_comment() { let content_URI: ByteArray = "ipfs://helloworld"; start_cheat_caller_address(publication_contract_address, USER_ONE.try_into().unwrap()); let user_one_profile_address = publication_dispatcher - .create_profile( - registry_contract_address, account_class_hash, 2478, profile_variant - ); + .create_profile(registry_contract_address, account_class_hash, 2478, profile_variant); let community_id = community_dispatcher.create_community(); let channel_id = channel_dispatcher.create_channel(community_id); @@ -1034,9 +987,7 @@ fn test_comment() { start_cheat_caller_address(publication_contract_address, USER_TWO.try_into().unwrap()); let user_two_profile_address = publication_dispatcher - .create_profile( - registry_contract_address, account_class_hash, 2478, profile_variant - ); + .create_profile(registry_contract_address, account_class_hash, 2478, profile_variant); community_dispatcher.join_community(community_id); channel_dispatcher.join_channel(channel_id); let content_URI_1 = "ipfs://QmSkDCsS32eLpcymxtn1cEn7Rc5hfefLBgfvZyjaryrga/"; @@ -1100,9 +1051,7 @@ fn test_comment_event_emission() { let content_URI: ByteArray = "ipfs://helloworld"; start_cheat_caller_address(publication_contract_address, USER_ONE.try_into().unwrap()); let user_one_profile_address = publication_dispatcher - .create_profile( - registry_contract_address, account_class_hash, 2478, profile_variant - ); + .create_profile(registry_contract_address, account_class_hash, 2478, profile_variant); let community_id = community_dispatcher.create_community(); let channel_id = channel_dispatcher.create_channel(community_id); @@ -1119,9 +1068,7 @@ fn test_comment_event_emission() { start_cheat_caller_address(publication_contract_address, USER_TWO.try_into().unwrap()); let user_two_profile_address = publication_dispatcher - .create_profile( - registry_contract_address, account_class_hash, 2478, profile_variant - ); + .create_profile(registry_contract_address, account_class_hash, 2478, profile_variant); community_dispatcher.join_community(community_id); channel_dispatcher.join_channel(channel_id); let user_two_comment_on_user_one_assigned_pub_id = publication_dispatcher @@ -1181,9 +1128,7 @@ fn test_repost() { let content_URI: ByteArray = "ipfs://helloworld"; start_cheat_caller_address(publication_contract_address, USER_ONE.try_into().unwrap()); let user_one_profile_address = publication_dispatcher - .create_profile( - registry_contract_address, account_class_hash, 2478, profile_variant - ); + .create_profile(registry_contract_address, account_class_hash, 2478, profile_variant); let community_id = community_dispatcher.create_community(); let channel_id = channel_dispatcher.create_channel(community_id); @@ -1200,9 +1145,7 @@ fn test_repost() { start_cheat_caller_address(publication_contract_address, USER_TWO.try_into().unwrap()); let user_two_profile_address = publication_dispatcher - .create_profile( - registry_contract_address, account_class_hash, 2478, profile_variant - ); + .create_profile(registry_contract_address, account_class_hash, 2478, profile_variant); community_dispatcher.join_community(community_id); channel_dispatcher.join_channel(channel_id); let repost_params = RepostParams { @@ -1255,9 +1198,7 @@ fn test_repost_event_emission() { let content_URI: ByteArray = "ipfs://helloworld"; start_cheat_caller_address(publication_contract_address, USER_ONE.try_into().unwrap()); let user_one_profile_address = publication_dispatcher - .create_profile( - registry_contract_address, account_class_hash, 2478, profile_variant - ); + .create_profile(registry_contract_address, account_class_hash, 2478, profile_variant); let community_id = community_dispatcher.create_community(); let channel_id = channel_dispatcher.create_channel(community_id); @@ -1275,9 +1216,7 @@ fn test_repost_event_emission() { start_cheat_caller_address(publication_contract_address, USER_TWO.try_into().unwrap()); let user_two_profile_address = publication_dispatcher - .create_profile( - registry_contract_address, account_class_hash, 2478, profile_variant - ); + .create_profile(registry_contract_address, account_class_hash, 2478, profile_variant); community_dispatcher.join_community(community_id); channel_dispatcher.join_channel(channel_id); let repost_params = RepostParams { @@ -1334,9 +1273,7 @@ fn test_get_publication_content_uri() { let content_URI: ByteArray = "ipfs://helloworld"; start_cheat_caller_address(publication_contract_address, USER_ONE.try_into().unwrap()); let user_one_profile_address = publication_dispatcher - .create_profile( - registry_contract_address, account_class_hash, 2478, profile_variant - ); + .create_profile(registry_contract_address, account_class_hash, 2478, profile_variant); let community_id = community_dispatcher.create_community(); let channel_id = channel_dispatcher.create_channel(community_id); @@ -1376,9 +1313,7 @@ fn test_get_publication_type() { let content_URI: ByteArray = "ipfs://helloworld"; start_cheat_caller_address(publication_contract_address, USER_ONE.try_into().unwrap()); let user_one_profile_address = publication_dispatcher - .create_profile( - registry_contract_address, account_class_hash, 2478, profile_variant - ); + .create_profile(registry_contract_address, account_class_hash, 2478, profile_variant); let community_id = community_dispatcher.create_community(); let channel_id = channel_dispatcher.create_channel(community_id); @@ -1423,9 +1358,7 @@ fn test_should_fail_if_banned_profile_from_posting() { start_cheat_caller_address(publication_contract_address, USER_ONE.try_into().unwrap()); // Create profile let user_one_profile_address = publication_dispatcher - .create_profile( - registry_contract_address, account_class_hash, 2478, profile_variant - ); + .create_profile(registry_contract_address, account_class_hash, 2478, profile_variant); // Check if community is created let community_id = community_dispatcher.create_community(); // Check if community is created @@ -1442,9 +1375,7 @@ fn test_should_fail_if_banned_profile_from_posting() { ); start_cheat_caller_address(publication_contract_address, USER_TWO.try_into().unwrap()); let user_one_profile_address = publication_dispatcher - .create_profile( - registry_contract_address, account_class_hash, 2478, profile_variant - ); + .create_profile(registry_contract_address, account_class_hash, 2478, profile_variant); community_dispatcher.join_community(community_id); channel_dispatcher.join_channel(channel_id); stop_cheat_caller_address(publication_contract_address); @@ -1494,9 +1425,7 @@ fn test_should_fail_if_not_community_member_while_posting() { start_cheat_caller_address(publication_contract_address, USER_ONE.try_into().unwrap()); let user_one_profile_address = publication_dispatcher - .create_profile( - registry_contract_address, account_class_hash, 2478, profile_variant - ); + .create_profile(registry_contract_address, account_class_hash, 2478, profile_variant); let community_id = community_dispatcher.create_community(); let channel_id = channel_dispatcher.create_channel(community_id); let _pub_assigned_id = publication_dispatcher @@ -1511,9 +1440,7 @@ fn test_should_fail_if_not_community_member_while_posting() { stop_cheat_caller_address(publication_contract_address); start_cheat_caller_address(publication_contract_address, USER_TWO.try_into().unwrap()); let user_two_profile_address = publication_dispatcher - .create_profile( - registry_contract_address, account_class_hash, 24998, profile_variant - ); + .create_profile(registry_contract_address, account_class_hash, 24998, profile_variant); let _pub_assigned_id = publication_dispatcher .post( PostParams { @@ -1550,9 +1477,7 @@ fn test_tip() { start_cheat_caller_address(publication_contract_address, USER_ONE.try_into().unwrap()); // Create profile let user_one_profile_address = publication_dispatcher - .create_profile( - registry_contract_address, account_class_hash, 2478, profile_variant - ); + .create_profile(registry_contract_address, account_class_hash, 2478, profile_variant); // Check if community is created let community_id = community_dispatcher.create_community(); // Check if community is created @@ -1571,9 +1496,7 @@ fn test_tip() { // USER_TWO joins community start_cheat_caller_address(publication_contract_address, USER_TWO.try_into().unwrap()); let _user_two_profile_address = publication_dispatcher - .create_profile( - registry_contract_address, account_class_hash, 2478, profile_variant - ); + .create_profile(registry_contract_address, account_class_hash, 2478, profile_variant); community_dispatcher.join_community(community_id); channel_dispatcher.join_channel(channel_id); stop_cheat_caller_address(publication_contract_address); @@ -1627,9 +1550,7 @@ fn test_collect() { start_cheat_caller_address(publication_contract_address, USER_ONE.try_into().unwrap()); // Create profile let user_one_profile_address = publication_dispatcher - .create_profile( - registry_contract_address, account_class_hash, 2478, profile_variant - ); + .create_profile(registry_contract_address, account_class_hash, 2478, profile_variant); // Check if community is created let community_id = community_dispatcher.create_community(); // Check if community is created @@ -1648,18 +1569,14 @@ fn test_collect() { start_cheat_caller_address(publication_contract_address, USER_TWO.try_into().unwrap()); let _user_two_profile_address = publication_dispatcher - .create_profile( - registry_contract_address, account_class_hash, 2478, profile_variant - ); + .create_profile(registry_contract_address, account_class_hash, 2478, profile_variant); community_dispatcher.join_community(community_id); channel_dispatcher.join_channel(channel_id); stop_cheat_caller_address(publication_contract_address); start_cheat_caller_address(publication_contract_address, USER_THREE.try_into().unwrap()); let _user_three_profile_address = publication_dispatcher - .create_profile( - registry_contract_address, account_class_hash, 2478, profile_variant - ); + .create_profile(registry_contract_address, account_class_hash, 2478, profile_variant); community_dispatcher.join_community(community_id); channel_dispatcher.join_channel(channel_id); stop_cheat_caller_address(publication_contract_address);