...
CTP (Combined Token Pool) and Global Staking Rewards Points (GSRP) will be initialized to 0.
Two new global variables will be tracked and will represent the last “valid” CTP (LCTP) and GSRP (LGSRP) values.
LCTP will be initialized to 1,000,000,000,000,000 (which the minimum staked amount to activate staking, or 1M FIO).
LGSRP will be initialized to 2,000,000,000,000,000 (which is double LCTP).
ROE will be computed by dividing LSTP by LGSRP.
If total tokens staked are >= 1M FIO AND activation date passed , ROE will be computed by dividing CTP by GSRP and LSTP LCTP and LGSRP will be updated every time CTP and GSRP changes.
If total tokens staked are < 1M at any time OR activation date not passed, ROE LCTP and LGSRP will be computed by dividing LSTP by LGSRPbe not be updated when CTP and GSRP changes.
Math safety
The ratios are initialized in a way to keep the ROE as close to 1 to limit the rounding loss issues when SUFs or SRPs are truncated.
It is still possible that rounding loss will occur, but is less likely and smaller in impact and deemed acceptable:
User may get different (potentially smaller) number of FIO than they staked if they stake/unstake before any fees were collected.
If all users unstake the tokens, there may not be enough tokens to distribute or some tokens may be left when all tokens are unstaked.
The following model demonstrates such loss. Please note that this is text-only model, due to significant digit limitation of Google Sheets.
For added safety, we should not cast any variables to long doubles or doubles or compute/store ROE in the interim, but instead compute using int-based math only:
To get SRPs (stake): SUFsStaked/CTP/GSRP
To get SUFs (unstake): SRPs*CTP/GSRP
Since SRPs*CTP is likely to overflow uint64_t, a uint128_t should be used for the interim calculation, see example
GSRP will fit into uint_64_t as it will ever only be double CTP, which is capped by max SUF supply.
The following checks should be added in code as additional safety checks:
Check for overflow of GSRP and interim and errorwith interim variables. See c++ example.
Dev steps
Implement LCTP and LGSRP as above
Implement int-based math for SUF → SRP and SRP → SUF calculation as in c++ example.
Add safety checks:
On unstake, check if enough tokens are left in CTP and if not transfer only what is left in CTP.
On unstake, check if enough srps are left in GSRP and if not deduct only what is left in GSRP.
Consider overflow check on interims.