Most tokenomics are vibes. A founder picks a billion-token supply, allocates 20% to the team, drops a pie chart on a pitch deck, and calls it a day. Nobody models what happens when half the team vest unlocks on the same Tuesday, or when a bear market slashes on-chain volume 80% while operating costs stay fixed.
token-simulator lets you stress-test supply dynamics, burn rates, vesting pressure, and vault yield before a single token is minted. Feed it your parameters, and it runs a deterministic month-by-month simulation of circulating supply, treasury balance, and staker returns.
create-protocol-v4 preset from the dropdown.5%. Watch what happens: the burn rate spikes past 2M tokens/month by month 8, circulating supply collapses, and staker APY becomes meaningless because there are no tokens left to stake. That is the failure mode this tool exists to find.Install from PyPI and run a 24-month simulation with the built-in preset:
pip install token-simulator token-simulator run --preset create-protocol-v4 --months 24
Sample CSV output (first 4 rows):
month,circ_supply,burned_cumul,treasury_usd,staker_apy,price_usd 0,100000000,0,500000,0.00,0.0200 1,102400000,48000,487200,11.42,0.0198 2,104700000,103200,474800,10.86,0.0195 3,106900000,165800,462100,10.34,0.0191
Pipe it into any analysis tool you like: pandas, a spreadsheet, or the built-in --plot flag for a terminal sparkline chart.
A preset is a YAML file (or a Python dict) describing your token economy. Here is the anatomy:
name: my-project
total_supply: 1_000_000_000
initial_circulating_pct: 10
initial_price: 0.02
pool_usdc: 500_000
revenue_streams:
- name: marketplace-fees
volume: 200_000 # USD/month at launch
growth_rate: 0.08 # 8% MoM
cap: 2_000_000 # max monthly volume
margin: 0.70
touches_burn_toll: true
- name: api-subscriptions
volume: 15_000
growth_rate: 0.12
cap: 500_000
margin: 0.90
touches_burn_toll: false
vest_buckets:
- name: team
fraction: 0.18
cliff: 12 # months
unlock: 24 # linear over 24 months after cliff
sell_at_unlock_pct: 40
- name: investors
fraction: 0.12
cliff: 6
unlock: 18
sell_at_unlock_pct: 60
- name: community
fraction: 0.10
cliff: 0
unlock: 12
sell_at_unlock_pct: 20
burn_toll_pct: 1.5
vault_yield_apy: 8.0
operating_cost: 5_000 # USD/month
from token_simulator import SimConfig, run
config = SimConfig(
name="my-project",
total_supply=1_000_000_000,
initial_circulating_pct=10,
initial_price=0.02,
pool_usdc=500_000,
revenue_streams=[
{"name": "marketplace-fees", "volume": 200_000,
"growth_rate": 0.08, "cap": 2_000_000,
"margin": 0.70, "touches_burn_toll": True},
{"name": "api-subscriptions", "volume": 15_000,
"growth_rate": 0.12, "cap": 500_000,
"margin": 0.90, "touches_burn_toll": False},
],
vest_buckets=[
{"name": "team", "fraction": 0.18,
"cliff": 12, "unlock": 24, "sell_at_unlock_pct": 40},
{"name": "investors", "fraction": 0.12,
"cliff": 6, "unlock": 18, "sell_at_unlock_pct": 60},
{"name": "community", "fraction": 0.10,
"cliff": 0, "unlock": 12, "sell_at_unlock_pct": 20},
],
burn_toll_pct=1.5,
vault_yield_apy=8.0,
operating_cost=5_000,
)
results = run(config, months=36)
print(results.to_csv())
Both paths produce identical output. Use YAML for quick iteration; use Python when you want to sweep parameters or plug into a larger pipeline.
Every token designer should simulate at least these five scenarios before publishing a whitepaper:
sell_at_unlock_pct to 80% across all buckets. Add 20% monthly user churn and drop average spend to $30. If circulating supply doubles in 6 months while price halves, your vesting schedule is a sell schedule.
growth_rate to -0.50 (50% MoM decline) after month 6. This tests whether your treasury survives on operating cost alone once the honeymoon period ends. Most protocols do not pass this test.
operating_cost to $20K/month instead of the $5K baseline. This is the "we hired two more engineers" scenario. Check whether the treasury hits zero before month 18 -- the typical cliff for a seed-funded project.
burn_toll_pct to 5% on $10M monthly volume. The simulator will show you exactly when supply implodes -- usually around month 14. Hyper-deflation sounds appealing in a pitch deck but makes the token unusable as a medium of exchange.
Tracked in issue #1. The deterministic sim gives you one trajectory per parameter set. Monte Carlo mode turns each parameter into a distribution:
growth_rate becomes Normal(0.08, 0.04)sell_at_unlock_pct becomes Uniform(20, 80)operating_cost becomes LogNormal(log(5000), 0.3)The engine runs 10,000 trajectories and produces p5 / p50 / p95 confidence bands for every output metric. Expected output shape:
month,circ_supply_p5,circ_supply_p50,circ_supply_p95,treasury_p5,... 0,100000000,100000000,100000000,500000,... 6,95200000,108400000,124600000,310000,... 12,82100000,115000000,162300000,120000,...
When the p5 band for treasury_usd crosses zero before month 18, your design has a structural solvency risk even under optimistic assumptions. That is the signal you redesign, not raise.
Add a simulation guard to your test suite so tokenomics regressions break the build:
import pytest
from token_simulator import SimConfig, run
@pytest.fixture
def config():
return SimConfig.from_yaml("presets/my-project.yaml")
def test_supply_never_negative(config):
results = run(config, months=36)
for row in results:
assert row.circ_supply >= 0, (
f"Circulating supply went negative in month {row.month}"
)
def test_treasury_survives_18_months(config):
results = run(config, months=18)
assert results[-1].treasury_usd > 0, (
"Treasury depleted before month 18"
)
def test_staker_apy_below_100(config):
results = run(config, months=36)
for row in results:
assert row.staker_apy < 100, (
f"Staker APY unrealistic ({row.staker_apy}%) in month {row.month}"
)
Run with pytest tests/test_tokenomics.py -v in CI. If someone tweaks a parameter and the supply goes negative, the pipeline fails. No more "we fixed it in the spreadsheet" surprises.
create-protocol-v4 preset.