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

Merged
merged 24 commits into from
Oct 31, 2024
Merged

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
  • 6 SECOND BLOCK TIMES: length of constants adjusted as necessary
  • 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.82511% with 32 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
pallets/capacity/src/lib.rs 94.79% 15 Missing ⚠️
...lets/capacity/src/migration/provider_boost_init.rs 0.00% 10 Missing ⚠️
pallets/capacity/src/types.rs 95.07% 7 Missing ⚠️
Files with missing lines Coverage Δ
common/primitives/src/capacity.rs 75.00% <100.00%> (+75.00%) ⬆️
pallets/capacity/src/types.rs 96.37% <95.07%> (+0.79%) ⬆️
...lets/capacity/src/migration/provider_boost_init.rs 0.00% <0.00%> (ø)
pallets/capacity/src/lib.rs 94.82% <94.79%> (-0.53%) ⬇️

@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
wilwade and others added 12 commits October 30, 2024 12:45
The goal of this PR is to removed added getters

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

- added feature flags for test only methods
- added a constant
- small refactor
Reward eras were 1-indexed but this made things too confusing.
* 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
…ists for a different provider (#2136)

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

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.

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.

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

- `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.

- [ ] 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 <[email protected]>
Co-authored-by: Shannon Wells <[email protected]>
fix capacity import in api-augment
remove unused constant
use ProviderBoostHistoryLimit value set in parameter_types
bump spec_version
Copy link
Collaborator

@JoeCap08055 JoeCap08055 left a comment

Choose a reason for hiding this comment

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

  • reviewed changes since previous review
  • built branch, ran unit & e2e tests

@shannonwells shannonwells force-pushed the feat/capacity-staking-rewards-impl branch from 9a57c37 to 3358e70 Compare October 30, 2024 21:14
@github-actions github-actions bot removed the metadata-changed Metadata has changed since the latest full release label Oct 30, 2024
@github-actions github-actions bot added the metadata-changed Metadata has changed since the latest full release label Oct 30, 2024
pallets/capacity/README.md Outdated Show resolved Hide resolved
Co-authored-by: Wil Wade <[email protected]>
@github-actions github-actions bot removed the metadata-changed Metadata has changed since the latest full release label Oct 31, 2024
@shannonwells shannonwells enabled auto-merge (squash) October 31, 2024 21:14
@github-actions github-actions bot added the metadata-changed Metadata has changed since the latest full release label Oct 31, 2024
@shannonwells shannonwells merged commit f862821 into main Oct 31, 2024
29 checks passed
@shannonwells shannonwells deleted the feat/capacity-staking-rewards-impl branch October 31, 2024 21:42
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