Skip to content

Commit

Permalink
Merge branch 'main' into adjust-LRNA-for-fees
Browse files Browse the repository at this point in the history
  • Loading branch information
poliwop committed Jun 27, 2023
2 parents 890f330 + c3bea45 commit 4b8c28b
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 20 deletions.
8 changes: 7 additions & 1 deletion hydradx/model/amm/omnipool_amm.py
Original file line number Diff line number Diff line change
Expand Up @@ -912,8 +912,14 @@ def execute_add_liquidity(
) -> tuple[OmnipoolState, Agent]:
"""Compute new state after liquidity addition"""

if quantity <= 0:
return state.fail_transaction('Quantity must be non-negative.', agent)

delta_Q = lrna_price(state, tkn_add) * quantity
if not (state.unique_id, tkn_add) in agent.holdings:
if (state.unique_id, tkn_add) in agent.holdings:
if agent.holdings[(state.unique_id, tkn_add)] != 0:
return state.fail_transaction(f'Agent already has liquidity in pool {tkn_add}.', agent)
else:
agent.holdings[(state.unique_id, tkn_add)] = 0

if agent.holdings[tkn_add] < quantity:
Expand Down
76 changes: 57 additions & 19 deletions hydradx/tests/test_omnipool_amm.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,40 @@ def test_add_liquidity(initial_state: oamm.OmnipoolState):
raise AssertionError(f'legal transaction failed against weight limit in {i} ({new_state.fail})')


@settings(max_examples=1)
@given(omnipool_config(token_count=3, lrna_fee=0, asset_fee=0))
def test_add_liquidity_with_existing_position_fails(initial_state: oamm.OmnipoolState):
old_state = initial_state
tkn = old_state.asset_list[0]
old_agent = Agent(
holdings={tkn: old_state.liquidity[tkn] / 10, (old_state.unique_id, tkn): old_state.shares[tkn] / 10}
)

delta_R = old_agent.holdings[tkn]

new_state, new_agents = oamm.add_liquidity(old_state, old_agent, delta_R, tkn)

if not new_state.fail:
raise AssertionError(f'Adding liquidity to an existing position should fail.')


@settings(max_examples=1)
@given(omnipool_config(token_count=3, lrna_fee=0, asset_fee=0))
def test_add_liquidity_with_quantity_zero_should_fail(initial_state: oamm.OmnipoolState):
old_state = initial_state
tkn = old_state.asset_list[0]
old_agent = Agent(
holdings={tkn: old_state.liquidity[tkn] / 10, (old_state.unique_id, tkn): old_state.shares[tkn] / 10}
)

delta_R = 0

new_state, new_agents = oamm.add_liquidity(old_state, old_agent, delta_R, tkn)

if not new_state.fail:
raise AssertionError(f'Adding liquidity with quantity zero should fail.')


@given(omnipool_config(token_count=3, withdrawal_fee=False))
def test_remove_liquidity_no_fee(initial_state: oamm.OmnipoolState):
i = initial_state.asset_list[2]
Expand Down Expand Up @@ -1545,52 +1579,56 @@ def test_volatility_limit(omnipool: oamm.OmnipoolState):
def test_LP_limits(omnipool: oamm.OmnipoolState, max_withdrawal_per_block, max_lp_per_block):
omnipool.max_withdrawal_per_block = max_withdrawal_per_block
omnipool.max_lp_per_block = max_lp_per_block
agent = Agent(holdings={'HDX': 10000000000})
state = omnipool.copy()
initial_agent = Agent(holdings={'HDX': 10000000000})
agent = initial_agent.copy()
oamm.execute_add_liquidity(
state=omnipool,
state=state,
agent=agent,
tkn_add='HDX',
quantity=omnipool.liquidity['HDX'] * max_lp_per_block
quantity=state.liquidity['HDX'] * max_lp_per_block
)
if omnipool.fail:
if state.fail:
raise AssertionError('Valid LP operation failed.')
omnipool.update()
state = omnipool.copy()
agent = initial_agent.copy()
oamm.execute_add_liquidity(
state=omnipool,
state=state,
agent=agent,
tkn_add='HDX',
quantity=omnipool.liquidity['HDX'] * max_lp_per_block + 1
quantity=state.liquidity['HDX'] * max_lp_per_block + 1
)
if not omnipool.fail:
if not state.fail:
raise AssertionError('Invalid LP operation succeeded.')
omnipool.update()
state = omnipool.copy()
agent = initial_agent.copy()
# add liquidity again to test remove liquidity
oamm.execute_add_liquidity(
state=omnipool,
state=state,
agent=agent,
tkn_add='HDX',
quantity=omnipool.liquidity['HDX'] * max_lp_per_block
quantity=state.liquidity['HDX'] * max_lp_per_block
)
if omnipool.fail:
if state.fail:
raise AssertionError('Second LP operation failed.')
withdraw_quantity = agent.holdings[('omnipool', 'HDX')]
total_shares = omnipool.shares['HDX']
total_shares = state.shares['HDX']
oamm.execute_remove_liquidity(
state=omnipool,
state=state,
agent=agent,
tkn_remove='HDX',
quantity=withdraw_quantity # agent.holdings[('omnipool', 'HDX')]
)
if withdraw_quantity / total_shares > max_withdrawal_per_block and not omnipool.fail:
if withdraw_quantity / total_shares > max_withdrawal_per_block and not state.fail:
raise AssertionError('Agent was able to remove too much liquidity.')
omnipool.update()
state.update()
oamm.execute_remove_liquidity(
state=omnipool,
state=state,
agent=agent,
tkn_remove='HDX',
quantity=omnipool.shares['HDX'] * max_withdrawal_per_block
quantity=state.shares['HDX'] * max_withdrawal_per_block
)
if omnipool.fail:
if state.fail:
raise AssertionError('Agent was not able to remove liquidity.')


Expand Down

0 comments on commit 4b8c28b

Please sign in to comment.