initial commit of AugmentedBondingCurve

This commit is contained in:
Andrew Chiw 2020-03-25 01:11:48 +01:00
commit 110d449cac
2 changed files with 119 additions and 0 deletions

76
abcurve.py Normal file
View File

@ -0,0 +1,76 @@
#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)

43
abcurve_test.py Normal file
View File

@ -0,0 +1,43 @@
from abcurve import AugmentedBondingCurve
import unittest
class TestAugmentedBondingCurve(unittest.TestCase):
def test_get_token_supply(self):
# R = 1, S0 = 1, V0 = 1.0, kappa = 2 should give this data:
# [0 1 2 3 4 5 6 7 8 9] -> [0.0, 1.0, 1.4142135623730951, 1.7320508075688772, 2.0, 2.23606797749979, 2.449489742783178, 2.6457513110645907, 2.8284271247461903, 3.0]
abc = AugmentedBondingCurve(1, 1, kappa=2)
self.assertEqual(abc.get_token_supply(), 1)
abc.current_reserve = 2
self.assertEqual(abc.get_token_supply(), 1.4142135623730951)
def test_get_token_price(self):
# [0 1 2 3 4 5 6 7 8 9] -> [0.0, 0.02, 0.0282842712474619, 0.034641016151377546, 0.04, 0.044721359549995794, 0.04898979485566356, 0.052915026221291815, 0.0565685424949238, 0.06]
abc = AugmentedBondingCurve(1, 1, kappa=2)
self.assertEqual(abc.get_token_price(), 2.0)
abc.current_reserve = 2
self.assertEqual(abc.get_token_price(), 2.8284271247461903)
def test_deposit(self):
abc = AugmentedBondingCurve(1, 1, kappa=2)
old_current_reserve = abc.current_reserve
old_token_supply = abc.current_token_supply
# print(abc)
tokens, realized_price = abc.deposit(4)
# print("The current price is", realized_price, "and you will get", tokens, "million tokens")
self.assertEqual(abc.current_token_supply, old_token_supply + tokens)
self.assertEqual(abc.current_reserve, old_current_reserve + 4)
# print(abc)
def test_burn(self):
abc = AugmentedBondingCurve(1, 1, kappa=2)
dai_million_returned, realized_price = abc.burn(0.5)
self.assertEqual(dai_million_returned, 0.75)
self.assertEqual(realized_price, 1.5)
self.assertEqual(abc.current_reserve, 0.25)
self.assertEqual(abc.current_token_supply, 0.5)
self.assertLess(abc.current_reserve, abc.initial_reserve)
self.assertLess(abc.current_token_supply, abc.initial_token_supply)