235 lines
7.8 KiB
Python
Executable File
235 lines
7.8 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
Currency Ledger Validation Script
|
|
Ensures ledger integrity and policy compliance
|
|
"""
|
|
|
|
import csv
|
|
import yaml
|
|
from datetime import datetime
|
|
import os
|
|
|
|
def load_policies():
|
|
"""Load policy configuration files"""
|
|
policies = {}
|
|
policy_dir = os.path.join(os.path.dirname(__file__), '..', 'policies')
|
|
|
|
with open(os.path.join(policy_dir, 'credit-rates.yml'), 'r') as f:
|
|
policies['credit_rates'] = yaml.safe_load(f)
|
|
|
|
with open(os.path.join(policy_dir, 'karma-rules.yml'), 'r') as f:
|
|
policies['karma_rules'] = yaml.safe_load(f)
|
|
|
|
with open(os.path.join(policy_dir, 'validation-rules.yml'), 'r') as f:
|
|
policies['validation'] = yaml.safe_load(f)
|
|
|
|
return policies
|
|
|
|
def validate_sc_ledger():
|
|
"""Validate Smartup Credits ledger"""
|
|
print("🔍 Validating Smartup Credits ledger...")
|
|
|
|
total_sc = 0
|
|
ledger_file = os.path.join(os.path.dirname(__file__), '..', 'ledger', 'smartup-credits', 'transactions.csv')
|
|
|
|
try:
|
|
with open(ledger_file, 'r') as f:
|
|
reader = csv.DictReader(f)
|
|
transaction_count = 0
|
|
|
|
for row in reader:
|
|
if row['type'] == 'SC':
|
|
total_sc += int(row['amount'])
|
|
transaction_count += 1
|
|
elif row['type'] == 'REDEEM':
|
|
total_sc -= int(row['amount'])
|
|
transaction_count += 1
|
|
|
|
print(f"✅ Total SC Outstanding: {total_sc}")
|
|
print(f"✅ Transactions Processed: {transaction_count}")
|
|
|
|
except FileNotFoundError:
|
|
print("❌ SC ledger file not found")
|
|
return False
|
|
except Exception as e:
|
|
print(f"❌ Error validating SC ledger: {e}")
|
|
return False
|
|
|
|
return True
|
|
|
|
def validate_treasury():
|
|
"""Validate treasury balance and 3x rule"""
|
|
print("🔍 Validating treasury balance...")
|
|
|
|
treasury_file = os.path.join(os.path.dirname(__file__), '..', 'ledger', 'treasury', 'balance.csv')
|
|
|
|
try:
|
|
with open(treasury_file, 'r') as f:
|
|
reader = csv.DictReader(f)
|
|
rows = list(reader)
|
|
|
|
if rows:
|
|
latest = rows[-1]
|
|
eur_balance = float(latest['total_eur_balance'])
|
|
sc_outstanding = int(latest['sc_outstanding'])
|
|
ratio = float(latest['ratio'])
|
|
|
|
print(f"✅ EUR Treasury: €{eur_balance}")
|
|
print(f"✅ SC Outstanding: {sc_outstanding} SC")
|
|
print(f"✅ Current Ratio: {ratio:.2f}")
|
|
|
|
# Check 3x rule
|
|
if sc_outstanding <= (eur_balance * 3):
|
|
print("✅ 3x Rule: COMPLIANT")
|
|
else:
|
|
print("❌ 3x Rule: VIOLATION - Too much SC outstanding!")
|
|
return False
|
|
else:
|
|
print("⚠️ Treasury initialized but no transactions yet")
|
|
|
|
except FileNotFoundError:
|
|
print("❌ Treasury file not found")
|
|
return False
|
|
except Exception as e:
|
|
print(f"❌ Error validating treasury: {e}")
|
|
return False
|
|
|
|
return True
|
|
|
|
def main():
|
|
"""Main validation function"""
|
|
print("🚀 Smartup Zero Currency Ledger Validation")
|
|
print("=" * 50)
|
|
|
|
# Load policies
|
|
try:
|
|
policies = load_policies()
|
|
print("✅ Policy files loaded successfully")
|
|
except Exception as e:
|
|
print(f"❌ Error loading policies: {e}")
|
|
return
|
|
|
|
# Validate ledgers
|
|
sc_valid = validate_sc_ledger()
|
|
treasury_valid = validate_treasury()
|
|
|
|
print("=" * 50)
|
|
if sc_valid and treasury_valid:
|
|
print("🎉 All validations PASSED - Ledger is healthy!")
|
|
else:
|
|
print("🚨 Validation FAILED - Check errors above")
|
|
|
|
if __name__ == "__main__":
|
|
main()
|
|
|
|
def validate_organizational_structure():
|
|
"""Validate organizational assignments against policies"""
|
|
print("🏢 Validating organizational structure...")
|
|
|
|
book_file = os.path.join(os.path.dirname(__file__), '..', 'ownership', 'book-of-owners.csv')
|
|
|
|
try:
|
|
with open(book_file, 'r') as f:
|
|
reader = csv.DictReader(f)
|
|
|
|
total_owners = 0
|
|
team_counts = {}
|
|
role_counts = {}
|
|
|
|
for owner in reader:
|
|
if owner['owner_id']: # Skip header comments
|
|
total_owners += 1
|
|
|
|
teams = [t.strip() for t in owner['team_memberships'].split(',') if t.strip()]
|
|
roles = [r.strip() for r in owner['role_assignments'].split(',') if r.strip()]
|
|
|
|
for team in teams:
|
|
team_counts[team] = team_counts.get(team, 0) + 1
|
|
|
|
for role in roles:
|
|
role_counts[role] = role_counts.get(role, 0) + 1
|
|
|
|
print(f"✅ Total Active Owners: {total_owners}")
|
|
print(f"✅ Teams with Members: {len(team_counts)}")
|
|
print(f"✅ Roles Assigned: {len(role_counts)}")
|
|
|
|
# Show team distribution
|
|
if team_counts:
|
|
print("\n📊 Team Membership Distribution:")
|
|
for team, count in team_counts.items():
|
|
print(f" {team}: {count} members")
|
|
|
|
except FileNotFoundError:
|
|
print("❌ Book of Owners not found")
|
|
return False
|
|
except Exception as e:
|
|
print(f"❌ Error validating organizational structure: {e}")
|
|
return False
|
|
|
|
return True
|
|
|
|
# Update main() function to include organizational validation
|
|
def main():
|
|
"""Main validation function"""
|
|
print("🚀 Smartup Zero Currency Ledger Validation")
|
|
print("=" * 50)
|
|
|
|
# Load policies
|
|
try:
|
|
policies = load_policies()
|
|
print("✅ Policy files loaded successfully")
|
|
except Exception as e:
|
|
print(f"❌ Error loading policies: {e}")
|
|
return
|
|
|
|
# Validate ledgers
|
|
sc_valid = validate_sc_ledger()
|
|
treasury_valid = validate_treasury()
|
|
org_valid = validate_organizational_structure()
|
|
|
|
print("=" * 50)
|
|
if sc_valid and treasury_valid and org_valid:
|
|
print("🎉 All validations PASSED - System is healthy!")
|
|
else:
|
|
print("🚨 Validation FAILED - Check errors above")
|
|
|
|
def validate_pending_sc_ledger():
|
|
"""Validate pending SC ledger and vesting rules"""
|
|
print("⏳ Validating Pending SC ledger...")
|
|
|
|
total_pending_sc = 0
|
|
ledger_file = os.path.join(os.path.dirname(__file__), '..', 'ledger', 'pending-sc', 'transactions.csv')
|
|
|
|
try:
|
|
with open(ledger_file, 'r') as f:
|
|
reader = csv.DictReader(f)
|
|
transaction_count = 0
|
|
|
|
for row in reader:
|
|
if row['type'] == 'PENDING_SC' and row['status'] != 'REJECTED':
|
|
total_pending_sc += int(row['amount'])
|
|
transaction_count += 1
|
|
|
|
print(f"✅ Total Pending SC: {total_pending_sc}")
|
|
print(f"✅ Pending Transactions: {transaction_count}")
|
|
|
|
# Check if pending SC is reasonable
|
|
if total_pending_sc > 50000: # Sanity check
|
|
print(f"⚠️ Large pending SC amount - ensure proper validation")
|
|
|
|
except FileNotFoundError:
|
|
print("📝 No pending SC transactions found")
|
|
return True
|
|
except Exception as e:
|
|
print(f"❌ Error validating pending SC ledger: {e}")
|
|
return False
|
|
|
|
return True
|
|
|
|
# Update main validation to include pending SC
|
|
# Add this line in the main() function after treasury_valid = validate_treasury():
|
|
# pending_valid = validate_pending_sc_ledger()
|
|
|
|
# Update the final check:
|
|
# if sc_valid and treasury_valid and pending_valid and org_valid:
|