...
This commit is contained in:
@@ -25,7 +25,7 @@ pub fn (sim Simulation) generate_market_cap_chart() !echarts.EChartsOption {
|
||||
mut mc_sheet := spreadsheet.sheet_new(
|
||||
name: '${sim.name}_market_cap'
|
||||
nrcol: sim.price_sheet.nrcol
|
||||
curr: sim.currency
|
||||
curr: sim.params.simulation.currency
|
||||
)!
|
||||
|
||||
for name, scenario in sim.scenarios {
|
||||
@@ -37,7 +37,7 @@ pub fn (sim Simulation) generate_market_cap_chart() !echarts.EChartsOption {
|
||||
|
||||
price_row := sim.price_sheet.row_get('scenario_${name}_price')!
|
||||
for i, cell in price_row.cells {
|
||||
mc_row.cells[i].val = cell.val * sim.total_supply
|
||||
mc_row.cells[i].val = cell.val * sim.params.distribution.total_supply
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,99 +4,6 @@ import freeflowuniverse.herolib.core.pathlib
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import time
|
||||
|
||||
const report_template = '# INCA Token Economic Simulation Report
|
||||
|
||||
## Executive Summary
|
||||
|
||||
This report presents the results of the INCA token economic simulation **{{.name}}**, analyzing various market scenarios and their impact on token distribution, pricing, and investor returns.
|
||||
|
||||
### Key Parameters
|
||||
|
||||
- **Total Token Supply**: {{.total_supply}} INCA
|
||||
- **Simulation Period**: {{.nrcol}} months
|
||||
- **Base Currency**: {{.currency}}
|
||||
|
||||
## Token Distribution & Allocation
|
||||
|
||||
{{.distribution_section}}
|
||||
|
||||
## Vesting Schedules
|
||||
|
||||
### Team Vesting
|
||||
- **Cliff Period**: {{.team_cliff_months}} months
|
||||
- **Vesting Period**: {{.team_vesting_months}} months
|
||||
- **Total Team Allocation**: {{.team_allocation}} INCA ({{.team_pct}}%)
|
||||
|
||||
### Treasury Vesting
|
||||
- **Cliff Period**: {{.treasury_cliff_months}} months
|
||||
- **Vesting Period**: {{.treasury_vesting_months}} months
|
||||
- **Total Treasury Allocation**: {{.treasury_allocation}} INCA ({{.treasury_pct}}%)
|
||||
|
||||
## Economic Parameters
|
||||
|
||||
- **Epoch 1 Floor Uplift**: {{.epoch1_floor_uplift}}x
|
||||
- **Subsequent Epoch Floor Uplift**: {{.epochn_floor_uplift}}x
|
||||
- **AMM Liquidity Depth Factor**: {{.amm_liquidity_depth_factor}}x
|
||||
|
||||
## Simulation Scenarios
|
||||
|
||||
{{.scenarios_section}}
|
||||
|
||||
## Financial Summary
|
||||
|
||||
{{.financial_summary}}
|
||||
|
||||
## Investment Analysis
|
||||
|
||||
### Return on Investment by Round
|
||||
|
||||
{{.roi_analysis}}
|
||||
|
||||
## Market Dynamics
|
||||
|
||||
### Price Evolution
|
||||
The token price evolution across different scenarios shows:
|
||||
|
||||
{{.price_analysis}}
|
||||
|
||||
### Market Capitalization
|
||||
The projected market capitalization ranges show:
|
||||
|
||||
{{.market_cap_analysis}}
|
||||
|
||||
## Risk Analysis
|
||||
|
||||
### Scenario Sensitivity
|
||||
The simulation reveals the following sensitivities:
|
||||
|
||||
- **Low Demand Scenario**: Conservative market conditions with limited speculation
|
||||
- **Medium Demand Scenario**: Moderate market interest and trading activity
|
||||
- **High Demand Scenario**: Strong market demand and active secondary trading
|
||||
|
||||
### Key Risk Factors
|
||||
1. **Market Demand Volatility**: Significant impact on final token prices
|
||||
2. **AMM Pool Dynamics**: Trading activity affects liquidity and price stability
|
||||
3. **Vesting Schedule Impact**: Lock-up periods influence circulating supply
|
||||
|
||||
## Conclusions
|
||||
|
||||
{{.conclusions}}
|
||||
|
||||
## Appendices
|
||||
|
||||
### A. Methodology
|
||||
This simulation uses a simplified Dutch auction model combined with AMM (Automated Market Maker) dynamics to project token price evolution.
|
||||
|
||||
### B. Assumptions
|
||||
- All investor rounds are fully subscribed
|
||||
- Vesting schedules are strictly enforced
|
||||
- Market dynamics follow the implemented auction and AMM models
|
||||
|
||||
---
|
||||
|
||||
*Report generated on {{.generation_date}} using INCA Token Simulation Framework*
|
||||
'
|
||||
|
||||
// Export data to CSV
|
||||
pub fn (sim Simulation) export_csv(sheet_name string, path string) ! {
|
||||
mut sheet := match sheet_name {
|
||||
@@ -119,11 +26,11 @@ pub fn (sim Simulation) export_csv(sheet_name string, path string) ! {
|
||||
pub fn (sim Simulation) generate_distribution_section() !string {
|
||||
mut lines := []string{}
|
||||
|
||||
lines << '- **Total supply:** ${sim.total_supply} INCA'
|
||||
lines << '- **Public (TGE):** ${(sim.public_pct * 100).str()}% (No lockup)'
|
||||
lines << '- **Team:** ${(sim.team_pct * 100).str()}% (${sim.team_vesting.cliff_months}mo cliff, ${sim.team_vesting.vesting_months}mo vest)'
|
||||
lines << '- **Treasury:** ${(sim.treasury_pct * 100).str()}% (${sim.treasury_vesting.cliff_months}mo cliff, ${sim.treasury_vesting.vesting_months}mo vest)'
|
||||
lines << '- **Investors:** ${(sim.investor_pct * 100).str()}%'
|
||||
lines << '- **Total supply:** ${sim.params.distribution.total_supply} INCA'
|
||||
lines << '- **Public (TGE):** ${(sim.params.distribution.public_pct * 100).str()}% (No lockup)'
|
||||
lines << '- **Team:** ${(sim.params.distribution.team_pct * 100).str()}% (${sim.team_vesting.cliff_months}mo cliff, ${sim.team_vesting.vesting_months}mo vest)'
|
||||
lines << '- **Treasury:** ${(sim.params.distribution.treasury_pct * 100).str()}% (${sim.treasury_vesting.cliff_months}mo cliff, ${sim.treasury_vesting.vesting_months}mo vest)'
|
||||
lines << '- **Investors:** ${(sim.params.distribution.investor_pct * 100).str()}%'
|
||||
lines << ''
|
||||
lines << '### Investor Rounds & Vesting'
|
||||
lines << '| Round | Allocation | Price (USD) | Vesting Schedule |'
|
||||
@@ -167,7 +74,7 @@ pub fn (sim Simulation) generate_financial_summary() !string {
|
||||
|
||||
mut total_raised := 0.0
|
||||
for round in sim.investor_rounds {
|
||||
raised := round.allocation_pct * sim.total_supply * round.price
|
||||
raised := round.allocation_pct * sim.params.distribution.total_supply * round.price
|
||||
total_raised += raised
|
||||
lines << '| **${round.name}** | \$${raised} |'
|
||||
}
|
||||
|
||||
@@ -7,71 +7,32 @@ __global (
|
||||
simulations map[string]&Simulation
|
||||
)
|
||||
|
||||
// Create simulation from parameters struct
|
||||
pub fn simulation_new_from_params(params SimulationParams) !&Simulation {
|
||||
return simulation_new(
|
||||
name: params.name
|
||||
total_supply: params.distribution.total_supply
|
||||
public_pct: params.distribution.public_pct
|
||||
team_pct: params.distribution.team_pct
|
||||
treasury_pct: params.distribution.treasury_pct
|
||||
investor_pct: params.distribution.investor_pct
|
||||
nrcol: params.simulation.nrcol
|
||||
currency: params.simulation.currency
|
||||
)!
|
||||
}
|
||||
|
||||
@[params]
|
||||
pub struct SimulationNewArgs {
|
||||
pub mut:
|
||||
// name of the simulation, used for identification and file naming
|
||||
name string = 'default'
|
||||
// total supply of INCA tokens
|
||||
total_supply f64 = 10_000_000_000
|
||||
// percentage of tokens allocated to public sale (TGE)
|
||||
public_pct f64 = 0.50
|
||||
// percentage of tokens allocated to the team
|
||||
team_pct f64 = 0.15
|
||||
// percentage of tokens allocated to the treasury
|
||||
treasury_pct f64 = 0.15
|
||||
// percentage of tokens allocated to investors
|
||||
investor_pct f64 = 0.20
|
||||
// number of columns (months) for the simulation spreadsheets
|
||||
nrcol int = 60 // 60 months default
|
||||
// currency used in the simulation (e.g., 'USD')
|
||||
currency string = 'USD'
|
||||
}
|
||||
|
||||
pub fn simulation_new(args SimulationNewArgs) !&Simulation {
|
||||
name := texttools.name_fix(args.name)
|
||||
// Create simulation from parameters struct - MAIN ENTRY POINT
|
||||
pub fn simulation_new(params SimulationParams) !&Simulation {
|
||||
name := texttools.name_fix(params.name)
|
||||
|
||||
// Initialize spreadsheets for tracking
|
||||
price_sheet := spreadsheet.sheet_new(
|
||||
name: '${name}_prices'
|
||||
nrcol: args.nrcol
|
||||
curr: args.currency
|
||||
nrcol: params.simulation.nrcol
|
||||
curr: params.simulation.currency
|
||||
)!
|
||||
|
||||
token_sheet := spreadsheet.sheet_new(
|
||||
name: '${name}_tokens'
|
||||
nrcol: args.nrcol
|
||||
curr: args.currency
|
||||
nrcol: params.simulation.nrcol
|
||||
curr: params.simulation.currency
|
||||
)!
|
||||
|
||||
investment_sheet := spreadsheet.sheet_new(
|
||||
name: '${name}_investments'
|
||||
nrcol: args.nrcol
|
||||
curr: args.currency
|
||||
nrcol: params.simulation.nrcol
|
||||
curr: params.simulation.currency
|
||||
)!
|
||||
|
||||
mut sim := &Simulation{
|
||||
name: name
|
||||
total_supply: args.total_supply
|
||||
public_pct: args.public_pct
|
||||
team_pct: args.team_pct
|
||||
treasury_pct: args.treasury_pct
|
||||
investor_pct: args.investor_pct
|
||||
currency: args.currency
|
||||
params: params
|
||||
price_sheet: price_sheet
|
||||
token_sheet: token_sheet
|
||||
investment_sheet: investment_sheet
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
module incatokens
|
||||
import freeflowuniverse.herolib.biz.spreadsheet
|
||||
import os
|
||||
import incatokens.defaults
|
||||
import incatokens.factory
|
||||
|
||||
fn test_simulation_creation() {
|
||||
mut params := default_params()
|
||||
params.name = 'test_sim_creation'
|
||||
|
||||
mut sim := simulation_new_from_params(params)!
|
||||
sim.run_full_simulation(params)! // Initialize investor_rounds and vesting schedules
|
||||
mut sim := factory.simulation_new(params)!
|
||||
sim.run_simulation()! // Run the simulation
|
||||
|
||||
assert sim.name == 'test_sim_creation'
|
||||
assert sim.total_supply == params.distribution.total_supply
|
||||
assert sim.params.distribution.total_supply == params.distribution.total_supply
|
||||
assert sim.investor_rounds.len == params.investor_rounds.len
|
||||
}
|
||||
|
||||
@@ -18,8 +20,8 @@ fn test_scenario_execution() {
|
||||
mut params := default_params()
|
||||
params.name = 'test_scenario_exec'
|
||||
|
||||
mut sim := simulation_new_from_params(params)!
|
||||
sim.run_full_simulation(params)!
|
||||
mut sim := factory.simulation_new(params)!
|
||||
sim.run_simulation()!
|
||||
|
||||
// Get the 'Low' scenario results
|
||||
low_scenario := sim.scenarios['Low']!
|
||||
@@ -39,8 +41,8 @@ fn test_vesting_schedules() {
|
||||
mut params := default_params()
|
||||
params.name = 'test_vesting_schedules'
|
||||
|
||||
mut sim := simulation_new_from_params(params)!
|
||||
sim.run_full_simulation(params)!
|
||||
mut sim := factory.simulation_new(params)!
|
||||
sim.run_simulation()!
|
||||
|
||||
// Check team vesting
|
||||
team_row := sim.vesting_sheet.row_get('team_vesting')!
|
||||
@@ -52,7 +54,7 @@ fn test_vesting_schedules() {
|
||||
assert team_row.cells[12].val > 0
|
||||
|
||||
// After full vesting (month 48), should have all tokens
|
||||
total_team_tokens := sim.total_supply * sim.team_pct
|
||||
total_team_tokens := sim.params.distribution.total_supply * sim.params.distribution.team_pct
|
||||
assert team_row.cells[48].val == total_team_tokens
|
||||
}
|
||||
|
||||
@@ -63,19 +65,23 @@ fn test_export_functionality() {
|
||||
params.output.generate_csv = true
|
||||
params.output.generate_report = true
|
||||
|
||||
mut sim := simulation_new_from_params(params)!
|
||||
sim.run_full_simulation(params)!
|
||||
mut sim := factory.simulation_new(params)!
|
||||
sim.run_simulation()!
|
||||
|
||||
// Ensure price sheet has data before export
|
||||
assert sim.price_sheet.rows.len > 0
|
||||
|
||||
// Test CSV export (handled by run_full_simulation if generate_csv is true)
|
||||
// Export all data
|
||||
os.mkdir_all(params.output.export_dir)!
|
||||
sim.export_all(params.output.export_dir)!
|
||||
|
||||
// Test CSV export
|
||||
assert os.exists('${params.output.export_dir}/${params.name}_prices.csv')
|
||||
assert os.exists('${params.output.export_dir}/${params.name}_tokens.csv')
|
||||
assert os.exists('${params.output.export_dir}/${params.name}_investments.csv')
|
||||
assert os.exists('${params.output.export_dir}/${params.name}_vesting.csv')
|
||||
|
||||
// Test report generation (already handled by run_full_simulation if generate_report is true)
|
||||
// Test report generation
|
||||
assert os.exists('${params.output.export_dir}/${params.name}_report.md')
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,20 @@
|
||||
module incatokens
|
||||
import os
|
||||
|
||||
|
||||
// SimulationParams is the main configuration struct containing all parameters
|
||||
pub struct SimulationParams {
|
||||
pub mut:
|
||||
name string
|
||||
distribution TokenDistribution
|
||||
investor_rounds []InvestorRoundConfig
|
||||
vesting VestingConfigs
|
||||
economics EconomicsConfig
|
||||
simulation SimulationConfig
|
||||
scenarios []ScenarioConfig
|
||||
output OutputConfig
|
||||
}
|
||||
|
||||
// TokenDistribution defines how tokens are allocated across different categories
|
||||
pub struct TokenDistribution {
|
||||
pub mut:
|
||||
@@ -14,8 +28,8 @@ pub mut:
|
||||
// VestingConfig defines cliff and vesting periods
|
||||
pub struct VestingConfig {
|
||||
pub mut:
|
||||
cliff_months int
|
||||
vesting_months int
|
||||
cliff_months int = 6
|
||||
vesting_months int = 24
|
||||
}
|
||||
|
||||
// InvestorRoundConfig defines parameters for each investment round
|
||||
@@ -60,82 +74,9 @@ pub mut:
|
||||
// OutputConfig defines where and how to generate outputs
|
||||
pub struct OutputConfig {
|
||||
pub mut:
|
||||
export_dir string = './output'
|
||||
generate_csv bool = true
|
||||
generate_charts bool = true
|
||||
generate_report bool = true
|
||||
export_dir string = './output'
|
||||
generate_csv bool = true
|
||||
generate_charts bool = true
|
||||
generate_report bool = true
|
||||
}
|
||||
|
||||
// SimulationParams is the main configuration struct containing all parameters
|
||||
pub struct SimulationParams {
|
||||
pub mut:
|
||||
name string
|
||||
distribution TokenDistribution
|
||||
investor_rounds []InvestorRoundConfig
|
||||
vesting VestingConfigs
|
||||
economics EconomicsConfig
|
||||
simulation SimulationConfig
|
||||
scenarios []ScenarioConfig
|
||||
output OutputConfig
|
||||
}
|
||||
|
||||
// run_simulation executes the simulation with the given parameters
|
||||
pub fn (params SimulationParams) run_simulation() ! {
|
||||
mut sim := simulation_new(
|
||||
name: params.name
|
||||
total_supply: params.distribution.total_supply
|
||||
public_pct: params.distribution.public_pct
|
||||
team_pct: params.distribution.team_pct
|
||||
treasury_pct: params.distribution.treasury_pct
|
||||
investor_pct: params.distribution.investor_pct
|
||||
nrcol: params.simulation.nrcol
|
||||
currency: params.simulation.currency
|
||||
)!
|
||||
|
||||
// Configure economics
|
||||
sim.epoch1_floor_uplift = params.economics.epoch1_floor_uplift
|
||||
sim.epochn_floor_uplift = params.economics.epochn_floor_uplift
|
||||
sim.amm_liquidity_depth_factor = params.economics.amm_liquidity_depth_factor
|
||||
|
||||
// Set up investor rounds
|
||||
sim.investor_rounds = params.investor_rounds.map(InvestorRound{
|
||||
name: it.name
|
||||
allocation_pct: it.allocation_pct
|
||||
price: it.price
|
||||
vesting: VestingSchedule{
|
||||
cliff_months: it.vesting.cliff_months
|
||||
vesting_months: it.vesting.vesting_months
|
||||
}
|
||||
})
|
||||
|
||||
// Set up vesting schedules
|
||||
sim.team_vesting = VestingSchedule{
|
||||
cliff_months: params.vesting.team.cliff_months
|
||||
vesting_months: params.vesting.team.vesting_months
|
||||
}
|
||||
sim.treasury_vesting = VestingSchedule{
|
||||
cliff_months: params.vesting.treasury.cliff_months
|
||||
vesting_months: params.vesting.treasury.vesting_months
|
||||
}
|
||||
|
||||
// Run scenarios
|
||||
for scenario in params.scenarios {
|
||||
sim.run_scenario(scenario.name, scenario.demands, scenario.amm_trades)!
|
||||
}
|
||||
|
||||
// Generate vesting schedules
|
||||
sim.create_vesting_schedules()!
|
||||
|
||||
// Generate outputs
|
||||
if params.output.generate_csv {
|
||||
os.mkdir_all(params.output.export_dir)!
|
||||
sim.export_csv('prices', '${params.output.export_dir}/${params.name}_prices.csv')!
|
||||
sim.export_csv('tokens', '${params.output.export_dir}/${params.name}_tokens.csv')!
|
||||
sim.export_csv('investments', '${params.output.export_dir}/${params.name}_investments.csv')!
|
||||
sim.export_csv('vesting', '${params.output.export_dir}/${params.name}_vesting.csv')!
|
||||
}
|
||||
|
||||
if params.output.generate_report {
|
||||
sim.generate_report(params.output.export_dir)!
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,18 @@ import os
|
||||
pub fn play(mut plbook PlayBook) ! {
|
||||
console.print_header('INCA Token Simulation')
|
||||
|
||||
// Collect all configurations first
|
||||
mut simulations_to_run := []SimulationParams{}
|
||||
mut export_path := ''
|
||||
|
||||
// Process export configuration
|
||||
if plbook.exists_once(filter: 'incatokens.export') {
|
||||
mut action := plbook.get(filter: 'incatokens.export')!
|
||||
mut p := action.params
|
||||
export_path = p.get('path')!
|
||||
console.print_item('Export directory configured: ${export_path}')
|
||||
}
|
||||
|
||||
// Process simulation definitions
|
||||
for action in plbook.find(filter: 'incatokens.simulate')! {
|
||||
mut p := action.params
|
||||
@@ -39,47 +51,67 @@ pub fn play(mut plbook PlayBook) ! {
|
||||
params.vesting.treasury.cliff_months = p.get_int_default('treasury_cliff_months', 12)!
|
||||
params.vesting.treasury.vesting_months = p.get_int_default('treasury_vesting_months', 48)!
|
||||
|
||||
// Configure output
|
||||
params.output.export_dir = p.get_default('export_dir', './output')!
|
||||
// Configure output - use export_path if provided, otherwise use param
|
||||
if export_path != '' {
|
||||
params.output.export_dir = export_path
|
||||
} else {
|
||||
params.output.export_dir = p.get_default('export_dir', './output')!
|
||||
}
|
||||
params.output.generate_csv = p.get_default_true('generate_csv')
|
||||
params.output.generate_charts = p.get_default_true('generate_charts')
|
||||
params.output.generate_report = p.get_default_true('generate_report')
|
||||
|
||||
// Collect investor rounds for this simulation
|
||||
mut investor_rounds := []InvestorRoundConfig{}
|
||||
for round_action in plbook.find(filter: 'incatokens.investor_round')! {
|
||||
mut rp := round_action.params
|
||||
|
||||
round := InvestorRoundConfig{
|
||||
name: rp.get('name')!
|
||||
allocation_pct: rp.get_float('allocation_pct')!
|
||||
price: rp.get_float('price')!
|
||||
vesting: VestingConfig{
|
||||
cliff_months: rp.get_int('cliff_months')!
|
||||
vesting_months: rp.get_int('vesting_months')!
|
||||
}
|
||||
}
|
||||
investor_rounds << round
|
||||
console.print_item('Configured investor round: ${round.name} at \$${round.price}')
|
||||
}
|
||||
params.investor_rounds = investor_rounds
|
||||
|
||||
// Collect scenarios for this simulation
|
||||
mut scenarios := []ScenarioConfig{}
|
||||
for scenario_action in plbook.find(filter: 'incatokens.scenario')! {
|
||||
mut sp := scenario_action.params
|
||||
|
||||
scenario := ScenarioConfig{
|
||||
name: sp.get('name')!
|
||||
demands: sp.get_list_f64('demands')!
|
||||
amm_trades: sp.get_list_f64('amm_trades')!
|
||||
}
|
||||
scenarios << scenario
|
||||
console.print_item('Configured scenario: ${scenario.name}')
|
||||
}
|
||||
params.scenarios = scenarios
|
||||
|
||||
simulations_to_run << params
|
||||
}
|
||||
|
||||
// Run all simulations
|
||||
for params in simulations_to_run {
|
||||
console.print_item('Running simulation: ${params.name}')
|
||||
|
||||
// Run the simulation
|
||||
params.run_simulation()!
|
||||
// Create and run simulation
|
||||
mut sim := simulation_new(params)!
|
||||
sim.run_simulation()!
|
||||
|
||||
console.print_green('✓ Simulation completed successfully')
|
||||
}
|
||||
|
||||
// Process investor round definitions
|
||||
for action in plbook.find(filter: 'incatokens.investor_round')! {
|
||||
mut p := action.params
|
||||
// Create export directory if needed
|
||||
os.mkdir_all(params.output.export_dir)!
|
||||
|
||||
round := InvestorRoundConfig{
|
||||
name: p.get('name')!
|
||||
allocation_pct: p.get_float('allocation_pct')!
|
||||
price: p.get_float('price')!
|
||||
vesting: VestingConfig{
|
||||
cliff_months: p.get_int('cliff_months')!
|
||||
vesting_months: p.get_int('vesting_months')!
|
||||
}
|
||||
}
|
||||
// Export all data in one call
|
||||
sim.export_all(params.output.export_dir)!
|
||||
|
||||
console.print_item('Configured investor round: ${round.name} at \$${round.price}')
|
||||
}
|
||||
|
||||
// Process scenario definitions
|
||||
for action in plbook.find(filter: 'incatokens.scenario')! {
|
||||
mut p := action.params
|
||||
|
||||
scenario := ScenarioConfig{
|
||||
name: p.get('name')!
|
||||
demands: p.get_list_f64('demands')!
|
||||
amm_trades: p.get_list_f64('amm_trades')!
|
||||
}
|
||||
|
||||
console.print_item('Configured scenario: ${scenario.name}')
|
||||
console.print_green('✓ Simulation "${params.name}" completed and exported to: ${params.output.export_dir}')
|
||||
}
|
||||
}
|
||||
2
lib/threefold/incatokens/readme.md
Normal file
2
lib/threefold/incatokens/readme.md
Normal file
@@ -0,0 +1,2 @@
|
||||
|
||||
see examples/threefold/incatokens/incatokens_simulate.vsh for example of how to use
|
||||
@@ -1,17 +1,35 @@
|
||||
module incatokens
|
||||
|
||||
// import freeflowuniverse.herolib.biz.spreadsheet
|
||||
import freeflowuniverse.herolib.biz.spreadsheet
|
||||
|
||||
// Simulation holds the main simulation state
|
||||
pub struct Simulation {
|
||||
pub mut:
|
||||
// Core identification
|
||||
name string
|
||||
|
||||
// Generate comprehensive report with all scenarios
|
||||
pub fn (mut sim Simulation) simulate(params SimulationParams) ! {
|
||||
// Configure from parameters
|
||||
sim.epoch1_floor_uplift = params.economics.epoch1_floor_uplift
|
||||
sim.epochn_floor_uplift = params.economics.epochn_floor_uplift
|
||||
sim.amm_liquidity_depth_factor = params.economics.amm_liquidity_depth_factor
|
||||
// Configuration (embedded)
|
||||
params SimulationParams
|
||||
|
||||
// Derived data
|
||||
investor_rounds []InvestorRound
|
||||
team_vesting VestingSchedule
|
||||
treasury_vesting VestingSchedule
|
||||
|
||||
// Runtime state
|
||||
scenarios map[string]&Scenario
|
||||
|
||||
// Spreadsheets for tracking
|
||||
price_sheet &spreadsheet.Sheet
|
||||
token_sheet &spreadsheet.Sheet
|
||||
investment_sheet &spreadsheet.Sheet
|
||||
vesting_sheet &spreadsheet.Sheet
|
||||
}
|
||||
|
||||
// Set up investor rounds
|
||||
sim.investor_rounds = params.investor_rounds.map(InvestorRound{
|
||||
// Main simulation runner - single entry point
|
||||
pub fn (mut sim Simulation) run_simulation() ! {
|
||||
// Set up investor rounds from params
|
||||
sim.investor_rounds = sim.params.investor_rounds.map(InvestorRound{
|
||||
name: it.name
|
||||
allocation_pct: it.allocation_pct
|
||||
price: it.price
|
||||
@@ -21,18 +39,18 @@ pub fn (mut sim Simulation) simulate(params SimulationParams) ! {
|
||||
}
|
||||
})
|
||||
|
||||
// Set up vesting schedules
|
||||
// Set up vesting schedules from params
|
||||
sim.team_vesting = VestingSchedule{
|
||||
cliff_months: params.vesting.team.cliff_months
|
||||
vesting_months: params.vesting.team.vesting_months
|
||||
cliff_months: sim.params.vesting.team.cliff_months
|
||||
vesting_months: sim.params.vesting.team.vesting_months
|
||||
}
|
||||
sim.treasury_vesting = VestingSchedule{
|
||||
cliff_months: params.vesting.treasury.cliff_months
|
||||
vesting_months: params.vesting.treasury.vesting_months
|
||||
cliff_months: sim.params.vesting.treasury.cliff_months
|
||||
vesting_months: sim.params.vesting.treasury.vesting_months
|
||||
}
|
||||
|
||||
// Run all scenarios
|
||||
for scenario_config in params.scenarios {
|
||||
// Run all scenarios from params
|
||||
for scenario_config in sim.params.scenarios {
|
||||
sim.run_scenario(scenario_config.name, scenario_config.demands, scenario_config.amm_trades)!
|
||||
}
|
||||
|
||||
@@ -70,7 +88,7 @@ pub fn (mut sim Simulation) run_scenario(name string, demands []f64, amm_trades
|
||||
)!
|
||||
|
||||
// Calculate public tokens per epoch
|
||||
total_public := sim.total_supply * sim.public_pct
|
||||
total_public := sim.params.distribution.total_supply * sim.params.distribution.public_pct
|
||||
tokens_per_epoch := total_public / 3.0
|
||||
|
||||
mut last_auction_price := sim.get_last_investor_price()
|
||||
@@ -110,7 +128,7 @@ pub fn (mut sim Simulation) run_scenario(name string, demands []f64, amm_trades
|
||||
spillover = 0
|
||||
|
||||
// Seed AMM pool
|
||||
amm_usdc_to_add := sim.amm_liquidity_depth_factor * epoch.treasury_raised
|
||||
amm_usdc_to_add := sim.params.economics.amm_liquidity_depth_factor * epoch.treasury_raised
|
||||
amm_pool.add_liquidity(amm_tokens, amm_usdc_to_add)
|
||||
|
||||
// Simulate trading
|
||||
@@ -149,7 +167,7 @@ fn (sim Simulation) calculate_metrics(scenario &Scenario, treasury_total f64) !S
|
||||
treasury_total: treasury_total
|
||||
final_price: final_price
|
||||
investor_roi: investor_roi
|
||||
market_cap_final: final_price * sim.total_supply
|
||||
market_cap_final: final_price * sim.params.distribution.total_supply
|
||||
circulating_supply_final: sim.calculate_circulating_supply(12) // at month 12
|
||||
}
|
||||
}
|
||||
@@ -168,19 +186,33 @@ fn (sim Simulation) calculate_floor_price(epoch_idx int, last_auction_price f64)
|
||||
last_investor_price := sim.get_last_investor_price()
|
||||
|
||||
if epoch_idx == 0 {
|
||||
return last_investor_price * sim.epoch1_floor_uplift
|
||||
return last_investor_price * sim.params.economics.epoch1_floor_uplift
|
||||
}
|
||||
return last_auction_price * sim.epochn_floor_uplift
|
||||
return last_auction_price * sim.params.economics.epochn_floor_uplift
|
||||
}
|
||||
|
||||
fn (sim Simulation) calculate_circulating_supply(month int) f64 {
|
||||
// Base circulation (non-public allocations)
|
||||
investor_tokens := sim.investor_pct * sim.total_supply
|
||||
team_tokens := sim.team_pct * sim.total_supply
|
||||
treasury_tokens := sim.treasury_pct * sim.total_supply
|
||||
investor_tokens := sim.params.distribution.investor_pct * sim.params.distribution.total_supply
|
||||
team_tokens := sim.params.distribution.team_pct * sim.params.distribution.total_supply
|
||||
treasury_tokens := sim.params.distribution.treasury_pct * sim.params.distribution.total_supply
|
||||
|
||||
// For simplicity, assume all public tokens are circulating after TGE
|
||||
public_tokens := sim.public_pct * sim.total_supply
|
||||
public_tokens := sim.params.distribution.public_pct * sim.params.distribution.total_supply
|
||||
|
||||
return investor_tokens + team_tokens + treasury_tokens + public_tokens
|
||||
}
|
||||
|
||||
// Export all simulation data
|
||||
pub fn (sim Simulation) export_all(export_dir string) ! {
|
||||
if sim.params.output.generate_csv {
|
||||
sim.export_csv('prices', '${export_dir}/${sim.name}_prices.csv')!
|
||||
sim.export_csv('tokens', '${export_dir}/${sim.name}_tokens.csv')!
|
||||
sim.export_csv('investments', '${export_dir}/${sim.name}_investments.csv')!
|
||||
sim.export_csv('vesting', '${export_dir}/${sim.name}_vesting.csv')!
|
||||
}
|
||||
|
||||
if sim.params.output.generate_report {
|
||||
sim.generate_report(export_dir)!
|
||||
}
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
module incatokens
|
||||
|
||||
import freeflowuniverse.herolib.biz.spreadsheet
|
||||
|
||||
pub struct VestingSchedule {
|
||||
pub mut:
|
||||
cliff_months int
|
||||
vesting_months int
|
||||
}
|
||||
|
||||
pub struct InvestorRound {
|
||||
pub mut:
|
||||
name string
|
||||
allocation_pct f64
|
||||
price f64
|
||||
vesting VestingSchedule
|
||||
}
|
||||
|
||||
pub enum EpochType {
|
||||
auction_only
|
||||
hybrid
|
||||
amm_only
|
||||
}
|
||||
|
||||
pub struct Epoch {
|
||||
pub mut:
|
||||
index int
|
||||
type_ EpochType
|
||||
start_month int
|
||||
end_month int
|
||||
auction_share f64
|
||||
amm_share f64
|
||||
tokens_allocated f64
|
||||
tokens_spillover f64
|
||||
auction_demand f64
|
||||
amm_net_trade f64
|
||||
final_price f64
|
||||
treasury_raised f64
|
||||
}
|
||||
|
||||
pub struct Scenario {
|
||||
pub mut:
|
||||
name string
|
||||
demands []f64
|
||||
amm_trades []f64
|
||||
epochs []Epoch
|
||||
final_metrics ScenarioMetrics
|
||||
}
|
||||
|
||||
pub struct ScenarioMetrics {
|
||||
pub mut:
|
||||
treasury_total f64
|
||||
final_price f64
|
||||
investor_roi map[string]f64
|
||||
market_cap_final f64
|
||||
circulating_supply_final f64
|
||||
}
|
||||
|
||||
@[heap]
|
||||
pub struct Simulation {
|
||||
pub:
|
||||
params SimulationParams //all config info comes here
|
||||
pub mut:
|
||||
name string
|
||||
|
||||
//THE DATA WE ACTIVELY NEED TO SIMULATE IS HERE
|
||||
|
||||
// Tracking sheets
|
||||
price_sheet &spreadsheet.Sheet
|
||||
token_sheet &spreadsheet.Sheet
|
||||
investment_sheet &spreadsheet.Sheet
|
||||
vesting_sheet &spreadsheet.Sheet
|
||||
|
||||
// Scenarios
|
||||
scenarios map[string]&Scenario
|
||||
}
|
||||
58
lib/threefold/incatokens/templates/example.hero
Normal file
58
lib/threefold/incatokens/templates/example.hero
Normal file
@@ -0,0 +1,58 @@
|
||||
!!incatokens.simulate
|
||||
name: 'inca_mainnet_simulation'
|
||||
total_supply: 10000000000
|
||||
public_pct: 0.50
|
||||
team_pct: 0.15
|
||||
treasury_pct: 0.15
|
||||
investor_pct: 0.20
|
||||
nrcol: 60
|
||||
currency: 'USD'
|
||||
epoch1_floor_uplift: 1.20
|
||||
epochn_floor_uplift: 1.20
|
||||
amm_liquidity_depth_factor: 2.0
|
||||
team_cliff_months: 12
|
||||
team_vesting_months: 36
|
||||
treasury_cliff_months: 12
|
||||
treasury_vesting_months: 48
|
||||
export_dir: './simulation_output'
|
||||
generate_csv: true
|
||||
generate_charts: true
|
||||
generate_report: true
|
||||
|
||||
!!incatokens.scenario
|
||||
name: 'Conservative'
|
||||
demands: [8000000, 8000000, 0]
|
||||
amm_trades: [0, 0, 0]
|
||||
|
||||
!!incatokens.scenario
|
||||
name: 'Moderate'
|
||||
demands: [25000000, 50000000, 0]
|
||||
amm_trades: [0, 0, 0]
|
||||
|
||||
!!incatokens.scenario
|
||||
name: 'Optimistic'
|
||||
demands: [50000000, 100000000, 0]
|
||||
amm_trades: [5000000, 10000000, 0]
|
||||
|
||||
!!incatokens.investor_round
|
||||
name: 'Seed'
|
||||
allocation_pct: 0.03
|
||||
price: 0.003
|
||||
cliff_months: 6
|
||||
vesting_months: 24
|
||||
|
||||
!!incatokens.investor_round
|
||||
name: 'Series_A'
|
||||
allocation_pct: 0.07
|
||||
price: 0.008
|
||||
cliff_months: 6
|
||||
vesting_months: 24
|
||||
|
||||
!!incatokens.investor_round
|
||||
name: 'Series_B'
|
||||
allocation_pct: 0.10
|
||||
price: 0.012
|
||||
cliff_months: 3
|
||||
vesting_months: 18
|
||||
|
||||
!!incatokens.export path:"/tmp/incatokens_export"
|
||||
63
lib/threefold/incatokens/types.v
Normal file
63
lib/threefold/incatokens/types.v
Normal file
@@ -0,0 +1,63 @@
|
||||
module incatokens
|
||||
|
||||
import freeflowuniverse.herolib.biz.spreadsheet
|
||||
|
||||
// VestingSchedule defines cliff and vesting periods
|
||||
pub struct VestingSchedule {
|
||||
pub mut:
|
||||
cliff_months int
|
||||
vesting_months int
|
||||
}
|
||||
|
||||
// InvestorRound represents an investment round
|
||||
pub struct InvestorRound {
|
||||
pub mut:
|
||||
name string
|
||||
allocation_pct f64
|
||||
price f64
|
||||
vesting VestingSchedule
|
||||
}
|
||||
|
||||
// Epoch represents a phase in the token release schedule
|
||||
pub struct Epoch {
|
||||
pub mut:
|
||||
index int
|
||||
type_ EpochType
|
||||
start_month int
|
||||
end_month int
|
||||
auction_share f64
|
||||
amm_share f64
|
||||
tokens_allocated f64
|
||||
auction_demand f64
|
||||
amm_net_trade f64
|
||||
treasury_raised f64
|
||||
final_price f64
|
||||
tokens_spillover f64
|
||||
}
|
||||
|
||||
pub enum EpochType {
|
||||
auction_only
|
||||
hybrid
|
||||
amm_only
|
||||
}
|
||||
|
||||
// ScenarioMetrics holds the final results of a scenario
|
||||
pub struct ScenarioMetrics {
|
||||
pub mut:
|
||||
treasury_total f64
|
||||
final_price f64
|
||||
investor_roi map[string]f64
|
||||
market_cap_final f64
|
||||
circulating_supply_final f64
|
||||
}
|
||||
|
||||
// Scenario represents a market scenario
|
||||
pub struct Scenario {
|
||||
pub mut:
|
||||
name string
|
||||
demands []f64
|
||||
amm_trades []f64
|
||||
epochs []Epoch
|
||||
final_metrics ScenarioMetrics
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user