Skip to content
This repository has been archived by the owner on May 15, 2024. It is now read-only.

Remove NFT collection generetaion from NFT-Staking genesis #240

Merged
merged 5 commits into from
Mar 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 36 additions & 1 deletion pallets/ajuna-nft-staking/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,12 @@ fn create_contract_clause<T: Config>(attr_key: u32, attr_value: u64) -> Contract
)
}

fn create_staking_contract_collection<T: Config>(account: &T::AccountId) -> T::CollectionId {
let collection_config = <T as crate::pallet::Config>::ContractCollectionConfig::get();
<T as crate::pallet::Config>::NftHelper::create_collection(account, account, &collection_config)
.expect("Should have create contract collection")
}

type ContractClauseOf<T> = ContractClause<
<T as frame_system::Config>::AccountId,
<T as Config>::ContractAttributeKey,
Expand All @@ -158,6 +164,15 @@ benchmarks! {
assert_last_event::<T>(Event::OrganizerSet { organizer }.into())
}

set_contract_collection_id {
let account = NftStake::<T>::treasury_account_id();
let collection_id = create_staking_contract_collection::<T>(&account);
Organizer::<T>::put(&account);
}: _(RawOrigin::Signed(account), collection_id)
verify {
assert_last_event::<T>(Event::ContractCollectionSet { collection_id }.into())
}

set_locked_state {
let organizer = prepare_account::<T>("ALICE");
Organizer::<T>::put(&organizer);
Expand All @@ -175,6 +190,10 @@ benchmarks! {
}

submit_staking_contract_token_reward {
let account = NftStake::<T>::treasury_account_id();
let collection_id = create_staking_contract_collection::<T>(&account);
ContractCollectionId::<T>::put(collection_id);

let caller = prepare_account::<T>("ALICE");
let reward_amt: BalanceOf<T> = 1_000_u32.into();
let reward = StakingRewardOf::<T>::Tokens(reward_amt);
Expand All @@ -187,6 +206,10 @@ benchmarks! {
}

submit_staking_contract_nft_reward {
let account = NftStake::<T>::treasury_account_id();
let collection_id = create_staking_contract_collection::<T>(&account);
ContractCollectionId::<T>::put(collection_id);

let caller = prepare_account::<T>("ALICE");
let collection_id = create_random_nft_collection::<T>(caller.clone());
let nft_addr = create_random_nft::<T>(&caller, collection_id, 0_u32.into());
Expand All @@ -200,6 +223,10 @@ benchmarks! {
}

take_staking_contract {
let account = NftStake::<T>::treasury_account_id();
let collection_id = create_staking_contract_collection::<T>(&account);
ContractCollectionId::<T>::put(collection_id);

let caller = prepare_account::<T>("ALICE");
let reward_amt: BalanceOf<T> = 1_000_u32.into();
let reward = StakingRewardOf::<T>::Tokens(reward_amt);
Expand All @@ -220,6 +247,10 @@ benchmarks! {
}

redeem_staking_contract_token_reward {
let account = NftStake::<T>::treasury_account_id();
let collection_id = create_staking_contract_collection::<T>(&account);
ContractCollectionId::<T>::put(collection_id);

let caller = prepare_account::<T>("ALICE");
let reward_amt: BalanceOf<T> = 1_000_u32.into();
let reward = StakingRewardOf::<T>::Tokens(reward_amt);
Expand All @@ -243,6 +274,10 @@ benchmarks! {
}

redeem_staking_contract_nft_reward {
let account = NftStake::<T>::treasury_account_id();
let collection_id = create_staking_contract_collection::<T>(&account);
ContractCollectionId::<T>::put(collection_id);

let caller = prepare_account::<T>("ALICE");
let collection_id = create_random_nft_collection::<T>(caller.clone());
let reward_nft_addr = create_random_nft::<T>(&caller, collection_id, 0_u32.into());
Expand All @@ -267,6 +302,6 @@ benchmarks! {
}

impl_benchmark_test_suite!(
NftStake, crate::mock::ExtBuilder::default().build(), crate::mock::Test
NftStake, crate::mock::ExtBuilder::default().create_collection(true).build(), crate::mock::Test
);
}
47 changes: 32 additions & 15 deletions pallets/ajuna-nft-staking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ pub mod pallet {
pub type TreasuryAccount<T: Config> = StorageValue<_, AccountIdOf<T>, OptionQuery>;

#[pallet::storage]
#[pallet::getter(fn contract_collection_id)]
pub type ContractCollectionId<T: Config> =
StorageValue<_, CollectionIdOf<T>, ResultQuery<Error<T>::ContractNotFound>>;

Expand Down Expand Up @@ -289,20 +290,16 @@ pub mod pallet {
if T::Currency::free_balance(&account_id) < min {
let _ = T::Currency::make_free_balance_be(&account_id, min);
}

let collection_config = T::ContractCollectionConfig::get();
let collection_id =
T::NftHelper::create_collection(&account_id, &account_id, &collection_config)
.expect("Should have create contract collection");
ContractCollectionId::<T>::put(collection_id);
}
}

#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> {
/// An organizer has been set.
OrganizerSet { organizer: T::AccountId },
OrganizerSet { organizer: AccountIdOf<T> },
/// The collection holding the staking contracts has been set.
ContractCollectionSet { collection_id: T::CollectionId },
/// The pallet's lock status has been set
LockedStateSet { locked_state: PalletLockedState },
/// A new staking contract has been successfully created
Expand All @@ -324,6 +321,8 @@ pub mod pallet {
pub enum Error<T> {
/// There is no account set as the organizer
OrganizerNotSet,
/// The contract collection is either non-existent or not owned by the organizer.
InvalidContractCollection,
/// The pallet is currently locked and cannot be interacted with.
PalletLocked,
/// The treasury doesn't have enough funds to pay the contract rewards.
Expand Down Expand Up @@ -353,29 +352,47 @@ pub mod pallet {

#[pallet::call]
impl<T: Config> Pallet<T> {
#[pallet::call_index(0)]
#[pallet::weight(T::WeightInfo::set_organizer())]
#[pallet::call_index(0)]
pub fn set_organizer(origin: OriginFor<T>, organizer: T::AccountId) -> DispatchResult {
ensure_root(origin)?;
Organizer::<T>::put(&organizer);
Self::deposit_event(Event::OrganizerSet { organizer });
Ok(())
}

#[pallet::weight(T::WeightInfo::set_contract_collection_id())]
#[pallet::call_index(1)]
pub fn set_contract_collection_id(
origin: OriginFor<T>,
collection_id: T::CollectionId,
) -> DispatchResult {
let account = Self::ensure_organizer(origin)?;
ensure!(
T::NftHelper::collection_owner(&collection_id)
.filter(|owner| *owner == account)
.is_some(),
Error::<T>::InvalidContractCollection
);
ContractCollectionId::<T>::put(collection_id);
Self::deposit_event(Event::ContractCollectionSet { collection_id });
Ok(())
}

#[pallet::weight(T::WeightInfo::set_locked_state())]
#[pallet::call_index(2)]
pub fn set_locked_state(
origin: OriginFor<T>,
locked_state: PalletLockedState,
) -> DispatchResult {
Self::ensure_organizer(origin)?;
let _ = Self::ensure_organizer(origin)?;
LockedState::<T>::put(locked_state);
Self::deposit_event(Event::LockedStateSet { locked_state });
Ok(())
}

#[pallet::weight(T::WeightInfo::fund_treasury())]
#[pallet::call_index(2)]
#[pallet::call_index(3)]
pub fn fund_treasury(origin: OriginFor<T>, fund_amount: BalanceOf<T>) -> DispatchResult {
let account = ensure_signed(origin)?;

Expand Down Expand Up @@ -404,7 +421,7 @@ pub mod pallet {
}

#[pallet::weight(T::WeightInfo::submit_staking_contract_nft_reward())]
#[pallet::call_index(3)]
#[pallet::call_index(4)]
pub fn submit_staking_contract(
origin: OriginFor<T>,
staking_contract: StakingContractOf<T>,
Expand Down Expand Up @@ -433,7 +450,7 @@ pub mod pallet {
}

#[pallet::weight(T::WeightInfo::take_staking_contract())]
#[pallet::call_index(4)]
#[pallet::call_index(5)]
pub fn take_staking_contract(
origin: OriginFor<T>,
contract_id: ContractItemIdOf<T>,
Expand Down Expand Up @@ -476,7 +493,7 @@ pub mod pallet {
}

#[pallet::weight(T::WeightInfo::redeem_staking_contract_nft_reward())]
#[pallet::call_index(5)]
#[pallet::call_index(6)]
pub fn redeem_staking_contract(
origin: OriginFor<T>,
contract_id: ContractItemIdOf<T>,
Expand Down Expand Up @@ -515,11 +532,11 @@ pub mod pallet {
}

impl<T: Config> Pallet<T> {
fn ensure_organizer(origin: OriginFor<T>) -> DispatchResult {
fn ensure_organizer(origin: OriginFor<T>) -> Result<AccountIdOf<T>, DispatchError> {
let maybe_organizer = ensure_signed(origin)?;
let existing_organizer = Self::organizer().ok_or(Error::<T>::OrganizerNotSet)?;
ensure!(maybe_organizer == existing_organizer, DispatchError::BadOrigin);
Ok(())
Ok(maybe_organizer)
}

fn ensure_unlocked() -> DispatchResult {
Expand Down
23 changes: 22 additions & 1 deletion pallets/ajuna-nft-staking/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
use crate::{self as pallet_nft_staking, *};
use frame_support::{
parameter_types,
traits::{AsEnsureOriginWithArg, ConstU16, ConstU64, Hooks},
traits::{tokens::nonfungibles_v2::Create, AsEnsureOriginWithArg, ConstU16, ConstU64, Hooks},
};
use frame_system::{
mocking::{MockBlock, MockUncheckedExtrinsic},
Expand Down Expand Up @@ -175,6 +175,7 @@ impl pallet_nft_staking::Config for Test {

pub struct ExtBuilder {
balances: Vec<(MockAccountId, MockBalance)>,
create_collection: bool,
}

impl Default for ExtBuilder {
Expand All @@ -187,6 +188,7 @@ impl Default for ExtBuilder {
(BOB, accounts_balance),
(CHARLIE, accounts_balance),
],
create_collection: true,
}
}
}
Expand All @@ -197,6 +199,11 @@ impl ExtBuilder {
self
}

pub fn create_collection(mut self, create_collection: bool) -> Self {
self.create_collection = create_collection;
self
}

pub fn build(self) -> sp_io::TestExternalities {
let config = GenesisConfig {
system: Default::default(),
Expand All @@ -206,6 +213,20 @@ impl ExtBuilder {

let mut ext: sp_io::TestExternalities = config.build_storage().unwrap().into();
ext.execute_with(|| System::set_block_number(1));
if self.create_collection {
ext.execute_with(|| {
let account_id = <Pallet<Test>>::treasury_account_id();
let collection_config =
<Test as crate::pallet::Config>::ContractCollectionConfig::get();
let collection_id = <Test as crate::pallet::Config>::NftHelper::create_collection(
&account_id,
&account_id,
&collection_config,
)
.expect("Should have create contract collection");
ContractCollectionId::<Test>::put(collection_id);
});
}
ext
}
}
Expand Down
69 changes: 69 additions & 0 deletions pallets/ajuna-nft-staking/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,75 @@ mod organizer {
}
}

mod set_contract_collection_id {
use super::*;

#[test]
fn set_contract_collection_id_succesfully() {
ExtBuilder::default().create_collection(false).build().execute_with(|| {
assert!(NftStake::contract_collection_id().is_err());

assert_ok!(NftStake::set_organizer(RuntimeOrigin::root(), ALICE));

let collection_config =
<Test as crate::pallet::Config>::ContractCollectionConfig::get();
let collection_id = <Test as crate::pallet::Config>::NftHelper::create_collection(
&ALICE,
&ALICE,
&collection_config,
)
.expect("Should have create contract collection");

assert_ok!(NftStake::set_contract_collection_id(
RuntimeOrigin::signed(ALICE),
collection_id
));
assert_eq!(NftStake::contract_collection_id().unwrap(), collection_id);

System::assert_last_event(mock::RuntimeEvent::NftStake(
crate::Event::ContractCollectionSet { collection_id },
));
});
}

#[test]
fn set_contract_collection_id_should_reject_non_existing_collection() {
ExtBuilder::default().create_collection(false).build().execute_with(|| {
assert!(NftStake::contract_collection_id().is_err());

assert_ok!(NftStake::set_organizer(RuntimeOrigin::root(), ALICE));

assert_noop!(
NftStake::set_contract_collection_id(RuntimeOrigin::signed(ALICE), 17),
Error::<Test>::InvalidContractCollection
);
});
}

#[test]
fn set_contract_collection_id_should_reject_non_organizer_owned_collection() {
ExtBuilder::default().create_collection(false).build().execute_with(|| {
assert!(NftStake::contract_collection_id().is_err());

assert_ok!(NftStake::set_organizer(RuntimeOrigin::root(), ALICE));

let collection_config =
<Test as crate::pallet::Config>::ContractCollectionConfig::get();
let collection_id = <Test as crate::pallet::Config>::NftHelper::create_collection(
&BOB,
&ALICE,
&collection_config,
)
.expect("Should have created contract collection");

assert_noop!(
NftStake::set_contract_collection_id(RuntimeOrigin::signed(ALICE), collection_id),
Error::<Test>::InvalidContractCollection
);
});
}
}

mod set_lock_state {
use super::*;

Expand Down
Loading