Skip to content

Commit

Permalink
Model lp fees (#140)
Browse files Browse the repository at this point in the history
* this looks like quite a clean way to observe fees collected

* re-ran with better parameter distribution

* narrowed consideration of trade volume % to just TKN

* added a section with just two trades

* deleted excess and made a clear chart

* added a disclaimer

* Implemented LRNA mint for asset fee - WIP

* Simpler version of the test, which works

* Extend to fuzz Omnipool state, fee

* Added spec change for LRNA specified LRNA trade

* Implemented for LRNA sales, added test

* Fixed SwapLRNA.ipynb spec omission

Specced LRNA mint in Spec.ipynb

* Implemented LRNA mint for swaps between assets

* Code cleanup

* Relaxed test_swap_lrna to allow LRNA minting during swap

* Extended to allow a custom percentage of LRNA mint to be enabled

* Added test to check lrna_mint_pct

* Moved the mint coefficient to Omnipool configuration

* PR cleanup

* edited description and moved it to the top

* added fee analysis notebook

* Failing test does not reproduce locally, even using reproduce_failure decorator. Loosening acceptable error in hope this resolves issue.

* new version of notebook

* re-ran notebook, finalized result

* looked at fees again with the new mechanism, confirmed that revenue for LPs is approximately double

* curve style fees in stableswap (#137)

* changed withdrawal fee for stableswap to match our runtime implementation

* allow more control over which assets are traded in back_and_forth

* increased max trade volume to 5%, changed trade strategy, and added a graph at the bottom which separately extrapolates to one year

* corrected back_and_forth trade strategy

* some minor corrections

* got rid of simulation and graph line for 0-trade scenario

* deleted some useless lines

* clarified a few things

* Reverting changes to specification

---------

Co-authored-by: poliwop <grove.colin@gmail.com>
  • Loading branch information
jepidoptera and poliwop committed Jul 21, 2023
1 parent 12edbd3 commit edf0659
Show file tree
Hide file tree
Showing 5 changed files with 648 additions and 13 deletions.
24 changes: 17 additions & 7 deletions hydradx/model/amm/omnipool_amm.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ def __init__(self,
remove_liquidity_volatility_threshold: float = 0,
withdrawal_fee: bool = True,
min_withdrawal_fee: float = 0.0001,
lrna_mint_pct: float = 0.0,
):
"""
tokens should be a dict in the form of [str: dict]
Expand Down Expand Up @@ -72,6 +73,7 @@ def __init__(self,
self.max_withdrawal_per_block = max_withdrawal_per_block
self.max_lp_per_block = max_lp_per_block
self.remove_liquidity_volatility_threshold = remove_liquidity_volatility_threshold
self.lrna_mint_pct = lrna_mint_pct
self.withdrawal_fee = withdrawal_fee
if withdrawal_fee:
self.min_withdrawal_fee = min_withdrawal_fee
Expand Down Expand Up @@ -422,8 +424,10 @@ def execute_swap(
)
# lrna_fee = state.last_lrna_fee[tkn_buy]

delta_Qj = -delta_Qi * (1 - lrna_fee)
delta_Rj = state.liquidity[tkn_buy] * -delta_Qj / (state.lrna[tkn_buy] + delta_Qj) * (1 - asset_fee)
delta_Qt = -delta_Qi * (1 - lrna_fee)
delta_Qm = (state.lrna[tkn_buy] + delta_Qt) * delta_Qt * asset_fee / state.lrna[tkn_buy] * state.lrna_mint_pct
delta_Qj = delta_Qt + delta_Qm
delta_Rj = state.liquidity[tkn_buy] * -delta_Qt / (state.lrna[tkn_buy] + delta_Qt) * (1 - asset_fee)
delta_L = min(-delta_Qi * lrna_fee, -state.lrna_imbalance)
delta_QH = -lrna_fee * delta_Qi - delta_L

Expand Down Expand Up @@ -491,11 +495,14 @@ def execute_lrna_swap(
return state.fail_transaction('insufficient lrna in pool', agent)
delta_ra = -state.liquidity[tkn] * delta_qa / (-delta_qa + state.lrna[tkn]) * (1 - asset_fee)

delta_qm = asset_fee * (-delta_qa) / state.lrna[tkn] * (state.lrna[tkn] - delta_qa) * state.lrna_mint_pct
delta_q = delta_qm - delta_qa

if modify_imbalance:
q = state.lrna_total
state.lrna_imbalance += delta_qa * (q + state.lrna_imbalance) / (q - delta_qa) + delta_qa
state.lrna_imbalance += -delta_q * (q + state.lrna_imbalance) / (q + delta_q) - delta_q

state.lrna[tkn] += -delta_qa
state.lrna[tkn] += delta_q
state.liquidity[tkn] += -delta_ra

elif delta_ra > 0:
Expand All @@ -504,13 +511,16 @@ def execute_lrna_swap(
return state.fail_transaction('insufficient assets in pool', agent)
elif delta_ra > agent.holdings[tkn]:
return state.fail_transaction('agent has insufficient assets', agent)
delta_qa = -state.lrna[tkn] * delta_ra / (state.liquidity[tkn] * (1 - asset_fee) - delta_ra)
denom = (state.liquidity[tkn] * (1 - asset_fee) - delta_ra)
delta_qa = -state.lrna[tkn] * delta_ra / denom
delta_qm = - asset_fee * (1 - asset_fee) * (state.liquidity[tkn] / denom) * delta_qa * state.lrna_mint_pct
delta_q = -delta_qa + delta_qm

if modify_imbalance:
q = state.lrna_total
state.lrna_imbalance += delta_qa * (q + state.lrna_imbalance) / (q - delta_qa) + delta_qa
state.lrna_imbalance -= delta_q * (q + state.lrna_imbalance) / (q + delta_q) + delta_q

state.lrna[tkn] += -delta_qa
state.lrna[tkn] += delta_q
state.liquidity[tkn] += -delta_ra

# buying LRNA
Expand Down
5 changes: 3 additions & 2 deletions hydradx/model/amm/trade_strategies.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,9 @@ def back_and_forth(
def strategy(state: GlobalState, agent_id: str):
omnipool: OmnipoolState = state.pools[pool_id]
agent: Agent = state.agents[agent_id]
for i in range(len(omnipool.asset_list)):
asset = omnipool.asset_list[i]
assets = list(set(agent.asset_list) & set(omnipool.asset_list))
for asset in assets:
# asset = agent.asset_list[i]
dr = percentage / 2 * omnipool.liquidity[asset]
lrna_init = state.agents[agent_id].holdings['LRNA']
oamm.execute_swap(omnipool, agent, tkn_sell=asset, tkn_buy='LRNA', sell_quantity=dr, modify_imbalance=False)
Expand Down
328 changes: 328 additions & 0 deletions hydradx/notebooks/Omnipool/LP_fees_analysis.ipynb

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion hydradx/tests/test_omnipool_agents.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ def test_omnipool_arbitrager_feeless(omnipool: oamm.OmnipoolState, market: list,

# Trading should be profitable
if old_value > new_value:
if new_value != pytest.approx(old_value, rel=1e-15):
if new_value != pytest.approx(old_value, rel=1e-12):
raise


Expand Down
Loading

0 comments on commit edf0659

Please sign in to comment.