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

Provider Boosting implementation #1694

Draft
wants to merge 65 commits into
base: main
Choose a base branch
from

Conversation

shannonwells
Copy link
Collaborator

@shannonwells shannonwells commented Oct 3, 2023

Goal

Implement a Provider Boost feature, whereby token holders may support the network and a specific Provider by means of a custom staking model. Token holders lock up a certain amount of token, and receive a return in Frequency token for this support. The token holder chooses a Provider to receive some Capacity, which the Provider may use to pay for chain transactions.

Token holders may still stake for MaximizedCapacity and receive no token return. As before, the entire benefit for staking would go to the targeted Provider for this type.

Discussion

Support the new staking type, Provider Boost

  1. The stake transaction now specifies the Staking Type of MaximizedCapacity which is stored with StakingTargetDetails.
  2. There are 3 new extrinsics:
    • provider_boost which specifies ProviderBoost staking type.
    • claim_staking_rewards which mints and transfers all eligible rewards in token to the staker.
    • change_staking_target which basically swaps your Provider Boost staking target from one Provider to another.
  3. The StakingType determines how much Capacity is generated for the targeted provider. For ProviderBoost type, 50% of the Capacity for MaximizedCapacity is generated when using provider_boost.
  4. The StakingType also determines if there is a periodic return in token to the staker. For ProviderBoost type, there is a periodic return. For MaximizedCapacity type, there isn't.

Issue rewards to Provider Boost accounts

  1. Rewards are a fixed amount based on the proportion of staked amount to total staked amount, and capped at 10% per year, or to ~0.0385% per Reward Era.
  2. Individual Rewards are calculated based on the number of complete RewardEras that the token holder has staked.
  3. A RewardEra is approximately two weeks of blocks.
  4. Reward Pool size is a constant.
  5. Rewards are are not compounded.
  6. Rewards are minted when they are claimed. All available Rewards are paid out when the claim_staking_rewards extrinsic succeeds.
  7. Rewards expire after 30 Reward Eras. This is the limit of the Reward Pool History storage and the limit of the individual Provider Boost History storage, so rewards cannot be claimed for earlier eras. With that said, if for example you ProviderBoost 10,000 FRQCY, and did nothing else for say 50 Reward Eras ("set and forget"), you would not lose everything. You would simply would not be paid out except for the last 30 Eras. Only the potential earnings for the 20 eras before that would be lost.

Allow a staking 'retarget'

A staker may change some or all of their staked token to target a different provider up to 16 times in a RewardEra without penalty. Otherwise, they must wait until the next RewardEra.

For more details, please see the Capacity Staking Rewards Implementation design doc, which links to the economic model for this feature.

Checklist

  • Chain spec updated
  • Custom RPC OR Runtime API added/changed? Updated js/api-augment.
  • Design doc(s) updated
  • Tests added
  • Benchmarks added
  • Weights updated

@codecov
Copy link

codecov bot commented Oct 4, 2023

Codecov Report

Attention: Patch coverage is 92.80899% with 32 lines in your changes missing coverage. Please review.

Files Patch % Lines
pallets/capacity/src/lib.rs 94.80% 15 Missing ⚠️
...lets/capacity/src/migration/provider_boost_init.rs 0.00% 10 Missing ⚠️
pallets/capacity/src/types.rs 95.00% 7 Missing ⚠️
Files Coverage Δ
common/primitives/src/capacity.rs 75.00% <100.00%> (+75.00%) ⬆️
pallets/capacity/src/types.rs 96.37% <95.00%> (+0.79%) ⬆️
...lets/capacity/src/migration/provider_boost_init.rs 0.00% <0.00%> (ø)
pallets/capacity/src/lib.rs 94.84% <94.80%> (-0.51%) ⬇️

@shannonwells shannonwells changed the title Feat/capacity staking rewards impl Provider Boosting implementation Oct 4, 2023
@github-actions github-actions bot added metadata-changed Metadata has changed since the latest full release metadata-version-not-incremented Metadata has changed since the latest full release, but the version has not been incremented and removed metadata-changed Metadata has changed since the latest full release metadata-version-not-incremented Metadata has changed since the latest full release, but the version has not been incremented labels Oct 5, 2023
@shannonwells shannonwells force-pushed the feat/capacity-staking-rewards-impl branch from 09ede24 to 164a197 Compare October 11, 2023 22:08
@github-actions github-actions bot removed metadata-changed Metadata has changed since the latest full release metadata-version-not-incremented Metadata has changed since the latest full release, but the version has not been incremented labels Oct 11, 2023
@shannonwells shannonwells force-pushed the feat/capacity-staking-rewards-impl branch 2 times, most recently from 82610e5 to ea9ccda Compare October 20, 2023 19:11
@github-actions github-actions bot added metadata-changed Metadata has changed since the latest full release metadata-version-not-incremented Metadata has changed since the latest full release, but the version has not been incremented labels Oct 20, 2023
@shannonwells shannonwells force-pushed the feat/capacity-staking-rewards-impl branch from b80b627 to 977ad65 Compare November 7, 2023 22:47
@github-actions github-actions bot removed metadata-changed Metadata has changed since the latest full release metadata-version-not-incremented Metadata has changed since the latest full release, but the version has not been incremented labels Nov 7, 2023
@shannonwells shannonwells force-pushed the feat/capacity-staking-rewards-impl branch from 977ad65 to 63f6651 Compare December 21, 2023 01:31
@shannonwells shannonwells force-pushed the feat/capacity-staking-rewards-impl branch 3 times, most recently from 0bf5c06 to defdb39 Compare April 22, 2024 18:02
@github-actions github-actions bot added the metadata-changed Metadata has changed since the latest full release label Apr 25, 2024
@shannonwells shannonwells force-pushed the feat/capacity-staking-rewards-impl branch from a159bb8 to aaeec80 Compare May 6, 2024 21:07
@github-actions github-actions bot added metadata-changed Metadata has changed since the latest full release metadata-version-not-incremented Metadata has changed since the latest full release, but the version has not been incremented and removed metadata-changed Metadata has changed since the latest full release metadata-version-not-incremented Metadata has changed since the latest full release, but the version has not been incremented labels May 6, 2024
…-rewards-impl

# Conflicts:
#	designdocs/provider_boosting_implementation.md
#	pallets/capacity/src/lib.rs
#	pallets/capacity/src/tests/stake_and_deposit_tests.rs
#	pallets/capacity/src/tests/unstaking_tests.rs
#	pallets/capacity/src/tests/withdraw_unstaked_tests.rs
@github-actions github-actions bot added metadata-changed Metadata has changed since the latest full release and removed metadata-changed Metadata has changed since the latest full release labels Aug 5, 2024
}

#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
fn on_initialize(current: BlockNumberFor<T>) -> Weight {
Self::start_new_epoch_if_needed(current)
.saturating_add(Self::start_new_reward_era_if_needed(current))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just leaving this as a note: we might want to consider using the new Poll hook instead of on_initialize. Here’s the relevant issue for reference: #2098.

@github-actions github-actions bot added metadata-changed Metadata has changed since the latest full release and removed metadata-changed Metadata has changed since the latest full release labels Aug 5, 2024
Passkey check only balance not nonce and don't pre-fund it

Working consistently
@github-actions github-actions bot added metadata-changed Metadata has changed since the latest full release and removed metadata-changed Metadata has changed since the latest full release labels Aug 5, 2024
Comment on lines +1222 to +1223
// We have already paid out for the previous era. Put one entry for the previous era as if that is when they staked,
// so they will be credited for current_era.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestions for better wording, or leave it out entirely?

# Goal
The goal of this PR is to address some feedbacks

- added feature flags for test only methods
- added a constant
- small refactor
@github-actions github-actions bot added metadata-changed Metadata has changed since the latest full release and removed metadata-changed Metadata has changed since the latest full release labels Aug 6, 2024
@github-actions github-actions bot added metadata-changed Metadata has changed since the latest full release and removed metadata-changed Metadata has changed since the latest full release labels Aug 6, 2024
# Goal
Reward eras were 1-indexed but this made things too confusing.
@github-actions github-actions bot removed the metadata-changed Metadata has changed since the latest full release label Aug 6, 2024
aramikm and others added 2 commits August 6, 2024 13:58
* Use unwrap_or_default for getting a reward pool chunk
* warning for inserting a new chunk failure
* code golf
* linting in e2e
* remove unnecessary change in helpers
@github-actions github-actions bot added the metadata-changed Metadata has changed since the latest full release label Aug 6, 2024
…ists for a different provider (#2136)

## Summary

A user can stake to multiple providers, but the minimum staking amount
is enforced only for the first staking action that the user submits.

## Issue details

During the staking process, both for the `stake` and `provider_boost`
extrinsics, a minimum staking amount should be enforced by the
`Runtime::MinimumStakingAmount` parameter.

The current implementation of
[ensure_can_stake](https://github.com/frequency-chain/frequency/blob/9ef58185f2230aaf92dc166fb8eade56a78e4cf3/pallets/capacity/src/lib.rs#L638)
verifies if the amount that the account is staking in total (the current
active staking and the new staking amount) is greater than the
`MinimumStakingAmount`:

```rust
let new_active_staking_amount = staking_details
	.active
	.checked_add(&stakable_amount)
	.ok_or(ArithmeticError::Overflow)?;

ensure!(
	new_active_staking_amount >= T::MinimumStakingAmount::get(),
	Error::<T>::StakingAmountBelowMinimum
);
```

This implies that the user has to stake the `MinimumStakingAmount` only
when they first submit a stake for a provider, all the subsequent
staking requests being accepted even with the amount of 1.

## Risk

The current implementation does not follow the intended use-case, as
described in the design documentation.
An attacker could stake the minimum required amount to a provider, and
then stake 1 token to each of the other available providers, underpaying
for the storage that they use. This can cause a storage bloating,
slowing down the network in the long run.

## Mitigation

The `ensure_can_stake` function should verify that the `stakable_amount`
is greater than `MinimumStakingAmount`, instead of verifying the
`new_active_staking_amount`.

Closes #2135 

# Discussion

- `ensure_can_stake` updated to remove the addition of the existing
stakes and check `stakable_amount`
- `get_stakable_amount_for` updated to use `reducible_balance` as
recommended by parity when using the `fungible` trait.
`reducible_balance` requires an Existential Deposit, so the unit test
values were updated.
- `/designdocs/capacity.md` updated to the latest code, and reflects
changes in language due to replacing `lock`s with `freeze`s.
- CI Checks are not running on this branch, but the unit tests and e2e
tests passed in local.

# Checklist
- [ ] Updated Pallet Readme?
- [ ] Updated js/api-augment for Custom RPC OR Runtime API?
- [x] Design doc(s) updated?
- [ ] Unit Tests added?
- [ ] e2e Tests added?
- [ ] Benchmarks added?
- [x] Spec version incremented?

---------

Co-authored-by: Wil Wade <wil.wade@amplica.io>
Co-authored-by: Shannon Wells <shannonwells@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
metadata-changed Metadata has changed since the latest full release Provider Boosting
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants