How do the Rewards Work?
Before you dive into the reward logic we advise you to check the tokenomics page and see how the Sienna tokens are distributed and vested.
Since there is a limited amount of rewards for each day, they need to be distributed among the top liquidity providers.
By locking funds, the user starts accruing a lifetime share of the pool which entitles them to an equal percentage of the total rewards, which are distributed daily and the user can claim one per day.
This lifetime share fluctuates as a result of the other user locking and unlocking amounts of funds for different amounts of time.
If it remains constant or increases, users are guaranteed a new reward every day. If they fall behind, they may be able to claim rewards less frequently, and need to lock more tokens to restore their place in the queue.
Endgame mode: give exactly this many tokens to the contract to pay out the remaining rewards.
The up-to-date rewards distribution can be checked by querying the RPT contract config. It will return how the vested 2500 tokens for rewards are distributed and across which pools.
Every time the amount of tokens locked in the pool is updated, the pool's lifetime liquidity is tallied and the timestamp is updated. This is the only user-triggered input to the pool.
If this is the first time someone is locking tokens in this pool the contracts store the timestamp. This is used to start the pool liquidity ratio calculation from the time of the first lock instead of from the time of contract init.
- A zero timestamp is special-cased - apparently, CosmWasm 0.10 can't tell the difference between
Noneand the 1970s.
After first locking LP tokens, users must reach a configurable age threshold, i.e.keep LP tokens locked for at least X blocks. During that time, their portion of the total liquidity ever provided increases.
The total reward for a user with an age under the threshold is zero.
The total reward for a user with an age above the threshold is
(claimed_rewards + budget) * user_lifetime_liquidity / pool_lifetime_liquidity
Since a user's total reward can diminish, it may happen that the amount claimed by a user so far is larger than the current total reward for that user. In that case, the user's claimable amount remains zero until they unlock more rewards than they've already claimed.
Since a user's total reward can diminish, it may happen that the amount remaining in the pool after a user has claimed is insufficient to pay out the next user's reward.
When a user calls the
Claimmethod of the contract to receive their rewards, the contract is performing the following sequence of checks and calculations to fulfill the request.
- Checks if the user must wait before their first claim.
- Checks if the user must wait between claims.
- Cheks if there is some unclaimed reward amount:
- In case there is continue;
- In case the unclaimed amount is 0 the contract returns an error:
- You've already received as much as your share of the reward pool allows. Keep your liquidity tokens locked and wait for more rewards to be vested, and/or lock more liquidity tokens to grow your share of the reward pool.
- Checks the user's liquidity token balance for two things:
- Update the user timestamp and the other things that may be synced to it and in the meantime, update how much has been claimed.
- Reset the cooldown so that the user has to wait before claiming again.
- Optionally, reset the user's
shareif they have currently had 0 tokens locked. The intent is for this to be the user's last reward claim after they've left the pool completely. If they provide exactly 0 liquidity at some point, when they come back they have to start over, which is OK because they can then start claiming rewards immediately, without waiting for threshold, only cooldown.
- Return the amount that the contract will send to the user.