contributions_to_token_batches(): takes desired_token_price as argument
TokenBatch: self.current_date to be set externally, unittests updated Commons unittest: initialization and burn()
This commit is contained in:
parent
dd98402875
commit
b77bb3a87e
23
hatch.py
23
hatch.py
|
|
@ -26,13 +26,14 @@ def hatch_raise_split_pools(total_hatch_raise, hatch_tribute) -> Tuple[float, fl
|
|||
collateral_pool = total_hatch_raise * (1-hatch_tribute)
|
||||
return funding_pool, collateral_pool
|
||||
|
||||
def contributions_to_token_batches(hatcher_contributions: List[int], initial_token_supply: int, vesting_80p_unlocked: int) -> List[float]:
|
||||
def contributions_to_token_batches(hatcher_contributions: List[int], desired_token_price: float, vesting_80p_unlocked: int) -> Tuple[List[float], float]:
|
||||
"""
|
||||
hatcher_contributions: a list of hatcher contributions
|
||||
initial_token_supply: NOT denominated in millions
|
||||
hatcher_contributions: a list of hatcher contributions in DAI/ETH/whatever
|
||||
desired_token_price: used to determine the initial token supply
|
||||
vesting_80p_unlocked: vesting parameter - the number of days after which 80% of tokens will be unlocked, including the cliff period
|
||||
"""
|
||||
total_hatch_raise = sum(hatcher_contributions)
|
||||
initial_token_supply = total_hatch_raise / desired_token_price
|
||||
|
||||
# In the hatch, everyone buys in at the same time, with the same price. So just split the token supply amongst the hatchers proportionally to their contributions
|
||||
tokens_per_hatcher = [(x / total_hatch_raise) * initial_token_supply for x in hatcher_contributions]
|
||||
|
|
@ -40,7 +41,7 @@ def contributions_to_token_batches(hatcher_contributions: List[int], initial_tok
|
|||
cliff_days, halflife_days = convert_80p_to_cliff_and_halflife(vesting_80p_unlocked)
|
||||
|
||||
token_batches = [TokenBatch(x, cliff_days, halflife_days, hatch=True) for x in tokens_per_hatcher]
|
||||
return token_batches
|
||||
return token_batches, initial_token_supply
|
||||
|
||||
class TokenBatch:
|
||||
def __init__(self, value: float, cliff_days: int, halflife_days: int, hatch = False):
|
||||
|
|
@ -51,16 +52,18 @@ class TokenBatch:
|
|||
self.halflife_days = halflife_days
|
||||
self.spent = 0
|
||||
|
||||
self.current_date = datetime.today() # to be set externally before each spend check
|
||||
|
||||
def __repr__(self):
|
||||
o = "TokenBatch {} {}, Unlocked: {}".format("Hatch" if self.hatch_tokens else "", self.value, self.unlocked_fraction(datetime.today()))
|
||||
o = "TokenBatch {} {}, Unlocked: {}".format("Hatch" if self.hatch_tokens else "", self.value, self.unlocked_fraction())
|
||||
return o
|
||||
|
||||
def unlocked_fraction(self, day: datetime = datetime.today()) -> float:
|
||||
def unlocked_fraction(self) -> float:
|
||||
"""
|
||||
returns what fraction of the TokenBatch is unlocked to date
|
||||
"""
|
||||
if self.hatch_tokens:
|
||||
days_delta = day - self.creation_date
|
||||
days_delta = self.current_date - self.creation_date
|
||||
u = vesting_curve(days_delta.days, self.cliff_days, self.halflife_days)
|
||||
return u if u > 0 else 0
|
||||
else:
|
||||
|
|
@ -72,7 +75,7 @@ class TokenBatch:
|
|||
returns the argument if successful for your convenience
|
||||
"""
|
||||
if x > self.spendable():
|
||||
raise Exception("Not so many tokens are available for you to spend yet!")
|
||||
raise Exception("Not so many tokens are available for you to spend yet ({})".format(self.current_date))
|
||||
|
||||
self.value -= x
|
||||
self.spent += x
|
||||
|
|
@ -118,8 +121,8 @@ class Commons:
|
|||
money_returned = dai
|
||||
|
||||
if self.exit_tribute:
|
||||
self._funding_pool += commons.exit_tribute * dai
|
||||
money_returned = (1-commons.exit_tribute) * dai
|
||||
self._funding_pool += self.exit_tribute * dai
|
||||
money_returned = (1-self.exit_tribute) * dai
|
||||
|
||||
return money_returned, realized_price
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ from hatch import *
|
|||
import unittest
|
||||
import datetime
|
||||
|
||||
class TestHatch(unittest.TestCase):
|
||||
class HatchTest(unittest.TestCase):
|
||||
def test_vesting_curve(self):
|
||||
self.assertEqual(vesting_curve(90, 90, 90), 0) # At Day 90, the cliff has just ended and the vesting curve has begun at 0
|
||||
self.assertEqual(vesting_curve(180, 90, 90), 0.5) # At Day 180, the cliff has ended and we are in the vesting curve, whose half-life is 90 as well, so at 180 we should get 0.5.
|
||||
|
|
@ -16,9 +16,11 @@ class TokenBatchTest(unittest.TestCase):
|
|||
tbh = TokenBatch(10000, 3, 3, True)
|
||||
tb = TokenBatch(10000, 5, 10, False)
|
||||
|
||||
self. assertEqual(tbh.unlocked_fraction(), 0)
|
||||
tbh.current_date = datetime.datetime.today() + datetime.timedelta(days=3)
|
||||
self.assertEqual(tbh.unlocked_fraction(), 0)
|
||||
self.assertEqual(tbh.unlocked_fraction(datetime.datetime.today() + datetime.timedelta(days=3)), 0)
|
||||
self.assertEqual(tbh.unlocked_fraction(datetime.datetime.today() + datetime.timedelta(days=6)), 0.5)
|
||||
tbh.current_date = datetime.datetime.today() + datetime.timedelta(days=6)
|
||||
self.assertEqual(tbh.unlocked_fraction(), 0.5)
|
||||
|
||||
self.assertEqual(tb.unlocked_fraction(), 1.0)
|
||||
|
||||
|
|
@ -39,22 +41,30 @@ class TokenBatchTest(unittest.TestCase):
|
|||
with self.assertRaises(Exception):
|
||||
tb.spend(10000)
|
||||
|
||||
class TestSystem(unittest.TestCase):
|
||||
def test_system(self):
|
||||
class CommonsTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
# 100,000 DAI invested for 1,000,000 tokens.
|
||||
desired_token_price = 0.1
|
||||
hatcher_contributions = [25000, 25000, 50000]
|
||||
token_supply_initial = sum(hatcher_contributions) / desired_token_price
|
||||
token_batches = contributions_to_token_batches(hatcher_contributions, token_supply_initial, 90)
|
||||
self.desired_token_price = 0.1
|
||||
self.hatcher_contributions = [25000, 25000, 50000]
|
||||
self.token_batches, self.token_supply_initial = contributions_to_token_batches(self.hatcher_contributions, self.desired_token_price, 90)
|
||||
|
||||
# Because of hatch_tribute, the collateral_pool is 0.7e6. This causes the token's post-hatch price to be 0.14.
|
||||
o = Commons(sum(hatcher_contributions), token_supply_initial, hatch_tribute=0.3)
|
||||
self.assertEqual(o._collateral_pool, 70000)
|
||||
self.assertEqual(o._funding_pool, 30000)
|
||||
self.assertEqual(o._token_supply, token_supply_initial)
|
||||
self.commons = Commons(sum(self.hatcher_contributions), self.token_supply_initial, hatch_tribute=0.3)
|
||||
|
||||
self.assertEqual(o.token_price(), 0.14)
|
||||
print(token_batches)
|
||||
# print(o.deposit(100))
|
||||
# print(o.token_price())
|
||||
# print(o._collateral_pool)
|
||||
def test_initialization(self):
|
||||
self.assertEqual(self.commons._collateral_pool, 70000)
|
||||
self.assertEqual(self.commons._funding_pool, 30000)
|
||||
self.assertEqual(self.commons._token_supply, self.token_supply_initial)
|
||||
|
||||
self.assertEqual(self.commons.token_price(), 0.14)
|
||||
|
||||
def test_burn_without_exit_tribute(self):
|
||||
old_token_supply = self.commons._token_supply
|
||||
old_collateral_pool = self.commons._collateral_pool
|
||||
|
||||
money_returned, realized_price = self.commons.burn(50000)
|
||||
|
||||
self.assertEqual(money_returned, 6825.0)
|
||||
self.assertEqual(realized_price, 0.1365)
|
||||
self.assertEqual(self.commons._token_supply, old_token_supply-50000)
|
||||
self.assertEqual(self.commons._collateral_pool, old_collateral_pool-money_returned)
|
||||
Loading…
Reference in New Issue