Staking ProtocolrewardsDistributionrateBasedRewardDistributionrateBasedLockRewardDistribution

RateBasedLockRewardDistributionFacet

This facet manages the logic and storage for the Rate-Based Lock Reward Distribution algorithm. The functions in this facet handle operations such as creating staking positions, calculating staking rewards based on lock periods and multipliers, as well as calculating claimable rewards for stakeholders. This contract is designed to support instant staking rewards distribution by default while maintaining flexibility for future updates and features (e.g., restake after unlock timestamp).

_It operates using the Layout struct defined in RateBasedLockRewardDistributionFacetStorage, which contains essential data for managing staking campaigns within the context of the Rate-Based rewards distribution schedule.

IMPORTANT:

  • Rate-Based Reward Distribution Facets should only be used in conjuction with RewardMinter Facets for configuring reward assets in staking campaigns.

  • This implementation is intended to be leveraged by campaigns where locking positions is a fundamental requirement for participation and instant staking rewards are featured. It does not cater to scenarios where stakeholders can freely unstake their positions at any time.

  • Reward rates should be scaled by 1e18 at the API level, allowing for calculations with up to 18 decimal precision._

RestakeDisabledDueToInstantStakeRewards

error RestakeDisabledDueToInstantStakeRewards()

Thrown due to restaking being disabled due to instant staking rewards featured.

CampaignRewardsDistributionConfigured

event CampaignRewardsDistributionConfigured(uint256 campaignId, uint256 rewardRate, bool isVirtualLockSupported)

Emitted at setCampaignRewardsDistribution().

RewardRateChanged

event RewardRateChanged(uint256 campaignId, uint256 newRewardRate)

Emitted at changeCampaignRate().

InstaStakeRewardsReceived

event InstaStakeRewardsReceived(uint256 campaignId, uint256 nftId, address owner, uint256 rewardPackets)

Emitted at applyStake()

setCampaignRewardsDistribution

function setCampaignRewardsDistribution(uint256 campaignId, bytes campaignRewardsDistributionData) external

Sets the rewards distribution schedule for a specified campaign.

_This function can only be called during the campaign's creation (see CampaignCreationSkeleton.createCampaign()). The reward rate must be scaled by 1e18 (18 decimal precision support).

Emits a {CampaignRewardsDistributionConfigured} event.

IMPORTANT: Reward Rate value should be scaled by 1e18 at the API level, allowing for 18 decimal precision._

Parameters

NameTypeDescription
campaignIduint256The unique identifier of the targeted staking campaign.
campaignRewardsDistributionDatabytesShould contain an ABI-encoded uint256 for the reward rate and a boolean indicating whether lock multipliers are supported.

changeCampaignRate

function changeCampaignRate(uint256 campaignId, uint256 newRate) external

Changes the rate of rewards for a specified campaign.

This function can only be called by the creator of the targeted campaign.

Parameters

NameTypeDescription
campaignIduint256The unique identifier of the targeted staking campaign.
newRateuint256The new reward rate to be applied for the campaign (must be scaled with 1e18).

applyStake

function applyStake(uint256 campaignId, uint256 nftId, uint256 virtualPacketsStaked, uint256 packetsStaked, address account) external

Creates a new staking position in the specified campaign.

_Staking rewards are transferred instantly to the position's creator.

If no amount multiplier is applied, virtualPacketsStaked will be equal to packetsStaked.

Emits a {InstaStakeRewardsReceived} event._

Parameters

NameTypeDescription
campaignIduint256The unique identifier of the targeted staking campaign.
nftIduint256The unique identifier of the NFT associated with the position.
virtualPacketsStakeduint256The number of staked (input) packets adjusted by the applicable amount multiplier (if any).
packetsStakeduint256The raw number of staked packets, before applying any multipliers.
accountaddressThe address of the user creating and owning the position.

applyRestake

function applyRestake(uint256, uint256) external view returns (uint256)

Reverts because restaking is not supported when instant staking rewards are featured.

This function always reverts with a custom message explaining that restaking is disabled due to the instant rewards feature.

Parameters

NameTypeDescription
uint256
uint256

applyUnstake

function applyUnstake(uint256 campaignId, uint256 nftId) external returns (uint256)

Called when a position's owner partially or fully unstakes.

Decreasing or closing a position (partially or fully unstaking) is only allowed after the position's lock period has expired.

Parameters

NameTypeDescription
campaignIduint256The unique identifier of the targeted staking campaign.
nftIduint256The unique identifier of the NFT associated with the position.

Return Values

NameTypeDescription
[0]uint256The current claimable amount of reward packets for the position.

getReward

function getReward(uint256 campaignId, uint256 nftId) external returns (uint256)

Returns the claimable rewards for a specific position.

The claimable rewards are calculated without accounting for lock multipliers. Claimable rewards begin to accrue after the position's lock period expires when instant staking rewards are featured.

Parameters

NameTypeDescription
campaignIduint256The unique identifier of the targeted staking campaign.
nftIduint256The unique identifier of the NFT associated with the position.

Return Values

NameTypeDescription
[0]uint256The amount of reward packets that can be claimed by the specified position.

getRestakeReward

function getRestakeReward(uint256, uint256) external view returns (uint256)

Reverts because restaking is not supported when instant staking rewards are featured.

This function alwayss revert with a custom message explaining that restaking is disabled due to the instant rewards feature.

Parameters

NameTypeDescription
uint256
uint256