Skip to content

Commit

Permalink
feat: functioning pool fixture
Browse files Browse the repository at this point in the history
  • Loading branch information
heswithme committed Oct 14, 2024
1 parent 98f103e commit db695d0
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 75 deletions.
2 changes: 1 addition & 1 deletion scripts/debug_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def main():
# Pytest arguments
pytest_args = [
"-s", # Do not capture output, allowing you to see print statements and debug info
"tests/unitary/twa", # Specific test to run
"tests/integration/test_stableswap.py", # Specific test to run
# '--maxfail=1', # Stop after the firstD failure
"--tb=short", # Shorter traceback for easier reading
"-rA", # Show extra test summary info
Expand Down
27 changes: 13 additions & 14 deletions tests/integration/address_book.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,20 @@
factory_twocrypto_ng = "0x98EE851a00abeE0d95D08cF4CA2BdCE32aeaAF7F"
factory_tricrypto_ng = "0x0c0e5f2fF0ff18a3be9b835635039256dC4B4963"

stables = {
"dai": {"address": "0x6b175474e89094c44da98b954eedeac495271d0f", "asset_type": 0},
"usdt": {"address": "0xdac17f958d2ee523a2206206994597c13d831ec7", "asset_type": 0},
"usdc": {"address": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", "asset_type": 0},
"usde": {"address": "0x4c9edd5852cd905f086c759e8383e09bff1e68b3", "asset_type": 0},
"frax": {"address": "0x853d955acef822db058eb8505911ed77f175b99e", "asset_type": 0},
}

yield_stables = {
"sdai": {"address": "0x83f20f44975d03b1b09e64809b757c47f942beea", "asset_type": 3},
"sfrax": {"address": "0xa663b02cf0a4b149d2ad41910cb81e23e1c41c32", "asset_type": 3},
"susde": {"address": "0x9d39a5de30e57443bff2a8307a4256c8797a3497", "asset_type": 3},
}
stables = [
{"name": "dai", "address": "0x6b175474e89094c44da98b954eedeac495271d0f", "asset_type": 0},
{"name": "usdt", "address": "0xdac17f958d2ee523a2206206994597c13d831ec7", "asset_type": 0},
{"name": "usdc", "address": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", "asset_type": 0},
{"name": "usde", "address": "0x4c9edd5852cd905f086c759e8383e09bff1e68b3", "asset_type": 0},
{"name": "frax", "address": "0x853d955acef822db058eb8505911ed77f175b99e", "asset_type": 0},
]

all_stables = {**stables, **yield_stables}
yield_stables = [
{"name": "sdai", "address": "0x83f20f44975d03b1b09e64809b757c47f942beea", "asset_type": 3},
{"name": "sfrax", "address": "0xa663b02cf0a4b149d2ad41910cb81e23e1c41c32", "asset_type": 3},
{"name": "susde", "address": "0x9d39a5de30e57443bff2a8307a4256c8797a3497", "asset_type": 3},
]
all_stables = [*stables, *yield_stables]

cryptos = {
"weth": {"address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"},
Expand Down
97 changes: 52 additions & 45 deletions tests/integration/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,40 +97,41 @@ def dev_address():


@pytest.fixture(scope="module")
def all_stablecoins():
return [ab.dai, ab.usdt, ab.usdc, ab.usde, ab.frax]
def stableswap_factory():
return boa.from_etherscan(ab.factory_stableswap_ng, "factory_stableswap_ng")


@pytest.fixture(scope="module")
def all_yield_stables():
return [ab.sdai, ab.sfrax, ab.susde]
def paired_tokens(request):
# This fixture is used to get upstream parametrization and populate the contracts
# Retrieve paired token combinations via request.param
tokens_list = request.param
# update the dict with contracts
for token in tokens_list:
token["contract"] = boa.from_etherscan(token["address"], token["name"])
return tokens_list


@pytest.fixture(scope="module")
def all_cryptos():
return [ab.weth, ab.steth, ab.wbtc, ab.tbtc]


@pytest.fixture(scope="module")
def stableswap_pool(request, vault, dev_address):
factory = boa.from_etherscan(ab.factory_stableswap_ng, "factory_stableswap_ng")

def stableswap_pool(stableswap_factory, vault, dev_address, paired_tokens):
# Retrieve token addresses and asset types from request.param
token_combo = request.param
coins = [vault.address] + [token["address"] for token in token_combo]
asset_types = [3] + [token.get("asset_type") for token in token_combo]

pool_size = 2
A = 2000
fee = 1000000
ma_exp_time = 866
implementation_idx = 0
pool_tokens = [
{"asset_type": 3, "name": "scrvusd", "address": vault.address, "contract": vault},
*paired_tokens,
]
coins = [token["address"] for token in pool_tokens]
asset_types = [token.get("asset_type") for token in pool_tokens]

pool_size = len(coins)
# pool parameters
A, fee, ma_exp_time, implementation_idx = (2000, 1000000, 866, 0)
method_ids = [b""] * pool_size
oracles = ["0x0000000000000000000000000000000000000000"] * pool_size
OFFPEG_FEE_MULTIPLIER = 20000000000

# deploy pool
with boa.env.prank(dev_address):
pool = factory.deploy_plain_pool(
pool_address = stableswap_factory.deploy_plain_pool(
"pool_name",
"POOL",
coins,
Expand All @@ -144,29 +145,35 @@ def stableswap_pool(request, vault, dev_address):
oracles,
)
pool_interface = boa.load_vyi("tests/integration/interfaces/CurveStableSwapNG.vyi")

return pool_interface.at(pool)


@pytest.fixture
def add_liquidity(request, vault, dev_address):
"""Fixture to add liquidity to a deployed pool."""

# Retrieve token addresses and asset types from request.param
token_combo = request.param
paired_tokens = [token["address"] for token in token_combo]
token_contracts = [vault] + [boa.from_etherscan(token, "token") for token in paired_tokens]
decimals = [token.decimals() for token in token_contracts]

# Fund `dev_address` with each token
for i, token in enumerate(token_contracts):
boa.deal(token, dev_address, 10_000_000 * 10 ** decimals[i])

# # Call add_liquidity from alice's account
# with boa.env.prank(alice):
# stableswap_pool.add_liquidity([deposit_amount] * n_coins, 0) # Use 0 for min_mint_amount

return stableswap_pool # Return pool with added liquidity
pool = pool_interface.at(pool_address)
# fund dev with tokens (free-mint erc20s and deposit vaults)
AMOUNT_STABLE = 1_000_000
dev_balances = []
for token in pool_tokens:
if token["asset_type"] == 0:
boa.deal(
token["contract"], dev_address, AMOUNT_STABLE * 10 ** token["contract"].decimals()
)
elif token["asset_type"] == 3:
underlying_token = token["contract"].asset()
underlying_contract = boa.from_etherscan(underlying_token, "token")
decimals = underlying_contract.decimals()
boa.deal(
underlying_contract,
dev_address,
AMOUNT_STABLE * 10**decimals,
)
underlying_contract.approve(
token["contract"],
AMOUNT_STABLE * 10**decimals,
sender=dev_address,
)
token["contract"].deposit(AMOUNT_STABLE * 10**decimals, dev_address, sender=dev_address)
# Approve pool to spend vault tokens
token["contract"].approve(pool, 2**256 - 1, sender=dev_address)
dev_balances.append(token["contract"].balanceOf(dev_address))
pool.add_liquidity(dev_balances, 0, dev_address, sender=dev_address)
return pool


@pytest.fixture(scope="module")
Expand Down
20 changes: 11 additions & 9 deletions tests/integration/test_stableswap.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
import pytest

from utils import generate_token_combinations
from utils import generate_list_combinations
import address_book as ab


@pytest.mark.parametrize(
"stableswap_pool",
generate_token_combinations(ab.all_stables), # Generate token combinations
indirect=True, # Pass token combinations to the fixture
)
def test_stableswap_pool_with_liquidity(stableswap_pool, add_liquidity):
N_COMBINATIONS = 1 # num of combinations in stableswap tests (>=36 => all combinations)

# produce tokens for stableswap to pair against crvusd
paired_token_combinations = generate_list_combinations(ab.all_stables, [1, 2], randomize=True)
tokens_subset = paired_token_combinations[0:N_COMBINATIONS]


@pytest.mark.parametrize("paired_tokens", tokens_subset, indirect=True)
def test_stableswap_pool_with_liquidity(stableswap_pool, paired_tokens):
"""
Test deploying stableswap pool with different token combinations,
then adds liquidity to the pool and checks balances.
"""

# Check balances in the pool after adding liquidity
n_coins = stableswap_pool.n_coins()
n_coins = stableswap_pool.N_COINS()
print(f"n_coins: {n_coins}")
for i in range(n_coins):
print(f"balance {i}: {stableswap_pool.balances(i)}")
14 changes: 8 additions & 6 deletions tests/integration/utils.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
from itertools import combinations
import address_book as ab
import random


def generate_token_combinations(other_tokens):
"""Generate all unique combinations with my_token and 1–2 other tokens."""
def generate_list_combinations(data_list, combo_sizes, randomize=False):
combos = []
for count in range(1, 3): # for 2 or 3 tokens in total
for combo in combinations(other_tokens.values(), count):
combos.append([*combo])
for count in combo_sizes:
for combo in combinations(data_list, count):
combos.append(list(combo)) # Convert each combination to a list
if randomize:
random.shuffle(combos)
return combos


# test functionality if run as a script
if __name__ == "__main__":
combos = generate_token_combinations(ab.all_stables)
combos = generate_list_combinations(ab.all_stables, [1, 2])
print(combos)
print(len(combos))

0 comments on commit db695d0

Please sign in to comment.