Skip to content

Commit de30a6c

Browse files
committed
fixed xyk tests
1 parent 70d5bc3 commit de30a6c

2 files changed

Lines changed: 53 additions & 11 deletions

File tree

hydradx/model/amm/xyk_amm.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,11 @@ def buy_limit(self, tkn_buy, tkn_sell):
7575

7676
def calculate_buy_from_sell(self, tkn_buy, tkn_sell, sell_quantity):
7777
x, y = self.liquidity[tkn_sell], self.liquidity[tkn_buy]
78-
return y * (- sell_quantity / (x + sell_quantity)) * (1 - self.trade_fee)
78+
return y * sell_quantity / (x + sell_quantity) * (1 - self.trade_fee)
7979

8080
def calculate_sell_from_buy(self, tkn_buy, tkn_sell, buy_quantity):
8181
x, y = self.liquidity[tkn_sell], self.liquidity[tkn_buy]
82-
return x * (- buy_quantity / (buy_quantity + y * (1 - self.trade_fee)))
82+
return x * (buy_quantity / (-buy_quantity + y * (1 - self.trade_fee)))
8383

8484
def price(self, tkn, denomination: str = ''):
8585
"""

hydradx/tests/test_xyk_amm.py

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import copy
22
import math
3+
from datetime import timedelta
34

45
import pytest
56
from hypothesis import given, strategies as st, assume, settings, reproduce_failure
@@ -11,6 +12,8 @@
1112
from hydradx.model.amm.agents import Agent
1213
from hydradx.model.amm.xyk_amm import XykState
1314

15+
settings.register_profile("long", deadline=timedelta(milliseconds=500), print_blob=True)
16+
settings.load_profile("long")
1417

1518
def test_xyk_init():
1619
tokens = {'A': 1000, 'B': 2000}
@@ -79,15 +82,54 @@ def test_spot(liq_A, liq_B, fee):
7982
st.floats(min_value=0.001, max_value=0.5)
8083
)
8184
def test_swap(liq_A, liq_B, fee, swap_pct):
85+
from hydradx.model.amm.xyk_amm import simulate_swap
86+
# Test sells
8287
tokens = {'A': liq_A, 'B': liq_B}
83-
xyk = XykState(tokens=tokens)
84-
85-
k_init = xyk.calculate_k()
8688
swap_quantity = tokens['A'] * swap_pct
8789
agent = Agent(holdings={'A': swap_quantity})
88-
89-
# Swap A for B
90-
91-
xyk.swap(agent, 'A', 'B', sell_quantity=swap_quantity)
92-
k_final = xyk.calculate_k()
93-
assert k_init == pytest.approx(k_final, rel=1e-12)
90+
for f in [0.0, fee]:
91+
xyk = XykState(tokens=tokens, trade_fee=f)
92+
k_init = xyk.calculate_k()
93+
for buy_tkn, sell_tkn in [('B', 'A'), ('A', 'B')]:
94+
new_state, new_agent = simulate_swap(xyk, agent, sell_tkn, buy_tkn, sell_quantity=swap_quantity)
95+
if f == 0.0:
96+
k_final = new_state.calculate_k()
97+
else:
98+
fee_taken = (xyk.liquidity[buy_tkn] - new_state.liquidity[buy_tkn]) * f/(1 - f)
99+
k_final = math.sqrt(new_state.liquidity[sell_tkn] * (new_state.liquidity[buy_tkn] - fee_taken))
100+
if k_init != pytest.approx(k_final, rel=1e-12):
101+
raise AssertionError("K value changed after swap")
102+
init_A_total = xyk.liquidity['A'] + agent.get_holdings('A')
103+
final_A_total = new_state.liquidity['A'] + new_agent.get_holdings('A')
104+
init_B_total = xyk.liquidity['B'] + agent.get_holdings('B')
105+
final_B_total = new_state.liquidity['B'] + new_agent.get_holdings('B')
106+
if init_A_total != pytest.approx(final_A_total, rel=1e-12):
107+
raise AssertionError("A total quantity changed after swap")
108+
if init_B_total != pytest.approx(final_B_total, rel=1e-12):
109+
raise AssertionError("B total quantity changed after swap")
110+
111+
# Test buys, feeless
112+
swap_A_quantity = tokens['A'] * swap_pct
113+
swap_B_quantity = tokens['B'] * swap_pct
114+
agent = Agent(enforce_holdings=False)
115+
for f in [0.0, fee]:
116+
xyk = XykState(tokens=tokens, trade_fee=f)
117+
k_init = xyk.calculate_k()
118+
for buy_tkn, sell_tkn in [('B', 'A'), ('A', 'B')]:
119+
buy_quantity = swap_A_quantity if buy_tkn == 'A' else swap_B_quantity
120+
new_state, new_agent = simulate_swap(xyk, agent, sell_tkn, buy_tkn, buy_quantity=buy_quantity)
121+
if f == 0.0:
122+
k_final = new_state.calculate_k()
123+
else:
124+
fee_taken = buy_quantity * f/(1 - f)
125+
k_final = math.sqrt(new_state.liquidity[sell_tkn] * (new_state.liquidity[buy_tkn] - fee_taken))
126+
if k_init != pytest.approx(k_final, rel=1e-12):
127+
raise AssertionError("K value changed after swap")
128+
init_A_total = xyk.liquidity['A'] + agent.get_holdings('A')
129+
final_A_total = new_state.liquidity['A'] + new_agent.get_holdings('A')
130+
init_B_total = xyk.liquidity['B'] + agent.get_holdings('B')
131+
final_B_total = new_state.liquidity['B'] + new_agent.get_holdings('B')
132+
if init_A_total != pytest.approx(final_A_total, rel=1e-12):
133+
raise AssertionError("A total quantity changed after swap")
134+
if init_B_total != pytest.approx(final_B_total, rel=1e-12):
135+
raise AssertionError("B total quantity changed after swap")

0 commit comments

Comments
 (0)