renamed one letter vars in abcurve
This commit is contained in:
parent
a12b6c2279
commit
f6a9f8011f
95
abcurve.py
95
abcurve.py
|
|
@ -1,76 +1,65 @@
|
||||||
#value function for a given state (R,S)
|
#value function for a given state (reserve,supply)
|
||||||
def invariant(R,S,kappa):
|
def invariant(reserve,supply,kappa):
|
||||||
return (S**kappa)/R
|
return (supply**kappa)/reserve
|
||||||
|
|
||||||
#given a value function (parameterized by kappa)
|
#given a value function (parameterized by kappa)
|
||||||
#and an invariant coeficient V0
|
#and an invariant coefficient invariant
|
||||||
#return Supply S as a function of reserve R
|
#return Supply supply as a function of reserve
|
||||||
def supply(R, kappa, V0):
|
def supply(reserve, kappa, invariant):
|
||||||
return (V0*R)**(1/kappa)
|
return (invariant*reserve)**(1/kappa)
|
||||||
|
|
||||||
#given a value function (parameterized by kappa)
|
#given a value function (parameterized by kappa)
|
||||||
#and an invariant coeficient V0
|
#and an invariant coeficient invariant
|
||||||
#return a spot price P as a function of reserve R
|
#return a spot price P as a function of reserve
|
||||||
def spot_price(R, kappa, V0):
|
def spot_price(reserve, kappa, invariant):
|
||||||
return kappa*R**((kappa-1)/kappa)/V0**(1/kappa)
|
return kappa*reserve**((kappa-1)/kappa)/invariant**(1/kappa)
|
||||||
|
|
||||||
#for a given state (R,S)
|
#for a given state (reserve,supply)
|
||||||
#given a value function (parameterized by kappa)
|
#given a value function (parameterized by kappa)
|
||||||
#and an invariant coeficient V0
|
#and an invariant coeficient invariant
|
||||||
#deposit deltaR to Mint deltaS
|
#deposit d_reserve to Mint d_supply
|
||||||
#with realized price deltaR/deltaS
|
#with realized price d_reserve/d_supply
|
||||||
def mint(deltaR, R,S, kappa, V0):
|
def mint(d_reserve, reserve,supply, kappa, invariant):
|
||||||
deltaS = (V0*(R+deltaR))**(1/kappa)-S
|
d_supply = (invariant*(reserve+d_reserve))**(1/kappa)-supply
|
||||||
realized_price = deltaR/deltaS
|
realized_price = d_reserve/d_supply
|
||||||
return deltaS, realized_price
|
return d_supply, realized_price
|
||||||
|
|
||||||
#for a given state (R,S)
|
#for a given state (reserve,supply)
|
||||||
#given a value function (parameterized by kappa)
|
#given a value function (parameterized by kappa)
|
||||||
#and an invariant coeficient V0
|
#and an invariant coeficient invariant
|
||||||
#burn deltaS to Withdraw deltaR
|
#burn d_supply to Withdraw d_reserve
|
||||||
#with realized price deltaR/deltaS
|
#with realized price d_reserve/d_supply
|
||||||
def withdraw(deltaS, R,S, kappa, V0):
|
def withdraw(d_supply, reserve,supply, kappa, invariant):
|
||||||
deltaR = R-((S-deltaS)**kappa)/V0
|
d_reserve = reserve-((supply-d_supply)**kappa)/invariant
|
||||||
realized_price = deltaR/deltaS
|
realized_price = d_reserve/d_supply
|
||||||
return deltaR, realized_price
|
return d_reserve, realized_price
|
||||||
|
|
||||||
class AugmentedBondingCurve:
|
class AugmentedBondingCurve:
|
||||||
def __init__(self, initial_reserve, initial_token_supply, kappa=2):
|
def __init__(self, reserve_initial, token_supply_initial, kappa=2):
|
||||||
"""Create a stateful bonding curve.
|
"""Create a stateless bonding curve.
|
||||||
|
|
||||||
initial_reserve (millions of DAI)
|
reserve_initial (millions of DAI)
|
||||||
initial_token_supply (millions)
|
token_supply_initial (millions)
|
||||||
kappa (the exponent part of the curve, default is 2)
|
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.kappa = kappa
|
||||||
self.invariant = (self.initial_token_supply**kappa) / self.initial_reserve
|
self.invariant = invariant(reserve_initial, token_supply_initial, kappa)
|
||||||
|
|
||||||
def __repr__(self):
|
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())
|
return "ABC Kappa: {}, Invariant: {}".format(self.kappa, self.invariant)
|
||||||
|
|
||||||
def deposit(self, dai_million):
|
def deposit(self, dai_millions, current_reserve, current_token_supply):
|
||||||
# Returns number of new tokens minted, and their realized price
|
# 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)
|
tokens, realized_price = mint(dai_millions, current_reserve, current_token_supply, self.kappa, self.invariant)
|
||||||
|
|
||||||
self.current_reserve += dai_million
|
|
||||||
self.current_token_supply += tokens
|
|
||||||
return tokens, realized_price
|
return tokens, realized_price
|
||||||
|
|
||||||
def burn(self, tokens_million):
|
def burn(self, tokens_millions, current_reserve, current_token_supply):
|
||||||
# Returns number of DAI that will be returned (excluding exit tribute) when the user burns their tokens, with their realized price
|
# 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)
|
dai_millions, realized_price = withdraw(tokens_millions, current_reserve, current_token_supply, self.kappa, self.invariant)
|
||||||
self.current_reserve -= dai_million
|
return dai_millions, realized_price
|
||||||
self.current_token_supply -= tokens_million
|
|
||||||
return dai_million, realized_price
|
|
||||||
|
|
||||||
def get_token_price(self):
|
def get_token_price(self, current_reserve):
|
||||||
return spot_price(self.current_reserve, self.kappa, self.invariant)
|
return spot_price(current_reserve, self.kappa, self.invariant)
|
||||||
|
|
||||||
def get_token_supply(self):
|
def get_token_supply(self, current_reserve):
|
||||||
return supply(self.current_reserve, self.kappa, self.invariant)
|
return supply(current_reserve, self.kappa, self.invariant)
|
||||||
|
|
|
||||||
|
|
@ -1,43 +1,47 @@
|
||||||
from abcurve import AugmentedBondingCurve
|
from abcurve import AugmentedBondingCurve, invariant, supply, spot_price, mint, withdraw
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
|
class TestOriginalEquations(unittest.TestCase):
|
||||||
|
def test_magnitude_orders(self):
|
||||||
|
# The equations are supposed to be used with 1 (million).
|
||||||
|
# But this makes things impractical from a programming perspective because you don't want to remember which variable is denoted in units what.
|
||||||
|
# Hopefully things work just the same if you put in 1000,000,000 instead of 1e3.
|
||||||
|
r = 10000
|
||||||
|
s = 1000000
|
||||||
|
kappa = 2
|
||||||
|
i = invariant(r, s, kappa)
|
||||||
|
print(i)
|
||||||
|
|
||||||
class TestAugmentedBondingCurve(unittest.TestCase):
|
class TestAugmentedBondingCurve(unittest.TestCase):
|
||||||
def test_get_token_supply(self):
|
def test_get_token_supply(self):
|
||||||
# R = 1, S0 = 1, V0 = 1.0, kappa = 2 should give this data:
|
# 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]
|
# [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)
|
abc = AugmentedBondingCurve(1, 1, kappa=2)
|
||||||
self.assertEqual(abc.get_token_supply(), 1)
|
self.assertEqual(abc.get_token_supply(1), 1)
|
||||||
|
|
||||||
abc.current_reserve = 2
|
self.assertEqual(abc.get_token_supply(2), 1.4142135623730951)
|
||||||
self.assertEqual(abc.get_token_supply(), 1.4142135623730951)
|
|
||||||
|
|
||||||
def test_get_token_price(self):
|
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]
|
# [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)
|
abc = AugmentedBondingCurve(1, 1, kappa=2)
|
||||||
self.assertEqual(abc.get_token_price(), 2.0)
|
self.assertEqual(abc.get_token_price(1), 2.0)
|
||||||
|
|
||||||
abc.current_reserve = 2
|
self.assertEqual(abc.get_token_price(2), 2.8284271247461903)
|
||||||
self.assertEqual(abc.get_token_price(), 2.8284271247461903)
|
|
||||||
|
|
||||||
def test_deposit(self):
|
def test_deposit(self):
|
||||||
abc = AugmentedBondingCurve(1, 1, kappa=2)
|
abc = AugmentedBondingCurve(1, 1, kappa=2)
|
||||||
old_current_reserve = abc.current_reserve
|
old_current_reserve = 1
|
||||||
old_token_supply = abc.current_token_supply
|
old_token_supply = 1
|
||||||
# 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)
|
# print(abc)
|
||||||
|
# Deposit 4 million DAI, given that the current reserve pool is 1 million DAI and there are 1 million tokens
|
||||||
|
tokens, realized_price = abc.deposit(4, 1, 1)
|
||||||
|
print("The current price is", realized_price, "and you will get", tokens, "million tokens")
|
||||||
|
self.assertEqual(tokens, 1.2360679774997898)
|
||||||
|
self.assertEqual(realized_price, 3.2360679774997894)
|
||||||
|
|
||||||
def test_burn(self):
|
def test_burn(self):
|
||||||
abc = AugmentedBondingCurve(1, 1, kappa=2)
|
abc = AugmentedBondingCurve(1, 1, kappa=2)
|
||||||
|
|
||||||
dai_million_returned, realized_price = abc.burn(0.5)
|
dai_million_returned, realized_price = abc.burn(0.5, 1, 1)
|
||||||
self.assertEqual(dai_million_returned, 0.75)
|
self.assertEqual(dai_million_returned, 0.75)
|
||||||
self.assertEqual(realized_price, 1.5)
|
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)
|
|
||||||
Loading…
Reference in New Issue