Skip to content

Commit

Permalink
test: add liquidity
Browse files Browse the repository at this point in the history
  • Loading branch information
AlbertoCentonze committed Feb 12, 2025
1 parent 520b84d commit 12c82f7
Show file tree
Hide file tree
Showing 3 changed files with 232 additions and 0 deletions.
85 changes: 85 additions & 0 deletions tests/unitary/pool/test_stableswap_invariant.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import pytest
import boa

from tests.unitary.utils import GodModePool

factory_deployer = boa.load_partial("contracts/main/TwocryptoFactory.vy")
s_amm_deployer = boa.load_partial("contracts/stableswap_invariant/TwocryptoStableswap.vy")
s_math_deployer = boa.load_partial("contracts/stableswap_invariant/TwocryptoStableswapMath.vy")


@pytest.fixture
def factory():
_deployer = boa.env.generate_address()
_fee_receiver = boa.env.generate_address()
_owner = boa.env.generate_address()

# assume(_fee_receiver != _owner != _deployer)

with boa.env.prank(_deployer):
amm_implementation = s_amm_deployer.deploy_as_blueprint()
# gauge_implementation = gauge_deployer.deploy_as_blueprint()

# view_contract = view_deployer.deploy()
math_contract = s_math_deployer.deploy()
print(math_contract.address)

_factory = factory_deployer.deploy()
_factory.initialise_ownership(_fee_receiver, _owner)

with boa.env.prank(_owner):
_factory.set_pool_implementation(amm_implementation, 0)
# _factory.set_gauge_implementation(gauge_implementation)
# _factory.set_views_implementation(view_contract)
_factory.set_math_implementation(math_contract)

return _factory


@pytest.fixture()
def tokens():
tgen = boa.load_partial(
"contracts/mocks/ERC20Mock.vy",
)
return [tgen("test", "test", 18), tgen("test", "test", 18)]


@pytest.fixture
def stable_pool(
factory,
params,
tokens,
):
print(params)
print(tokens)
"""Creates a factory based pool with the following fuzzed parameters:
Custom strategies can be passed as argument to override the default
"""

pool = factory.deploy_pool(
"stateful simulation",
"SIMULATION",
tokens,
0,
params["A"],
params["gamma"],
params["mid_fee"],
params["out_fee"],
params["fee_gamma"],
params["allowed_extra_profit"],
params["adjustment_step"],
params["ma_time"],
params["initial_prices"][
1
], # TODO careful started on diff prices even tho stableswap invariant is used
)

pool = s_amm_deployer.at(pool)

return GodModePool(pool, tokens)


def test_simple(stable_pool):
amounts = [10**18, 10**18]

stable_pool.add_liquidity(amounts)
52 changes: 52 additions & 0 deletions tests/unitary/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import boa

from tests.utils.tokens import mint_for_testing

god = boa.env.generate_address()


class GodModePool:
def __init__(self, instance, coins):
self.instance = instance
self.coins = coins
self.plotting = {}
for c in self.coins:
c.approve(self.instance, 2**256 - 1, sender=god)

def __getattr__(self, name):
return getattr(self.instance, name)

def donate(self, amounts, update_ema=False):
self.__premint_amounts(amounts)

self.instance.donate(amounts, sender=god)

if update_ema:
self.__update_ema()

def exchange(self, i, dx, update_ema=False):
if i == 0:
amounts = [dx, 0]
else:
amounts = [0, dx]
self.__premint_amounts(amounts)

self.instance.exchange(i, 1 - i, dx, 0, sender=god)

if update_ema:
self.__update_ema()

def add_liquidity(self, amounts, update_ema=False):
self.__premint_amounts(amounts)

self.instance.add_liquidity(amounts, 0, sender=god)

if update_ema:
self.__update_ema()

def __premint_amounts(self, amounts):
for c, amount in zip(self.coins, amounts):
mint_for_testing(c, god, amount)

def __update_ema(self):
boa.env.time_travel(seconds=86400 * 7)
95 changes: 95 additions & 0 deletions tests/utils/strategies.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,3 +180,98 @@ def pool_from_preset(draw, preset=sampled_from(all_presets)):
ma_exp_time=just(params["ma_exp_time"]),
)
)


# TODO no need to have these as separate strategies, reduce code duplication
s_amm_deployer = boa.load_partial("contracts/stableswap_invariant/TwocryptoStableswap.vy")
s_math_deployer = boa.load_partial("contracts/stableswap_invariant/TwocryptoStableswapMath.vy")


@composite
def stableswap_factory(
draw,
):
_deployer = draw(deployer)
_fee_receiver = draw(fee_receiver)
_owner = draw(owner)

assume(_fee_receiver != _owner != _deployer)

with boa.env.prank(_deployer):
amm_implementation = s_amm_deployer.deploy_as_blueprint()
gauge_implementation = gauge_deployer.deploy_as_blueprint()

view_contract = view_deployer.deploy()
math_contract = s_math_deployer.deploy()

_factory = factory_deployer.deploy()
_factory.initialise_ownership(_fee_receiver, _owner)

with boa.env.prank(_owner):
_factory.set_pool_implementation(amm_implementation, 0)
_factory.set_gauge_implementation(gauge_implementation)
_factory.set_views_implementation(view_contract)
_factory.set_math_implementation(math_contract)

return _factory


@composite
def stable_pool(
draw,
A=A,
gamma=gamma,
fees=fees(),
fee_gamma=fee_gamma,
allowed_extra_profit=allowed_extra_profit,
adjustment_step=adjustment_step,
ma_exp_time=ma_exp_time,
price=price,
):
"""Creates a factory based pool with the following fuzzed parameters:
Custom strategies can be passed as argument to override the default
"""

# Creates a factory based pool with the following fuzzed parameters:
_factory = draw(stableswap_factory())
mid_fee, out_fee = draw(fees)

# TODO should test weird tokens as well (non-standard/non-compliant)
tokens = [draw(token), draw(token)]

with boa.env.prank(draw(deployer)):
_pool = _factory.deploy_pool(
"stateful simulation",
"SIMULATION",
tokens,
0,
draw(A),
draw(gamma),
mid_fee,
out_fee,
draw(fee_gamma),
draw(allowed_extra_profit),
draw(adjustment_step),
draw(ma_exp_time),
draw(price),
)

_pool = s_amm_deployer.at(_pool)

note(
"deployed pool with "
+ "A: {:.2e}".format(_pool.A())
+ ", gamma: {:.2e}".format(_pool.gamma())
+ ", price: {:.2e}".format(_pool.price_oracle())
+ ", fee_gamma: {:.2e}".format(_pool.fee_gamma())
+ ", allowed_extra_profit: {:.2e}".format(_pool.allowed_extra_profit())
+ ", adjustment_step: {:.2e}".format(_pool.adjustment_step())
+ "\n coin 0 has {} decimals".format(tokens[0].decimals())
+ "\n coin 1 has {} decimals".format(tokens[1].decimals())
)
return _pool


if __name__ == "__main__":
print(stableswap_factory().example())
print(stable_pool().example())

0 comments on commit 12c82f7

Please sign in to comment.