def calculate_supply_information(economics: BaseEconomics) -> Dict: """Calculates the NU token supply information.""" supply_info = OrderedDict() max_supply = NU.from_nunits(economics.total_supply) # Initial Supply Information initial_supply_info = OrderedDict() supply_info['initial_supply'] = initial_supply_info initial_supply_info['total_allocated'] = float(INITIAL_SUPPLY.to_tokens()) # - Locked allocations locked_allocations = OrderedDict() initial_supply_info['locked_allocations'] = locked_allocations now = maya.now() vest_saft2_team_factor = vesting_remaining_factor(vesting_months=SAFT2_TEAM_VESTING_MONTHS, cliff=False, now=now) vest_worklock_factor = vesting_remaining_factor(vesting_months=WORKLOCK_VESTING_MONTHS, cliff=True, now=now) vest_nuco_factor = vesting_remaining_factor(vesting_months=NUCO_VESTING_MONTHS, cliff=True, now=now) vest_university_factor = vesting_remaining_factor(vesting_months=UNIVERSITY_VESTING_MONTHS, cliff=True, now=now) vested_nu = NU(0, 'NU') saft2_locked_supply = NU(value=(SAFT2_INITIAL_SUPPLY.to_nunits() * vest_saft2_team_factor), denomination='NuNit') vested_nu += (SAFT2_INITIAL_SUPPLY - saft2_locked_supply) team_locked_supply = NU(value=(TEAM_INITIAL_SUPPLY.to_nunits() * vest_saft2_team_factor), denomination='NuNit') vested_nu += (TEAM_INITIAL_SUPPLY - team_locked_supply) nuco_locked_supply = NU(value=(NUCO_INITIAL_SUPPLY.to_nunits() * vest_nuco_factor), denomination='NuNit') vested_nu += (NUCO_INITIAL_SUPPLY - nuco_locked_supply) worklock_locked_supply = NU(value=(economics.worklock_supply * vest_worklock_factor), denomination='NuNit') vested_nu += NU(value=(economics.worklock_supply - worklock_locked_supply.to_nunits()), denomination='NuNit') university_locked_supply = NU(value=(UNIVERSITY_INITIAL_SUPPLY.to_nunits() * vest_university_factor), denomination='NuNit') vested_nu += (UNIVERSITY_INITIAL_SUPPLY - university_locked_supply) locked_allocations['saft2'] = float(saft2_locked_supply.to_tokens()) locked_allocations['team'] = float(team_locked_supply.to_tokens()) locked_allocations['company'] = float(nuco_locked_supply.to_tokens()) locked_allocations['worklock'] = float(worklock_locked_supply.to_tokens()) locked_allocations['university'] = float(university_locked_supply.to_tokens()) total_locked_allocations = (saft2_locked_supply + team_locked_supply + nuco_locked_supply + worklock_locked_supply + university_locked_supply) # - Unlocked Allocations unlocked_supply_info = OrderedDict() initial_supply_info['unlocked_allocations'] = unlocked_supply_info unlocked_supply_info['saft1'] = float(SAFT1_SUPPLY.to_tokens()) unlocked_supply_info['casi'] = float(CASI_SUPPLY.to_tokens()) unlocked_supply_info['vested'] = float(vested_nu.to_tokens()) ecosystem_supply = INITIAL_SUPPLY - total_locked_allocations - (SAFT1_SUPPLY + CASI_SUPPLY + vested_nu) unlocked_supply_info['ecosystem'] = float(ecosystem_supply.to_tokens()) total_unlocked_allocations = SAFT1_SUPPLY + CASI_SUPPLY + vested_nu + ecosystem_supply # Staking Rewards Information staking_rewards_info = OrderedDict() supply_info['staking_rewards_supply'] = staking_rewards_info initial_supply_with_rewards = NU.from_nunits(economics.initial_supply) # economics value includes issued rewards staking_rewards_remaining = max_supply - initial_supply_with_rewards staking_rewards_issued = initial_supply_with_rewards - INITIAL_SUPPLY staking_rewards_total_allocated = staking_rewards_remaining + staking_rewards_issued staking_rewards_info['total_allocated'] = float(staking_rewards_total_allocated.to_tokens()) staking_rewards_info['staking_rewards_issued'] = float(staking_rewards_issued.to_tokens()) staking_rewards_info['staking_rewards_remaining'] = float(staking_rewards_remaining.to_tokens()) # Max Supply supply_info['max_supply'] = float(max_supply.to_tokens()) # Current Total Supply supply_info['current_total_supply'] = float(initial_supply_with_rewards.to_tokens()) # Est. Circulating Supply supply_info['est_circulating_supply'] = float(total_unlocked_allocations.to_tokens()) return supply_info
def test_NU(token_economics): # Starting Small min_allowed_locked = NU(token_economics.minimum_allowed_locked, 'NuNit') assert token_economics.minimum_allowed_locked == int(min_allowed_locked.to_nunits()) min_NU_locked = int(str(token_economics.minimum_allowed_locked)[0:-18]) expected = NU(min_NU_locked, 'NU') assert min_allowed_locked == expected # Starting Big min_allowed_locked = NU(min_NU_locked, 'NU') assert token_economics.minimum_allowed_locked == int(min_allowed_locked) assert token_economics.minimum_allowed_locked == int(min_allowed_locked.to_nunits()) assert str(min_allowed_locked) == '15000 NU' # Alternate construction assert NU(1, 'NU') == NU('1.0', 'NU') == NU(1.0, 'NU') # Arithmetic # NUs one_nu = NU(1, 'NU') zero_nu = NU(0, 'NU') one_hundred_nu = NU(100, 'NU') two_hundred_nu = NU(200, 'NU') three_hundred_nu = NU(300, 'NU') # Nits one_nu_wei = NU(1, 'NuNit') three_nu_wei = NU(3, 'NuNit') assert three_nu_wei.to_tokens() == Decimal('3E-18') assert one_nu_wei.to_tokens() == Decimal('1E-18') # Base Operations assert one_hundred_nu < two_hundred_nu < three_hundred_nu assert one_hundred_nu <= two_hundred_nu <= three_hundred_nu assert three_hundred_nu > two_hundred_nu > one_hundred_nu assert three_hundred_nu >= two_hundred_nu >= one_hundred_nu assert (one_hundred_nu + two_hundred_nu) == three_hundred_nu assert (three_hundred_nu - two_hundred_nu) == one_hundred_nu difference = one_nu - one_nu_wei assert not difference == zero_nu actual = float(difference.to_tokens()) expected = 0.999999999999999999 assert actual == expected # 3.14 NU is 3_140_000_000_000_000_000 NuNit pi_nuweis = NU(3.14, 'NU') assert NU('3.14', 'NU') == pi_nuweis.to_nunits() == NU(3_140_000_000_000_000_000, 'NuNit') # Mixed type operations difference = NU('3.14159265', 'NU') - NU(1.1, 'NU') assert difference == NU('2.04159265', 'NU') result = difference + one_nu_wei assert result == NU(2041592650000000001, 'NuNit') # Similar to stake read + metadata operations in Staker collection = [one_hundred_nu, two_hundred_nu, three_hundred_nu] assert sum(collection) == NU('600', 'NU') == NU(600, 'NU') == NU(600.0, 'NU') == NU(600e+18, 'NuNit') # # Fractional Inputs # # A decimal amount of NuNit (i.e., a fraction of a NuNit) pi_nuweis = NU('3.14', 'NuNit') assert pi_nuweis == three_nu_wei # Floor # A decimal amount of NU, which amounts to NuNit with decimals pi_nus = NU('3.14159265358979323846', 'NU') assert pi_nus == NU(3141592653589793238, 'NuNit') # Floor # Positive Infinity with pytest.raises(NU.InvalidAmount): _inf = NU(float('infinity'), 'NU') # Negative Infinity with pytest.raises(NU.InvalidAmount): _neg_inf = NU(float('-infinity'), 'NU') # Not a Number with pytest.raises(InvalidOperation): _nan = NU(float('NaN'), 'NU') # Rounding NUs assert round(pi_nus, 2) == NU("3.14", "NU") assert round(pi_nus, 1) == NU("3.1", "NU") assert round(pi_nus, 0) == round(pi_nus) == NU("3", "NU")
def verify_supply_information(supply_information: Dict, max_supply: NU, initial_supply_with_rewards: NU, worklock_supply: NU, future_date: MayaDT): assert supply_information['initial_supply']['total_allocated'] == float( INITIAL_SUPPLY.to_tokens()) # Locked vest_24_months = vesting_remaining_factor(vesting_months=24, cliff=False, now=future_date) vest_6_months_cliff = vesting_remaining_factor(vesting_months=6, cliff=True, now=future_date) vest_3_years_cliff = vesting_remaining_factor(vesting_months=3 * 12, cliff=True, now=future_date) vest_5_years_cliff = vesting_remaining_factor(vesting_months=5 * 12, cliff=True, now=future_date) vested_nu = NU(0, 'NU') saft2_supply = NU(value=(SAFT2_INITIAL_SUPPLY.to_nunits() * vest_24_months), denomination='NuNit') assert supply_information['initial_supply']['locked_allocations'][ 'saft2'] == float(saft2_supply.to_tokens()) vested_nu += SAFT2_INITIAL_SUPPLY - saft2_supply team_supply = NU(value=(TEAM_INITIAL_SUPPLY.to_nunits() * vest_24_months), denomination='NuNit') assert supply_information['initial_supply']['locked_allocations'][ 'team'] == float(team_supply.to_tokens()) vested_nu += TEAM_INITIAL_SUPPLY - team_supply nuco_supply = NU(value=(NUCO_INITIAL_SUPPLY.to_nunits() * vest_5_years_cliff), denomination='NuNit') assert supply_information['initial_supply']['locked_allocations'][ 'company'] == float(nuco_supply.to_tokens()) vested_nu += NUCO_INITIAL_SUPPLY - nuco_supply wl_supply = NU(value=(worklock_supply.to_nunits() * vest_6_months_cliff), denomination='NuNit') assert supply_information['initial_supply']['locked_allocations'][ 'worklock'] == float(wl_supply.to_tokens()) vested_nu += worklock_supply - wl_supply university_supply = NU(value=(UNIVERSITY_INITIAL_SUPPLY.to_nunits() * vest_3_years_cliff), denomination='NuNit') assert (supply_information['initial_supply']['locked_allocations'] ['university'] == float(university_supply.to_tokens())) vested_nu += UNIVERSITY_INITIAL_SUPPLY - university_supply total_locked = saft2_supply + team_supply + nuco_supply + wl_supply + university_supply # Unlocked assert supply_information['initial_supply']['unlocked_allocations'][ 'saft1'] == float(SAFT1_SUPPLY.to_tokens()) assert supply_information['initial_supply']['unlocked_allocations'][ 'casi'] == float(CASI_SUPPLY.to_tokens()) months_transpired = months_transpired_since_launch(now=future_date) vesting_times_and_amounts = OrderedDict({ WORKLOCK_VESTING_MONTHS: worklock_supply, SAFT2_TEAM_VESTING_MONTHS: (SAFT2_INITIAL_SUPPLY + TEAM_INITIAL_SUPPLY), UNIVERSITY_VESTING_MONTHS: UNIVERSITY_INITIAL_SUPPLY, NUCO_VESTING_MONTHS: NUCO_INITIAL_SUPPLY, }) if months_transpired > min(NUCO_VESTING_MONTHS, WORKLOCK_VESTING_MONTHS, UNIVERSITY_VESTING_MONTHS, SAFT2_TEAM_VESTING_MONTHS): vested_total = NU(0, 'NU') for vesting_months, vesting_value in vesting_times_and_amounts.items(): if months_transpired > vesting_months: assert vested_nu >= vesting_value # >= vesting amount (redundant but meh) vested_total += vesting_value assert vested_nu >= vested_total # >= vesting total assert supply_information['initial_supply']['unlocked_allocations'][ 'vested'] == float(vested_nu.to_tokens()) ecosystem_supply = INITIAL_SUPPLY - total_locked - SAFT1_SUPPLY - CASI_SUPPLY - vested_nu assert (supply_information['initial_supply']['unlocked_allocations'] ['ecosystem'] == float(ecosystem_supply.to_tokens())) total_unlocked = SAFT1_SUPPLY + CASI_SUPPLY + vested_nu + ecosystem_supply # Staking Rewards assert (supply_information['staking_rewards_supply']['total_allocated'] == float((max_supply - INITIAL_SUPPLY).to_tokens())) assert (supply_information['staking_rewards_supply'] ['staking_rewards_issued'] == float( (initial_supply_with_rewards - INITIAL_SUPPLY).to_tokens())) assert (supply_information['staking_rewards_supply'] ['staking_rewards_remaining'] == float( (max_supply - initial_supply_with_rewards).to_tokens())) # Max Supply assert supply_information['max_supply'] == float(max_supply.to_tokens()) # Circulating Supply assert supply_information['est_circulating_supply'] == float( total_unlocked.to_tokens())