Proposed Staking Changes 2021-09-30

The following changes are proposed to address https://fioprotocol.atlassian.net/wiki/spaces/DAO/pages/413368526 and https://fioprotocol.atlassian.net/wiki/spaces/DAO/pages/413335602 :

CTP and GSRP initial values and last value tracking

  • 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 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, LCTP and LGSRP will be 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 with 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.