Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Analysis and Testing

Sample C++ code

http://cpp.sh/9ohpl8jt7y

Code Block
languagecpp
// Staking unstake example with rounding
#include <iostream>
#include <string>
typedef unsigned __int128 uint128_t;

int main()
{
uint64_t  lctp = 10000000000000001003835500000000; // Last Combined Token Pool
uint64_t lgsrp = 2000000000000000; // Last Global Staking Reward Points
const uint128_t mult = 1000000000000000000; // mult constant is a multiplier factor to be used in int division. An int will be first multiplied by the mult before it's divided to ensure high precision.

// Stake SUFs
uint64_t stake = 3000000000000; // Amount of tokens to be staked
std::cout << "Staking " << stake << " SUFs \n";
uint128_t interim_mult_lctp = (uint128_t) lctp * mult; // LCTP is multiplied by mult and stored as interim variable
uint128_t interim_mult_lctpBYlgsrp = interim_mult_lctp / (uint128_t) lgsrp; // interim variable interim_mult_lctp is now divided by LGSRP
uint128_t interim_mult_stake = (uint128_t) stake * mult; // Amount of SUFs to stake is now multiplied by mult and stored as interim variable
uint128_t got_srp_big = interim_mult_stake / interim_mult_lctpBYlgsrp; // The 2 interim variables are now divided to produce number of SRPs to award
// Round instead of truncate
uint128_t rem_got_srp_big = interim_mult_stake % interim_mult_lctpBYlgsrp;
if (rem_got_srp_big >= (interim_mult_lctpBYlgsrp / (uint128_t) 2)) {
    got_srp_big++;
}
uint64_t got_srp = (uint64_t) got_srp_big; // This just converts from uint128 to uint64. Not sure if this is needed
std::cout << "Got " << got_srp << " SRPs \n";

// Unstake SUFs... I mean SRPs
uint64_t user_srps = got_srp1990000000000000; // Number of SRPs held by specific user
uint64_t user_staked_suf = 3000000000000995000000000000; // Number of SUFs staked by specific user
uint64_t unstake = 20000000000001000000000000; // Number of SUFs to be unstaked
// First we need to determine how many SRPs need to be unstaked, since we only get SUF as input
uint64_t srps_unstake;
if (unstake == user_staked_suf) {
    srps_unstake = user_srps; // If all SUFs then all SRPs
} else {
    uint128_t interim_mult_unstake = (uint128_t) unstake * mult; // unstake sufs are multiplied by mult and stored as interim variable
    uint128_t interim_suf_share = (uint128_t) interim_mult_unstake / (uint128_t) user_staked_suf; // the interim variable is divided by staked sufs to get upscaled share of srp
    uint128_t interim_srps_unstake_upscaled = interim_suf_share * (uint128_t) user_srps; // user's SRPs are multiplied by upscaled share of SUFs being unstaked to produce upscaled SRPs to unstake
    uint128_t interim_srps_unstake = interim_srps_unstake_upscaled / mult; // SRPs are downscaled by dividing by multiplier
    // Round instead of truncate
    uint128_t rem_interim_srps_unstake = interim_srps_unstake_upscaled % mult;
    if (rem_interim_srps_unstake >= (mult / (uint128_t) 2)) {
        interim_srps_unstake++;
    }
    srps_unstake = (uint64_t) interim_srps_unstake; // This just converts from uint128 to uint64. Not sure if this is needed
}
std::cout << "Unstaking " << srps_unstake << " SRPs \n";
uint128_t interim_usrplctp = (uint128_t) srps_unstake * (uint128_t) lctp; // SRPs being unstaked are multiplied by LCTP first
uint128_t got_suf_big = interim_usrplctp / (uint128_t) lgsrp; // Then are divided by LGSRP
// Round instead of truncate
uint128_t rem_got_suf_big = interim_usrplctp % (uint128_t) lgsrp;
if (rem_got_suf_big >= ((uint128_t) lgsrp / (uint128_t) 2)) {
    got_suf_big++;
}
uint64_t

// Take 90% of reward
uint128_t topay;
uint128_t reward = got_suf_big =- (uint64uint128_t) got_suf_big) unstake;
if (reward > 0) {
    uint128_t reward10 = reward / (uint128_t) 10;
    // Round instead of truncate
    uint128_t rem_reward10 = reward % (uint128_t) 10;
    if (rem_reward10 >= ((uint128_t) 10 / (uint128_t) 2)) {
        reward10++;
    }
    reward = reward - reward10;  
    topay = unstake + reward;
} else topay = reward;
uint64_t got_suf = (uint64_t) topay; // This just converts from uint128 to uint64. Not sure if this is needed
std::cout << "Got " << got_suf << " SUFs \n";
}

...