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
Analysis of Augmented Bonding curve subsystem for "Commons Stack"
Notebook header cell:
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
%matplotlib inline
#integer_units = 10**12 #account for decimal places to a token
#scale_units = 10**6 #millions of tokens, million of DAI
#mu = integer_units*scale_units
#value function for a given state (R,S)
def invariant(R,S,kappa):
return (S**kappa)/R
#given a value function (parameterized by kappa)
#and an invariant coeficient V0
#return Supply S as a function of reserve R
def supply(R, kappa, V0):
return (V0*R)**(1/kappa)
#given a value function (parameterized by kappa)
#and an invariant coeficient V0
#return a spot price P as a function of reserve R
def spot_price(R, kappa, V0):
return kappa*R**((kappa-1)/kappa)/V0**(1/kappa)
#for a given state (R,S)
#given a value function (parameterized by kappa)
#and an invariant coeficient V0
#deposit deltaR to Mint deltaS
#with realized price deltaR/deltaS
def mint(deltaR, R,S, kappa, V0):
deltaS = (V0*(R+deltaR))**(1/kappa)-S
realized_price = deltaR/deltaS
return deltaS, realized_price
#for a given state (R,S)
#given a value function (parameterized by kappa)
#and an invariant coeficient V0
#burn deltaS to Withdraw deltaR
#with realized price deltaR/deltaS
def withdraw(deltaS, R,S, kappa, V0):
deltaR = R-((S-deltaS)**kappa)/V0
realized_price = deltaR/deltaS
return deltaR, realized_price
d0 = 5 #million DAI
p0 = .01 #DAI per tokens
theta = .4
R0 = d0*(1-theta) #million DAI
S0 = d0/p0
kappa = 6
V0 = invariant(R0,S0,kappa)
reserve = np.arange(0,100,.01)
supp = np.array([supply(r,kappa, V0) for r in reserve])
price = np.array([spot_price(r,kappa, V0) for r in reserve])
fig, ax1 = plt.subplots()
color = 'tab:red'
ax1.set_xlabel('Reserve (Millions of xDAI)')
ax1.set_ylabel('Supply (Millions of Tokens)', color=color)
ax1.plot(reserve, supp,'--', color=color)
ax1.tick_params(axis='y', labelcolor=color)
ax2 = ax1.twinx() # instantiate a second axes that shares the same x-axis
color = 'tab:blue'
ax2.set_ylabel('Price in xDAI per Token', color=color) # we already handled the x-label with ax1
ax2.plot(reserve, price,'-.', color=color)
ax2.tick_params(axis='y', labelcolor=color)
ax1.vlines(R0,0,supp[-1], alpha=.5)
ax1.text(R0+.02*reserve[-1], supp[-1], "Initial Value R="+str(int(100*R0)/100)+" mil xDAI")
ax1.text(R0+.02*reserve[-1], .95*supp[-1], "Initial Value S="+str(S0)+" mil Tokens")
#ax1.hlines(S0,0,R0)
ax2.text(R0+.02*reserve[-1], price[3], "Initial Value p1="+str(int(100*spot_price(R0,kappa,V0))/100))
plt.title('Augmented Bonding Curve with Invariant S^'+str(kappa)+'/R')
fig.tight_layout() # otherwise the right y-label is slightly clipped
plt.show()
fig, ax1 = plt.subplots()
cp = 100
color = 'tab:red'
ax1.set_xlabel('Supply (Millions of Tokens)')
ax1.set_ylabel('Reserve (Millions of xDAI)', color=color)
ax1.plot(supp[cp:], reserve[cp:],'--', color=color)
ax1.tick_params(axis='y', labelcolor=color)
ax2 = ax1.twinx() # instantiate a second axes that shares the same x-axis
color = 'tab:blue'
ax2.set_ylabel('Price in xDAI per Token', color=color) # we already handled the x-label with ax1
ax2.plot(supp[cp:], price[cp:],'-.', color=color)
ax2.tick_params(axis='y', labelcolor=color)
ax1.vlines(S0,0,reserve[-1], alpha=.5)
ax1.text(S0*1.02, reserve[-1], "Initial Value S="+str(int(100*S0)/100)+" mil tokens")
ax1.text(S0*1.02, .95*reserve[-1], "Initial Value R="+str(R0)+" mil xDAI")
#ax1.hlines(S0,0,R0)
ax2.text(S0*1.02, price[3], "Initial Value p1="+str(int(100*spot_price(R0,kappa,V0))/100))
plt.title('Augmented Bonding Curve with Invariant S^'+str(kappa)+'/R')
fig.tight_layout() # otherwise the right y-label is slightly clipped
plt.show()
#given V0 and kappa
#sweep the reserve
reserve = None
reserve = np.arange(.01,100,.01)
price = np.array([spot_price(r,kappa, V0) for r in reserve])
#realized price for withdrawing burning .1% of tokens
withdraw_price=[withdraw(supply(r,kappa,V0)/1000, r,supply(r,kappa,V0), kappa, V0)[1] for r in reserve]
#realized price for depositing .1% more Xdai into the reserve
mint_price=[mint(r/1000, r, supply(r,kappa,V0), kappa, V0)[1] for r in reserve]
from IPython.display import Image
Image(filename='slippage.jpeg')
pdf = pd.DataFrame({'reserve':reserve, 'spot_price':price, '.1% mint_price':mint_price,'.1% withdraw_price':withdraw_price })
pdf.plot(x='reserve')
<matplotlib.axes._subplots.AxesSubplot at 0x1a21eee160>
pdf['mint_slippage'] = (pdf['.1% mint_price']-pdf['spot_price'])/pdf['spot_price']
pdf['withdraw_slippage'] = (pdf['spot_price']-pdf['.1% withdraw_price'])/pdf['spot_price']
pdf.plot(x='reserve', y = ['mint_slippage', 'withdraw_slippage'])#, logy=True)
<matplotlib.axes._subplots.AxesSubplot at 0x1a22526358>
#given V0 and kappa
R = 20
S = supply(R,kappa,V0)
p = spot_price(R,kappa,V0)
#sweep the transaction fraction
TXF = np.logspace(-6, 0, num=1000)
#realized price for withdrawing burning .1% of tokens
withdraw_price2=[withdraw(S*txf, R,S, kappa, V0)[1] for txf in TXF]
#realized price for depositing .1% more Xdai into the reserve
mint_price2=[mint(R*txf, R,S, kappa, V0)[1] for txf in TXF]
print(S)
685.9431568581422
pdf2 = pd.DataFrame({'tx_fraction':TXF, 'spot_price':p*np.ones(len(TXF)), 'mint_price':mint_price2,'withdraw_price':withdraw_price2 })
pdf2.plot(x='tx_fraction',y=['mint_price','withdraw_price','spot_price'], logx=True)
<matplotlib.axes._subplots.AxesSubplot at 0x1a2255b780>
pdf2['mint_slippage'] = (pdf2['mint_price']-pdf2['spot_price'])/pdf2['spot_price']
pdf2['withdraw_slippage'] = (pdf2['spot_price']-pdf2['withdraw_price'])/pdf2['spot_price']
pdf2.plot(x='tx_fraction', y = ['mint_slippage', 'withdraw_slippage'], logx=True, logy=True)
<matplotlib.axes._subplots.AxesSubplot at 0x1a22b0ae48>
Kappa_List = [2,4,6,8]
for kappa in Kappa_List:
V0 = invariant(R0,S0,kappa)
reserve = np.arange(0,100,.01)
supp = np.array([supply(r,kappa, V0) for r in reserve])
price = np.array([spot_price(r,kappa, V0) for r in reserve])
fig, ax1 = plt.subplots()
color = 'tab:red'
ax1.set_xlabel('Reserve (Millions of xDAI)')
ax1.set_ylabel('Supply (Millions of Tokens)', color=color)
ax1.plot(reserve, supp,'--', color=color)
ax1.tick_params(axis='y', labelcolor=color)
ax2 = ax1.twinx() # instantiate a second axes that shares the same x-axis
color = 'tab:blue'
ax2.set_ylabel('Price in xDAI per Token', color=color) # we already handled the x-label with ax1
ax2.plot(reserve, price,'-.', color=color)
ax2.tick_params(axis='y', labelcolor=color)
ax1.vlines(R0,0,supp[-1], alpha=.5)
ax1.text(R0+.02*reserve[-1], supp[-1], "Initial Value R="+str(int(100*R0)/100)+" mil xDAI")
ax1.text(R0+.02*reserve[-1], .95*supp[-1], "Initial Value S="+str(int(100*S0)/100)+" mil Tokens")
#ax1.hlines(S0,0,R0)
ax2.text(R0+.02*reserve[-1], price[3], "Initial Value p1="+str(int(1000*spot_price(R0,kappa,V0))/1000))
plt.title('Augmented Bonding Curve with Invariant S^'+str(kappa)+'/R')
fig.tight_layout() # otherwise the right y-label is slightly clipped
plt.show()
#Power function independent variables for analysis
vec_d0 = np.arange(2.5,5.1,.1) #millon dai
vec_theta = np.arange(.1,.55,.05) #unitless
mat_R0 = np.outer(vec_d0.T, (1-vec_theta)) #million dai
vec_p0 = np.arange(.01,.11,.01) #dai per token
mat_S0 = np.outer(vec_d0.T, vec_p0) #milion tokens
vec_kappa = np.arange(2,9,1) #integer
mat_return_ratio = np.outer(vec_kappa.T, (1-vec_theta))
p0_lab = [str(int(100*p)/100) for p in vec_p0]
th_lab = [str(int(100*th)/100) for th in vec_theta]
k_lab = [str(k) for k in vec_kappa]
sns.heatmap(mat_return_ratio.T,yticklabels=th_lab, xticklabels=k_lab, annot=True)
plt.yticks(rotation=0)
plt.xlabel('Invariant Power: Kappa')
plt.ylabel('Funding Pool Fraction: Theta')
plt.title('Hatch Return Rate p1/p0')
Text(0.5, 1.0, 'Hatch Return Rate p1/p0')
d_lab = [str(int(100*d)/100) for d in vec_d0]
sns.heatmap(vec_d0-mat_R0.T,yticklabels=th_lab, xticklabels=d_lab)#, annot=True)
plt.yticks(rotation=0)
plt.xlabel('Initial Fundraise: d0 (Millions of xDAI)')
plt.ylabel('Funding Pool Fraction: Theta')
plt.title('Funding Pool Funds at Launch (Millions of xDAI)')
Text(0.5, 1.0, 'Funding Pool Funds at Launch (Millions of xDAI)')
d_lab = [str(int(100*d)/100) for d in vec_d0]
sns.heatmap(mat_R0.T,yticklabels=th_lab, xticklabels=d_lab)#, annot=True)
plt.yticks(rotation=0)
plt.title('Initial Reserve: R0 (Millions of xDAI)')
plt.ylabel('Funding Pool Fraction: Theta')
plt.xlabel('Intial Raise d0 (Millions of xDAI)')
Text(0.5, 15.0, 'Intial Raise d0 (Millions of xDAI)')
sns.heatmap(mat_S0.T,yticklabels=p0_lab, xticklabels=d_lab)#, annot=True)
plt.yticks(rotation=0)
plt.title('Initial Supply: S0 (Millions of Tokens)')
plt.ylabel('Hatch Sale Price: p0 (xDAI per Token)')
plt.xlabel('Intial Raise d0 (Millions of xDAI)')
Text(0.5, 15.0, 'Intial Raise d0 (Millions of xDAI)')