renamed one letter vars in abcurve

This commit is contained in:
Andrew Chiw 2020-04-21 16:14:30 +02:00
parent a12b6c2279
commit f6a9f8011f
2 changed files with 67 additions and 74 deletions

View File

@ -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)

View File

@ -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)