{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import seaborn as sns\n",
    "\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# CIC Initialization Notebook\n",
    "\n",
    "### Goals\n",
    " - Define the Mathematics of the CIC Bonding Curve in formal terms\n",
    " - Identify and make explicit the paramters\n",
    " - Define the initial state as a function of the parameters\n",
    " - Demonstrate the Bonding Curve Shape as a function of the parameters\n",
    "\n",
    "### Formal Foundations\n",
    "For a detailed Treatment of properties of Bonding Curves see:\n",
    "[From Curved Bonding to Configuration Spaces](https://epub.wu.ac.at/7385)\n",
    "and subsequent Publications on the subject appearing in the Proceedings of IEEE ICBC 2020 and MARBLE 2020.\n",
    "\n",
    "### System Scope\n",
    "Broad Mapping of the Grassroots Economics CIC Ecosystem including the CIC Users, the operators of the CIC Program and the underlying smart contracts:\n",
    "![Conservation of Flow](CICecosystem.jpeg)\n",
    "\n",
    "Zooming in on the Bonding Curve Smart Contract Subsystem:\n",
    "![Conservation of Flow](CICecosubsystem.jpeg)\n",
    "\n",
    "Explicit mapping of Conservation Equations which will regulate the supply of CIC tokens relative to xDAI reserves.\n",
    "![Conservation of Flow](GrassrootsEconomicsCICcontractconservation.jpeg)\n",
    "\n",
    "### Questions to be Answered\n",
    " - Choose Parameters which characterize the bonding curve mechanisms: $\\kappa$ and $\\phi$\n",
    " - Choose the initial conditions for Supply $S_0$ and Reserve $R_0$\n",
    " - Note that due to the Bonding Curve construction its initial conditions partially determine the systems properties."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Bonding Curve Mathematics"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Basic Definitions\n",
    "- $R$ = xDai in Reserve\n",
    "- $S$ = Total Supply of CIC tokens\n",
    "- $P$ = Spot Price of the Bonding Curve$^*$\n",
    "- $P \\cdot S$ = Market Cap implied by the Spot Price and Token Supply\n",
    "- $\\frac{R}{P \\cdot S}$ = Reserve Ratio in the Liquidity Pool$^\\dagger$\n",
    "\n",
    "$^*$ The spot price is the limiting price for both the Bond-to-Mint and the Burn-to-Withdraw Mechanisms in the case with no fees. Realized prices account for slippage and fees, see references.\n",
    "\n",
    "$^\\dagger$ Bonding Curves such as the one being employed by the CIC systems are tools which enforce the Reserve Ratio to be a constant $\\rho \\in (0,1)$, also called the connector weight. In this work we work with the \"curvature\" $\\kappa = \\frac{1}{\\rho} = \\frac{P \\cdot S}{R}$ in order to align notation with associated academic work."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Invariance and Consequences\n",
    "Consider the Conservation Function:\n",
    "- $V(S,R) = \\frac{S^\\kappa}{R}$\n",
    "- As a consquence, $P = -\\frac{\\partial V}{\\partial} = \\kappa \\frac{R}{S}\n",
    "\n",
    "In the absense of Fees:\n",
    "- $V(S,R) = \\frac{S^\\kappa}{R}$ is constant\n",
    "- $V(S,R) = V_0$ where $V_0 = \\frac{S_0^\\kappa}{R_0}$ where $S_0$ and $R_0$ are the initial Supply and Reserve, respectively.\n",
    "\n",
    "![Invariant](CICinvariant.jpeg)\n",
    "\n",
    "In the presence of Fees:\n",
    "- $V(S^+,R^+) > V(S,R)$ for all admissible actions\n",
    "- $V(S_t,R_t) > V_0$ for all $t>0$ where the index $t$ is an ordering of all transcations on the contract.\n",
    "- Under the invariant enforcing logic with fees, the reserve accumulates relative to the supply, essentially violating the invariant, but in a manner guaranteed to increase $V$. A concept introduced formally in [A State-Space Modeling Framework for Engineering Blockchain-Enabled\n",
    "Economic Systems](https://arxiv.org/pdf/1807.00955.pdf) which was presented at the International Conference on Complex Systems, May 2018.\n",
    "- Formal properties such as this are implicit in designs being designed and developed in a range of DeFi applications including but not limited to Bancor, Uniswap, Balancer, Fairmint. Such properties will serve as the basis of any formal stability claims over compositions of DeFi subsystems in to higher order financial systems.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Conservation Function Enforcing Deposit-to-Mint with Fees\n",
    " - Deposit $\\Delta R$ xDAI to mint $\\Delta S$ CIC tokens\n",
    " - Apply Fee $\\phi$: $\\Delta R' = (1-\\phi) \\Delta R$\n",
    " - Conservation equation: $V(R+ \\Delta R', S+\\Delta S) = \\frac{(S+\\Delta S)^\\kappa}{R+\\Delta R'} =\\frac{S^\\kappa}{R}$\n",
    " - Derived Mint equation: $\\Delta S = mint\\big(\\Delta R ; (R,S)\\big)= S\\big(\\sqrt[\\kappa]{(1+(1-\\phi)\\frac{\\Delta R}{R})}-1\\big)$\n",
    " \n",
    "### Conservation Function Enforcing Burn-to-Withdraw with Fees\n",
    " - Burn $\\Delta S$ CIC tokens to withdraw $\\Delta R$ xDAI\n",
    " - Applying fee $\\phi$: $\\Delta R = (1-\\phi) \\Delta R'$\n",
    " - Conservation equation: $V(R- \\Delta R', S-\\Delta S) = \\frac{(S-\\Delta S)^\\kappa}{R-\\Delta R'} =\\frac{S^\\kappa}{R}$\n",
    " - Derived Withdraw equation: $\\Delta R = withdraw\\big(\\Delta S ; (R,S)\\big)= R(1-\\phi)\\big(1-(1-\\frac{\\Delta S}{S})^\\kappa \\big)$\n",
    "\n",
    "### Properties of the Parameters\n",
    "- Require $\\kappa >0$; any $\\kappa \\in (0,1)$ is over reserved, $\\kappa =1$ results in a constant price $P=\\frac{R}{S}$ and is essentially a fully reserved system but may still be very useful when composed with other mechanisms (eg Pool tokens in Uniswap instances, the reserve in this case is a unit of liquidity which is the constant product mixture of eth and token), and when $\\kappa > 1$ the properties widely attributed to bonding curves hold. Additionally, the equations simplify significantly for $\\kappa=2$ which makes it an obvious choice when other considerations don't rule it out.\n",
    "- Require $\\phi \\ge 0$. When $\\phi=0$ the system is completely discribed by $\\kappa$ and the associated invariant function as above. When $\\phi>0$ it adds friction limiting the conditions under which an agent might choose to swap. It is important to note that this friction compounds with the slippage induced by the conservation law. The slippage is related to the curvature $\\kappa$ via the first order condition for convex functions. \n",
    "- Both the slippage and the fee add friction, for large transactions relative to the liquidity pool the slippage dominates the fee, but for small transactions relative to the liquidity pool the fee dominates the slippage. In the case where the distribution of transactions size is estimatable, it may make sense to position the fee based on how strong an effect is desired relative to slippage."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Initialization Equations\n",
    "\n",
    "- Input $R_0$ xDai to generate $S_0$ initial supply\n",
    "- \"Hatch\" sale \"Price\" $p_0$ (xDai per token minted) determines the initial supply: $S_0 = R_0/p_0$\n",
    "- The 'Connector Weight' in Bancor terms maps to the concept 'Reserve Ratio' $\\rho=\\frac{1}{\\kappa}=\\frac{R}{P \\cdot S}$\n",
    "- The initial spot price $P_0$ once the curve is live is $\\kappa \\frac{R_0}{S_0}$\n",
    "- Note that $\\frac{P_0}{p_0} = \\frac{\\kappa R_0/S_0}{R_0/S_0}= \\kappa$ is leverage applied in deploying the bonding curve.\n",
    "\n",
    "### Inputs from Stakeholder\n",
    "- $R_0= 40000$ xDAI\n",
    "- Conversion rate between USD and Kenyan Shilling is approximately 1:100\n",
    "- assume $P_0 =  1/100$ in order to ensure spot price is the right order of magnitude.\n",
    "- leverage rate from past discussions, considering $\\kappa =4$\n",
    "- above implies $S_0 = 4 \\times 100 \\times 40000 = 160\\, Million$ for the initial supply of CIC tokens "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Functions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "#value function for a given state (R,S)\n",
    "def invariant(R,S,kappa):\n",
    "    return (S**kappa)/R\n",
    "\n",
    "#given a value function (parameterized by kappa)\n",
    "#and an invariant coeficient V\n",
    "#return Supply S as a function of reserve R\n",
    "def supply(R, kappa, V):\n",
    "    return (V*R)**(1/kappa)\n",
    "\n",
    "#given a value function (parameterized by kappa)\n",
    "#and an invariant coeficient V\n",
    "#return a spot price P as a function of reserve R\n",
    "def spot_price(R, kappa, V):\n",
    "    return kappa*R**((kappa-1)/kappa)/V**(1/kappa)\n",
    "\n",
    "#for a given state (R,S)\n",
    "#given a value function (parameterized by kappa and phi)\n",
    "#and an invariant coeficient V\n",
    "#deposit deltaR to Mint deltaS\n",
    "#with realized price deltaR/deltaS\n",
    "def mint(deltaR, R,S, kappa, V, phi):\n",
    "    deltaS = (V*(R+(1-phi)*deltaR))**(1/kappa)-S\n",
    "    realized_price = deltaR/deltaS\n",
    "    return deltaS, realized_price\n",
    "\n",
    "#for a given state (R,S)\n",
    "#given a value function (parameterized by kappa and phi)\n",
    "#and an invariant coeficient V\n",
    "#burn deltaS to Withdraw deltaR\n",
    "#with realized price deltaR/deltaS\n",
    "def withdraw(deltaS, R,S, kappa, V0, phi):\n",
    "    deltaR = (R-((S-deltaS)**kappa)/(V0))*(1-phi)\n",
    "    realized_price = deltaR/deltaS\n",
    "    return deltaR, realized_price\n",
    "\n",
    "#for a given state (R,S)\n",
    "#given a value function (parameterized by kappa and phi)\n",
    "#and an invariant coeficient V\n",
    "#computed based on desired withdraw deltaR\n",
    "#with realized price deltaR/deltaS\n",
    "def withdrawR(deltaR, R,S, kappa, V, phi):\n",
    "    deltaS = S-(V*(R-(1-phi)*deltaR))**(1/kappa)\n",
    "    realized_price = deltaR/deltaS\n",
    "    return deltaS, realized_price"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Variable Declarations"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 49784 characters]\n",
      "text/plain": [
       "<Figure size 720x360 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "R0 =  40 #thousand xDAI\n",
    "kappa = 4 #leverage\n",
    "P0 = 1/100 #initial price\n",
    "S0 = kappa*R0/P0\n",
    "p0 = R0/S0\n",
    "phi = .01\n",
    "\n",
    "#initial value of conservation function\n",
    "V0 = invariant(R0,S0,kappa)\n",
    "\n",
    "reserve = np.arange(0,500,.05)\n",
    "supp = np.array([supply(r,kappa, V0) for r in reserve])\n",
    "price = np.array([spot_price(r,kappa, V0) for r in reserve])\n",
    "\n",
    "fig, ax1 = plt.subplots(figsize=(10,5))\n",
    "\n",
    "color = 'tab:red'\n",
    "ax1.set_xlabel('Reserve (Thousands)')\n",
    "ax1.set_ylabel('Supply (Thousands)', color=color)\n",
    "ax1.plot(reserve, supp,'-', color=color)\n",
    "ax1.tick_params(axis='y', labelcolor=color)\n",
    "\n",
    "ax2 = ax1.twinx()  # instantiate a second axes that shares the same x-axis\n",
    "\n",
    "color = 'tab:blue'\n",
    "ax2.set_ylabel('Price in xDAI per CIC token', color=color)  # we already handled the x-label with ax1\n",
    "ax2.plot(reserve, price,'-.', color=color)\n",
    "ax2.tick_params(axis='y', labelcolor=color)\n",
    "\n",
    "ax1.vlines(R0,0,S0, alpha=.5)\n",
    "ax1.scatter(R0,S0, color='red', marker='D')\n",
    "# ax1.text(R0+.02*reserve[-1], .9*supp[-1], \"Initial Value R0=\"+str(int(100*R0)/100)+\" million Reserve Units\")\n",
    "# ax1.text(R0+.02*reserve[-1], .70*supp[-1], \"Initial Value S0=\"+str(S0)+\" million Tokens\")\n",
    "ax1.text(-.4, .9*supp[-1], \"R0=\"+str(int(100*R0)/100)+\" thousand xDAI\")\n",
    "ax1.text(-.4, .80*supp[-1], \"S0=\"+str(S0)+\" thousand CIC Tokens\")\n",
    "\n",
    "#ax1.hlines(S0,0,R0)\n",
    "\n",
    "# ax2.text(R0+.02*reserve[-1], price[25], \"Initial Value P0=\"+str(spot_price(R0,kappa,V0)))\n",
    "# ax2.text(R0+.02*reserve[-1], price[25]/10, \"where P_hatch=\"+str(p0))\n",
    "ax2.text(R0+.04*reserve[-1], price[25], \"P0=\"+str(spot_price(R0,kappa,V0))+\" where P_hatch=\"+str(p0))\n",
    "ax2.scatter(R0,spot_price(R0,kappa,V0), color=color)\n",
    "\n",
    "plt.title('Bonding Curve with Conservation Function V = S^'+str(kappa)+'/R')\n",
    "fig.tight_layout()  # otherwise the right y-label is slightly clipped\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The figure above represents the base case as determined by the originally suggested values by the stakeholder."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 48772 characters]\n",
      "text/plain": [
       "<Figure size 720x360 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax1 = plt.subplots(figsize=(10,5))\n",
    "\n",
    "cp = 100\n",
    "color = 'tab:red'\n",
    "ax1.set_xlabel('Supply (Thousands)')\n",
    "ax1.set_ylabel('Reserve (Thousands)', color=color)\n",
    "ax1.plot(supp[cp:], reserve[cp:],'--', color=color)\n",
    "ax1.tick_params(axis='y', labelcolor=color)\n",
    "\n",
    "ax2 = ax1.twinx()  # instantiate a second axes that shares the same x-axis\n",
    "\n",
    "color = 'tab:blue'\n",
    "ax2.set_ylabel('Price in xDAI per CIC Token', color=color)  # we already handled the x-label with ax1\n",
    "ax2.plot(supp[cp:], price[cp:],'-.', color=color)\n",
    "ax2.tick_params(axis='y', labelcolor=color)\n",
    "\n",
    "ax1.vlines(S0,0,reserve[-1], alpha=.5)\n",
    "ax1.text(S0*1.02, reserve[-1], \"S0=\"+str(int(100*S0)/100)+\" Thousands of CIC tokens\")\n",
    "ax1.text(S0*1.02, .95*reserve[-1], \"R0=\"+str(R0)+\" Thousands of xDAI\")\n",
    "#ax1.hlines(S0,0,R0)\n",
    "\n",
    "ax2.text(S0*1.02, price[3], \"P0=\"+str(spot_price(R0,kappa,V0))+\" where P_hatch=\"+str(p0))\n",
    "\n",
    "\n",
    "plt.title('Bonding Curve with Conservation Function V= S^'+str(kappa)+'/R')\n",
    "fig.tight_layout()  # otherwise the right y-label is slightly clipped\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "#given V0 and kappa\n",
    "#sweep the reserve\n",
    "reserve = None\n",
    "reserve = np.arange(.01,100,.01)\n",
    "price = np.array([spot_price(r,kappa, V0) for r in reserve])\n",
    "\n",
    "#realized price for withdrawing burning .1% of tokens (without fee)\n",
    "burn_price=[withdraw(supply(r,kappa,V0)/1000, r,supply(r,kappa,V0), kappa, V0, 0)[1] for r in reserve]\n",
    "\n",
    "#realized price for depositing .1% more Xdai into the reserve (without fee)\n",
    "mint_price=[mint(r/1000, r, supply(r,kappa,V0), kappa, V0, 0)[1] for r in reserve]\n",
    "\n",
    "#realized price for withdrawing .1% of the Xdai from the reserve (without fee)\n",
    "withdraw_price=[withdrawR(r/1000, r, supply(r,kappa,V0), kappa, V0, 0)[1] for r in reserve]\n",
    "\n",
    "#realized price for depositing .1% more Xdai into the reserve (with fee)\n",
    "mint_price_fee=[mint(r/1000, r, supply(r,kappa,V0), kappa, V0, phi)[1] for r in reserve]\n",
    "\n",
    "#realized price for withdrawing .1% of the Xdai from the reserve (with fee)\n",
    "withdraw_price_fee=[withdrawR(r/1000, r, supply(r,kappa,V0), kappa, V0, phi)[1] for r in reserve]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "#from IPython.display import Image\n",
    "#Image(filename='slippage.jpeg')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "pdf = pd.DataFrame({'reserve':reserve, 'spot_price':price, '.1% mint_price':mint_price,'.1% withdraw_price':withdraw_price,'.1% mint_price w/fee':mint_price_fee,'.1% withdraw_price w/fee':withdraw_price_fee })"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>reserve</th>\n",
       "      <th>spot_price</th>\n",
       "      <th>.1% mint_price</th>\n",
       "      <th>.1% withdraw_price</th>\n",
       "      <th>.1% mint_price w/fee</th>\n",
       "      <th>.1% withdraw_price w/fee</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0.01</td>\n",
       "      <td>0.000020</td>\n",
       "      <td>0.000020</td>\n",
       "      <td>0.000020</td>\n",
       "      <td>0.000020</td>\n",
       "      <td>0.000020</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0.02</td>\n",
       "      <td>0.000033</td>\n",
       "      <td>0.000033</td>\n",
       "      <td>0.000033</td>\n",
       "      <td>0.000034</td>\n",
       "      <td>0.000034</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0.03</td>\n",
       "      <td>0.000045</td>\n",
       "      <td>0.000045</td>\n",
       "      <td>0.000045</td>\n",
       "      <td>0.000046</td>\n",
       "      <td>0.000046</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0.04</td>\n",
       "      <td>0.000056</td>\n",
       "      <td>0.000056</td>\n",
       "      <td>0.000056</td>\n",
       "      <td>0.000057</td>\n",
       "      <td>0.000057</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0.05</td>\n",
       "      <td>0.000066</td>\n",
       "      <td>0.000067</td>\n",
       "      <td>0.000066</td>\n",
       "      <td>0.000067</td>\n",
       "      <td>0.000067</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   reserve  spot_price  .1% mint_price  .1% withdraw_price  \\\n",
       "0     0.01    0.000020        0.000020            0.000020   \n",
       "1     0.02    0.000033        0.000033            0.000033   \n",
       "2     0.03    0.000045        0.000045            0.000045   \n",
       "3     0.04    0.000056        0.000056            0.000056   \n",
       "4     0.05    0.000066        0.000067            0.000066   \n",
       "\n",
       "   .1% mint_price w/fee  .1% withdraw_price w/fee  \n",
       "0              0.000020                  0.000020  \n",
       "1              0.000034                  0.000034  \n",
       "2              0.000046                  0.000046  \n",
       "3              0.000057                  0.000057  \n",
       "4              0.000067                  0.000067  "
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pdf.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.axes._subplots.AxesSubplot at 0x1a158cb358>"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 26792 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "pdf.plot(x='reserve')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "pdf['mint_slippage'] = (pdf['.1% mint_price']-pdf['spot_price'])/pdf['spot_price']\n",
    "pdf['withdraw_slippage'] = (pdf['spot_price']-pdf['.1% withdraw_price'])/pdf['spot_price']\n",
    "pdf['mint_slippage_fee'] = (pdf['.1% mint_price w/fee']-pdf['spot_price'])/pdf['spot_price']\n",
    "pdf['withdraw_slippage_fee'] = (pdf['spot_price']-pdf['.1% withdraw_price w/fee'])/pdf['spot_price']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[<matplotlib.axes._subplots.AxesSubplot object at 0x1a15fa37b8>,\n",
       "        <matplotlib.axes._subplots.AxesSubplot object at 0x1a15fcaba8>]],\n",
       "      dtype=object)"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 11716 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 12436 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "pdf[['mint_slippage', 'withdraw_slippage']].hist()\n",
    "pdf[['mint_slippage_fee', 'withdraw_slippage_fee']].hist()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/anaconda3/lib/python3.6/site-packages/ipykernel_launcher.py:43: RuntimeWarning: invalid value encountered in double_scalars\n"
     ]
    }
   ],
   "source": [
    "#given V0 and kappa\n",
    "R = 400\n",
    "S = supply(R,kappa,V0)\n",
    "p = spot_price(R,kappa,V0)\n",
    "#sweep the transaction fraction\n",
    "TXF = np.logspace(-6, 1, num=5000)\n",
    "\n",
    "#realized price for withdrawing txf of Xdai\n",
    "withdraw_price2=[withdrawR(R*txf, R,S, kappa, V0, 0)[1] for txf in TXF]\n",
    "withdraw_price2_fee=[withdrawR(R*txf, R,S, kappa, V0, phi)[1] for txf in TXF]\n",
    "\n",
    "#realized price for depositing txf more Xdai into the reserve\n",
    "mint_price2=[mint(R*txf, R,S, kappa, V0,0)[1] for txf in TXF]\n",
    "mint_price2_fee=[mint(R*txf, R,S, kappa, V0,phi)[1] for txf in TXF]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "pdf2 = pd.DataFrame({'tx_fraction':TXF, 'spot_price':p*np.ones(len(TXF)), 'mint_price':mint_price2,'withdraw_price':withdraw_price2, 'mint_price_fee':mint_price2_fee,'withdraw_price_fee':withdraw_price2_fee })"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.axes._subplots.AxesSubplot at 0x1a16041da0>"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 21388 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "pdf2.plot(x='tx_fraction',y=['mint_price','withdraw_price','mint_price_fee','withdraw_price_fee','spot_price'], logx=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "pdf2['bond_to_mint_slippage'] = (pdf2['mint_price']-pdf2['spot_price'])/pdf2['spot_price']\n",
    "pdf2['burn_to_withdraw_slippage'] = (pdf2['spot_price']-pdf2['withdraw_price'])/pdf2['spot_price']\n",
    "\n",
    "pdf2['bond_to_mint_slippage_fee'] = (pdf2['mint_price_fee']-pdf2['spot_price'])/pdf2['spot_price']\n",
    "pdf2['burn_to_withdraw_slippage_fee'] = (pdf2['spot_price']-pdf2['withdraw_price_fee'])/pdf2['spot_price']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "ticks=[10**k for k in range(-6,1)]\n",
    "bound = .026 #need to figure out this analytically in terms of kappa and phi"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Text(0.5, 0, 'Transaction size as percent of the asset Burned or Bonded\\nnormalizd units: bonded/Reserve, burned/Supply')"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 37852 characters]\n",
      "text/plain": [
       "<Figure size 720x216 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots(figsize=(10,3))\n",
    "ax.hlines(phi, TXF[0],TXF[-1], linestyle='--')\n",
    "ax.hlines(1, TXF[0],TXF[-1], linestyle='--')\n",
    "ax.vlines(bound, ticks[0],ticks[-1], linestyle='--')\n",
    "ax.vlines(1, ticks[0],ticks[-1], linestyle='--')\n",
    "pdf2.plot(x='tx_fraction', y = ['bond_to_mint_slippage', 'burn_to_withdraw_slippage'], logx=True, logy=True, ax=ax)\n",
    "plt.title(\"Friction for Bond and Withdraw accounting Without Fee\")\n",
    "plt.ylabel(\"\"\"Percentage Change:\n",
    "Realized Price\n",
    "Relative to Spot Price\"\"\")\n",
    "plt.yticks([10**k for k in range(-6,1)])\n",
    "plt.xlabel(\"\"\"Transaction size as percent of the asset Burned or Bonded\n",
    "normalizd units: bonded/Reserve, burned/Supply\"\"\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Text(0.5, 0, 'Transaction size as percent of the xDAI Reserve\\nnormalizd units: bonded/Reserve, withdraw/Reserve')"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 54496 characters]\n",
      "text/plain": [
       "<Figure size 720x360 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots(figsize=(10,5))\n",
    "ax.hlines(phi, TXF[0],TXF[-1], linestyle='--')\n",
    "ax.hlines(1, TXF[0],TXF[-1], linestyle='--')\n",
    "ax.vlines(bound, ticks[0],ticks[-1], linestyle='--')\n",
    "ax.vlines(1, ticks[0],ticks[-1], linestyle='--')\n",
    "pdf2.plot(x='tx_fraction', y = ['bond_to_mint_slippage', 'burn_to_withdraw_slippage','bond_to_mint_slippage_fee', 'burn_to_withdraw_slippage_fee'], logx=True, logy=True, ax=ax)\n",
    "plt.title(\"Friction for Bond and Withdraw accounting With and Without Fee, phi=\"+str(phi))\n",
    "plt.ylabel(\"\"\"Percentage Change:\n",
    "Realized Price\n",
    "Relative to Spot Price\"\"\")\n",
    "plt.yticks([10**k for k in range(-6,1)])\n",
    "plt.xlabel(\"\"\"Transaction size as percent of the xDAI Reserve\n",
    "normalizd units: bonded/Reserve, withdraw/Reserve\"\"\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[(0.01, 4.475559505492301), (0.02509430066318874, 10.0)]"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 57316 characters]\n",
      "text/plain": [
       "<Figure size 720x360 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots(figsize=(10,5))\n",
    "ax.hlines(phi, TXF[0],TXF[-1], linestyle='--')\n",
    "ax.hlines(1, TXF[0],TXF[-1], linestyle='--')\n",
    "ax.vlines(bound, ticks[0],ticks[-1], linestyle='--')\n",
    "ax.vlines(1, ticks[0],ticks[-1], linestyle='--')\n",
    "#ax.plot([ticks[0],ticks[-1]],[ticks[0]*phi,ticks[-1]*phi], 'k--')\n",
    "pdf2.plot(x='tx_fraction', y = ['bond_to_mint_slippage', 'burn_to_withdraw_slippage','bond_to_mint_slippage_fee', 'burn_to_withdraw_slippage_fee'], logx=True, logy=True, ax=ax)\n",
    "plt.title(\"Friction for Bond and Withdraw accounting With and Without Fee, phi=\"+str(phi))\n",
    "plt.ylabel(\"\"\"Percentage Change:\n",
    "Realized Price\n",
    "Relative to Spot Price\"\"\")\n",
    "plt.yticks(ticks)\n",
    "plt.xlabel(\"\"\"Transaction size as percent of the xDAI Reserve\n",
    "normalizd units: bonded/Reserve, withdraw/Reserve\"\"\")\n",
    "axis = ax.axis()\n",
    "ax.set(xlim=((1.0-(1.0-phi)**(1.0/kappa))*10, axis[1]), ylim=(phi, axis[3]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Text(0.5, 0, 'Transaction size as percent of the xDAI Reserve\\nnormalizd units: bonded/Reserve, withdraw/Reserve')"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 37260 characters]\n",
      "text/plain": [
       "<Figure size 720x216 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots(figsize=(10,3))\n",
    "ax.hlines(phi, TXF[0],TXF[-1], linestyle='--')\n",
    "ax.hlines(1, TXF[0],TXF[-1], linestyle='--')\n",
    "ax.vlines(bound, ticks[0],ticks[-1], linestyle='--')\n",
    "ax.vlines(1, ticks[0],ticks[-1], linestyle='--')\n",
    "pdf2.plot(x='tx_fraction', y = ['bond_to_mint_slippage_fee', 'burn_to_withdraw_slippage_fee'], logx=True, logy=True, ax=ax)\n",
    "plt.title(\"Friction for Bond and Withdraw accounting With Fee, phi=\"+str(phi))\n",
    "plt.ylabel(\"\"\"Percentage Change:\n",
    "Realized Price\n",
    "Relative to Spot Price\"\"\")\n",
    "plt.yticks(ticks)\n",
    "plt.xlabel(\"\"\"Transaction size as percent of the xDAI Reserve\n",
    "normalizd units: bonded/Reserve, withdraw/Reserve\"\"\")\n",
    "\n",
    "#axis = ax.axis()\n",
    "#ax.set(xlim=(bound*.99, axis[1]), ylim=(phi, axis[3]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[(0.01, 4.261370305570391), (0.02574, 10.0)]"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 37752 characters]\n",
      "text/plain": [
       "<Figure size 720x216 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots(figsize=(10,3))\n",
    "ax.hlines(phi, TXF[0],TXF[-1], linestyle='--')\n",
    "ax.hlines(1, TXF[0],TXF[-1], linestyle='--')\n",
    "ax.vlines(bound, ticks[0],ticks[-1], linestyle='--')\n",
    "ax.vlines(1, ticks[0],ticks[-1], linestyle='--')\n",
    "pdf2.plot(x='tx_fraction', y = ['bond_to_mint_slippage_fee', 'burn_to_withdraw_slippage_fee'], logx=True, logy=True, ax=ax)\n",
    "plt.title(\"Friction for Bond and Withdraw accounting With Fee, phi=\"+str(phi))\n",
    "plt.ylabel(\"\"\"Percentage Change:\n",
    "Realized Price\n",
    "Relative to Spot Price\"\"\")\n",
    "plt.yticks(ticks)\n",
    "plt.xlabel(\"\"\"Transaction size as percent of the asset Burned or Bonded\n",
    "normalizd units: bonded/Reserve, burned/Supply\"\"\")\n",
    "\n",
    "axis = ax.axis()\n",
    "ax.set(xlim=(bound*.99, axis[1]), ylim=(phi, axis[3]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "i am getting like 2.6% limiting slippage for burn to withdraw, need to reverse engineer analytics solution\n",
    "\n",
    "or Needs debugging"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.025"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "10*phi/4"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.02509430066318874"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(1-(1-phi)**(1/kappa))*10"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3162"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pdf2.burn_to_withdraw_slippage_fee.apply(np.abs).idxmin()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tx_fraction                      0.000011\n",
       "spot_price                       0.056234\n",
       "mint_price                       0.056234\n",
       "withdraw_price                   0.056234\n",
       "mint_price_fee                   0.056802\n",
       "withdraw_price_fee               0.056802\n",
       "bond_to_mint_slippage            0.000004\n",
       "burn_to_withdraw_slippage        0.000004\n",
       "bond_to_mint_slippage_fee        0.010105\n",
       "burn_to_withdraw_slippage_fee   -0.010097\n",
       "Name: 737, dtype: float64"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pdf2.iloc[737]"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "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.7.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
