myco-bonding-curve/notebooks/03_commitment_channels.ipynb

242 lines
8.2 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Commitment-Based Issuance Channels\n",
"\n",
"Exploring labor, subscription, and staking issuance — parallel minting paths that don't require financial reserves."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"\n",
"%matplotlib inline\n",
"plt.rcParams['figure.figsize'] = (12, 5)\n",
"plt.rcParams['figure.dpi'] = 100"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Labor Issuance\n",
"\n",
"Proof-of-contribution attestations converted to tokens at governed rates."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from src.commitments.labor import (\n",
" create_default_system, ContributorState,\n",
" attest_contribution, claim_tokens,\n",
")\n",
"\n",
"system = create_default_system()\n",
"contributors = {\n",
" 'alice': ContributorState(address='alice'),\n",
" 'bob': ContributorState(address='bob'),\n",
" 'carol': ContributorState(address='carol'),\n",
"}\n",
"\n",
"# Simulate contributions over 30 days\n",
"daily_minted = {name: [] for name in contributors}\n",
"total_minted = {name: 0 for name in contributors}\n",
"days = list(range(30))\n",
"\n",
"for day in days:\n",
" t = float(day)\n",
" # Alice: consistent code contributor\n",
" contributors['alice'] = attest_contribution(system, contributors['alice'], 'code', 5.0, t)\n",
" system, contributors['alice'], tokens = claim_tokens(system, contributors['alice'], 'code', t)\n",
" daily_minted['alice'].append(tokens)\n",
" total_minted['alice'] += tokens\n",
"\n",
" # Bob: governance contributor (less frequent)\n",
" if day % 3 == 0:\n",
" contributors['bob'] = attest_contribution(system, contributors['bob'], 'governance', 3.0, t)\n",
" system, contributors['bob'], tokens = claim_tokens(system, contributors['bob'], 'governance', t)\n",
" else:\n",
" tokens = 0\n",
" daily_minted['bob'].append(tokens)\n",
" total_minted['bob'] += tokens\n",
"\n",
" # Carol: community (high frequency)\n",
" contributors['carol'] = attest_contribution(system, contributors['carol'], 'community', 10.0, t)\n",
" system, contributors['carol'], tokens = claim_tokens(system, contributors['carol'], 'community', t)\n",
" daily_minted['carol'].append(tokens)\n",
" total_minted['carol'] += tokens\n",
"\n",
"fig, axes = plt.subplots(1, 2, figsize=(14, 5))\n",
"\n",
"# Daily minting\n",
"ax = axes[0]\n",
"for name, mints in daily_minted.items():\n",
" cumulative = np.cumsum(mints)\n",
" ax.plot(days, cumulative, '-o', markersize=3, label=name)\n",
"ax.set_xlabel('Day')\n",
"ax.set_ylabel('Cumulative MYCO minted')\n",
"ax.set_title('Labor Issuance Over Time')\n",
"ax.legend()\n",
"\n",
"# Total breakdown\n",
"ax = axes[1]\n",
"names = list(total_minted.keys())\n",
"values = list(total_minted.values())\n",
"colors = ['#2196F3', '#4CAF50', '#FF9800']\n",
"ax.bar(names, values, color=colors)\n",
"ax.set_ylabel('Total MYCO minted')\n",
"ax.set_title('Total Labor Issuance by Contributor')\n",
"for i, v in enumerate(values):\n",
" ax.text(i, v + 5, f'{v:.0f}', ha='center')\n",
"\n",
"plt.tight_layout()\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Subscription Issuance\n",
"\n",
"Recurring pledges with growing loyalty multipliers."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from src.commitments.subscription import (\n",
" SubscriptionSystem, create_subscription, process_payment,\n",
" create_default_tiers, loyalty_multiplier,\n",
")\n",
"\n",
"tiers = create_default_tiers()\n",
"system = SubscriptionSystem(tiers=tiers)\n",
"\n",
"# Create subscribers at different tiers\n",
"system, _ = create_subscription(system, 'alice', 'supporter', 0.0)\n",
"system, _ = create_subscription(system, 'bob', 'sustainer', 0.0)\n",
"system, _ = create_subscription(system, 'carol', 'patron', 0.0)\n",
"\n",
"# Simulate 12 months of payments\n",
"months = list(range(1, 13))\n",
"monthly_tokens = {name: [] for name in ['alice', 'bob', 'carol']}\n",
"\n",
"for month in months:\n",
" t = month * 30.0\n",
" for name in ['alice', 'bob', 'carol']:\n",
" system, tokens = process_payment(system, name, t)\n",
" monthly_tokens[name].append(tokens)\n",
"\n",
"fig, axes = plt.subplots(1, 2, figsize=(14, 5))\n",
"\n",
"# Monthly tokens by tier\n",
"ax = axes[0]\n",
"for name, label in [('alice', 'Supporter ($10/mo)'), ('bob', 'Sustainer ($25/mo)'), ('carol', 'Patron ($100/mo)')]:\n",
" ax.plot(months, monthly_tokens[name], '-o', markersize=4, label=label)\n",
"ax.set_xlabel('Month')\n",
"ax.set_ylabel('MYCO minted')\n",
"ax.set_title('Monthly Subscription Issuance (grows with loyalty)')\n",
"ax.legend()\n",
"\n",
"# Loyalty multiplier curve\n",
"ax = axes[1]\n",
"days = np.linspace(0, 730, 200)\n",
"multipliers = [loyalty_multiplier(d, max_multiplier=2.0, halflife_days=180) for d in days]\n",
"ax.plot(days / 30, multipliers, 'b-', linewidth=2)\n",
"ax.axhline(y=2.0, color='r', linestyle='--', alpha=0.5, label='Max (2x)')\n",
"ax.axvline(x=6, color='gray', linestyle=':', alpha=0.5, label='Halflife (6 months)')\n",
"ax.set_xlabel('Months subscribed')\n",
"ax.set_ylabel('Loyalty multiplier')\n",
"ax.set_title('Loyalty Multiplier Growth')\n",
"ax.legend()\n",
"\n",
"plt.tight_layout()\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Staking Issuance\n",
"\n",
"Lock MYCO for duration T, earn bonus via concave multiplier curve."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from src.commitments.staking import (\n",
" StakingParams, lockup_multiplier, compute_pending_bonus,\n",
" StakingSystem, create_stake,\n",
")\n",
"\n",
"fig, axes = plt.subplots(1, 2, figsize=(14, 5))\n",
"\n",
"# Multiplier curves comparison\n",
"ax = axes[0]\n",
"durations = np.linspace(0, 365, 200)\n",
"for curve, color in [('sqrt', 'blue'), ('log', 'green'), ('linear', 'red')]:\n",
" params = StakingParams(multiplier_curve=curve)\n",
" mults = [lockup_multiplier(d, params) for d in durations]\n",
" ax.plot(durations / 30, mults, color=color, linewidth=2, label=f'{curve} curve')\n",
"\n",
"ax.set_xlabel('Lockup duration (months)')\n",
"ax.set_ylabel('Bonus multiplier')\n",
"ax.set_title('Staking Multiplier Curves')\n",
"ax.legend()\n",
"\n",
"# Bonus accumulation\n",
"ax = axes[1]\n",
"params = StakingParams(multiplier_curve='sqrt')\n",
"for lockup, color in [(30, 'blue'), (90, 'green'), (180, 'orange'), (365, 'red')]:\n",
" system = StakingSystem(params=params)\n",
" system, pos = create_stake(system, 'staker', 1000.0, 'MYCO', float(lockup), 0.0)\n",
" times = np.linspace(0, lockup, 100)\n",
" bonuses = [compute_pending_bonus(pos, params, t) for t in times]\n",
" ax.plot(times / 30, bonuses, color=color, linewidth=2, label=f'{lockup}d lockup')\n",
"\n",
"ax.set_xlabel('Time (months)')\n",
"ax.set_ylabel('Pending bonus (MYCO)')\n",
"ax.set_title('Staking Bonus Accumulation (1000 MYCO staked)')\n",
"ax.legend()\n",
"\n",
"plt.tight_layout()\n",
"plt.show()"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python",
"version": "3.11.0"
}
},
"nbformat": 4,
"nbformat_minor": 4
}