77 lines
2.9 KiB
Python
77 lines
2.9 KiB
Python
#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
|
|
|
|
class AugmentedBondingCurve:
|
|
def __init__(self, initial_reserve, initial_token_supply, kappa=2):
|
|
"""Create a stateful bonding curve.
|
|
|
|
initial_reserve (millions of DAI)
|
|
initial_token_supply (millions)
|
|
kappa (the exponent part of the curve, default is 2)
|
|
"""
|
|
self.initial_reserve = initial_reserve
|
|
self.initial_token_supply = initial_token_supply
|
|
|
|
self.current_reserve = self.initial_reserve
|
|
self.current_token_supply = self.initial_token_supply
|
|
|
|
self.kappa = kappa
|
|
self.invariant = (self.initial_token_supply**kappa) / self.initial_reserve
|
|
|
|
def __repr__(self):
|
|
return "ABC Reserve {} million; Token_Supply {} million; Current Token Price {}".format(self.current_reserve, self.current_token_supply, self.get_token_price())
|
|
|
|
def deposit(self, dai_million):
|
|
# Returns number of new tokens minted, and their realized price
|
|
tokens, realized_price = mint(dai_million, self.current_reserve, self.current_token_supply, self.kappa, self.invariant)
|
|
|
|
self.current_reserve += dai_million
|
|
self.current_token_supply += tokens
|
|
return tokens, realized_price
|
|
|
|
def burn(self, tokens_million):
|
|
# Returns number of DAI that will be returned (excluding exit tribute) when the user burns their tokens, with their realized price
|
|
dai_million, realized_price = withdraw(tokens_million, self.current_reserve, self.current_token_supply, self.kappa, self.invariant)
|
|
self.current_reserve -= dai_million
|
|
self.current_token_supply -= tokens_million
|
|
return dai_million, realized_price
|
|
|
|
def get_token_price(self):
|
|
return spot_price(self.current_reserve, self.kappa, self.invariant)
|
|
|
|
def get_token_supply(self):
|
|
return supply(self.current_reserve, self.kappa, self.invariant)
|