diff --git a/pallets/pallet-bonded-coins/src/mock.rs b/pallets/pallet-bonded-coins/src/mock.rs index df56db37be..7bd25ab5c6 100644 --- a/pallets/pallet-bonded-coins/src/mock.rs +++ b/pallets/pallet-bonded-coins/src/mock.rs @@ -36,7 +36,7 @@ pub type AccountId = ::AccountId; // accounts pub(crate) const ACCOUNT_00: AccountId = AccountId::new([0u8; 32]); pub(crate) const ACCOUNT_01: AccountId = AccountId::new([1u8; 32]); -const ACCOUNT_99: AccountId = AccountId::new([99u8; 32]); +pub(crate) const ACCOUNT_99: AccountId = AccountId::new([99u8; 32]); // assets pub(crate) const DEFAULT_BONDED_CURRENCY_ID: AssetId = 1; pub(crate) const DEFAULT_COLLATERAL_CURRENCY_ID: AssetId = 0; diff --git a/pallets/pallet-bonded-coins/src/tests/transactions/create_pool.rs b/pallets/pallet-bonded-coins/src/tests/transactions/create_pool.rs index bc1d3adb2e..3f9f03d4b8 100644 --- a/pallets/pallet-bonded-coins/src/tests/transactions/create_pool.rs +++ b/pallets/pallet-bonded-coins/src/tests/transactions/create_pool.rs @@ -6,6 +6,7 @@ use frame_support::{ }; use frame_system::{pallet_prelude::OriginFor, RawOrigin}; use pallet_assets::Error as AssetsPalletErrors; +use sp_core::bounded_vec; use sp_runtime::{ArithmeticError, BoundedVec}; use sp_std::ops::Sub; @@ -38,7 +39,7 @@ fn single_currency() { origin, curve, DEFAULT_COLLATERAL_CURRENCY_ID, - BoundedVec::truncate_from(vec![bonded_token]), + bounded_vec![bonded_token], DEFAULT_BONDED_DENOMINATION, true )); @@ -118,7 +119,7 @@ fn multi_currency() { min_balance: 1, }; - let bonded_tokens = vec![bonded_token; 3]; + let bonded_tokens = bounded_vec![bonded_token; 3]; let next_asset_id = NextAssetId::::get(); @@ -126,7 +127,7 @@ fn multi_currency() { origin, curve, DEFAULT_COLLATERAL_CURRENCY_ID, - BoundedVec::truncate_from(bonded_tokens), + bonded_tokens, DEFAULT_BONDED_DENOMINATION, true )); @@ -179,7 +180,7 @@ fn can_create_identical_pools() { origin.clone(), curve.clone(), DEFAULT_COLLATERAL_CURRENCY_ID, - BoundedVec::truncate_from(vec![bonded_token.clone()]), + bounded_vec![bonded_token.clone()], DEFAULT_BONDED_DENOMINATION, true )); @@ -188,7 +189,7 @@ fn can_create_identical_pools() { origin, curve, DEFAULT_COLLATERAL_CURRENCY_ID, - BoundedVec::truncate_from(vec![bonded_token]), + bounded_vec![bonded_token], DEFAULT_BONDED_DENOMINATION, true )); @@ -226,7 +227,7 @@ fn fails_if_collateral_not_exists() { origin, curve, 100, - BoundedVec::truncate_from(vec![bonded_token]), + bounded_vec![bonded_token], DEFAULT_BONDED_DENOMINATION, true ), @@ -258,7 +259,7 @@ fn cannot_create_circular_pool() { curve, // try specifying the id of the currency to be created as collateral next_asset_id, - BoundedVec::truncate_from(vec![bonded_token]), + bounded_vec![bonded_token], DEFAULT_BONDED_DENOMINATION, true ), @@ -291,8 +292,8 @@ fn handles_asset_id_overflow() { origin, curve, 0, - BoundedVec::truncate_from(vec![bonded_token; 2]), - 10, + bounded_vec![bonded_token; 2], + DEFAULT_BONDED_DENOMINATION, true ), ArithmeticError::Overflow diff --git a/pallets/pallet-bonded-coins/src/tests/transactions/mod.rs b/pallets/pallet-bonded-coins/src/tests/transactions/mod.rs index ca68349384..6087db4cd9 100644 --- a/pallets/pallet-bonded-coins/src/tests/transactions/mod.rs +++ b/pallets/pallet-bonded-coins/src/tests/transactions/mod.rs @@ -1,6 +1,8 @@ mod burn_into; mod create_pool; mod mint_into; +mod reset_manager; +mod reset_team; mod set_lock; mod swap_into; mod unlock; diff --git a/pallets/pallet-bonded-coins/src/tests/transactions/reset_manager.rs b/pallets/pallet-bonded-coins/src/tests/transactions/reset_manager.rs new file mode 100644 index 0000000000..560af42645 --- /dev/null +++ b/pallets/pallet-bonded-coins/src/tests/transactions/reset_manager.rs @@ -0,0 +1,95 @@ +use frame_support::{assert_err, assert_ok}; +use frame_system::RawOrigin; + +use crate::{ + mock::{runtime::*, *}, + types::PoolStatus, + Error as BondingPalletErrors, Event as BondingPalletEvents, Pools, +}; + +#[test] +fn changes_manager() { + let curve = get_linear_bonding_curve(); + + let pool_details = generate_pool_details( + vec![DEFAULT_BONDED_CURRENCY_ID], + curve, + false, + Some(PoolStatus::Active), + Some(ACCOUNT_00), + None, + None, + ); + let pool_id = calculate_pool_id(&[DEFAULT_BONDED_CURRENCY_ID]); + ExtBuilder::default() + .with_pools(vec![(pool_id.clone(), pool_details.clone())]) + .build() + .execute_with(|| { + let origin = RawOrigin::Signed(ACCOUNT_00).into(); + assert_ok!(BondingPallet::reset_manager(origin, pool_id.clone(), Some(ACCOUNT_01))); + + System::assert_has_event( + BondingPalletEvents::ManagerUpdated { + id: pool_id.clone(), + manager: Some(ACCOUNT_01), + } + .into(), + ); + + let new_details = Pools::::get(&pool_id).unwrap(); + assert_eq!(new_details.manager, Some(ACCOUNT_01)); + assert_eq!(new_details.owner, pool_details.owner) + }) +} + +#[test] +fn only_manager_can_change_manager() { + let curve = get_linear_bonding_curve(); + + let manager = AccountId::new([10u8; 32]); + let pool_details = generate_pool_details( + vec![DEFAULT_BONDED_CURRENCY_ID], + curve, + false, + Some(PoolStatus::Active), + Some(manager.clone()), + None, + Some(ACCOUNT_00), + ); + let pool_id = calculate_pool_id(&[DEFAULT_BONDED_CURRENCY_ID]); + ExtBuilder::default() + .with_pools(vec![(pool_id.clone(), pool_details.clone())]) + .build() + .execute_with(|| { + let owner_origin = RawOrigin::Signed(ACCOUNT_00).into(); + let other_origin = RawOrigin::Signed(ACCOUNT_01).into(); + + assert_err!( + BondingPallet::reset_manager(owner_origin, pool_id.clone(), Some(ACCOUNT_00)), + BondingPalletErrors::::NoPermission + ); + + assert_err!( + BondingPallet::reset_manager(other_origin, pool_id.clone(), Some(ACCOUNT_00)), + BondingPalletErrors::::NoPermission + ); + + let new_details = Pools::::get(&pool_id).unwrap(); + assert_eq!(new_details.manager, Some(manager)); + }) +} + +#[test] +fn cant_change_manager_if_pool_nonexistent() { + let pool_id = calculate_pool_id(&[DEFAULT_BONDED_CURRENCY_ID]); + ExtBuilder::default().build().execute_with(|| { + let origin = RawOrigin::Signed(ACCOUNT_00).into(); + + assert!(Pools::::get(&pool_id).is_none()); + + assert_err!( + BondingPallet::reset_manager(origin, pool_id.clone(), Some(ACCOUNT_00)), + BondingPalletErrors::::PoolUnknown + ); + }) +} diff --git a/pallets/pallet-bonded-coins/src/tests/transactions/reset_team.rs b/pallets/pallet-bonded-coins/src/tests/transactions/reset_team.rs new file mode 100644 index 0000000000..a3b4322217 --- /dev/null +++ b/pallets/pallet-bonded-coins/src/tests/transactions/reset_team.rs @@ -0,0 +1,184 @@ +use frame_support::{assert_err, assert_ok, traits::fungibles::roles::Inspect}; +use frame_system::RawOrigin; + +use crate::{ + mock::{runtime::*, *}, + types::{PoolManagingTeam, PoolStatus}, + Error as BondingPalletErrors, +}; + +#[test] +fn resets_team() { + let pool_details = generate_pool_details( + vec![DEFAULT_BONDED_CURRENCY_ID], + get_linear_bonding_curve(), + false, + Some(PoolStatus::Active), + Some(ACCOUNT_00), + None, + None, + ); + let pool_id = calculate_pool_id(&[DEFAULT_BONDED_CURRENCY_ID]); + + ExtBuilder::default() + .with_pools(vec![(pool_id.clone(), pool_details.clone())]) + .build() + .execute_with(|| { + let manager_origin = RawOrigin::Signed(ACCOUNT_00).into(); + + assert_ok!(BondingPallet::reset_team( + manager_origin, + pool_id.clone(), + PoolManagingTeam { + admin: ACCOUNT_00, + freezer: ACCOUNT_01, + }, + 0 + )); + + assert_eq!( + ::Fungibles::admin(DEFAULT_BONDED_CURRENCY_ID), + Some(ACCOUNT_00) + ); + assert_eq!( + ::Fungibles::freezer(DEFAULT_BONDED_CURRENCY_ID), + Some(ACCOUNT_01) + ); + assert_eq!( + ::Fungibles::owner(DEFAULT_BONDED_CURRENCY_ID), + Some(pool_id.clone()) + ); + assert_eq!( + ::Fungibles::issuer(DEFAULT_BONDED_CURRENCY_ID), + Some(pool_id) + ); + }) +} + +#[test] +fn does_not_change_team_when_not_live() { + let pool_details = generate_pool_details( + vec![DEFAULT_BONDED_CURRENCY_ID], + get_linear_bonding_curve(), + false, + Some(PoolStatus::Refunding), + Some(ACCOUNT_00), + None, + None, + ); + let pool_id = calculate_pool_id(&[DEFAULT_BONDED_CURRENCY_ID]); + + ExtBuilder::default() + .with_pools(vec![(pool_id.clone(), pool_details.clone())]) + .build() + .execute_with(|| { + let manager_origin = RawOrigin::Signed(ACCOUNT_00).into(); + + assert_err!( + BondingPallet::reset_team( + manager_origin, + pool_id.clone(), + PoolManagingTeam { + admin: ACCOUNT_00, + freezer: ACCOUNT_00, + }, + 0 + ), + BondingPalletErrors::::PoolNotLive + ); + + assert_eq!( + ::Fungibles::admin(DEFAULT_BONDED_CURRENCY_ID), + Some(pool_id) + ); + }) +} + +#[test] +fn only_manager_can_change_team() { + let curve = get_linear_bonding_curve(); + + let manager = AccountId::new([10u8; 32]); + let pool_details = generate_pool_details( + vec![DEFAULT_BONDED_CURRENCY_ID], + curve, + false, + Some(PoolStatus::Active), + Some(manager.clone()), + None, + Some(ACCOUNT_00), + ); + let pool_id = calculate_pool_id(&[DEFAULT_BONDED_CURRENCY_ID]); + ExtBuilder::default() + .with_pools(vec![(pool_id.clone(), pool_details.clone())]) + .build() + .execute_with(|| { + let owner_origin = RawOrigin::Signed(ACCOUNT_00).into(); + let other_origin = RawOrigin::Signed(ACCOUNT_01).into(); + + assert_err!( + BondingPallet::reset_team( + owner_origin, + pool_id.clone(), + PoolManagingTeam { + admin: ACCOUNT_00, + freezer: ACCOUNT_00, + }, + 0 + ), + BondingPalletErrors::::NoPermission + ); + + assert_err!( + BondingPallet::reset_team( + other_origin, + pool_id.clone(), + PoolManagingTeam { + admin: ACCOUNT_00, + freezer: ACCOUNT_00, + }, + 0 + ), + BondingPalletErrors::::NoPermission + ); + + assert_eq!( + ::Fungibles::admin(DEFAULT_BONDED_CURRENCY_ID), + Some(pool_id) + ); + }) +} + +#[test] +fn handles_currency_idx_out_of_bounds() { + let pool_details = generate_pool_details( + vec![DEFAULT_BONDED_CURRENCY_ID], + get_linear_bonding_curve(), + false, + Some(PoolStatus::Active), + Some(ACCOUNT_00), + None, + None, + ); + let pool_id = calculate_pool_id(&[DEFAULT_BONDED_CURRENCY_ID]); + + ExtBuilder::default() + .with_pools(vec![(pool_id.clone(), pool_details.clone())]) + .build() + .execute_with(|| { + let manager_origin = RawOrigin::Signed(ACCOUNT_00).into(); + + assert_err!( + BondingPallet::reset_team( + manager_origin, + pool_id.clone(), + PoolManagingTeam { + admin: ACCOUNT_00, + freezer: ACCOUNT_00, + }, + 2 + ), + BondingPalletErrors::::IndexOutOfBounds + ); + }) +}