Staking
Introduction
Staking is an analogue of a bank deposit, receiving passive earnings due to simple storage of cryptomonets. The percentage of income may be different – it all depends on the term of the deposit.
Anyone can create their own Staking program and run it on the Gear Network. To do this, Gear created an example which is available on GitHub.
This article explains the programming interface, data structure, basic functions and explains their purpose. It can be used as is or modified to suit your own scenarios.
Mathematics
You can deposit tokens into the staking program and later claim that token (or another fungible token) for a reward.
Staking involves depositing fungible tokens into a program to earn rewards. These rewards, minted at regular intervals (e.g., per minute), are distributed equitably among all stakers.
How staking works:
Consider Alice, staking 100 tokens and Bob, staking 50 tokens. If reward tokens are minted every minute, and after one week Alice decides to unstake her tokens, the total tokens in the staking program remain 150. The duration of Alice's staking period is 7 days and the reward tokens accumulated can be calculated based on this timeframe:
A week later, Bob chooses to unstake his 50 tokens. In the initial week, he staked 50 tokens from 150. In the second week, he staked 50 tokens from 50. Here’s how to determine his reward:
It is possible to generalize the formula:
where:
- - reward for user for time interval ;
- - rewards minted per minute;
- - total staked amount of tokens at time ;
- - token staked by user at time ;
To apply the formula, one needs to store for each user and time interval, and for each time interval. To calculate a reward, a for loop must be executed for each time interval. This process consumes a significant amount of gas and storage. A more efficient approach is feasible:
Let for a user is constant for . Then:
That equation can be further simplified:
So, the equation to calculate the amount of reward that a user will receive from t=a to t=b under the condition the number of tokens he staked is constant:
Based on that equation the implementation in the program can be written:
(staker.balance * self.tokens_per_stake) / DECIMALS_FACTOR + staker.reward_allowed - staker.reward_debt - staker.distributed