You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
228 lines
8.8 KiB
228 lines
8.8 KiB
|
3 months ago
|
#!/usr/bin/env python3
|
||
|
|
"""
|
||
|
|
PoWHD Pricing Simulation
|
||
|
|
Demonstrates how the bonding curve pricing works in pyramid contracts
|
||
|
|
"""
|
||
|
|
|
||
|
|
import matplotlib.pyplot as plt
|
||
|
|
import numpy as np
|
||
|
|
|
||
|
|
class PoWHDSimulator:
|
||
|
|
def __init__(self):
|
||
|
|
# Constants from the contract
|
||
|
|
self.initial_price = 0.0000001 # ETH
|
||
|
|
self.price_increment = 0.00000001 # ETH
|
||
|
|
self.dividend_fee = 0.10 # 10%
|
||
|
|
self.referral_fee = 0.03 # 3%
|
||
|
|
|
||
|
|
# State variables
|
||
|
|
self.token_supply = 0
|
||
|
|
self.total_eth_in = 0
|
||
|
|
self.total_dividends = 0
|
||
|
|
|
||
|
|
def calculate_buy_price(self, token_amount=1):
|
||
|
|
"""Calculate price to buy specified number of tokens"""
|
||
|
|
if self.token_supply == 0:
|
||
|
|
return self.initial_price + self.price_increment
|
||
|
|
|
||
|
|
# Simplified linear approximation for demonstration
|
||
|
|
current_price = self.initial_price + (self.token_supply * self.price_increment)
|
||
|
|
return current_price
|
||
|
|
|
||
|
|
def calculate_tokens_for_eth(self, eth_amount):
|
||
|
|
"""Calculate how many tokens you get for ETH (after fees)"""
|
||
|
|
# Deduct fees first
|
||
|
|
after_fees = eth_amount * (1 - self.dividend_fee - self.referral_fee)
|
||
|
|
|
||
|
|
# Simplified calculation (real contract uses quadratic formula)
|
||
|
|
if self.token_supply == 0:
|
||
|
|
tokens = after_fees / (self.initial_price + self.price_increment)
|
||
|
|
else:
|
||
|
|
current_price = self.initial_price + (self.token_supply * self.price_increment)
|
||
|
|
tokens = after_fees / current_price
|
||
|
|
|
||
|
|
return tokens
|
||
|
|
|
||
|
|
def buy_tokens(self, eth_amount, has_referrer=False):
|
||
|
|
"""Simulate buying tokens"""
|
||
|
|
# Calculate fees
|
||
|
|
dividend_fee_amount = eth_amount * self.dividend_fee
|
||
|
|
referral_fee_amount = eth_amount * self.referral_fee if has_referrer else 0
|
||
|
|
net_eth = eth_amount - dividend_fee_amount - referral_fee_amount
|
||
|
|
|
||
|
|
# Calculate tokens received
|
||
|
|
tokens = self.calculate_tokens_for_eth(eth_amount)
|
||
|
|
|
||
|
|
# Update state
|
||
|
|
self.token_supply += tokens
|
||
|
|
self.total_eth_in += eth_amount
|
||
|
|
self.total_dividends += dividend_fee_amount
|
||
|
|
|
||
|
|
return tokens, net_eth, dividend_fee_amount, referral_fee_amount
|
||
|
|
|
||
|
|
def simulate_pyramid_lifecycle(self, investors=100):
|
||
|
|
"""Simulate a complete pyramid lifecycle"""
|
||
|
|
results = []
|
||
|
|
|
||
|
|
# Early investors (get good deals)
|
||
|
|
for i in range(20):
|
||
|
|
eth_investment = 0.1 + (i * 0.05) # 0.1 to 1.0 ETH
|
||
|
|
tokens, net_eth, div_fee, ref_fee = self.buy_tokens(eth_investment, has_referrer=(i>5))
|
||
|
|
|
||
|
|
results.append({
|
||
|
|
'investor': i+1,
|
||
|
|
'phase': 'Early',
|
||
|
|
'eth_invested': eth_investment,
|
||
|
|
'tokens_received': tokens,
|
||
|
|
'price_per_token': eth_investment / tokens if tokens > 0 else 0,
|
||
|
|
'total_supply': self.token_supply,
|
||
|
|
'total_eth_in': self.total_eth_in
|
||
|
|
})
|
||
|
|
|
||
|
|
# Middle investors (prices rising)
|
||
|
|
for i in range(20, 70):
|
||
|
|
eth_investment = 0.5 + (i * 0.02) # Increasing investments
|
||
|
|
tokens, net_eth, div_fee, ref_fee = self.buy_tokens(eth_investment, has_referrer=True)
|
||
|
|
|
||
|
|
results.append({
|
||
|
|
'investor': i+1,
|
||
|
|
'phase': 'Growth',
|
||
|
|
'eth_invested': eth_investment,
|
||
|
|
'tokens_received': tokens,
|
||
|
|
'price_per_token': eth_investment / tokens if tokens > 0 else 0,
|
||
|
|
'total_supply': self.token_supply,
|
||
|
|
'total_eth_in': self.total_eth_in
|
||
|
|
})
|
||
|
|
|
||
|
|
# Late investors (very expensive)
|
||
|
|
for i in range(70, investors):
|
||
|
|
eth_investment = 1.0 + (i * 0.1) # Large investments, few tokens
|
||
|
|
tokens, net_eth, div_fee, ref_fee = self.buy_tokens(eth_investment, has_referrer=True)
|
||
|
|
|
||
|
|
results.append({
|
||
|
|
'investor': i+1,
|
||
|
|
'phase': 'Late',
|
||
|
|
'eth_invested': eth_investment,
|
||
|
|
'tokens_received': tokens,
|
||
|
|
'price_per_token': eth_investment / tokens if tokens > 0 else 0,
|
||
|
|
'total_supply': self.token_supply,
|
||
|
|
'total_eth_in': self.total_eth_in
|
||
|
|
})
|
||
|
|
|
||
|
|
return results
|
||
|
|
|
||
|
|
def plot_results(results):
|
||
|
|
"""Create visualizations of the pyramid mechanics"""
|
||
|
|
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(15, 12))
|
||
|
|
|
||
|
|
investors = [r['investor'] for r in results]
|
||
|
|
prices = [r['price_per_token'] for r in results]
|
||
|
|
tokens = [r['tokens_received'] for r in results]
|
||
|
|
total_supply = [r['total_supply'] for r in results]
|
||
|
|
eth_invested = [r['eth_invested'] for r in results]
|
||
|
|
|
||
|
|
# Color code by phase
|
||
|
|
colors = []
|
||
|
|
for r in results:
|
||
|
|
if r['phase'] == 'Early':
|
||
|
|
colors.append('green')
|
||
|
|
elif r['phase'] == 'Growth':
|
||
|
|
colors.append('orange')
|
||
|
|
else:
|
||
|
|
colors.append('red')
|
||
|
|
|
||
|
|
# Plot 1: Price per token over time
|
||
|
|
ax1.scatter(investors, prices, c=colors, alpha=0.7)
|
||
|
|
ax1.set_xlabel('Investor Number')
|
||
|
|
ax1.set_ylabel('Price per Token (ETH)')
|
||
|
|
ax1.set_title('Token Price Escalation')
|
||
|
|
ax1.set_yscale('log')
|
||
|
|
|
||
|
|
# Plot 2: Tokens received vs ETH invested
|
||
|
|
ax2.scatter(eth_invested, tokens, c=colors, alpha=0.7)
|
||
|
|
ax2.set_xlabel('ETH Invested')
|
||
|
|
ax2.set_ylabel('Tokens Received')
|
||
|
|
ax2.set_title('Diminishing Returns')
|
||
|
|
ax2.set_yscale('log')
|
||
|
|
|
||
|
|
# Plot 3: Total token supply growth
|
||
|
|
ax3.plot(investors, total_supply, 'b-', linewidth=2)
|
||
|
|
ax3.set_xlabel('Investor Number')
|
||
|
|
ax3.set_ylabel('Total Token Supply')
|
||
|
|
ax3.set_title('Token Supply Growth')
|
||
|
|
|
||
|
|
# Plot 4: ETH investment amounts
|
||
|
|
ax4.bar(investors, eth_invested, color=colors, alpha=0.7)
|
||
|
|
ax4.set_xlabel('Investor Number')
|
||
|
|
ax4.set_ylabel('ETH Invested')
|
||
|
|
ax4.set_title('Investment Amounts by Phase')
|
||
|
|
|
||
|
|
# Add legend
|
||
|
|
from matplotlib.patches import Patch
|
||
|
|
legend_elements = [
|
||
|
|
Patch(facecolor='green', label='Early Investors (Profit)'),
|
||
|
|
Patch(facecolor='orange', label='Growth Phase'),
|
||
|
|
Patch(facecolor='red', label='Late Investors (Likely Loss)')
|
||
|
|
]
|
||
|
|
fig.legend(handles=legend_elements, loc='upper right')
|
||
|
|
|
||
|
|
plt.tight_layout()
|
||
|
|
plt.savefig('/home/crappy/ponzi/pyramid_analysis.png', dpi=300, bbox_inches='tight')
|
||
|
|
print("Visualization saved as 'pyramid_analysis.png'")
|
||
|
|
|
||
|
|
def print_analysis(results):
|
||
|
|
"""Print detailed analysis of the pyramid"""
|
||
|
|
print("\n" + "="*60)
|
||
|
|
print("PYRAMID ANALYSIS RESULTS")
|
||
|
|
print("="*60)
|
||
|
|
|
||
|
|
early_investors = [r for r in results if r['phase'] == 'Early']
|
||
|
|
late_investors = [r for r in results if r['phase'] == 'Late']
|
||
|
|
|
||
|
|
print(f"\nEARLY INVESTORS (First 20):")
|
||
|
|
print(f" Average price per token: {np.mean([r['price_per_token'] for r in early_investors]):.8f} ETH")
|
||
|
|
print(f" Average tokens received: {np.mean([r['tokens_received'] for r in early_investors]):.2f}")
|
||
|
|
print(f" Total ETH invested: {sum([r['eth_invested'] for r in early_investors]):.2f} ETH")
|
||
|
|
|
||
|
|
print(f"\nLATE INVESTORS (Last 30):")
|
||
|
|
print(f" Average price per token: {np.mean([r['price_per_token'] for r in late_investors]):.8f} ETH")
|
||
|
|
print(f" Average tokens received: {np.mean([r['tokens_received'] for r in late_investors]):.2f}")
|
||
|
|
print(f" Total ETH invested: {sum([r['eth_invested'] for r in late_investors]):.2f} ETH")
|
||
|
|
|
||
|
|
price_ratio = (np.mean([r['price_per_token'] for r in late_investors]) /
|
||
|
|
np.mean([r['price_per_token'] for r in early_investors]))
|
||
|
|
|
||
|
|
print(f"\nPRICE ESCALATION:")
|
||
|
|
print(f" Late investors pay {price_ratio:.1f}x more per token than early investors")
|
||
|
|
|
||
|
|
total_eth = results[-1]['total_eth_in']
|
||
|
|
print(f"\nOVERALL PYRAMID:")
|
||
|
|
print(f" Total ETH collected: {total_eth:.2f} ETH")
|
||
|
|
print(f" Total tokens issued: {results[-1]['total_supply']:.2f}")
|
||
|
|
print(f" Average price per token: {total_eth / results[-1]['total_supply']:.8f} ETH")
|
||
|
|
|
||
|
|
if __name__ == "__main__":
|
||
|
|
print("Simulating PoWHD Pyramid Contract...")
|
||
|
|
|
||
|
|
# Create simulator and run simulation
|
||
|
|
sim = PoWHDSimulator()
|
||
|
|
results = sim.simulate_pyramid_lifecycle(100)
|
||
|
|
|
||
|
|
# Generate analysis
|
||
|
|
print_analysis(results)
|
||
|
|
|
||
|
|
try:
|
||
|
|
plot_results(results)
|
||
|
|
except ImportError:
|
||
|
|
print("\nMatplotlib not available - skipping visualization")
|
||
|
|
print("Install with: pip install matplotlib")
|
||
|
|
|
||
|
|
print("\n" + "="*60)
|
||
|
|
print("KEY TAKEAWAYS:")
|
||
|
|
print("="*60)
|
||
|
|
print("1. Early investors get tokens much cheaper")
|
||
|
|
print("2. Price escalates exponentially with more participants")
|
||
|
|
print("3. Late investors pay premium prices for fewer tokens")
|
||
|
|
print("4. System requires constant new money to sustain")
|
||
|
|
print("5. Mathematical certainty that late investors will lose")
|
||
|
|
print("="*60)
|