-
Notifications
You must be signed in to change notification settings - Fork 364
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
dAppStaking - Bonus rewards mechanism rework #1379
Comments
@ipapandinas I would suggest a bit different solution which should be technically simpler & better for the user IMO. The bonus reward or the loyalty flag is tied to a particular stake, not the account. On the other side, Therefore I'd suggest to track whether the stake can be moved on the level of singular stake. Tech Solution Suggestion
#[derive(Encode, Decode, MaxEncodedLen, Copy, Clone, Debug, PartialEq, Eq, TypeInfo, Default)]
pub struct SingularStakingInfo {
/// Amount staked before, if anything.
pub(crate) previous_staked: StakeAmount,
/// Staked amount
pub(crate) staked: StakeAmount,
/// Indicates whether a staker is a loyal staker or not.
pub(crate) loyal_staker: bool,
} We can modify it to something like: #[derive(Encode, Decode, MaxEncodedLen, Copy, Clone, Debug, PartialEq, Eq, TypeInfo, Default)]
pub struct SingularStakingInfo {
/// Amount staked before, if anything.
pub(crate) previous_staked: StakeAmount,
/// Staked amount
pub(crate) staked: StakeAmount,
/// Indicates whether a staker is a loyal staker or not.
pub(crate) period_stake: PeriodStake
}
enum PeriodStake {
/// Bonus for this stake has been forfeited, staker won't receive anything
BonusForfeited,
/// Staker can move some or all stake one more time without loosing the reward.
/// This value would be deprecated later.
OneMoveRemaining,
/// The amount of safe 'moves' remaning, where staker can move all or part of this stake to another dApp
SafeMovesRemaining(u8),
} The benefit of this approach is that we don't need to do any storage migration since |
Thank you for the insights! I agree that tracking moves at the singular stake level makes sense for improving user fairness and control, especially for those supporting multiple dApps. Your suggested design is also very clever—I really like it! I propose simplifying the enum slightly: enum BonusStatus {
BonusForfeited,
SafeMovesRemaining(u8),
} With The initial value for Here are the expected outcomes for the given scenarios: Stake reallocation to a newly registered or previously unstaked dAppThe bonus decreases or is forfeited if moves are exhausted. For example:
Bonus migration within already staked dApps:Combine existing stake and reduce move count accordingly.
WDYT? I’ll continue updating the original issue body to clarify the implementation as we discuss. |
For the enum simplification, I'd prefer if it was as you suggested, if it works & makes life simpler.
We shouldn't need to do runtime upgrade to change this value though - it's unnecessarily complex and will be something we need to keep track of & prepare. Running it through the governance will also consume time. All of that being said - we have multiblock migration now, it's simple to write & test, so might as well as do it I guess 🤷♂️. For the |
Just to confirm I've captured your idea, are you suggesting of having two new config params? Something like:
Here is a first interface proposal and logic outline for the pub fn move(
origin: OriginFor<T>,
from_smart_contract: T::SmartContract,
to_smart_contract: T::SmartContract,
amount: Option<Balance>
) -> DispatchResult Logic: steps and checks
|
In case we decide to take the route without migration & without the dummy value Few comments:
|
Perfect! I've edited the original issue's body accordingly |
Context
This issue proposes improvements to the bonus rewards mechanism in dAppStaking to enhance user flexibility and align with community feedback.
Suggested Solutions
Introduce a new
move
extrinsic that enables users to reallocate their staked voting bonus between dApps while preserving the bonus reward.This new extrinsic will support two main use cases:
MaxBonusMovesPerPeriod
of maximum allowed regular moves per period (2 by default) to allow limited bonus reallocation during the Build&Earn subperiod. Usingmove
during the Voting subperiod, reallocates the voting stake without increasing the move counter.Nov 6 EDIT: From discussion below
Interface Proposal
The new
move
extrinsicThe new config params
TempBonusMovesForOngoingPeriod
- used in the ongoing periodMaxBonusMovesPerPeriod
- use in the next periodThe updated
SingularStakingInfo
structThe bonus status definition
SafeMovesRemaining
will be set toMaxBonusMovesPerPeriod
in each period, with an initial default set toTempBonusMovesForOngoingPeriod
of 1 for the ongoing period.BonusForfeited
andSafeMovesRemaining(_)
are respectively encoded to false and true to avoid a storage migration.Logic Steps and Checks
from_smart_contract
andto_smart_contract
are distinct.to_smart_contract
registrationamount
to move:from_smart_contract
’s staked balancebonus_status
:from_smart_contract
is unregistered, maintain thebonus_status
.to_smart_contract
is registered andSafeMovesRemaining
> 0, decrementSafeMovesRemaining
.SafeMovesRemaining
reaches zero, setbonus_status
toBonusForfeited
.from from_smart_contract
using existing unstake logic.to_smart_contract
using existing stake logic.Move
event with:account
/from_smart_contract
/to_smart_contract
/amount
/bonus_status
Some expected outcomes scenarios
Stake reallocation to a new or previously unstaked dApp
Bonus migration between already staked dApps
Consistency Steps
bonus_status
and removeloyal_staker
fromSingularStakingInfo
- Verify that the move counter resets appropriately at the start of each new period
- Prevents moves beyond the configurable cap
- Verify that the move counter is not increased for unregistered dApps
- Verify that the move counter is not increased for moves during the Voting subperiod
Ensure that the actual bonus reward calculation (also for unregistered dApps) & staking / unstaking / claiming mechanisms still work.
The text was updated successfully, but these errors were encountered: