[FIP-21] FIO Staking Development Spec

Links

Design

ย 

  • This section addresses some of the higher level questions and design issues that must be addressed by the project.

Questions Re FIP-21

Question

Answer

Question

Answer

Would it be useful to provide a getter that will tell the user what the rewards amount will be if they unstake now?

whats your opinion on a getter get_staking_rewards(pubkey, amount) returning a breakdown of the rewards and principle..

I would make it more generic and not pass the amount. Also we may need to add staked tokens in get_balance. Let me spec it. (Still TBD?)

stakefio, unstakefio is bundled, what is the fee when the bundle count is expired?

TBD: do some analysis of the finished implementation and come up with recommend.

What are the specific logistics of daily_staking_rewards, and total_staking_rewards?

The daily_staking_rewards should only be used to understand if tokens for staking rewards needs to be minted. Both the total and the daily should be incremented together in synchrony otherwise.

do we need to have the Rate of Exchange (ROE) stored in state. We can compute it when needed, it looks like everywhere we need it we are reading the state table with the info anyway, so its just a divide computation to arrive at the value.

its fine to use the values that make up this value and compute it on the fly as needed and not store it in state.

What are the units of SRP. should we come up with a units of SRP for this, i also would like to understand if theres any decimal resolution necessary for SRPs (similar to SUFs)..

lets call them SUS (smallest units SRP) and lets use 9 decimals just as we do SUFs.

When a user performs multiple stakings, lets say day one they stake 200 FIO, day 2 they stake 100 FIO, then they call unstake on 250 FIO. is it safe to assume that unstaking will perform logic that looks for the longest duration staking and apply that ROE for the amount to unstake, perform that unstake, then go to the next staking event and apply the remained to that event, and so on until all of the desired amount is unstaked, the final stake will need to be โ€œadaptedโ€ so as to remain accurate, in this case the day 2 stake will need adapted to become 50 FIO instead of the original 100.

we just store SRPs which are computed when we stake, these are additively recorded upon staking, and decremented upon unsticking.

we also store the total number of FIO which are staked per account, these are also additively recorded upon staking a dn decremented upon unstaking.

so we need two numbers stored by account total_SRPs and total_staked_fio.

The FIP will be reviewed with this in mind and we will attempt to clarify this at the FIP level.

Some clarity is needed regarded what to do when there are locked tokens (Mainnet locks, and general locks)

if an account has genesis locked tokens or General (FIP-6) locks are they prohibited from staking?

Accounts are never prohibited from staking.

if the account has main net locked tokens, then the user may stake and unstake the unlocked portion of those tokens in that account (all unlocked tokens are eligible for staking, and should stake and unstake as expected).

if the account has general locked tokens, then the user may stake and unstake the unlocked portion of those tokens in the account (all unlocked tokens are eligible for staking, and should stake and unstake as expected).

the FIP will be examined to see if clarification can be added.

RAM increment amounts are not specified for the actions in this FIP please add details for RAM increment amounts

these will be computed during development, and updated into the FIP a place holder will be added for this.

Add a line in the implementation of actions to check for max FIO transaction size exceeded.

this will be added to the FIP

ย 

Design Approach/Overview

New Constants (dev complete 3/29/2021)

Constant values will be added to the system for the following items:

COMBINED_TOKEN_POOL_MINIMUM โ€“ this will be set to 1,000,000,000,000,000 FIO SUFS

STAKING_REWARDS_RESERVE_MAXIMUM โ€“ this will be set to 25,000,000,000,000,000 FIO SUFS.

New Table

We will create a new table in state called the global staking info info this will have the following attributes.

staked_token_pool โ€“

this will be the total FIO tokens staked for all FIO users.

(units FIO SUF)

combined_token_pool โ€“

this will be the total FIO tokens staked for all FIO users plus the staking rewards for all FIO users.

(units FIO SUF)

rewards_token_pool โ€“

this is the amount of rewards collected from fees plus the amount of rewards minted. it is also the amount of rewards available for all of the fio accounts with staked tokens.

(units SUFs)

global_SRP_count โ€“

this is the global SRP count used to compute the rate of exchange for staking rewards.

(Units SUS)

total_staking_rewards โ€“

this is the value of the total staking rewards

(units SUFs)

daily_staking_rewards โ€“

this is the value of the staking rewards per day.

(units SUFs)

staking_rewards_reserve_minted โ€“

this is the amount that has been minted so far for rewards.

(units SUFs)

Requirement: Storing the values of the total_SRPs, and the total_staked_fio by FIO account

There are a couple of approaches to this which should be considered:

Approach #1: Binary Extension of eosio_name/accountmap

The accountmap table already exists within the FIO Protocol. This table can be extended using binary extenstion to add a new attribute called rate_of_exchange.

advantages โ€“ no duplication of account in state tables.

disadvantages โ€“

migration issues after update.

testing after the binary extension is very important, after the deployment of the binary extension, the table entries that have not yet set the value of this new attribute will not return the new attribute in the return data using get table, we must test scenarios where an account has been updated to the new table struct, but has not yet done staking, and then calls unstake, we must also test these updated accounts for staking.

ย 

Approach #2 (PREFERRED): Create new table with mapping for accounts that stake:

This approach would create a new table called user staking, this table would contain entries for accounts that have staked. when an account unstakes, the entry for that account would be removed from state.

Each user staking record has the following attributes.

  • id โ€“ unique id for the staking event.

  • account โ€“ the account that staked.

  • total_SRPs โ€“ the total SRPs to be awarded (units SUSs).

  • total_staked_fio โ€“ the total fio staked by this account (units SUFs)

dis-advantages โ€“ this approach duplicates the account info in state for accounts that stake.

advantages โ€“

this approach only stores staking records in state for staking events for accounts, accounts that do not stake will not have any additional state information associated with the account.

this approach has no migration issues since a new table is created to hold the staking info for accounts.

this approach does not impact the account map or other areas of fio.

ย 

Requirement: lock tokens for existing accounts.

We must design a means for the FIO Protocol to perform 2 operations which it does not today:

1) add general locks to a pre-existing FIO account.

The initial thought on this is to make a new contract action that does the job of creating a lock on a pre-existing account, this should only be callable contract to contract (authorization checks should prohibit other callers from calling the action).

2) modify pre-existing lock information to properly record the resulting locks whenever unstaking occurs.

The initial thought is to make a new action addlockperiod which will only be callable contract to contract, (authorization checks should prohibit other callers from calling the action).

  • We need to properly lock for 7 days when a user unstakes tokens, even when they have other locked tokens within the account.

  • When an account has a pre-existing FIP-6 lock (or Main net locks). We need to manage the accounts FIO and general (FIP-6) lock information so that the locking information remains accurate going forward.

We need to do some optimized form of the following logic:

Check to see if the account has Main net locks.

if (main net locks exist) { Check to see if the account has a general lock (fip-6) already. if (general locks exist) { adapt the lock amount, remaining lock amount, and lock periods to add the new 7 day lock. } else { verify the remaining locked amount in the account. (amount in account - main net remaining locked >= amount to lock) make a new general lock with one seven day period. } } else if main net locks do not exist. { Check to see if the account has a general lock (fip-6) already. if (general locks exist) { adapt the lock amount, remaining lock amount, and lock periods to add the new 7 day lock. } else { make a new general lock with one seven day period. } }

Requirement: Accumulate and manage staking rewards

Proposed:

  • Modify the fio.common process_rewards, processbucketrewards, and processrewardsnotpid to perform the accumulation and management of staking rewards

  • Small cleanup of code, to remove int literals from these methods, and use global constants.

Requirement: Perform fee accounting, and new BP claim logic to manage staking rewards (including minting)

Proposed:

  • Modify the existing bpclaim action in the fio.treasury towards this purpose.

Requirement: Compute the usable balance accurately when an account has staked tokens.

Proposed:

  • Modify the existing logic computing usable balance to include staking amounts. (fio.token contract). Presently main net locked tokens and general (FIP-6) locks cannot co-exist within an account. This FIP specifies that main net locks, general locks, and staking of tokens can all co-exist within an account in FIO. This will require some careful rework of the logic computing usable balances for transfer.

Requirement: staked tokens count towards votable balance.

Proposed:

  • since we will permit main net and FIP-6 locks to co-exist (for unstaking only, you still cannot create a lock on an account with existing tokens), we must combine the votable balance computations to provide an accurate votable balance when both types of lock are co-existing in the same account.

Requirement: staked tokens cannot be used to pay fees.

  • we must ensure that staked token balances are accounted for properly in fee pay logic. this affects fio.token contract transfer action, we must ensure that staked amounts are accounted for accurately.

Requirement: TPIDs will receive a percentage of the Fees AND part of staking rewards.

  • When user unstakes FIO Tokens, the TPID attached to the unstake action receives 10% of the difference between tokens being unstaked and FIO Tokens received as a result of SRP to FIO Token conversion. If no TPID is provided, the 10% remains undistributed.

Requirement: TPIDs will receive a percentage of the Fees AND part of staking rewards.

  • When user unstakes FIO Tokens, the TPID attached to the unstake action receives 10% of the difference between tokens being unstaked and FIO Tokens received as a result of SRP to FIO Token conversion. If no TPID is provided, the 10% remains undistributed.

Requirement: If auto proxy is used in the staking call, the code should not fail voting checks if this is the first call using tpid (when the auto proxy is being established IN the staking call).

  • we must enforce this business rule.

Summary of changes to fio and fio.contracts

  • a list of affected contracts, files and changes to files. including logic will be posted.

    • fio.common.hpp โ€“ add new constants for

      • STAKED_TOKEN_POOL_MINIMUM,

      • STAKING_REWARDS_RESERVE_MAXIMUM

      • process_rewards โ€“ modify percentages, integrate update to staking globals.

      • processbucketrewards โ€“ modify percentages, integrate update staking globals.

      • processrewardsnotpid โ€“ modify percentages, integrate update staking globals.

      • add constants for percentage amounts in rewards processing, instead of int literals.

      • set_auto_proxy โ€“ add a new common method to set auto proxy (usable from bundled fees in staking)

    • fio.staking.hpp

      • staking_info โ€“ struct for the global staking info records in the global staking table.

      • account_staking_info โ€“ struct for account staking info records in account_staking table.

      • add new tables

        • global_staking โ€“ the table to hold global staking info.

        • account_staking โ€“ the table holding account-wise staking info.

    • fio.staking.cpp

      • stakefio โ€“ perform the staking of fio.

      • unstakefio โ€“ perform the unstaking of fio.

      • add the following actions to the fio.staking contract

        • //FIP-21 actions to update staking state. //clrgdailyrew performs the clearing of the daily rewards. // params none! // logic // set daily_staking_rewards = 0; //incgstkmint increments the staking_rewards_reserves_minted // params // amountfiosufs, this is the amount of FIO that has been minted, units SUFs //FIP-21 actions to update staking state.

          ย 

    • fio.system.cpp --add new actions for (these actions will be added to the fio.staking contract, once this is prototyped successfully this document will be updated).

      • adaptlock โ€“ update FIP-6 locks.

      • updbpclaim โ€“ update to perform necessary accounting for staking.

      • resetclaim โ€“ update to perform necessary accounting for staking.

    • voting.cpp

      • the computation of the votable balance will be modified to properly consider accounts having main net locks, general locks and staked tokens (along with the rules for voting for these)..

    • fio.treasury.cpp โ€“

      • bpclaim โ€“ modify to perform modified logic for staking, including minting of staking rewards according to spec.

    • fio.token.hpp --

      • can_transfer, can_transfer_general โ€“ we will combine the logic of these 2 calls into one call that checks main net locks, general (FIP-6) locks, and staking amount to determine the allowability of transfers.

Summary of FIO core changes.

In order for new contracts to be added to the Fio Protocol, the FIO core code must be modified to add new system accounts to the list of system accounts. This is somewhat limiting and forces the systems core code to be upgraded by all BPs, integrators, exchanges, and API node operators. The solution to this is to provide enhancements to the FIO core so that the system uses the contract names in the actions table to determine the list of system accounts. These changes will be developed and delivered before this project delivers, and this will remove the need for future mandatory upgrades for projects introducing new contracts and system accounts (such as wrapping, marketplace, and any others that come about).

Actions and Endpoints

  • New Actions

    • stakefio

    • unstakefio

    • adaptlock

    • please see above list of actions in fio.staking for comprehensive list.

  • Modified Actions

    • updlbpclaim

    • resetclaim

    • bpclaim

    • transfer

    • trnsfiopubky

Structs and ABIs

  • ABI changes will be published here as development commences.

Tables

  • fio.system โ€“ establish a new table for general locks locktokensv2 the old table will be retired.

    • establish the use of an unlock amount instead of a percentage.

  • fio.staking contract

    • staking table โ€“ this is the new table which will hold global state items relating to staking.

      • uint64_t staked_token_pool โ€“ this will be the total FIO tokens staked for all FIO users. (units FIO SUF)

      • uint64_t combined_token_pool โ€“ this will be the total FIO tokens staked for all FIO users plus the staking rewards. (units FIO SUF)

      • uint64_t rewards_token_pool โ€“ this is the value of the total staking rewards (units SUFs)

      • uint64_t global_SRP_count โ€“this is the global SRP count used to compute the rate of exchange for staking rewards. (Units SUS)

      • uint64_t daily_staking_rewards โ€“ this is the value of the staking rewards per day. (units SUFs)

      • uint64_t staking_rewards_reserve_minted โ€“this is the amount that has been minted so far for rewards. (units SUFs)

      • uint64_t treasury_staking_rewards โ€“this is the amount of FIO in the treasury ear marked for staking rewards. (units SUFs)

    • stakeaccount โ€“ this is a new table that will hold staking information by FIO account.

      • uint64_t id โ€“ unique id for the staking event

      • name account โ€“ the account that staked.

      • uint64_t total_SRPs โ€“ the total SRPs to be awarded (units SUSs).

      • uint64_t total_staked_fio โ€“ the total fio staked by this account (units SUFs)

Project Plan

color key

(blue items โ€“ in progress)

(green items โ€“ completed)

(black items โ€“ to be completed)

  • Epic โ€“ FIO staking

    • Stories

      • Produce design spec, and revise FIP-21. (1 week Complete)

        • review internal, and community.

      • FIO Staking Development (3 weeks In progress 85% complete)

        • implement the solution as per FIP-21 and detailed development spec.

          • Started work March 29

          • constants implemented

          • staking global state implemented

          • account staking implementation implemented

          • port existing work to new contract fio.staking, completed

            • make shell of the new contract and integrate into the build.

            • integrate all table implementations for staking into fio.staking contract.

            • integrate stake and unstake shell into fio.staking contract.

          • Develop new logic to permit new contracts and system accounts to be added to the FIO protocol without mandatory core upgrades (completed, in QA for Bahamas)

          • implement and test actions to update global state for staking. In progress (100% completed)

            • implement stakefio (completed)

            • implement unstakefio (completed)

            • implement modified locking mechanism to support unstakefio (completed)

            • impelement and test incgrewards

            • implement and test clrdrewards

            • implement and test recorddaily

          • adapt usable balance logic

          • adapt voting power logic

          • transfer

          • transfer using pub key

          • modify fee collection logic

            • process_rewards

            • processbucketrewards

            • processrewardsnotpic

          • bpclaim

            • bpclaim

          • implement the removal of expired periods during lock adaptation on unstaking.

          • implement the use of an existing period if there is a period in this same day during unstaking

          • Implement new model for general locks, place SUF amount instead of percent.

            • retire old lock tokens and replace with locktokensv2 table.

            • integrate new table throughout contracts and chain_plugin.

        • Dev test. (30% completed)

          • Regression testing (runs of fio.test) completed

          • dev test cases

            • pre existing main net locks (test all unlocking periods using transfer and vote producer) (manual testing completed)

            • pre existing main net locks (test staking and transfer before and after first unlock period) (javascript fio.test integrated testing completed)

            • modify all general locks tests to run with the new v2 general locks table.

            • modify performance tests to use new general locks structure

            • modify tests to perform auto proxy testing.

        • develop tests matching test plan in design spec.

        • internal code review

        • internal testing review.

        • perform QA and resolve all issues (comprehensive QA analysis)

        • Acceptance testing review by product owner.

      • FIO staking โ€“ Security/Performance testing (dev net) (1 week)

        • develop tests to load system and drive volume of requests (we desire a max stakes test, and also a volume of staking unstaking requests once loaded maximally) performance test plan is still TBD.

      • Rollout testing (dev net) (2 days)

        • load previous version of contracts, perform contract MSIGs, repeat load testing.

      • Test net testing โ€“ (1 week)

        • roll out msigs, perform subset of functional tests on test net (tests to be performed are TBD)

      • Main net rollout (2 days)

        • roll out MSIGs, perform minimal success testing to verify deployment (tests to be performed are TBD).

  • security of the new locking actions will require relatively complete QA testing (a test plan will be published).

Risks

  • Performance analysis should be performed on dev net. A testing plan will be published.

  • security of the new locking actions will require relatively complete QA testing (a test plan will be published).

  • This FIP provides that main net locks, general (FIP-6) locks, and staking amounts can co-exist together within an account. So testing of main net locks, and general locks will need to be performed to ensure bugs are not introduced.

SDK Requirements

  • Update all SDKs to include new endpoints for staking.

  • FIOSdk_typescript

    • integrate stakefio into SDK (6 hours) (completed)

    • expand tests to cover stakefio in SDK (4 hours)

    • Integrate unstakefio into SDK (6 hours)

    • expand tests to cover unstakefio (4 hours)

    • integrate changes to get_balance (4 hours)

    • integrate get_staked_info into SDK (6 hours)

    • expand tests to cover get_staked_info (4 hours)

  • FIOSdk_Kotlin

    • integrate stakefio into SDK (6 hours)

    • expand tests to cover stakefio in SDK (4 hours)

    • Integrate unstakefio into SDK (6 hours)

    • expand tests to cover unstakefio (4 hours)

    • integrate changes to get_balance (4 hours)

    • integrate get_staked_info into SDK (6 hours)

    • expand tests to cover get_staked_info (4 hours)

  • FIOSdk_IOS

    • integrate stakefio into SDK (6 hours)

    • expand tests to cover stakefio in SDK (4 hours)

    • Integrate unstakefio into SDK (6 hours)

    • expand tests to cover unstakefio (4 hours)

    • integrate changes to get_balance (4 hours)

    • integrate get_staked_info into SDK (6 hours)

    • expand tests to cover get_staked_info (4 hours)

Functional Testing

Design

  • Main net (genesis) locks functional testing

  • APPROACH --

    • The approach is to cover the required regression testing as efficiently as possible, transfer fio pub key, voting for producers, staking and unstakingre are the critical calls requiring testing (and the grant amounts need to be very large grants in the 10s of M in fio), these calls need to be tested so as to ensure overflow errors are not present, and that the proper unlocking is performed by the system according to the schedule. For QA testing it will be important to create test accounts that have been granted the largest and smallest scale of FIO genesis grants (is this 100M and 1M), then test these grants in various ways throughout the unlocking periods.

    • The FIO Protocol needs to be set up to have a shorted unlocking period for testing, (in the current staking branch for fio.contracts, the current time set for genesis locking periods is 2 minutes.)

    • The fio.test repository should cnfigure the index.js so that the only test to be run is the test stake-mainnet-locked-tokens.js

    • init a dev local test environment by running the 20_debug_staking.sh during chain startup. (the dev branch for staking is already set up to run this script during startup)

    • When the chain is initialized. IMMEDIATELY run the rpm test to run these tests.

    • expected results, the tests will run and the later tests MAY experience a duplicate tx error, this is OK as long as duplicate TX error is the only error you see.

    • these tests run minimal staking tests on the genesis locked token account and they are NOT meant to test token unlocking.

  • ย 

  • Testing Genesis locked token grant unlocking.

    • pre-test setup (not completed yet)

      • set up the 20_debug_staking.sh script to create 2 new locked token accounts

        • one with 10M (be sure to make lock amounts fully populated in resolution, IE 10123456123456789 to encourage overflows if they happen).

        • one with 1M

      • tests to be performed.

        • Test Suite 1 โ€“ basic unlock using transfer.

          • unlock funds on both accounts by calling transfer every 2 minutes, and verifying the proper amount is unlocked at each unlock period.

        • Test Suite 2 โ€“ basic unlock using vote prducers

          • unlock funds on both accounts by calling vote producers every 2 minutes, and verifying the proper amount is unlocked at each unlock period.

        • Test Suite 3 โ€“ intermittent unlocking using transfer

          • unlock at period 3 only then wait for the end of all locks and unlock again using transfer, verify proper amounts are unlocked.

        • Test Suite 5 โ€“ intermittent unlocking using voting

          • unlock at period 3 only then wait for the end of all locks and unlock again using vote producers, verify proper amounts are unlocked.

        • Test Suite 6 โ€“ errors testing.

          • Transfer errors testing

            • try to transfer more than is unlocked during period 1.

            • unlock period 1 funds using transfer

            • try to transfer successful amount.

            • try to transfer more than whats left, see failure

            • unlock period 2 funds

            • try to transfer successful amount.

            • try to transfer more than whats left, see failure

        • Test Suite 7 โ€“ voting tests.

          • perform vote and verify the voting power of each account

            • unlock period 1 funds using transfer

            • reverify voting power.

        • Test Suite 8 โ€“ multiple calls tests

          • perform vote after period 1 passes

          • verify lock amount.

          • vote again changing your vote

          • verify no change in lock amounts.

          • vote again changing your vote

          • verify no change in lock amounts.

          • wait for period 2

          • call transfer

          • verify lock amount

          • call transfer

          • verify lock amount remains as before (cuz the next unlock hasn't happened yet)

          • call transfer

          • verify lock amount remains as before (cuz the next unlock hasn't happened yet)

  • General (FIP-6) locks testing

    • regression test general locks, unlocking and transfer especially.

    • existing tests may be adequate for this.

  • Staking rewards Tests

    • load system with load which does not provide minting. (less than 1M staked).

      • verify correct BP rewards

      • verify correct staking rewards.

    • load system with load which does provide minting. (more than 1M staked)

      • verify correct BP rewards

      • verify correct staking rewards.

  • stakefio

    • Authorization Tests

      • call using authority not matching actor, invalid signature error.

    • Parameter tests

      • set amount 0 invalid amount error.

      • set amount -100 invalid amount error.

      • set max_fee 0 invalid fee error.

      • set max_fee -100 invalid fee error

      • set invalid tpid โ€“ invalid tpid error.

      • set invalid actor โ€“ invalid actor error.

    • Success tests

      • stake fio from an account that has genesis tokens unlocked. verify global state results

        • perform multiple consecutive stakes of varying amounts that are premised. verify global state results

      • stake fio from an account that has FIP-6 locked token grant, and unlocked tokens. verify global state results

        • perform multiple consecutive stakes of varying amounts that are premised. verify global state results

      • stake from an account with FIP-6 locked token grant and tokens added to account. verify global state results

        • perform multiple consecutive stakes of varying amounts that are premised. verify global state results

      • stake from an account without any locked token grants. verify global state results

        • perform multiple consecutive stakes of varying amounts that are premised. verify global state results

      • stake fio using a tpid that has this staking call being the very first time this tpid is used. and WITHOUT voting first.

        • verify the stake is successful.

      • stake fio using a tpid that been established through its use in previous calls.

        • verify the stake is successful.

    • Failure tests

      • stake more than account has unlocked, fio from an account that has genesis locked tokens.

      • stake more than account has unlocked, fio from an account that has FIP-6 locked tokens.

      • stake more than account has, fio from an account that has no locked tokens.

      • stake fio using a tpid that is NOT set as proxy (and without voting first).

  • unstakefio

    • Authorization Tests

      • call using authority not matching actor, invalid signature error.

    • Parameter tests

      • set amount 0 invalid amount error.

      • set amount -100 invalid amount error.

      • set max_fee 0 invalid fee error.

      • set max_fee -100 invalid fee error

      • set invalid tpid โ€“ invalid tpid error.

      • set invalid actor โ€“ invalid actor error.

    • Success tests

      • unstake amount less than what was staked. verify accounting. verify lock result

        • examine if this is necessary to test on locked token accounts. verify lock result

      • unstake remained that is staked. verify accounting. verify lock amount.

        • examine if this is necessary to test on locked token accounts.

    • Failure tests

      • unstake more than remaining staked. verify error/exceptioin.

  • adaptlock

    • Authorization Tests

      • call as a non system account, verify this fails with auth error.

    • Parameter tests

      • call with duration on locking period set to 0

      • call with duration on locking period set to -100

      • call with percent set to 0

      • call with percent set to -1

    • Success tests

      • see unstake fio success tests, these drive these success cases.

    • Failure tests

      • see unstake failure tests, these test through this logic.

  • updatestake

    • Authorization Tests

      • call as a non system account, verify this fails with auth error.

    • Parameter tests

      • call with invalid parameters, for each parameter, verify errors.

    • Success tests

      • call bpclaim, verify that daily staking is updated as expected.

      • see stakefio success tests

      • see staking rewards tests.

    • Failure tests.

      • evaluate, and discover any test cases necessary.

Results

  • Link to JS tests and description of which test sections were updated/added

  • Paste results of tests

Performance Testing

Design

  • Load the system with 50k accounts holding FIO.

    • make each account to have staked tokens.

    • hit the chain with volumes of stake and unstake operations (verify the results after each).

    • the goal is to ensure that as the FIO protocol expands in adoption, that larger volumes of staking users won't become problematic.

  • ย 

Results

  • Summary of performance tests that were run and results

Fork Testing plan

  • This project does not introduce any mandatory changes to existing table structures, no fork testing is required.

  • A pre and post contracts update will be published.

  • Modifications to add new endpoints to the chain code will be tested.

    • changes to get_staked

Rollout/Release plan

  • a comprehensive list of all necessary changes will be published

    • chain code update for new endpoints. call each new endpoint and verify success case function.

    • fio.treasury

    • fio.system

    • all contracts using fio.common.hpp (a complete list will be made as development proceeds using contract hashes).

  • Include (new actions, removed actions, MSIGs for all required operations, and step by step instructions.

    • verify success case stakefio, unstakefio, get_staked_info (use the functional tests to verify success cases).

Rollout/Release verification plan

  • verify success case stakefio, unstakefio, get_staked_info (use the functional tests to verify success cases).

ย 

Branching Strategy/Code logistics

  • Development branches for this effort will be created as follows.

    • fio โ€“ feature/FIO-staking-fio-develop-05122021

    • fio.contracts โ€“ feature/FIP-21-Staking-fio-contracts-develop-03212021

    • fio.devtools โ€“ feature/FIP-21-Staking-fio-devtools-develop-04282021

ย 

Project Progress

  • 3/19 Review of the Detailed Design Specification

    • attendees Lukes Stokes, Paweล‚ Mastelerz, Adam Androuladakus, Casey Gardener, Todd G.

    • discussions included

      • Is is more desirable to move towards a notion of rewards points, and away from the notion of SRP (a token, that isn't a token).

        • it was deemed desirable to move to the notion of rewards points (SRP).

      • the necessity of the 7 day holding period.

        • deemed to be necessary to discourage gaming style use of the process.

      • should the rewards points be a whole number.

        • deemed to be necessary to maintain the 9 digit resolution.

      • should we consider to purge general locks of any already used locking periods as we go through the process of modifying locks to add new locking periods for the 7 day locking period.

        • YES

      • to prohibit a performance based attack on the locking periods, is it best to establish one time of day for seven day unlocking period, and then set all unstaking events done that day to use this locking period (IE: modify this locking period as multiple unstaking events occur during the same day).

        • YES

      • What if a general lock is made which is not votable?

        • Make the general grant votable? this has implications.

        • Make the staked amount to be not votable.

        • fail the staking request with an error, and instruct the user to stake in another account.

        • the most desirable option is to fail with an error. this will be implemented.

      • Can you add information to the design addressing the management of voting weights?

        • yes, this is completed.

      • add information for the important requirements ( tpids receive part of rewards, must have voted in the past 30 days).

ย 

  • 3/30 Made strategic decision to place staking into its own distinct contract and account fio.staking.

    • during implementation it became obvious that the implementation of staking by adding actions and tables into the fio.system contract would considerably contribute to the contract bloat of that contract.

    • it was also deemed somewhat more organized to place all of the structures and actions pertaining to the staking within a central contract named for this purpose, this helps to clarify the location of the key structures and actions involved in staking going forward, and also provides a clean compartmentalization of the staking data and functionality.

    • it will add a day or two to the project, but the gains we get by way of comprehensibility, and maintainability will be significant, and so this is seen as an easy decision.

  • ย 

  • 4/1 The team met to discuss the necessity for core upgrades that are presently required to deliver new contracts and system accounts within the Fio Protocol. It was proposed that we can use the actions table to make a list of distinct system accounts and use this, and so in the future we can avoid any mandatary upgrades being required whenever new contracts and system accounts are added to the Fio Protocol.

    • This underwent a quick feasibility prototype which proved the concept should work acceptably.

    • NOTE โ€“ testing must be performed before we go forward in delivering this approach.

      • full playback testing

      • test with 400 actions in the actions table

      • test with 400 actions in the actions table and also perform set code on system contract.

      • test with 400 actions in the actions table and also perform set code on system contract after bloating the system contract to increase its size.

      • test that a new contract can be added using operational msig and set contracts.

    • After submitting the PR for these changes, work will resume on the staking project. These changes may deliver with Bahamas and so should position the protocol well for staking, marketplace, and wrapping.

  • 4/8/2021 implementation completed and functional testing completed on changes to permit adding contracts without core changes.

  • 4/15/2021 release testing discovered an issue with playback, a fix was strategized and implemented. This Took a few days.

  • 4/22/2021 dev net testing uncovered some issues with support for the dev net environment a fix was implemented, this took a few days.

  • 4/25/2021 rollout to test net with Bahamas, and work re-focuses on the staking contract development.

  • 4/28/2021 4 system calls implemented and dev tested.

  • 4/292021 system calls refactored into in line logic in stakefio and unstakefio (stakefio is completed and dev tested, unstakefio is 75%, need to focus next on the lock modifications to support the rest of the unstakefio implementation).

  • 5/8/2021 completed initial testing of spendable balance for transfer, and voting weight with genesis locks and after unstaking (and so having general locks as well).

  • 5/9/2021 completed implementation and dev test of collection of fees and staking rewards, and minting of bp rewards when BP claim is called.

  • 5/13/2021 regression tests completed, modifications to fio.test to integrate staking specific tests begins.

  • 5/17/2021 genesis locks dev testing is completed (test first 3 locking periods and also unlocking after all locking periods have passed).

  • 5/17/2021 beginning to integrate the dev test plan into a set of javascript tests in the fio.test repo.

  • 5/17/2021 Added fio.staking abi to the fiosdk_typescript repo.

  • 5/26/2021 during the beginning of the regression tests development, it was discovered 2 important requirements are yet to be addressed.

    • first, when locks are adapted, old (or expired) locking periods should be removed.

    • second, when adapting locking periods, if there is a pre-existing period that exists on the same day as the period to be added, this period should be adapted instead of adding a new period.

    • both of these requirements will be addressed immediately..

  • 5/27/2021 discover issue with the locking period precision, initial discussions with pawel, document the possible paths forward.

    • the limitations of 3 decimal places prohibits unstaking of small amounts (internal calculations go t zero)

    • recommend the use of a SUF amount for locking periods and retirement of the existing lock tokens table for general locks.

    • meeting is scheduled to discuss the options and decide the path forward.

  • 6/2/2021 Decision was made to go with the use of SUF amount within locking periods.

    • implemented all necessary changes throughout the protocols contracts and chain plugin to integrate the vs table (locktokensv2).

    • modify existing staking dev tests and get clean run of these.

    • continue modifying all pre-existing tests for general locks.

  • 6/7/2021 complete performance testing on modified general locks.

    • modify all performance tests to function with new design.

    • complete testing on local dev box and dev net.

  • 6/10 Testing auto proxy uses to satisfy the staking voting requirements (as a result of a request from Paul from edge)

    • testing verifies that fio has a bug in all bundle fees, auto proxy is not processed in any fio bundled fee calls, only when a fee is collected.

    • modified the protocol to add a new set_auto_proxy in fio.common and integrate into staking.

    • dev test these changes by modifying startup so casey@dapixdev is a proxy and mod the tests to use him as tpid, verify that the staking code handles this as desired (the stake is called without having to vote because the tpid is specified and so auto proxy).

    • ย 

  • ย 

  • ย 

  • ย 

  • ย 

ย 

ย