Skip to content

CADLabs/fei-protocol-model

Repository files navigation

All Contributors

Python package

A modular dynamical-systems model of Fei Protocol's Protocol-controlled Value (PCV) Monetary Policy and proposed FEI Savings Rate mechanism, based on the open-source Python library radCAD.

This code repo is based on the CADLabs Ethereum Economic Model radCAD modelling & simulation project template.

See the Ethereum Economic Model README notebook for a good introduction to the radCAD experiment and modelling workflow.

Excerpts from experiments/notebooks/1_sanity_checks.ipynb:

Sanity Checks

FEI Capital Allocation

Total FEI Supply

Table of Contents


Introduction

The Fei Protocol Model was developed to support public policy making and management of protocol risk and health.

The objectives for the model for each stakeholder group identified during requirements specification were:

Stakeholder group 1: Fei Protocol Policy Makers

  • Inform public policy and decision making by evaluating simulated protocol health, risk, resilience e.g. Contractionary Monetary Policy
  • Inform effective management of PCV under different scenarios and failure modes
  • Evaluate and sustainably increase demand for FEI

Stakeholder group 2: Fei Holders

  • Obtain transparency and confidence as to the mechanics and resilience of the system behind PCV management

Stakeholder group 3: Tribe DAO

  • Better understand the levers impacting PCV management

From these requirements, three System Goals were developed:

  • Goal 1: Sustainably increase demand for FEI
  • Goal 2: Manage PCV risk
  • Goal 3: Optimise PCV capital efficiency

Finally, the model aimed to achieve the following outcomes:

  • Ability to make model-informed design decisions, illuminating complex relationships and downstream effects
  • Ability to support effective PCV management under different scenarios and failure modes
  • Ability to simulate FEI demand with different FEI Savings Rates under different market conditions

A number of assumptions were made in the scoping and development of the model, and any suggested extensions outside the scope of the MVP modelling effort have been proposed in the modelling roadmap. The following is a list of features currently implemented in the model:

Model Features

Directory Structure

  • data/: Datasets and API data sources (such as Etherscan.io and Beaconcha.in) used in the model
  • docs/: Misc. documentation such as auto-generated docs from Python docstrings and Markdown docs
  • experiments/: Analysis notebooks and experiment workflow (such as configuration and execution)
  • logs/: Experiment runtime log files
  • model/: Model software architecture (structural and configuration modules)
  • tests/: Unit and integration tests for model and notebooks

Model Architecture

The model/ directory contains the model's software architecture in the form of two categories of modules: structural modules and configuration modules.

Structural Modules

The model is composed of several structural modules in the model/parts/ directory:

Module Description
accounting.py Assorted accounting of aggregate State Variables such as Protocol Owned FEI, User-circulating FEI, etc.
fei_capital_allocation.py Implementation of a model enconding user-circulating FEI movements
fei_savings_deposit.py Implementation of the FEI Savings Deposit
liquidity_pools.py Implementation of a generic Uniswap style FEI-Volatile Liquidity Pool
money_markets.py Implementation of a generic Aave/Compound style Money Market
pcv_management.py Implementation of PCV management processes and strategies
pcv_yield.py Implementation of PCV yield processes and strategies
peg_stability_module.py Implementation of a Fei Peg Stability Module for minting and redemption
price_processes.py State update functions for drawing samples from misc. projected or stochastic asset price processes
system_metrics.py Assorted system metrics
uniswap.py Uniswap style Constant Function Market Maker functions

Configuration Modules

The model is configured using several configuration modules in the model/ directory:

Module Description
constants.py Constants used in the model, e.g. number of epochs in a year, Gwei in 1 Ether
initialization.py Code used to set up the Initial State of the model before each subset from the System Parameters
state_update_blocks.py cadCAD model State Update Block structure, composed of Policy and State Update Functions
state_variables.py Model State Variable definition, configuration, and defaults
stochastic_processes.py Helper functions to generate stochastic environmental processes
system_parameters.py Model System Parameter definition, configuration, and defaults
types.py Various Python types used in the model, such as the PCVDeposit Class and calculation units
utils.py Misc. utility and helper functions

Model Assumptions

For a comprehensive list of modelling assumptions made see ASSUMPTIONS.md.

Differential Model Specification

The Differential Model Specification depicts the model's overall structure across System States, System Inputs, System Parameters, State Update Logic and System Metrics.

In addition to the LucidChart link above, a copy of the diagram has been included below, and there is a PDF version.

Differential Specification Diagram

Environment Setup

The following steps guide you through how to set up a custom development environment using Python 3 and Jupyter.

Please note the following prerequisites before getting started:

  • Python: tested with versions 3.8, 3.9
  • NodeJS might be needed if using Plotly with Jupyter Lab (Plotly works out the box when using the Anaconda/Conda package manager with Jupyter Lab or Jupyter Notebook)

First, set up a Python 3 virtualenv development environment (or use the equivalent Anaconda step):

# Create a virtual environment using Python 3 venv module
python3 -m venv venv
# Activate virtual environment
source venv/bin/activate

Make sure to activate the virtual environment before each of the following steps.

Secondly, install the Python 3 dependencies using Pip, from the requirements.txt file within your new virtual environment:

# Install Python 3 dependencies inside virtual environment
pip install -r requirements.txt

To create a new Jupyter Kernel specifically for this environment, execute the following command:

python3 -m ipykernel install --user --name python-cadlabs-fei --display-name "Python (CADLabs Fei Model)"

You'll then be able to select the kernel with display name Python (CADLabs Fei Model) to use for your notebook from within Jupyter.

To start Jupyter Notebook or Lab (see notes about issues with using Plotly with Jupyter Lab):

jupyter notebook
# Or:
jupyter lab

For more advanced Unix/macOS users, a Makefile is also included for convenience that simply executes all the setup steps. For example, to setup your environment and start Jupyter Lab:

# Setup environment
make setup
# Start Jupyter Lab
make start-lab

Known Issues

Plotly doesn't display in Jupyter Lab

To install and use Plotly with Jupyter Lab, you might need NodeJS installed to build Node dependencies, unless you're using the Anaconda/Conda package manager to manage your environment. Alternatively, use Jupyter Notebook which works out the box with Plotly.

See https://plotly.com/python/getting-started/

You might need to install the following "lab extension":

jupyter labextension install jupyterlab-plotly@4.14.3

Windows Issues

If you receive the following error and you use Anaconda, try: conda install -c anaconda pywin32

DLL load failed while importing win32api: The specified procedure could not be found.

Simulation Experiments

The experiments/ directory contains modules for configuring and executing simulation experiments, as well as performing post-processing of the results.

The experiments/notebooks/ directory contains Jupyter notebooks exploring each part of the model as well as generic data analysis and model validation.

1. Sanity Checks

See experiments/notebooks/1_sanity_checks.ipynb

The purpose of this notebook is to perform a set of sanity checks that validate the expected key system dynamics, as well as the relationships between different key state variables. These analyses should also serve as an educational explanatory tool for less intuitive system dynamics and as an introduction to the model.

Analysis 1: System Dynamics Over Volatile Asset Price Trajectories

The purpose of this analysis is to illustrate and validate the driving influence of the Volatile Asset price on key system dynamics.

Analysis 2.1: State Variable Relationships

The purpose of this analysis is to illustrate and validate the relationships between and distribution of key system state variables using the model's default experiment initial state and system parameters.

Analysis 2.2: State Variable Correlation

The purpose of this analysis is to illustrate and validate the correlation between key system state variables.

Analysis 3: Liquidity Pool Dynamics

The purpose of this analysis is to illustrate and validate the effect of a step change in the Volatile Asset price on the liquidity pool imbalance, resulting minting and redemption, and capital allocation.

2. FEI Savings Rate Analyses

See experiments/notebooks/2_fei_savings_rate.ipynb

The purpose of this notebook is to showcase how the radCAD Fei Protocol Model can leverage large-scale simulations to provide data-driven insights into monetary policy setting. Specifically, we’ll consider the development of a FEI Savings Rate according to existing FIPs, with relevant qualitative and probabilistic conclusions.

3. Protocol Controlled Value

See experiments/notebooks/3_protocol_controlled_value.ipynb

The purpose of this notebook is to illustrate and evaluate the effect of a target Stable Backing Ratio and Contractionary Monetary Policy applied to Liquidity Pool protocol-owned liquidity on key system dynamics and KPIs.

Analysis 1: FEI Volatile Liquidity Pool Leverage

This analysis serves to answer the what-if question: What leverage effect does protocol-owned liquidity have on total FEI supply and collateralization of the protocol in different market trends?

Analysis 2: PCV at Risk for Stable Backing Ratio Targets

The analysis serves to answer the what-if question: What effect does a PCV management strategy targetting a Stable Backing Ratio have on PCV at Risk and collateralization of the protocol? We'll statistically evaluate the efficacy of different policy settings.

Historical Datasets

See experiments/notebooks/historical_datasets.ipynb

The purpose of this notebook is to perform Exploratory Data Analysis of real Fei Protocol datasets using checkthechain.

Liquidity Pools Notebook

See experiments/notebooks/liquidity_pools_notebook.ipynb

The purpose of this notebook is to illustrate the operation of the generic FEI-Volatile Liquidity Pool subsystem.

Money Markets Notebook

See experiments/notebooks/money_markets_notebook.ipynb

The purpose of this notebook is to illustrate the operation of the generic Money Market subsystem.

PCV Management Notebook

See experiments/notebooks/pcv_management_notebook.ipynb

The purpose of this notebook is to illustrate PCV management strategies.

PCV Yield Notebook

See experiments/notebooks/pcv_yield_notebook.ipynb

The purpose of this notebook is to illustrate PCV yield accrual and management.

Model Extension Roadmap

The modular nature of the model makes structural and experiment-level extensions straightforward. The Model Extension Roadmap provides some inspiration.

Tests

We use Pytest to test the model module code, as well as the notebooks.

To execute the Pytest tests:

source venv/bin/activate
python3 -m pytest tests

To run the full GitHub Actions CI Workflow (see .github/workflows):

source venv/bin/activate
make test

Simulation Profiling

A notebook exists to perform simulation time profiling of individual State Update Blocks of the model, see [experiments/notebooks/simulation_profiling/simulation_timestep_substep_profiling.ipynb]. Simulation time profiling of PRs is also performed in the GitHub Action pipeline, and included in each PR by a bot. See the Makefile and GitHub Action file for more details.

Memory profiling can also be performed using the memory-profiler Python package:

make profile-memory target="tests/test_notebook_memory.py 1_sanity_checks.ipynb"

Change Log

See CHANGELOG.md for notable changes and versions.

Acknowledgements

Storm and the rest of the Fei Protocol team for their close collaboration and guidance in creating this model.

Contributors ✨

Thanks goes to these wonderful contributors (see emoji key):

cadlabsgt
cadlabsgt

πŸ’» πŸ“– πŸ€” πŸ”¬ πŸ‘€ βœ…
Benjamin Scholtz
Benjamin Scholtz

πŸ“† πŸ’» πŸ“– πŸ€” πŸ”¬ πŸ‘€
vmeylan
vmeylan

πŸ’» πŸ€” πŸ”¬ πŸ‘€
Danilo Lessa Bernardineli
Danilo Lessa Bernardineli

πŸ’» πŸ€” πŸ”¬
sslivkoff
sslivkoff

πŸ€” πŸ”¬ πŸ‘€ πŸ§‘β€πŸ«

This project follows the all-contributors specification. Contributions of any kind welcome!

License

The code repository CADLabs/fei-protocol-model is licensed under the GNU General Public License v3.0.

Permissions of this strong copyleft license are conditioned on making available complete source code of licensed works and modifications, which include larger works using a licensed work under the same license. Copyright and license notices must be preserved. Contributors provide an express grant of patent rights.

If you'd like to cite this code and/or research, we suggest the following format:

CADLabs, Fei Protocol Model, (2023), GitHub repository, https://github.com/CADLabs/fei-protocol-model

@misc{CADLabs2023,
  author = {CADLabs},
  title = {Fei Protocol Model},
  year = {2023},
  publisher = {GitHub},
  journal = {GitHub repository},
  howpublished = {\url{https://github.com/CADLabs/fei-protocol-model}},
  version = {v0.1.1}
}