Skip to content

Commit

Permalink
feat: make contracts upgradeable
Browse files Browse the repository at this point in the history
  • Loading branch information
Darlington02 committed Dec 17, 2024
1 parent 977075e commit aaa3d17
Show file tree
Hide file tree
Showing 23 changed files with 260 additions and 198 deletions.
7 changes: 7 additions & 0 deletions Scarb.lock
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ dependencies = [
"openzeppelin_access",
"openzeppelin_introspection",
"openzeppelin_token",
"openzeppelin_upgrades",
"snforge_std",
"token_bound_accounts",
]
Expand Down Expand Up @@ -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"
Expand Down
1 change: 1 addition & 0 deletions Scarb.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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" }
Expand Down
25 changes: 23 additions & 2 deletions src/coloniznft/coloniznft.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)]
Expand All @@ -41,6 +44,8 @@ pub mod ColonizNFT {
impl OwnableImpl = OwnableComponent::OwnableImpl<ContractState>;
impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;

impl UpgradeableInternalImpl = UpgradeableComponent::InternalImpl<ContractState>;


// *************************************************************************
// STORAGE
Expand All @@ -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<u256, u64>,
Expand All @@ -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", "");
}

Expand All @@ -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
// *************************************************************************
Expand Down
8 changes: 6 additions & 2 deletions src/community/community.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -895,11 +898,12 @@ pub mod CommunityComponent {
fn _deploy_community_nft(
ref self: ComponentState<TContractState>,
community_id: u256,
community_owner: ContractAddress,
community_nft_impl_class_hash: ClassHash,
salt: felt252
) -> ContractAddress {
let mut constructor_calldata: Array<felt252> = 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(
Expand Down
36 changes: 32 additions & 4 deletions src/community/communitynft.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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<ContractState>;
impl ERC721InternalImpl = ERC721Component::InternalImpl<ContractState>;

// add an owner
#[abi(embed_v0)]
impl OwnableImpl = OwnableComponent::OwnableImpl<ContractState>;
impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;

impl UpgradeableInternalImpl = UpgradeableComponent::InternalImpl<ContractState>;

// *************************************************************************
// STORAGE
// *************************************************************************
Expand All @@ -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<u256, u64>,
user_token_id: Map<ContractAddress, u256>,
Expand All @@ -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);
}

Expand Down Expand Up @@ -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
// *************************************************************************
Expand Down
22 changes: 20 additions & 2 deletions src/follownft/follownft.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)]
Expand All @@ -40,6 +42,8 @@ pub mod Follow {
impl OwnableImpl = OwnableComponent::OwnableImpl<ContractState>;
impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;

impl UpgradeableInternalImpl = UpgradeableComponent::InternalImpl<ContractState>;

// *************************************************************************
// STORAGE
// *************************************************************************
Expand All @@ -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,
Expand All @@ -72,6 +78,8 @@ pub mod Follow {
SRC5Event: SRC5Component::Event,
#[flat]
OwnableEvent: OwnableComponent::Event,
#[flat]
UpgradeableEvent: UpgradeableComponent::Event,
Followed: Followed,
Unfollowed: Unfollowed,
FollowerBlocked: FollowerBlocked,
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
// *************************************************************************
Expand Down
Loading

0 comments on commit aaa3d17

Please sign in to comment.