#!/usr/bin/env perl
# Copyright 2019-2020 The Hush developers
# Released under the GPLv3
use warnings;
use strict;


my $supply   = 0.0;
my $block    = 0; # Block 0 in Hush Smart chains is the BTC genesis block
my $puposhis = 100_000_000;
my $subsidy0 = 1_250_000_000;
my $halvings = 0;
my $initial  = 6178674 * $puposhis;
my $interval = 1_680_000; # ~4 years of 75s blocks
my $stop     = shift || -1;
my $totalfr  = 0; # total paid out to FR address


if ($stop eq 'help' or $stop =~ m/-h/) {
    die <<HELP;
# Simulate the total supply on Hush v3 mainnet
# Block Reward: Total Coinbase In Block
# Subsidy     : Coinbase Earned by Miner
# FR          : Founders Reward (10%)
# Block Reward = Subsidy + FR
Usage: ./hush_supply  &> supply.csv
       ./hush_supply HEIGHT &> supply.csv # stop at HEIGHT
# This will generate CSV in the form of:
# block, supply, reward, subsidy, fr, totalfr, halvings
HELP
}


printf "# block, supply, reward, subsidy, fr, totalfr, halvings\n";

# Block Reward Amounts in puposhis
# The non-integral amounts cannot be represented exactly
# 12.5 * 100000000          = 1250000000
# 12.5 * 100000000 / 2      = 625000000
# 12.5 * 100000000 / 4      = 312500000
# 12.5 * 100000000 / 8      = 156250000
# 12.5 * 100000000 / 16     = 78125000
# 12.5 * 100000000 / 32     = 39062500
# 12.5 * 100000000 / 64     = 19531250
# 12.5 * 100000000 / 128    = 9765625
# 12.5 * 100000000 / 256    = 4882812.5
# 12.5 * 100000000 / 512    = 2441406.25
# 12.5 * 100000000 / 1024   = 1220703.125
# 12.5 * 100000000 / 2048   = 610351.5625
# 12.5 * 100000000 / 4096   = 305175.78125
# 12.5 * 100000000 / 8192   = 152587.890625
# 12.5 * 100000000 / 16384  = 76293.9453125
# 12.5 * 100000000 / 32768  = 38146.97265625
# 12.5 * 100000000 / 65536  = 19073.486328125



# Halving Block Heights
# 340000 + 1680000    = 2020000
# 340000 + 1680000*2  = 3700000
# 340000 + 1680000*3  = 5380000
# 340000 + 1680000*4  = 7060000
# 340000 + 1680000*5  = 8740000
# 340000 + 1680000*6  = 10420000
# 340000 + 1680000*7  = 12100000
# 340000 + 1680000*8  = 13780000
# 340000 + 1680000*9  = 15460000
# 340000 + 1680000*10 = 17140000
# 340000 + 1680000*11 = 18820000
# 340000 + 1680000*12 = 20500000
# 340000 + 1680000*13 = 22180000
# 340000 + 1680000*14 = 23860000
# 340000 + 1680000*15 = 25540000


sub hush_block_reward
{
    my $reward   = 0;
    my $height   = shift;
    my $halvings = 0;

    # TODO: Cover all halvings until BR=0
    if  ($height     >= 23860000)    {
        $reward       = 19073; # 0.486328125 deviation
        $halvings     = 15;
    } elsif ($height >= 22180000)    {
        $reward       = 38146; # 0.97265625 deviation
        $halvings     = 14;
    } elsif ($height >= 20500000)    {
        $reward       = 152587; # 0.890625sat deviation
        $halvings     = 13;
    } elsif ($height >= 18820000)    {
        $reward       = 305175; # 0.78125sat deviation
        $halvings     = 12;
    } elsif ($height >= 17140000)    {
        $reward       = 305175; # 0.78125sat deviation
        $halvings     = 11;
    } elsif ($height >= 15460000)    {
        $reward       = 610351; # 0.5625sat deviation
        $halvings     = 10;
    } elsif ($height >= 13780000)    {
        $reward       = 1220703; # 0.125sat deviation
        $halvings     = 9
    } elsif ($height >= 12100000) {
        $reward       = 2441406; # 0.25sat deviation
        $halvings     = 8
    } elsif ($height >= 10420000) {
        $reward       = 4882812; # 0.5sat deviation
        $halvings     = 7;
    } elsif ($height >= 8740000)  {
        $reward       = 9765625; # last exact reward
        $halvings     = 6;
    } elsif ($height >= 7060000)  {
        $reward       = 19531250; # 0.1953125 HUSH
        $halvings     = 5;
    } elsif ($height >= 5380000)  {
        $reward       = 39062500; # 0.390625 HUSH
        $halvings     = 4;
    } elsif ($height >= 3700000) {
        $reward       = 78125000;  # 0.78125 HUSH
        $halvings     = 3;
    } elsif ($height >= 2020000) {
        $reward       = 156250000; # 1.5625 HUSH
        $halvings     = 2;
    } elsif ($height >= 340000) {
        $reward       = 312500000; # 3.125 HUSH
        $halvings     = 1;
    } elsif ($height >= 128) {
        $reward = 1250000000; # 12.5 HUSH
    }

    return ($reward,$halvings);
}

# We know BR will go to zero between 7 and 8th halvings
while ($halvings <= 10) {
    $block++;
    my ($reward,$halvings) = hush_block_reward($block);
    my $fr                 = int($reward /  10);
    my $subsidy            = $reward - $fr;
    
    if($block == 1) {
        # initial airdrop of funds from HUSH v2 network @ Block 500000
        $reward = $initial;
        $subsidy= $reward;
        $fr     = 0;
    }
    $supply    += $reward;
    $totalfr   += $fr;

    # all values in puposhis
    # block, current supply, block reward amount, fr, totalfr, number of halvings
    printf "%d,%d,%d,%d,%d,%d,%d\n", $block, $supply, $reward, $subsidy, $fr, $totalfr, $halvings;
    exit(0) if $block == $stop;
    exit(0) if ($block > 128 && $reward == 0);
    exit(-1) if ($supply >= 21_000_000*$puposhis);
}
