Repository navigation
feat(key-staking): epoch reward staking contract for key holders - #1080
Open
solaawojobi00-bit wants to merge 2 commits into
Open
solaawojobi00-bit wants to merge 2 commits into
solaawojobi00-bit wants to merge 2 commits into
Conversation
|
@solaawojobi00-bit Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
Member
|
Conflict |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
feat(key-staking): epoch reward staking contract for creator key holders
Problem
Key holders had no way to lock tokens for a fixed number of epochs and earn a share of protocol fee revenue. The existing
creator-keysstaking is lock-and-claim per creator and has no epoch reward pools, no treasury-gated funding, and no per-epoch distribution event.stake(key_id, amount, epochs)fund_epoch(epoch_id, amount), treasury-onlyunstakefails withEpochNotCompleteget_stake_rewardsreturns accrued and projectedEpochRewardDistributedeventSolution
New
key-staking-contractcrate, following the bookkeeping-only pattern oflp-reward-contract(no token transfers). Epochs derive from the ledger timestamp. A stake opened in epochsforkepochs earns from epochss..s+kand can be unstaked once the current epoch reachess+k. Each epoch's pool is split pro-rata to stake weight (the staked amount) active in that epoch.Changes
key-staking-contract/src/lib.rs: the contract.initialize(treasury, epoch_duration): one-time setup; stores the treasury address that may fund epochs.stake: validates amount > 0 and 1..=52 epochs (bounds per-stake iteration), adds weight to each epoch in range.unstake: auth by staker, blocked withEpochNotCompleteuntil the lock ends, returns principal plus accrued rewards, closes the position.fund_epoch:require_authon the stored treasury; rejects ended epochs (EpochEnded) so pools are final once an epoch completes.get_stake_rewards:accrued(completed epochs) andprojected(remaining epochs at current pools/weights).distribute_epoch: permissionless, once per completed epoch, emitsEpochRewardDistributed { epoch_id, total_distributed }. Added because a contract cannot act by itself at epoch end; rewards do not depend on it being called.key-staking-contract/src/test.rs: 13 tests.Cargo.toml/Cargo.lock: register the new workspace member.Regression Tests
unstakeblocked before epoch completion withEpochNotCompleteunstake_before_epoch_completion_fails_with_epoch_not_completerewards_are_split_pro_rata_to_stake_weight_within_epoch,rewards_accumulate_only_over_the_epochs_a_stake_is_active,late_staker_does_not_earn_from_epochs_before_it_joinedfund_epochrestricted to treasuryfund_epoch_requires_the_treasury_contract_auth(no auth and a stranger are rejected; treasury succeeds)get_stake_rewardsaccurate accrued valuesget_stake_rewards_reports_accrued_and_projected_values,projected_rewards_shrink_when_another_staker_joins_the_epochEpochRewardDistributedwith correct epoch and totaldistribute_epoch_emits_event_with_epoch_and_total_distributed,distribute_epoch_without_stakers_distributes_nothingstake_validates_amount_and_epoch_count,unstake_twice_and_unknown_stake_are_rejected,fund_epoch_rejects_bad_amount_and_ended_epochs_and_accumulates,initialize_is_one_time_and_contract_requires_itTesting
Notes for Reviewers
total_distributedis the epoch's full pool when stakers exist and 0 when none do. Floor-division dust (under one unit per stake) is not paid out, and an epoch with no stakers keeps its funding undistributed.creator-keysstaking is untouched; this is a separate contract concern.lp-reward-contract. Happy to add if preferred.Cargo.lockchange is only the new workspace member.Closes #1069