Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dApp Staking v3 - Legacy Ledger Support #1120

Merged
merged 3 commits into from
Jan 3, 2024
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
50 changes: 37 additions & 13 deletions pallets/dapp-staking-v3/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,30 @@ pub mod pallet {

#[pallet::call]
impl<T: Config> Pallet<T> {
/// Wrapper around _legacy-like_ `unbond_and_unstake`.
///
/// Used to support legacy Ledger users so they can start the unlocking process for their funds.
#[pallet::call_index(4)]
#[pallet::weight(T::WeightInfo::unlock())]
pub fn unbond_and_unstake(
origin: OriginFor<T>,
_contract_id: T::SmartContract,
#[pallet::compact] value: Balance,
) -> DispatchResult {
// Once new period begins, all stakes are reset to zero, so all it remains to be done is the `unlock`
Self::unlock(origin, value)
}

/// Wrapper around _legacy-like_ `withdraw_unbonded`.
///
/// Used to support legacy Ledger users so they can reclaim unlocked chunks back into
/// their _transferable_ free balance.
#[pallet::call_index(5)]
#[pallet::weight(T::WeightInfo::claim_unlocked(T::MaxNumberOfStakedContracts::get()))]
pub fn withdraw_unbonded(origin: OriginFor<T>) -> DispatchResultWithPostInfo {
Self::claim_unlocked(origin)
}

/// Used to enable or disable maintenance mode.
/// Can only be called by manager origin.
#[pallet::call_index(0)]
Expand Down Expand Up @@ -706,7 +730,7 @@ pub mod pallet {
/// This doesn't remove the dApp completely from the system just yet, but it can no longer be used for staking.
///
/// Can be called by dApp staking manager origin.
#[pallet::call_index(4)]
#[pallet::call_index(6)]
#[pallet::weight(T::WeightInfo::unregister())]
pub fn unregister(
origin: OriginFor<T>,
Expand Down Expand Up @@ -744,7 +768,7 @@ pub mod pallet {
/// After adjustment, lock amount must be greater than zero and in total must be equal or greater than the minimum locked amount.
///
/// Locked amount can immediately be used for staking.
#[pallet::call_index(5)]
#[pallet::call_index(7)]
#[pallet::weight(T::WeightInfo::lock())]
pub fn lock(origin: OriginFor<T>, #[pallet::compact] amount: Balance) -> DispatchResult {
Self::ensure_pallet_enabled()?;
Expand Down Expand Up @@ -783,7 +807,7 @@ pub mod pallet {
/// Only the amount that isn't actively used for staking can be unlocked.
/// If the amount is greater than the available amount for unlocking, everything is unlocked.
/// If the remaining locked amount would take the account below the minimum locked amount, everything is unlocked.
#[pallet::call_index(6)]
#[pallet::call_index(8)]
#[pallet::weight(T::WeightInfo::unlock())]
pub fn unlock(origin: OriginFor<T>, #[pallet::compact] amount: Balance) -> DispatchResult {
Self::ensure_pallet_enabled()?;
Expand Down Expand Up @@ -836,7 +860,7 @@ pub mod pallet {
}

/// Claims all of fully unlocked chunks, removing the lock from them.
#[pallet::call_index(7)]
#[pallet::call_index(9)]
#[pallet::weight(T::WeightInfo::claim_unlocked(T::MaxNumberOfStakedContracts::get()))]
pub fn claim_unlocked(origin: OriginFor<T>) -> DispatchResultWithPostInfo {
Self::ensure_pallet_enabled()?;
Expand Down Expand Up @@ -866,7 +890,7 @@ pub mod pallet {
Ok(Some(T::WeightInfo::claim_unlocked(removed_entries)).into())
}

#[pallet::call_index(8)]
#[pallet::call_index(10)]
#[pallet::weight(T::WeightInfo::relock_unlocking())]
pub fn relock_unlocking(origin: OriginFor<T>) -> DispatchResult {
Self::ensure_pallet_enabled()?;
Expand Down Expand Up @@ -903,7 +927,7 @@ pub mod pallet {
/// and same for `Build&Earn` subperiod.
///
/// Staked amount is only eligible for rewards from the next era onwards.
#[pallet::call_index(9)]
#[pallet::call_index(11)]
#[pallet::weight(T::WeightInfo::stake())]
pub fn stake(
origin: OriginFor<T>,
Expand Down Expand Up @@ -1030,7 +1054,7 @@ pub mod pallet {
/// In case amount is unstaked during `Voting` subperiod, the `voting` amount is reduced.
/// In case amount is unstaked during `Build&Earn` subperiod, first the `build_and_earn` is reduced,
/// and any spillover is subtracted from the `voting` amount.
#[pallet::call_index(10)]
#[pallet::call_index(12)]
#[pallet::weight(T::WeightInfo::unstake())]
pub fn unstake(
origin: OriginFor<T>,
Expand Down Expand Up @@ -1132,7 +1156,7 @@ pub mod pallet {

/// Claims some staker rewards, if user has any.
/// In the case of a successfull call, at least one era will be claimed, with the possibility of multiple claims happening.
#[pallet::call_index(11)]
#[pallet::call_index(13)]
#[pallet::weight({
let max_span_length = T::EraRewardSpanLength::get();
T::WeightInfo::claim_staker_rewards_ongoing_period(max_span_length)
Expand Down Expand Up @@ -1226,7 +1250,7 @@ pub mod pallet {
}

/// Used to claim bonus reward for a smart contract, if eligible.
#[pallet::call_index(12)]
#[pallet::call_index(14)]
#[pallet::weight(T::WeightInfo::claim_bonus_reward())]
pub fn claim_bonus_reward(
origin: OriginFor<T>,
Expand Down Expand Up @@ -1291,7 +1315,7 @@ pub mod pallet {
}

/// Used to claim dApp reward for the specified era.
#[pallet::call_index(13)]
#[pallet::call_index(15)]
#[pallet::weight(T::WeightInfo::claim_dapp_reward())]
pub fn claim_dapp_reward(
origin: OriginFor<T>,
Expand Down Expand Up @@ -1347,7 +1371,7 @@ pub mod pallet {

/// Used to unstake funds from a contract that was unregistered after an account staked on it.
/// This is required if staker wants to re-stake these funds on another active contract during the ongoing period.
#[pallet::call_index(14)]
#[pallet::call_index(16)]
#[pallet::weight(T::WeightInfo::unstake_from_unregistered())]
pub fn unstake_from_unregistered(
origin: OriginFor<T>,
Expand Down Expand Up @@ -1416,7 +1440,7 @@ pub mod pallet {
/// Entry is considered to be expired if:
/// 1. It's from a past period & the account wasn't a loyal staker, meaning there's no claimable bonus reward.
/// 2. It's from a period older than the oldest claimable period, regardless whether the account was loyal or not.
#[pallet::call_index(15)]
#[pallet::call_index(17)]
#[pallet::weight(T::WeightInfo::cleanup_expired_entries(
T::MaxNumberOfStakedContracts::get()
))]
Expand Down Expand Up @@ -1481,7 +1505,7 @@ pub mod pallet {
/// Not intended to be used in production, except in case of unforseen circumstances.
///
/// Can only be called by manager origin.
#[pallet::call_index(16)]
#[pallet::call_index(18)]
#[pallet::weight(T::WeightInfo::force())]
pub fn force(origin: OriginFor<T>, forcing_type: ForcingType) -> DispatchResult {
Self::ensure_pallet_enabled()?;
Expand Down
58 changes: 58 additions & 0 deletions pallets/dapp-staking-v3/src/test/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,18 @@ fn maintenace_mode_call_filtering_works() {
DappStaking::force(RuntimeOrigin::root(), ForcingType::Era),
Error::<Test>::Disabled
);
assert_noop!(
DappStaking::unbond_and_unstake(
RuntimeOrigin::signed(1),
MockSmartContract::wasm(1 as AccountId),
100
),
Error::<Test>::Disabled
);
assert_noop!(
DappStaking::withdraw_unbonded(RuntimeOrigin::signed(1),),
Error::<Test>::Disabled
);
})
}

Expand Down Expand Up @@ -503,6 +515,29 @@ fn lock_with_incorrect_amount_fails() {
})
}

#[test]
fn unbond_and_unstake_is_ok() {
ExtBuilder::build().execute_with(|| {
// Lock some amount
let account = 2;
let lock_amount = 101;
assert_lock(account, lock_amount);

// 'unbond_and_unstake' some amount, assert expected event is emitted
let unlock_amount = 19;
let dummy_smart_contract = MockSmartContract::Wasm(1);
assert_ok!(DappStaking::unbond_and_unstake(
RuntimeOrigin::signed(account),
dummy_smart_contract,
unlock_amount
));
System::assert_last_event(RuntimeEvent::DappStaking(Event::Unlocking {
account,
amount: unlock_amount,
}));
})
}

#[test]
fn unlock_basic_example_is_ok() {
ExtBuilder::build().execute_with(|| {
Expand Down Expand Up @@ -682,6 +717,29 @@ fn unlock_with_exceeding_unlocking_chunks_storage_limits_fails() {
})
}

#[test]
fn withdraw_unbonded_is_ok() {
ExtBuilder::build().execute_with(|| {
// Lock & immediatelly unlock some amount
let account = 2;
let lock_amount = 97;
let unlock_amount = 11;
assert_lock(account, lock_amount);
assert_unlock(account, unlock_amount);

// Run for enough blocks so the chunk becomes claimable
let unlocking_blocks = DappStaking::unlocking_period();
run_for_blocks(unlocking_blocks);
assert_ok!(DappStaking::withdraw_unbonded(RuntimeOrigin::signed(
account
)));
System::assert_last_event(RuntimeEvent::DappStaking(Event::ClaimedUnlocked {
account,
amount: unlock_amount,
}));
})
}

#[test]
fn claim_unlocked_is_ok() {
ExtBuilder::build().execute_with(|| {
Expand Down
Loading