The Staking Protocol is a generic powerhouse for creating staking platforms, utilizing the Multi-Facet Proxy (Diamond) Standard EIP-2535 comprising various facet types responsible for handling and executing specific actions. This standard enables the staking protocol to offer a highly modular and customizable no-code solution, facilitating the creation of diverse staking platforms. Each staking platform can subsequently host and manage multiple staking projects, providing flexibility and efficiency in handling various staking scenarios.
Unlike traditional staking protocols that often restrict users to predefined scenarios and one-to-one mappings of ERC20 assets, Evergon's staking protocol allows creators to tailor every aspect of their staking, from asset types to reward mechanisms.
The Evergon Staking Protocol is designed to host any staking use case you envision, rather than being limited to predefined scenarios.
While the staking protocol provides the tools and capabilities, it is up to the staking platform creators to decide how to use them. Each staking platform can have different configurations and rules based on their requirements.
Deploy Your Staking Platform
Deploying a staking platform is a straightforward, no-code solution that involves just a few steps. With only one Diamond deployment and the integration of our pre-deployed facets (all necessary facet contracts are pre-deployed by the Evergon team).
Creators integrate these pre-deployed facets into their Diamond contract by making external calls to add the desired facets. This integration allows creators to customize their staking platform by selecting and configuring facets. By doing so, they adjust parameters and functionalities without needing to write or deploy new code, offering a highly flexible and user-friendly solution.
Step | Description |
---|---|
1. Diamond Deployment | Deploy a single Diamond contract (SolidStateDiamond). |
2. Facet Integration | Integrate specific implementation contracts (Facets) with the Diamond. |
3. Storage Initialization | Initialize the Diamond's storage based on the platform's requirements. |
Setting up your staking platform can be done without incurring additional deployment costs. By deploying a single Diamond contract and integrating pre-deployed facets, the process becomes significantly more cost-effective compared to deploying multiple full contracts. This approach reduces gas fees for users, as it requires only minimal deployments and external calls.
Staking platform creators can configure and deploy platforms with specific reward distribution algorithms:
- A creator can set up a platform to allow only independent algorithms, ensuring rewards are calculated based solely on individual staking activities.
- Alternatively, staking platform creators can set up platforms where a shared algorithm is used for all staking pools. More versatile platforms can also be configured, allowing staking pool creators to choose from multiple algorithms (or a combination of them), including rate-based, complex, and pre-stake reward distributions.
Additionally, the creator defines the types of ERC assets that can be used for staking.
How Staking Pools Are Created
Staking pool creators can set up custom staking pools using the createCampaign
function.
The campaignCreationData
includes:
- Optional Selectors: Settings that can be customized.
- Data to Execute: Information needed for these settings.
On a staking platform with various internal facets, the staking pool creator gathers the necessary data for each facet and uses the createCampaign function to start the staking pool. For instance, the staking pool creator configures the minimum and maximum staking amounts and specific lock periods using these facets.
The LockVariationsFacet ensures users can only lock their assets within a predefined range of lock periods, such as one to two years, preventing staking attempts outside this period. For instance, if the staking pool allows a lock period between one and two years, users cannot stake assets with a lock period shorter than one year or longer than two years.
Similarly, the CampaignAmountsFacet verifies that staked amounts fall within the allowed range, such as between 10,000 and 100,000 tokens. This facet ensures that any staked amounts outside these limits are rejected. For example, if the staking pool specifies a minimum of 10,000 tokens and a maximum of 100,000 tokens, any attempt to stake below 10,000 or above 100,000 tokens will be disallowed.
Stake Assets
When a user stakes assets, several steps ensure the process is valid and secure:
-
Verification:
- Verify if the user is eligible to stake, considering factors like KYC requirements.
- Ensure the lock period falls within allowed ranges (e.g., 1-2 years).
- Validate the staked amount falls within predefined limits (e.g., 10,000 to 100,000 tokens).
-
Transfer of Assets: Handles the actual transfer of staked assets into the staking pool.
-
Storage: All staking data is stored securely, with facets ensuring data integrity and accessibility.
When a user stakes assets in a staking pool, a position is created and represented by an ERC721 NFT LP token. These tokens can be sold or transferred, enhancing the liquidity and utility of staking positions. The NFT LP token is burned when the position is closed by fully unstaking.
The token includes the following:
campaignId
: The associated staking pool's ID.packetsStaked
: The number of staked packets.virtualPacketsStaked
: The number of virtual packets (adjusted by multipliers).startingTimestamp
: The timestamp when the position was created.unlockTimestamp
: When the staked assets can be withdrawn.rewardPacketsToBePaid
: Rewards yet to be received.rewardPacketsPaid
: Rewards already received.
Understanding Staking Types
Staking involves users depositing assets and earning rewards based on four key variables:
- The quantity of assets staked by a user.
- The duration for which the assets are staked.
- The collective amount staked by all users.
- The overall duration of the staking pool.
Packets
In many staking scenarios, participants are required to stake multiple types of assets in specific ratios. For instance, a staking pool might require participants to stake a combination of three different tokens, such as one unit of Token A, three units of Token B, and two units of Token C. Managing such specific requirements manually can be complex and error-prone.
A packet encapsulates this complexity into a single, indivisible unit that represents the predefined combination of assets. Instead of dealing with individual tokens and their amounts, users and the staking platform handle packets, which streamline the staking process.
Example: For every 1 unit of Token A, you need 3 units of Token B and 2 units of Token C. This combination is defined as one packet: Packet = [1 Token A, 3 Token B, 2 Token C]. When a user wants to stake, they specify the number of packets instead of individual amounts for each token. For example, if a user wants to stake 10 packets, it automatically translates to staking 10 units of Token A, 30 units of Token B, and 20 units of Token C.
Facets
Crafting a successful staking pool requires careful consideration of essential actions. From offering participants the ability to stake and unstake (fully or partially) and implementing stringent amount validation mechanisms and reward algorithms, to defining lock periods and possibly penalties for premature withdrawals. All of the possible key actions potentially involved within the context of a staking pool are addressed through the facet types presented below, which are incorporated in the Evergon Staking Protocol.
The Staking Facet serves as the foundational building block of the Evergon's Staking Protocol, orchestrating and coordinating the execution of other type implementation facets in a specific order. It encompasses the following basic functions:
stake()
fullyUnstake()
partialUnstake()
getReward()
If the staking platform creator enables instant rewards, then eligible rewards are immediately calculated and distributed to stakers. This distribution happens when the staker creates staking positions using the
stake()
function or when they unstake using thepartialUnstake()
orfullyUnstake()
functions. The protocol ensures that rewards are promptly distributed to users in these scenarios.
Generic Facets
Facet Type | Description |
---|---|
AccessControl Facet | Manages admin roles and access control. |
Skeleton Facets
Facet Type | Description |
---|---|
Staking Facet | Exposes functions for staking operations (stake, unstake, receive rewards). |
ERC721 Facet | Represents and tracks staking positions through NFT LP tokens. |
Campaign Creation Facet | Enables the creation of customized staking pools, configured by internal facets. |
Internal Facets
Category | Description |
---|---|
RewardsDistributionFacet | Defines reward distribution mechanisms (predefined total rewards or rate-based calculations). |
CreatorEligibility | Defines who can create staking pools (role-based or address-based eligibility). |
StakersEligibility | Defines who can stake in staking pools (role-based or address-based eligibility). |
CampaignTimes | Manages staking pool timing (start and end timestamps). |
CampaignAmounts | Handles amount-related configurations (hard caps or range limits). |
LockVariationsFacet | Manages lock periods (static or range-based configurations). |
TransferInputFacet | Manages input asset transfers (various token types). |
TransferRewardFacet | Handles reward transfers (minting or transferring tokens). |
WithdrawalVariationsFacet | Enforces lock periods where unstaking is not allowed before the lock ends and manages withdrawal rules (including penalties for early unstaking). |
VirtualAmountMultiplierFacet | Defines amount multipliers (static or range-based). |
Sub-Internal Facets
Facet Type | Description |
---|---|
VirtualLockMultiplier | Lock-wise multipliers (static or range-based) can only be used in unshared algorithms. |
The "TransferInput" facet type consists of multiple facet implementations, each responsible for the transfer operation of a specific type of token when a user stakes. For example, when ERC20 tokens are staked, the "Erc20InputFacet" is employed to execute the transferring of the assets from the user to the staking pool.
Functions
Function Type | Description | Example |
---|---|---|
Initialization Functions | Handle platform-wide configurations and are called once by the admin. | AccessControl facet initialization sets the admin address. |
Setter Functions | Manage staking pool-specific configurations and are called during pool creation. | StaticLockPeriodFacet initializes with the maximum lock period. |
Reward Distribution Mechanisms
The creator of a staking platform selects which types of reward distribution mechanisms (e.g., rate-based, pre-stake reward distribution, complex reward distribution ) are supported and can be applied to staking pools (generated within the platform).
In designing the Evergon Staking Protocol, a range of reward distribution algorithms were considered to cater to different staking needs. These algorithms fall into two main categories:
- Collective Algorithms: The staking of each user is influenced by the staking activities of other users. This means that the total reward pool is shared among all participants based on their individual contributions during a specific period of time.
- Independent Algorithms: The rewards a user earns are solely based on their own staking activities, independent of other users' stakes. This means that your rewards are calculated purely based on the amount you stake and the duration for which you stake, without being influenced by the actions of other users.
Collective Algorithms (shared)
Collective algorithms distribute rewards among users based on their staked amounts relative to the total amount staked by all participants. here the total amount staked, staking period, and total staking period affect the rewards, making it the most complex type.
Pre-Stake Reward Distribution
This is the simplest algorithm in the collective category, as rewards are shared purely based on the amount staked by each user.
- All users must stake their assets before the staking period begins.
- Once the staking period starts, no additional staking is allowed, and all users are locked into their staked amounts for the entire duration.
- The staking pool has a defined start and end date (e.g., from August 1st to August 30th).
- Rewards are distributed based on the proportion of each user's stake relative to the total amount staked.
Example:
- User A stakes 5000 tokens.
- User B stakes 3000 tokens.
- The total reward pool is 16000 tokens.
Both users stake their tokens for the same duration. The rewards are distributed proportionally:
- User A receives a reward of 10,000 tokens (5000/8000 * 16000).
- User B receives a reward of 6,000 tokens (3000/8000 * 16000).
In this scenario, the total reward is divided based on the stake amount relative to the total staked amount, ensuring that each user gets a fair share corresponding to their contribution.
Complex Reward Distribution
This algorithm is used in scenarios where the timing and amount of rewards are uncertain. The Synthetix Reward Algorithm is an example of this type, where rewards are notified by a specific entity and distributed according to the staked amounts and staking durations. Rewards are distributed based on both the amount and the time of staking.
Example:
- User A stakes 1,000 tokens at the start of the week.
- User B stakes 1,000 tokens in the middle of the week.
- The total reward pool for that week is 3,000 tokens.
The rewards are distributed based on the staking duration:
- User A, who staked for the entire week, receives a reward of 2,000 tokens.
- User B, who staked for half of the week, receives a reward of 1,000 tokens.
In this scenario, User A receives 2x more rewards due to staking for a longer duration, reflecting the fair distribution of rewards based on both the amount and duration of the stakes.
Independent Algorithms (unshared)
Independent algorithms calculate rewards independently of other users' stakes. The rate-based reward algorithm is a prime example.
Rate-Based Reward Distribution
Rewards are provided at a fixed rate per second, regardless of the total amount staked by other users. Rewards can be paid out instantly when a user stakes, giving them the option to use the rewards immediately, which depends on the configuration set by the staking platform creator.
For example, if the reward rate is 0.8 tokens per second, a user staking 100 tokens will receive rewards at a rate proportional to this amount, unaffected by the stakes of others.
Example:
- User A stakes 5000 tokens with a reward rate of 0.1 tokens per second.
- User B stakes 3000 tokens with a reward rate of 0.1 tokens per second.
Both users will receive rewards based on their individual staked amounts and the reward rate:
- User A earns 0.1 tokens per second for their 5000 tokens.
- User B earns 0.1 tokens per second for their 3000 tokens.
In this setup, User Aβs rewards are unaffected by User Bβs stake and vice versa. Each userβs rewards are determined by their own staking amount and the pre-set reward rate, ensuring a straightforward and independent calculation.
In a rate-based algorithm, you can also configure a virtual balance that gets multipliers depending on the lock period. This system ensures that the longer and more you stake, the higher your effective rewards will be, reflecting both the duration and amount of your staking.
There are two types of these multipliers:
-
Continuous Multipliers: Instead of fixed categories like bronze, silver, and gold, your multiplier increases continuously. For example, you can have a multiplier of 1.0 for amounts up to 50,000 tokens. If you have 35,000 tokens staked, your multiplier could be 1.5, meaning you get a little more reward as you get closer to the next category.
-
Interval Multipliers: These are fixed categories where, for instance, bronze has a multiplier of 1.0, silver has 1.2, and gold has 1.5. Even within these categories, the multiplier can vary slightly if you are about to reach the next level, providing a smoother transition in rewards as your staked amount increases.
For example, if you stake from 0 to 1 year, your multiplier is 1.0; if you stake from 1 to 2 years, your multiplier increases to 1.2; and if you stake for 2 to 4 years, which is the maximum, your multiplier is even higher.
Virtual Balance
Depending on the staking platform's configuration, virtual balances may or may not be implemented. This means that creators might choose to use virtual balances to apply conditions like multipliers for longer lock periods or penalties for early withdrawals, while others might stick to actual balances without these adjustments.
Virtual Balance is a mechanism to adjust the actual balances of users' staked assets based on certain rules and multipliers. These adjustments help reflect the true value/weight of the staked assets after applying specific conditions like lock periods or withdrawal penalties. This mechanism ensures that staking rewards and penalties are fair and accurately reflect the user's commitment and actions.
By using Virtual Balances, the protocol can encourage long-term staking, discourage early withdrawals:
-
Base Amount: This is the actual amount of assets a user has staked. Let's say you staked 100 tokens.
-
Multipliers: These are factors that can increase or decrease your base amount based on certain conditions. For example, if you stake your assets for a longer period, you might get a higher multiplier, like 1.5x.
-
Penalties: These are factors that can decrease your base amount if you do something like withdrawing your assets before the end of the lock period.
There are two types of multipliers used in the protocol: Amount Multipliers and Lock Multipliers.
Amount Multipliers
- These adjust rewards based on the amount of tokens staked.
- They can be used in various algorithms, including non-rate-based ones, as they are independent of the lock period.
Lock Multipliers
- These adjust rewards based on the duration for which tokens are locked.
- They can only be used in rate-based algorithms because they rely on the lock period to calculate rewards.
- In collective algorithms, where all participants have the same lock period, Lock Multipliers are not applicable as they would disrupt the uniformity of rewards.
Penalties
The protocol itself provides the underlying structure and rules for implementing staking platforms, which includes the capability to impose penalties on users. These penalties are not platform-specific but are instead a fundamental part of the protocol's design. This allows the staking platform creators to choose if penalties are supported, meaning that staking pools created within their platform can include penalty mechanisms. If the staking platform supports penalties, staking pool creators can then configure their own specific rules for penalties within the framework provided by the staking protocol.
-
Protocol's Role: The staking protocol offers the fundamental capabilities and rules that platform creators can use to design their staking pools. This includes the ability to impose penalties on users who do not adhere to the rules, such as withdrawing staked assets before the end of the lock period.
-
Penalty Implementation: The protocol provides the mechanism to categorize and adjust the base amount of staked assets through penalties. For instance, if a user withdraws their assets before the end of the lock period, a penalty can be applied to decrease the assets they can claim.