Skip to content
This repository was archived by the owner on Nov 3, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
266233d
rename baseline_model to consensus_pledge_model
danlessa Feb 15, 2023
16866b0
remove old sims
danlessa Feb 15, 2023
297e199
add todos
danlessa Feb 15, 2023
6086fde
Add Consensus Pledge State & Param Types + initial dfs,
danlessa Feb 15, 2023
6bae583
Add PSUBs and first viable runs of the sim,
danlessa Feb 15, 2023
273d0f5
Add Sector onboard/renew/expire logic,
danlessa Feb 17, 2023
dc5bfae
Added logic for updating the reward schedule
jackhack00 Feb 20, 2023
45b512c
Merge pull request #1 from jackhack00/Jakob-tests
danlessa Feb 20, 2023
3a740c3
Fixed immediate_release, days_passed and floats
jackhack00 Feb 21, 2023
691c1c6
Merge branch 'main' of https://github.com/BlockScience/filecoin-conse…
jackhack00 Feb 21, 2023
72f4bc7
Changed params / state
jackhack00 Feb 21, 2023
d225221
Merge pull request #2 from jackhack00/Jakob-tests
danlessa Feb 21, 2023
6d0afa8
Fixed reward.blockreward, added token distribution
jackhack00 Feb 22, 2023
0c0befd
Merge branch 'main' of https://github.com/BlockScience/filecoin-conse…
jackhack00 Feb 22, 2023
cb27dce
fixed FiltoVest
jackhack00 Feb 22, 2023
938283a
Merge pull request #3 from jackhack00/Jakob-tests
danlessa Feb 23, 2023
a8f32f4
All PSUBs are implemented and partially tested,
danlessa Feb 23, 2023
685a85a
some fixes + debug plots
danlessa Feb 23, 2023
599ba48
PoC integration with the previous streamlit app
danlessa Mar 3, 2023
9c19120
fix token_distribution ref / ent
danlessa Mar 8, 2023
4d26360
initialization of past sectors
danlessa Mar 8, 2023
3fc1017
checkpoint
danlessa Mar 8, 2023
478b286
update nb
danlessa Mar 8, 2023
281d2cf
add profiling
danlessa Mar 8, 2023
5dab070
add profiling
danlessa Mar 8, 2023
c3920bd
sync
danlessa Mar 8, 2023
66e9504
make streamlit app run
danlessa Mar 9, 2023
cadb4f0
sync
danlessa Mar 9, 2023
ed6de81
update requirements
danlessa Mar 9, 2023
30d8a4f
sync
danlessa Mar 9, 2023
7691da0
checkpoint
danlessa Mar 9, 2023
caeb7c9
checkpoint
danlessa Mar 9, 2023
459a449
checkpoint
danlessa Mar 9, 2023
670f99e
fix renew=0% bug
danlessa Mar 9, 2023
692b397
change streamlit app to use single cpu
danlessa Mar 9, 2023
0894e4e
use joblib
danlessa Mar 9, 2023
a15dda2
cosmetic changes
danlessa Mar 9, 2023
f15ec96
Edit experiments
SeanMcOwen Mar 14, 2023
9555fd5
Update time tracking documentations
SeanMcOwen Mar 14, 2023
fbb9784
Update some time documentation
SeanMcOwen Mar 14, 2023
d24887b
Add more typing documentation
SeanMcOwen Mar 14, 2023
5943dca
Update types
SeanMcOwen Mar 14, 2023
1598879
Finish types
SeanMcOwen Mar 14, 2023
b84399f
Finish structure
SeanMcOwen Mar 14, 2023
0593a8d
Scaffold docstrings for logic
SeanMcOwen Mar 14, 2023
d7ea7c1
Update more logic
SeanMcOwen Mar 17, 2023
73c5ead
Quick updates
SeanMcOwen Mar 17, 2023
c18f120
more cleanup
SeanMcOwen Mar 17, 2023
9a81b5c
More logic update
SeanMcOwen Mar 17, 2023
2eeadc1
More logic updates
SeanMcOwen Mar 17, 2023
5ce70c2
Finish all logic updates
SeanMcOwen Mar 17, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -129,4 +129,9 @@ dmypy.json
.pyre/

# .DS_Store
.DS_Store
.DS_Store


data/simulations/*.pkl.gz
.vscode
profiling/output.pstats
14 changes: 9 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
# filecoin-baseline-incentives

> TODO: Re-factor this document to reflect that'we re doing an Consesus Pledge Model

Interactive Calculator for the economic incentives around the Filecoin Baseline Minting based on cadCAD + Streamlit.

## How to run it

- Option 1 (CLI): Just pass `python -m baseline_model`
- Option 1 (CLI): Just pass `python -m consensus_pledge_model`
This will generate an pickled file at `data/simulations/` using the default single run
system parameters & initial state.
- To perform a multiple run, pass `python -m baseline_model -e`
- Option 2 (cadCAD-tools easy run method): Import the objects at `baseline_model/__init__.py`
and use them as arguments to the `cadCAD_tools.execution.easy_run` method. Refer to `baseline_model/__main__.py` to an example.
- To perform a multiple run, pass `python -m consensus_pledge_model -e`
- Option 2 (cadCAD-tools easy run method): Import the objects at `consensus_pledge_model/__init__.py`
and use them as arguments to the `cadCAD_tools.execution.easy_run` method. Refer to `consensus_pledge_model/__main__.py` to an example.
- Option 3 (Streamlit, local)
- `streamlit run app/main.py`
- Option 4 (Streamlit, cloud)
1. Fork the repo
2. Go to https://share.streamlit.io/ and log in
Expand All @@ -19,7 +23,7 @@ and use them as arguments to the `cadCAD_tools.execution.easy_run` method. Refer
## File structure

- `app/`: The `streamlit` app
- `baseline_model/`: the `cadCAD` model as encapsulated by a Python Module
- `consensus_pledge_model/`: the `cadCAD` model as encapsulated by a Python Module
- `data/`: Simulation / Post-processed datasets
- `notebooks/`:
- `scripts/`:
Expand Down
104 changes: 104 additions & 0 deletions SPEC.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# Model Spec

[Base Model: Filecoin Baseline Incentives](https://github.com/BlockScience/filecoin-baseline-incentives)

## Assumptions

- All Sectors are Capacity Commitments
- Quality Adjustment can also be applied to CC Sectors
- All sectors have an 6-month lifetime, renewable

## Model Parameters

- `target_locked_supply (%)`
- `storage_pledge_factor (Days)`
- `VestingSchedule (dict[Days, FIL])`
- Reward Schedule Params
- `linear_duration (Days)`
- `immediate_release_fraction (%)`
- Behavioural Params
- `onboarding_rate (PiB/day)`
- `onboarding_quality_factor ([1, 10])`
- `renewal_probability (%)`

## World State

- `days_passed (Days)`: Set-up initially to XXX days
- `delta_days (Days)`: Set-up initially to 1 day
- `aggregate_sectors (list[AggregateSector])`
- `AggregateSector`
- `rb_power (PiB)`
- `qa_power (QA-PiB)`
- `remaining_days (Days)`
- `storage_pledge (FIL)`
- `consensus_pledge (FIL)`
- `collateral_in_fil (metric, FIL)`
- `RewardSchedule (dict[Days, FIL])`
- `locked_in_fil (metric, FIL)`
- `token_distribution (dataclass)`
- `minted (FIL)`: (endogenous)
- `vested (FIL)`: Set-up initially to XXXX kFIL
- `collateral (FIL)`: (endogenous)
- `locked_rewards (FIL)`: (endogenous)
- `burnt (FIL)`: Set-up initially to XXXX kFIL
- `locked (metric, FIL)`
- `available (metric, FIL)`
- `circulating = (metric, FIL)`
- From Baseline Edu Calculator
- `power_qa (QA-PiB)`: (endogenous)
- `power_rb (PiB)`: (endogenous)
- `baseline (PiB)`: (endogenous)
- `cumm_capped_power (PiB*Days)`: (endogenous)
- `effective_days_passed (Days)`: Set-up initially to XXXX years
- `reward (tuple[FIL, FIL])`: (endogenous)

### Initializing the `aggregate_sectors` historical data


#### Assumptions
- Network QAP is held constant during the initialization phase
- Storage and Consensus Pledge per Sector is held constant during the initialization phase

#### Sequence

1. Create AggregateSectors with equal sizes and with lifetimes varying from 0 days to 180 days
2. Set-up their collaterals to be constant values
3. Retro-simulate their reward schedules by assuming an constant share of the Network QAP


## Simulation Sequence

- Time Section
- Pass Time
- Evolve Sector Lifetime
- Collateral Metrics Section
- Initial & Storage Pledge on this Round
- Sector Decisions Section
- Sector Onboarding Decision
- Sector Renewal Decision
- Expire Sectors
- Baseline & Rewards Section
- RB & QA Power from Sectors
- Cummulative Capped Power
- Effective Network Time
- Reward
- Rewards & Vesting Section
- Award & Lock Rewards
- Unlock Scheduled Rewards
- Vest FIL according to Schedule
- Token Supply Section
- Compute Token Distribution

## Scenarios

- Standard Scenario
- User Scenario
- Compared to the Standard Scenario, the TLS is user-provided
- Counterfactual Scenario
- Compared to the Standard Scenario, the TLS is set to zero



# References

- [Reviewing the Target Locked Supply](/90MrWid8QHejWGAju9EaDw)
168 changes: 148 additions & 20 deletions app/chart.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@

class PlotlyChart(ABC):
def __init__(self, chart, use_container_width=True):
self.chart = st.plotly_chart(chart, use_container_width=use_container_width)
self.chart = st.plotly_chart(
chart, use_container_width=use_container_width)

@abstractclassmethod
def build(cls):
Expand All @@ -21,45 +22,46 @@ def build(cls):
def compose_x_domain(num_steps):
return (
C["days_after_launch"] / C["days_per_year"],
(C["days_after_launch"] + num_steps * C["days_per_step"]) / C["days_per_year"],
(C["days_after_launch"] + num_steps *
C["days_per_step"]) / C["days_per_year"],
)


class NetworkPowerPlotlyChart(PlotlyChart):
@classmethod
def build(cls, df, num_steps):
def build(cls, df, num_steps, vline):
chart = px.line(
df,
x="years_passed",
y="network_power",
color="scenario",
title="Network Power vs. Time",
y=["power_rb", "baseline"],
title="RB Network Power vs. Time",
labels={
"years_passed": "Year",
"network_power": "Raw Bytes Network Power (RB PiB)",
"value": "Raw Bytes Network Power (RB PiB)",
},
range_x=cls.compose_x_domain(num_steps),
range_y=(1e4, 2e6),
log_y=True,
range_y=(0, 50_000),
# log_y=True,
)
chart.add_vline(vline, line_dash="dot")
return cls(chart)


class MiningUtilityPlotlyChart(PlotlyChart):
class QAPowerPlotlyChart(PlotlyChart):
@classmethod
def build(cls, df, num_steps):
chart = px.line(
df,
x="years_passed",
y="mining_utility",
color="scenario",
title="Mining Utility vs. Time",
y='power_qa',
title="QA Power vs. Time",
labels={
"years_passed": "Year",
"mining_utility": "Mining Utility (% of baseline scenario)",
"power_qa": "QA Network Power (QA PiB)",
},
range_x=cls.compose_x_domain(num_steps),
range_y=(0.4, 2.5),
range_y=(0, 150_000),
# log_y=True,
)
return cls(chart)

Expand All @@ -78,7 +80,7 @@ def build(cls, df, num_steps):
"effective_network_time": "Effective Network Time (Years)",
},
range_x=cls.compose_x_domain(num_steps),
range_y=(1.5, 8),
range_y=(2.5, 4.5),
)
return cls(chart)

Expand All @@ -97,7 +99,7 @@ def build(cls, df, num_steps):
"simple_reward": "Simple Reward (FIL / month)",
},
range_x=cls.compose_x_domain(num_steps),
range_y=(1e6, 3e6),
range_y=(60_000, 100_0000),
)
return cls(chart)

Expand All @@ -116,7 +118,7 @@ def build(cls, df, num_steps):
"baseline_reward": "Baseline Reward (FIL / month)",
},
range_x=cls.compose_x_domain(num_steps),
range_y=(1e6, 7e6),
range_y=(50_000, 150_0000),
)
return cls(chart)

Expand All @@ -135,7 +137,133 @@ def build(cls, df, num_steps):
"marginal_reward": "Marginal Reward (FIL / (month * RB PiB))",
},
range_x=cls.compose_x_domain(num_steps),
range_y=(0, 1e3),
# log_y=True
range_y=(0.1, 1000),
log_y=True
)

return cls(chart)


class TokenDistributionPlotlyChart(PlotlyChart):
@classmethod
def build(cls, df, num_steps, vline):
chart = px.line(
df,
x="years_passed",
y=["fil_circulating",
# "fil_vested",
'fil_locked'],
title="Token Distribution - Circulating vs Locked",
line_dash='scenario',
labels={
"years_passed": "Year",
"value": "FIL"
},
range_x=cls.compose_x_domain(num_steps),
range_y=(0, 500_000_000),
# log_y=True,
)
chart.add_vline(vline, line_dash="dot")
return cls(chart)


class TokenLockedDistributionPlotlyChart(PlotlyChart):
@classmethod
def build(cls, df, num_steps, vline):
chart = px.line(
df,
x="years_passed",
y=["fil_collateral", "fil_locked_reward"],
title="Locked Token Distribution - Collateral vs Locked Rewards",
line_dash='scenario',
labels={
"years_passed": "Year",
"value": "FIL"
},
range_x=cls.compose_x_domain(num_steps),
range_y=(0, 150_000_000),
# log_y=True,
)
chart.add_vline(vline, line_dash="dot")
return cls(chart)


class CriticalCostPlotlyChart(PlotlyChart):
@classmethod
def build(cls, df, num_steps, vline):
chart = px.line(
df,
x="years_passed",
y="critical_cost",
title="Critical Cost",
line_dash='scenario',
labels={
"years_passed": "Year",
"critical_cost": "FIL"
},
range_x=cls.compose_x_domain(num_steps),
range_y=(0, 40_000_000),
# log_y=True,
)
chart.add_vline(vline, line_dash="dot")
return cls(chart)


class CirculatingSurplusPlotlyChart(PlotlyChart):
@classmethod
def build(cls, df, num_steps, vline):
chart = px.line(
df,
x="years_passed",
y="circulating_surplus",
title="Circulating Surplus",
line_dash='scenario',
labels={
"years_passed": "Year",
'circulating_surplus': "Excess Circulating Supply vs Critical Cost"
},
range_x=cls.compose_x_domain(num_steps),
range_y=(5, 5000),
log_y=True
)
chart.add_vline(vline, line_dash="dot")
return cls(chart)

class CirculatingSupplyPlotlyChart(PlotlyChart):
@classmethod
def build(cls, df, num_steps, vline):
chart = px.line(
df,
x="years_passed",
y=["circulating_supply", 'locked_supply'],
title="Circulating and Locked Supply",
line_dash='scenario',
labels={
"years_passed": "Year",
"value": "\% of Available FIL"
},
range_x=cls.compose_x_domain(num_steps),
range_y=(0, 1),
)
chart.update_yaxes(tickformat=".0%")
chart.add_vline(vline, line_dash="dot")
return cls(chart)


class OnboardingCollateralPlotlyChart(PlotlyChart):
@classmethod
def build(cls, df, num_steps, vline):
chart = px.line(
df,
x="years_passed",
y="consensus_pledge_per_new_qa_power",
title="Initial Pledge per QA-PiB",
labels={
"years_passed": "Year",
"value": "FIL per QA-PiB"
},
range_x=cls.compose_x_domain(num_steps),
range_y=(0, 8_000),
)
chart.add_vline(vline, line_dash="dot")
return cls(chart)
Loading