diff --git a/docs/experiment.md b/docs/experiment.md deleted file mode 100644 index 93481621..00000000 --- a/docs/experiment.md +++ /dev/null @@ -1,33 +0,0 @@ -# Experiment - -## Overview -### action -Actions are the atomic signals passed between the simulation engine and simulation agents (keepers). -- `key` states the type of action (currently `OPEN_VAULT`, `DENT`, `TEND`, `DEAL`, `POKE`, `BITE`). -- `keeper` states the keeper that is performing the action. -- `handler` states the function that will be called. -- `args` states the arguments that will be passed to the `handler`. -- `kwargs` states any additional arguments that are needed. - -## Common Conventions - -## Functions - -### init -- contracts: dict of smart contract classes, e.g. {"Cat": MyCustomCatClass} -- keepers: dict of keeper classes, e.g. {"MyCustomKeeper": MyCustomKeeperClass} -- sort_actions: sort key used to decide the order in which keepers act each timestep -- ilk_ids: list of ilks by their ticker symbol -- Token: token class -- stat_trackers: list of methods that measure stats over the course of the experiment, e.g.: [num_new_kicks] -- parameters: dict of parameters used to instantiate the contracts, keepers, and simulation, e.g.: {"Spotter": {...}, "MyCustomKeeper": {...}, "timesteps": ... -### run -The core function of the simulation. -Initializes assets, smart contracts, state, and keepers. -One timestep consists of the following: -- send an `action` object to signal stat-tracking functions to begin tracking data. -- iterates through all `action` objects queued in a timestep, sorted by a sorting function (defaults to random). Also tracks state in between `action` handler executions. - -- send an `action` object to signal stat-tracking functions to end tracking data. -## Outputting Data -After the core simulation loop has completed, we will output the by writing the `state` object to a file. \ No newline at end of file diff --git a/docs/getting_started.md b/docs/getting_started.md deleted file mode 100644 index 328401c1..00000000 --- a/docs/getting_started.md +++ /dev/null @@ -1,77 +0,0 @@ -# Getting Started - -**Note: These instructions are written for Mac OS** - -## Setting up the environment -1. If you don't already have them, install the XCode Command Line Tools and Homebrew: - ```bash - xcode-select --install - /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)" - ``` -2. Install these dependencies for building Python environments: - ```bash - brew install openssl readline sqlite3 xz zlib - ``` -3. If you don't already have it, install `pyenv`: - ```bash - brew install pyenv - ``` -4. Install Python 3.8.6 using `pyenv`: - ```bash - pyenv install 3.8.6 - ``` -5. Make sure you add the following to your `~/.zshrc` or `~/.bash_profile` afterwards: - ```bash - export PATH="$HOME/.pyenv/bin:$PATH" - eval "$(pyenv init -)" - ``` - and then run: - ```bash - source PATH_TO_SHELL_PROFILE # ~/.zshrc, ~/.bash_profile, or whatever else you have set up - ``` -6. Clone the repo & enter the project root: - ```bash - git clone https://github.com/akirillo/bab-stablesims.git - cd bab-stablesims - ``` -7. Verify the current Python version is 3.8.6, and that the `pyenv` interpreter being used: - ```bash - python3 --version - # Python 3.8.6 - which python3 - # $HOME/.pyenv/shims/python3 - ``` - - **If not**, make sure that you have all other virtual environments deactivated & that `$HOME/.pyenv/bin` takes precedence in your `$PATH` over other Python installations. - - E.g. if you see `(base)` at the beginning of your terminal prompt, you likely have a conda base environment active, so run a `conda deactivate` - - The version is set by the `.python-version` file in the project root -8. Create a virtual environment (at the project root) and activate it using: - ```bash - python3 -m venv stablesims-venv - . ./stablesims-venv/bin/activate - ``` - - You'll want to be sure that **this and only this** virtual environment is activated any time you try to run some code -9. Install `poetry` (our package manager, think `yarn` or `npm` for Python): - ```bash - curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python - - ``` - and then run: - ```bash - source $HOME/.poetry/env - ``` -10. Install dependencies: - ```bash - poetry install - ``` -11. Activate `autohooks`, which we use for pre-commit git hooks (formatting & linting): - ```bash - poetry run autohooks activate - ``` - -## Helpful resources -- [Maker DAO Black Thursday post-mortem](https://blog.makerdao.com/the-market-collapse-of-march-12-2020-how-it-impacted-makerdao/) -- [Maker Protocol 101 slide deck](https://drive.google.com/file/d/1bEOlNk2xUXgwy0I_UlB_8tPPZ8mH1gy9/view) -- [Maker Protocol FAQs](https://github.com/makerdao/community/tree/master/faqs) -- [Maker Protocol docs](https://docs.makerdao.com/) - - Specifically, the [smart contracts glossary](https://docs.makerdao.com/other-documentation/system-glossary) and [general glossary](https://github.com/makerdao/community/blob/master/faqs/glossary.md) -- [Maker Protocol source code](https://github.com/makerdao/dss) - - I suggest enabling [annotations](https://docs.makerdao.com/other-documentation/smart-contract-annotations) for this (you can just prepend https://via.hypothes.is/ to any URL in the repo, like [this](https://via.hypothes.is/https://github.com/makerdao/dss/blob/master/src/vat.sol)) diff --git a/docs/introduction.md b/docs/introduction.md deleted file mode 100644 index 751c59d4..00000000 --- a/docs/introduction.md +++ /dev/null @@ -1,9 +0,0 @@ -# Introduction - -StableSims is a clone of the [Maker Protocol](https://github.com/makerdao/dss) written in object-oriented Python. In addition to recreating the smart contracts, we've also made our own keeper models, along with a lightweight engine for simulating keeper interactions with the protocol. - -[Smart contract classes](./smart_contracts.md) - -Keeper models - -Simulation engine diff --git a/docs/keepers.md b/docs/keepers.md deleted file mode 100644 index 89cf0093..00000000 --- a/docs/keepers.md +++ /dev/null @@ -1,59 +0,0 @@ -# Keepers - -## Overview - -## Common Conventions - -The Keeper class follows similar conventions as the smart contracts. See [smart_contracts.md](./smart_contracts.md) for explanations. - -## Classes -### Keeper - -The base interface for all other keeper classes. `generate_actions_for_timestep` returns an array of `action` objects that is run by [experiment.py](../experiments/experiment.py) - -### VaultKeeper -> superclass: Keeper - -Class representation of a keeper that owns vaults. `open_max_vaults` will open the maximum possible number of vaults for each ilk. - -### NaiveVaultKeeper -> superclass: VaultKeeper - -The Naive Vault Keeper will open the maximum number of vaults possible at each timestep. - -### AuctionKeeper -> superclass: VaultKeeper - -The base interface for auction keeper classes. -Refer to [Maker's Auction Keeper Bot Setup Guide](https://docs.makerdao.com/keepers/auction-keepers/auction-keeper-bot-setup-guide) for documentation for the output format. -- `find_bids_to_place` will take `now` (current timestep as String TODO) as input and will output a dictionary with `ilk_ids` as keys and lists of bids as values. -- `run_bidding_model` will take `bid`, `ilk_id` as inputs and will output a dictionary with "price" as a key and the bid price as the value. -- `place_bid` will take `bid_id`, `price`,`ilk_id`, `now` as inputs and will output an `action` object based on whether the auction is in a `TEND` or `DENT` phase. This function will also verify that the bid is valid based on the checks that Maker makes (proposed bid is greater than latest bid, etc.) -- `find_bids_to_deal` will take `now` as input and will output a dictionary of valid bids to be dealt. It filters through the bids of a specific `ilk_id`, finding the bids that belong to the current keeper. -- `deal_bid` will take `bid_id`, `ilk_id`, `now` as inputs and will output an `action` that will deal the bid. - -### FlipperKeeper -> superclass: FlipperKeeper - -The base interface for all other `FlipperKeeper` classes. Inherits from `VaultKeeper`. It will also find, deal, and place bids during both dent and tend phases, and keeps track of a set of Flipper contracts for every Ilk type that it's interested in. -- `find_and_deal_bids` uses `find_bids_to_deal` and `deal_bids` to append multiple action objects to the actions array. - -### NaiveFlipperKeeper -> superclass: FlipperKeeper - -The Naive Flipper Keeper will start an auction with a bid value that is 5% of the tab/lot. Consecutive bids will increase by the beg + a small, random amount of padding. - -### PatientFlipperKeeper -> superclass: FlipperKeeper - -Runs the same bidding model as the Naive Flipper Keeper, however will only place bids when the auction has not started yet and there does not exist another keeper with enough DAI to cover the auction's `tab`. - -### SpotterKeeper -> superclass: Keeper - -Will update the `ilk_id` prices using the `poke` function that is part of the `spotter` smart contract. - -### BiteKeeper -> superclass: Keeper - -Will bite urns with liquidation ratios that are too low using the `bite` function that is part of the `cat` smart contract. diff --git a/docs/smart_contracts.md b/docs/smart_contracts.md deleted file mode 100644 index a082194c..00000000 --- a/docs/smart_contracts.md +++ /dev/null @@ -1,54 +0,0 @@ -# Smart Contracts - -## Overview - -We've only ported over the smart contracts necessary for our simulations. This currently includes: -| Our implementation | Maker implementation | -| - | - | -| [`cat.py`](../pydss/cat.py) | [`cat.sol`](https://github.com/makerdao/dss/blob/master/src/cat.sol) | -| [`flip.py`](../pydss/flip.py) | [`flip.sol`](https://github.com/makerdao/dss/blob/master/src/flip.sol) | -| [`join.py`](../pydss/join.py) | [`join.sol`](https://github.com/makerdao/dss/blob/master/src/join.sol) | -| [`spotter.py`](../pydss/spotter.py) | [`spot.sol`](https://github.com/makerdao/dss/blob/master/src/spot.sol) | -| [`vat.py`](../pydss/vat.py) | [`vat.sol`](https://github.com/makerdao/dss/blob/master/src/vat.sol) | -| [`vow.py`](../pydss/vow.py) | [`vow.sol`](https://github.com/makerdao/dss/blob/master/src/vow.sol) | - -In addition to these smart contracts from the Dai stablecoin system (DSS), we've also created a `Token` class that loosely mimics the [ERC-20 spec](https://eips.ethereum.org/EIPS/eip-20) / [dai.sol](https://github.com/makerdao/dss/blob/master/src/dai.sol) contract. - -Finally, to handle the protocol's fixed-point integer `Wad`, `Rad`, and `Ray` units, we simply forked the `numeric.py` package from Maker's [`pymaker`](https://github.com/makerdao/pymaker) package. - -## Common Conventions - -The guiding principle in implementing these smart contract classes was to **replicate the Maker source code as closely as possible.** This even included variable naming conventions, with some slight adjustments. - -### `self.ADDRESS` - -This is the only field shared by all smart contract classes (it's purpose should be evident). -There's no smart contract base class, nor other shared abstractions (e.g. `msg.sender` functionality) - that's pushing into territory we deemed to be low-level for StableSims. - -### `Ilk` / `Bid` class redefinition - -In files such as `vat.py` and `cat.py`, there are different definitions of the `Ilk` class. While their contents are slightly different, one might stop to ponder why we didn't consolidate all of the fields into one top-level `Ilk` class, or set up an inheritance structure of any sort. - -The reason for this, is that such is the layout of the Maker source code. The `Ilk` struct is redefined as best fit in the smart contracts where it's used. - -You'll see redefinitions of the `Bid` class in the `Flipper`, `Flapper`, and `Flopper` smart contracts (WIP) as well, according to the same convention. - -### Extra parameters - -In some cases, you might spot additional method parameters that aren't present in the Maker source code, namely `now` and `sender`. These correspond to the expressions `now` and `msg.sender` in Solidity, respectively. They are only passed in when needed in the method. - -Should we ever make a base smart contract class, this time- and caller-awareness functionality should be encapsulated by it. - -### Missing & extra logic - -Occasionally, you may find logical discrepancies between our code and the Maker source code. For example, we are missing some smart contract functions, such as `hope` and `nope` on the `Vat`, and omit these function calls wherever they should appear in the code. Logic is only ommitted when it isn't necessary for our simulations. - -Sometimes, on the other hand, you'll see tidbits of extraneous logic - likely a bunch of instance variable-setting in a smart contract class's `__init__` method. This is necessary to match the default instantiation of variables in Solidity. - -### Variable naming - -As mentioned, variable names were copied from the source code in almost all cases. However, for consistency in variable naming outside of the smart contract classes, the following exceptions are made: -1. Wherever the variable name `ilk` was used in the source code to refer to the address of an Ilk, we use the variable name `ilk_id` - - Note that this doesn't include e.g. the `frob` method of the `Vat` contract, where the Ilk's address is denoted by the parameter `i`. -2. Wherever the variable name `bid` was used in the source code to refer to the address of a Bid, we use the variable name `bid_id` -3. The Ilk-specific `file` methods (e.g. those in `Cat` and `Vat` that take an `ilk_id` parameter) are renamed to `file_ilk` to avoid method overloading. diff --git a/docs/stats.md b/docs/stats.md deleted file mode 100644 index 9056b2a4..00000000 --- a/docs/stats.md +++ /dev/null @@ -1,36 +0,0 @@ -# Stats - -## Overview -A set of methods used to calculate statistics over the course of an -experiment. -Each such method is a higher-order function returning a `track_stat` method -that takes in a `state` object from an `Experiment`'s `run` method, and an `action` object. -The higher-order function can take in whatever parameters it may need to -provide to `track_stat`. - -## Common Conventions -Each `track_stat` function is expected to record its statistic in the `state["stats"]` dict that is part of `experiment.py`. The key will be equivalent to the higher-order function's name (e.g. `num_bids_placed` is the name of the HOF, and also we save the result to `state["stats"]["num_bids_placed"]`. Each `track_stat` function will be run after a Keeper executes in an action -in a timestep, so an intended design pattern is to guard your logic in -`track_stat` w/ a predicate that ensures you're only executing the method -in response to a specific action you were listening for. - -## Functions -### ilk_price - -Updates the ilk values in `stats`. Takes in an `ilk_id` as an argument and updates the `ilk_price` dictionary that maps Ilk ID's to Ilk spot values when the action key is `POKE`. - -### num_new_bites - -Updates the number of new bites in `stats`. When the action key is `T_START` the `num_new_bites` field will be reset. When the action key is `BITE` the `num_new_bites` field will be incremented. - -### num_bids_places - -Updates the number of bids placed in `stats`. When the action key is `T_START` the `num_bids_placed` field will be reset. When the action key is `TEND` the `num_bids_placed` field will be incremented. - -### num_active_bids - -Updates the number of current active bids across all ilks and flippers in `stats`. Will update the `num_active_bids` field to match the number of bids found on a specific Flipper, categorized by `ilk_id`. - -### keeper_gem_balances - -Updates the balances of ilk for each keeper in `stats`. When the action key is `T_END` each Keeper's Ilk balance will be updated. Recorded as a dictionary mapping Keeper addresses to objects containing `ilk_id`'s mapped to Ilk values. \ No newline at end of file