diff --git a/efficient_fees/service_stake.ipynb b/efficient_fees/service_stake.ipynb new file mode 100644 index 0000000..136b857 --- /dev/null +++ b/efficient_fees/service_stake.ipynb @@ -0,0 +1,139 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 116, + "id": "eca38ae3-3df1-40f9-9a4b-ddc539559aba", + "metadata": {}, + "outputs": [], + "source": [ + "from dataclasses import dataclass\n", + "\n", + "@dataclass\n", + "class ServiceNetwork:\n", + " total_nmo_stake: int = 0\n", + " total_lp_supply: int = 0\n", + " \n", + " def stake(self, nmo):\n", + " if self.total_nmo_stake == 0:\n", + " # this is the only staker in the network\n", + " self.total_nmo_stake = nmo\n", + " self.total_lp_supply = 1.0\n", + " return self.total_lp_supply\n", + " \n", + " lp_tokens = nmo / self.total_nmo_stake * self.total_lp_supply\n", + " self.total_nmo_stake += nmo\n", + " self.total_lp_supply += lp_tokens\n", + " return lp_tokens\n", + "\n", + " def unstake(self, lp_tokens):\n", + " nmo = self.query_stake(lp_tokens)\n", + " self.total_nmo_stake -= nmo\n", + " self.total_lp_supply -= lp_tokens\n", + " return nmo\n", + "\n", + " def query_stake(self, lp_tokens):\n", + " nmo = lp_tokens / self.total_lp_supply * self.total_nmo_stake \n", + " return nmo\n", + " \n", + " def reward(self, r_nmo):\n", + " self.total_nmo_stake += r_nmo\n", + "\n", + "def print_lp_positions(sn, lpers):\n", + " print(f\"{\"actor\":^7}|{\"lp\":^5}|{\"nmo\":^7}\")\n", + " print(\"-------+-----+-------\")\n", + " for actor, lp in lpers.items():\n", + " print(f\"{actor:7}|{lp:5.2f}|{sn.query_stake(lp):7.2f}\")\n", + "\n", + " print(\"-------+-----+-------\")\n", + " print(\"{actor:7}|{lp:5.2f}|{nmo:7.2f}\".format(actor=\"total\", lp=sum(lpers.values()), nmo=sum(sn.query_stake(lp) for lp in lpers.values())))" + ] + }, + { + "cell_type": "code", + "execution_count": 119, + "id": "0b58cd02-3427-4388-992b-8347cb2a601a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " actor | lp | nmo \n", + "-------+-----+-------\n", + "alice | 1.00| 10.00\n", + "bob | 1.00| 10.00\n", + "charlie| 3.00| 30.00\n", + "-------+-----+-------\n", + "total | 5.00| 50.00\n", + "\n", + "network is rewarded by 5 NMO\n", + "\n", + " actor | lp | nmo \n", + "-------+-----+-------\n", + "alice | 1.00| 11.00\n", + "bob | 1.00| 11.00\n", + "charlie| 3.00| 33.00\n", + "-------+-----+-------\n", + "total | 5.00| 55.00\n", + "\n", + "new stakers after network rewards get fewer LP tokens\n", + "\n", + " actor | lp | nmo \n", + "-------+-----+-------\n", + "alice | 1.00| 11.00\n", + "bob | 1.00| 11.00\n", + "charlie| 3.00| 33.00\n", + "dan | 0.91| 10.00\n", + "-------+-----+-------\n", + "total | 5.91| 65.00\n" + ] + } + ], + "source": [ + "sn = ServiceNetwork()\n", + "\n", + "stakers = {\"alice\": 10, \"bob\": 10, \"charlie\": 30}\n", + "\n", + "lpers = {actor: sn.stake(nmo) for actor, nmo in stakers.items()}\n", + "\n", + "print_lp_positions(sn, lpers)\n", + "\n", + "print(\"\")\n", + "print(\"network is rewarded by 5 NMO\")\n", + "sn.reward(5)\n", + "print(\"\")\n", + "\n", + "print_lp_positions(sn, lpers)\n", + "\n", + "print(\"\")\n", + "print(\"new stakers after network rewards get fewer LP tokens\")\n", + "print(\"\")\n", + "stakers[\"dan\"] = 10\n", + "lpers[\"dan\"] = sn.stake(stakers[\"dan\"])\n", + "print_lp_positions(sn, lpers)\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/efficient_fees/shell.nix b/efficient_fees/shell.nix new file mode 100644 index 0000000..8d96840 --- /dev/null +++ b/efficient_fees/shell.nix @@ -0,0 +1,23 @@ +{ pkgs ? import {} }: + +pkgs.mkShell { + buildInputs = with pkgs; [ + # Defines a python + set of packages. + (python3.withPackages (ps: with ps; with python3Packages; [ + jupyter + ipython + + # Uncomment the following lines to make them available in the shell. + # pandas + numpy + matplotlib + scipy + sympy + pyvis + networkx + ])) + ]; + + # Automatically run jupyter when entering the shell. + shellHook = "jupyter notebook"; +}