""" Display and table formatting functions for lockdrop analysis. This module contains functions for displaying analysis results in formatted tables and organizing the presentation of calculation results. """ import pandas as pd from decimal import Decimal from tabulate import tabulate from .constants import ( PENALTY_RATES, LOCKDROP_ALLOCATION, STAR_ALLOCATION_PERCENT, GALAXY_ALLOCATION_PERCENT, LOCKDROP_DURATION_BLOCKS, TOTAL_SUPPLY, NUM_STARS, NUM_GALAXIES, NUM_PLANETS, LOCKDROP_ALLOCATION_PERCENT ) def print_table_with_borders(df, title=""): """Print DataFrame with borders using tabulate.""" if title: print(f"\n{title}") print(tabulate(df, headers='keys', tablefmt='grid', showindex=False)) def print_constants_summary(): """Display core constants as formatted tables.""" print("=" * 80) print("šŸ“Š $Z LOCKDROP DISTRIBUTION - CORE CONSTANTS") print("=" * 80) # Lockdrop Allocation Table lockdrop_df = pd.DataFrame({ 'Parameter': ['Total Supply (1 $Z per Urbit ID)', 'Lockdrop Allocation %', 'Lockdrop Allocation ($Z)'], 'Value': [f"{TOTAL_SUPPLY:,}", f"{LOCKDROP_ALLOCATION_PERCENT:.2%}", f"{LOCKDROP_ALLOCATION:,.1f}"] }) print_table_with_borders(lockdrop_df, "šŸ”’ LOCKDROP ALLOCATION") # Points Distribution Table points_df = pd.DataFrame({ 'Point Type': ['Galaxies', 'Stars', 'Planets (excl.)'], 'Count': [f"{NUM_GALAXIES:,}", f"{NUM_STARS:,}", f"{NUM_PLANETS:,}"], 'Allocation %': [f"{GALAXY_ALLOCATION_PERCENT:.3%}", f"{STAR_ALLOCATION_PERCENT:.3%}", "0%"] }) print_table_with_borders(points_df, "🌟 URBIT POINT DISTRIBUTION") # Penalty Schedule Table penalty_df = pd.DataFrame({ 'Lock Period': ['5 Years', '4 Years', '3 Years', '2 Years', '1 Year'], 'Penalty Rate': [f"{PENALTY_RATES[year]:.2%}" for year in [5, 4, 3, 2, 1]], 'Token % of Max': ['100%', '80%', '60%', '40%', '20%'] }) print_table_with_borders(penalty_df, "āš–ļø PENALTY SCHEDULE") print("\n" + "="*80) def print_allocation_calculations(allocation_data): """Print basic allocation calculation tables.""" lockdrop_allocation_stars = LOCKDROP_ALLOCATION * STAR_ALLOCATION_PERCENT lockdrop_allocation_galaxies = LOCKDROP_ALLOCATION * GALAXY_ALLOCATION_PERCENT total_stars_locked = allocation_data['total_stars_locked'] total_galaxies_locked = allocation_data['total_galaxies_locked'] rounding_error_per_star = allocation_data['rounding_error_per_star'] rounding_error_per_galaxy = allocation_data['rounding_error_per_galaxy'] adjusted_max_allocation_per_star = allocation_data['adjusted_max_allocation_per_star'] adjusted_max_allocation_per_galaxy = allocation_data['adjusted_max_allocation_per_galaxy'] adjusted_z_per_star_per_block = allocation_data['adjusted_z_per_star_per_block'] adjusted_z_per_galaxy_per_block = allocation_data['adjusted_z_per_galaxy_per_block'] total_rounding_error_stars = allocation_data['total_rounding_error_stars'] total_rounding_error_galaxies = allocation_data['total_rounding_error_galaxies'] print("=" * 80) print("šŸ”¢ ALLOCATION CALCULATIONS") print("=" * 80) # Raw Allocations Table raw_allocation_per_star = lockdrop_allocation_stars / total_stars_locked if total_stars_locked > 0 else Decimal('0') raw_allocation_per_galaxy = lockdrop_allocation_galaxies / total_galaxies_locked if total_galaxies_locked > 0 else Decimal('0') raw_allocations_df = pd.DataFrame({ 'Point Type': ['Stars', 'Galaxies'], 'Total Allocation ($Z)': [f"{lockdrop_allocation_stars:,.1f}", f"{lockdrop_allocation_galaxies:,.1f}"], 'Max Per Point ($Z)': [f"{raw_allocation_per_star:,.6f}", f"{raw_allocation_per_galaxy:,.6f}"] }) print_table_with_borders(raw_allocations_df, "šŸ’° RAW PARTICIPANT ALLOCATIONS") # Quanta Calculations Table raw_z_per_star_per_block = raw_allocation_per_star / LOCKDROP_DURATION_BLOCKS if total_stars_locked > 0 else Decimal('0') raw_z_per_galaxy_per_block = raw_allocation_per_galaxy / LOCKDROP_DURATION_BLOCKS if total_galaxies_locked > 0 else Decimal('0') quanta_df = pd.DataFrame({ 'Point Type': ['Stars', 'Galaxies'], 'Raw Z per Block': [f"{raw_z_per_star_per_block:.15f}", f"{raw_z_per_galaxy_per_block:.15f}"], 'Adjusted Z per Block (q)': [f"{adjusted_z_per_star_per_block:.6f}", f"{adjusted_z_per_galaxy_per_block:.6f}"] }) print_table_with_borders(quanta_df, "āš™ļø QUANTA CALCULATION") # Adjusted Allocations Table (after quanta calculation) percentage_rounding_error_stars = total_rounding_error_stars / TOTAL_SUPPLY * 100 if total_stars_locked > 0 else Decimal('0') percentage_rounding_error_galaxies = total_rounding_error_galaxies / TOTAL_SUPPLY * 100 if total_galaxies_locked > 0 else Decimal('0') # Separate tables for better readability star_adjusted_df = pd.DataFrame({ 'Metric': ['Adjusted Max per Star', 'Rounding Error per Star', 'Total Rounding Error', 'Rounding Error %'], 'Value': [f"{adjusted_max_allocation_per_star:,.6f} $Z", f"{rounding_error_per_star:.9f} $Z", f"{total_rounding_error_stars:,.6f} $Z", f"{percentage_rounding_error_stars:.8f}%"], 'Note': ['Before bonus', 'Per star loss', 'Goes to bonus pool', 'Of total supply'] }) galaxy_adjusted_df = pd.DataFrame({ 'Metric': ['Adjusted Max per Galaxy', 'Rounding Error per Galaxy', 'Total Rounding Error', 'Rounding Error %'], 'Value': [f"{adjusted_max_allocation_per_galaxy:,.6f} $Z", f"{rounding_error_per_galaxy:.9f} $Z", f"{total_rounding_error_galaxies:,.6f} $Z", f"{percentage_rounding_error_galaxies:.8f}%"], 'Note': ['Before bonus', 'Per galaxy loss', 'Goes to bonus pool', 'Of total supply'] }) print("\nšŸŽÆ QUANTA ADJUSTED PARTICIPANT ALLOCATIONS") print_table_with_borders(star_adjusted_df, "⭐ Star Adjustments") print_table_with_borders(galaxy_adjusted_df, "🌌 Galaxy Adjustments") print("\n" + "="*80) def print_penalty_analysis(allocation_data): """Print penalty system analysis using values before bonus calculations.""" print("=" * 80) print("āš–ļø PENALTY SYSTEM ANALYSIS") print("=" * 80) # Use adjusted allocations (after penalties, before bonus distribution) adjusted_max_allocation_per_star = allocation_data['adjusted_max_allocation_per_star'] adjusted_max_allocation_per_galaxy = allocation_data['adjusted_max_allocation_per_galaxy'] penalty_analysis_df = pd.DataFrame({ 'Lock Period': ['5 Years', '4 Years', '3 Years', '2 Years', '1 Year'], 'Penalty Rate': [f"{PENALTY_RATES[year]:.2%}" for year in [5, 4, 3, 2, 1]], 'Star Allocation ($Z)': [f"{adjusted_max_allocation_per_star * (1 - PENALTY_RATES[year]):,.6f}" for year in [5, 4, 3, 2, 1]], 'Galaxy Allocation ($Z)': [f"{adjusted_max_allocation_per_galaxy * (1 - PENALTY_RATES[year]):,.6f}" for year in [5, 4, 3, 2, 1]], 'vs Max Allocation': ['100%', '80%', '60%', '40%', '20%'] }) print_table_with_borders(penalty_analysis_df, "šŸ“Š PENALTY ADJUSTED ALLOCATIONS (Before Bonus Distribution)") print("\n" + "="*80) def print_participation_summary(allocation_data): """Print participation distribution summary.""" stars_counts = allocation_data['stars_counts'] galaxies_counts = allocation_data['galaxies_counts'] total_stars_locked = allocation_data['total_stars_locked'] total_galaxies_locked = allocation_data['total_galaxies_locked'] # Consolidated participation and lock period distribution participation_df = pd.DataFrame({ 'Lock Period': ['1 Year', '2 Years', '3 Years', '4 Years', '5 Years', 'Total'], 'Stars': [f"{stars_counts[year]:,}" for year in [1, 2, 3, 4, 5]] + [f"{total_stars_locked:,}"], '% of Total Stars': [f"{stars_counts[year]/NUM_STARS:.2%}" for year in [1, 2, 3, 4, 5]] + [f"{total_stars_locked/NUM_STARS:.2%}"], 'Galaxies': [f"{galaxies_counts[year]:,}" for year in [1, 2, 3, 4, 5]] + [f"{total_galaxies_locked:,}"], '% of Total Galaxies': [f"{galaxies_counts[year]/NUM_GALAXIES:.2%}" for year in [1, 2, 3, 4, 5]] + [f"{total_galaxies_locked/NUM_GALAXIES:.2%}"], 'Total': [f"{stars_counts[year] + galaxies_counts[year]:,}" for year in [1, 2, 3, 4, 5]] + [f"{total_stars_locked + total_galaxies_locked:,}"], }) print("=" * 80) print_table_with_borders(participation_df, "šŸŽÆ PARTICIPANTS LOCK PERIOD DISTRIBUTION") print("\n" + "="*80) def print_bonus_pool_calculations(allocation_data, bonus_data): """Print detailed bonus pool calculations.""" stars_counts = allocation_data['stars_counts'] galaxies_counts = allocation_data['galaxies_counts'] adjusted_max_allocation_per_star = allocation_data['adjusted_max_allocation_per_star'] adjusted_max_allocation_per_galaxy = allocation_data['adjusted_max_allocation_per_galaxy'] total_rounding_error_stars = allocation_data['total_rounding_error_stars'] total_rounding_error_galaxies = allocation_data['total_rounding_error_galaxies'] print("=" * 80) print("šŸŽ BONUS POOL CALCULATIONS") print("=" * 80) # Star Bonus Pool Analysis star_bonus_df = pd.DataFrame({ 'Component': ['Penalty Pool', 'Rounding Error Bonus', 'Total Star Bonus Pool', 'Recipients (5Y Stars)', 'Bonus per 5Y Star', 'Final 5Y Star Allocation'], 'Value': [f"{bonus_data['star_penalty_pool']:,.6f} $Z", f"{total_rounding_error_stars:,.6f} $Z", f"{bonus_data['star_bonus_pool_total']:,.6f} $Z", f"{stars_counts[5]:,}", f"{bonus_data['bonus_per_star_5_years']:,.6f} $Z", f"{adjusted_max_allocation_per_star + bonus_data['bonus_per_star_5_years']:,.6f} $Z"] }) print_table_with_borders(star_bonus_df, "⭐ STAR BONUS POOL ANALYSIS") # Galaxy Bonus Pool Analysis galaxy_bonus_df = pd.DataFrame({ 'Component': ['Penalty Pool', 'Rounding Error Bonus', 'Total Galaxy Bonus Pool', 'Recipients (5Y Galaxies)', 'Bonus per 5Y Galaxy', 'Final 5Y Galaxy Allocation'], 'Value': [f"{bonus_data['galaxy_penalty_pool']:,.6f} $Z", f"{total_rounding_error_galaxies:,.6f} $Z", f"{bonus_data['galaxy_bonus_pool_total']:,.6f} $Z", f"{galaxies_counts[5]:,}", f"{bonus_data['bonus_per_galaxy_5_years']:,.6f} $Z", f"{adjusted_max_allocation_per_galaxy + bonus_data['bonus_per_galaxy_5_years']:,.6f} $Z"] }) print_table_with_borders(galaxy_bonus_df, "🌌 GALAXY BONUS POOL ANALYSIS") print("\n" + "="*80) def print_final_allocations_and_verification(allocation_data, final_data): """Print final allocations and verification tables.""" stars_counts = allocation_data['stars_counts'] galaxies_counts = allocation_data['galaxies_counts'] final_star_allocations = final_data['final_star_allocations'] final_galaxy_allocations = final_data['final_galaxy_allocations'] star_z_per_block = final_data['star_z_per_block'] galaxy_z_per_block = final_data['galaxy_z_per_block'] total_stars_allocation = final_data['total_stars_allocation'] total_galaxies_allocation = final_data['total_galaxies_allocation'] print("=" * 80) print("āœ… FINAL ALLOCATIONS & VERIFICATION") print("=" * 80) # Star Final Allocations Table star_final_df = pd.DataFrame({ 'Lock Period': ['5 Years', '4 Years', '3 Years', '2 Years', '1 Year'], 'Penalty': [f"{PENALTY_RATES[year]:.2%}" for year in [5, 4, 3, 2, 1]], 'Final Allocation (per star) ($Z)': [f"{final_star_allocations[year]:,.8f}" for year in [5, 4, 3, 2, 1]], 'Z per Block': [f"{star_z_per_block[year]:,.8f}" for year in [5, 4, 3, 2, 1]], 'Participants': [f"{stars_counts[year]:,}" for year in [5, 4, 3, 2, 1]] }) print_table_with_borders(star_final_df, "⭐ FINAL STAR ALLOCATIONS") # Galaxy Final Allocations Table galaxy_final_df = pd.DataFrame({ 'Lock Period': ['5 Years', '4 Years', '3 Years', '2 Years', '1 Year'], 'Penalty': [f"{PENALTY_RATES[year]:.2%}" for year in [5, 4, 3, 2, 1]], 'Final Allocation (per galaxy) ($Z)': [f"{final_galaxy_allocations[year]:,.8f}" for year in [5, 4, 3, 2, 1]], 'Z per Block': [f"{galaxy_z_per_block[year]:,.8f}" for year in [5, 4, 3, 2, 1]], 'Participants': [f"{galaxies_counts[year]:,}" for year in [5, 4, 3, 2, 1]] }) print_table_with_borders(galaxy_final_df, "🌌 FINAL GALAXY ALLOCATIONS") # Verification and Rounding Error Analysis lockdrop_allocation_stars = LOCKDROP_ALLOCATION * STAR_ALLOCATION_PERCENT lockdrop_allocation_galaxies = LOCKDROP_ALLOCATION * GALAXY_ALLOCATION_PERCENT final_rounding_error_stars = lockdrop_allocation_stars - total_stars_allocation final_rounding_error_galaxies = lockdrop_allocation_galaxies - total_galaxies_allocation final_rounding_error = final_rounding_error_stars + final_rounding_error_galaxies verification_df = pd.DataFrame({ 'Category': ['Star Allocations', 'Galaxy Allocations', 'Combined'], 'Calculated Total': [f"{total_stars_allocation:.8f} $Z", f"{total_galaxies_allocation:.8f} $Z", f"{total_stars_allocation + total_galaxies_allocation:.8f} $Z"], 'Expected Total': [f"{lockdrop_allocation_stars:.8f} $Z", f"{lockdrop_allocation_galaxies:.8f} $Z", f"{LOCKDROP_ALLOCATION:.8f} $Z"], 'Rounding Error': [f"{final_rounding_error_stars:.8f} $Z", f"{final_rounding_error_galaxies:.8f} $Z", f"{final_rounding_error:.8f} $Z"] }) print_table_with_borders(verification_df, "šŸ” ALLOCATION VERIFICATION") print("\nšŸ“ NOTE: Final rounding errors go to Zenith Foundation") print("\n" + "="*80) def print_analysis_tables(allocation_data, bonus_data, final_data): """Print comprehensive analysis tables - calls all the detailed sections.""" print_participation_summary(allocation_data) print_allocation_calculations(allocation_data) print_penalty_analysis(allocation_data) print_bonus_pool_calculations(allocation_data, bonus_data) print_final_allocations_and_verification(allocation_data, final_data)