Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Model lp fees #140

Merged
merged 38 commits into from
Jul 21, 2023
Merged
Show file tree
Hide file tree
Changes from 37 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
5912659
this looks like quite a clean way to observe fees collected
jepidoptera May 26, 2023
5318427
re-ran with better parameter distribution
jepidoptera May 29, 2023
997f8cb
narrowed consideration of trade volume % to just TKN
jepidoptera Jun 5, 2023
5d3715e
added a section with just two trades
jepidoptera Jun 8, 2023
e9fcd5d
deleted excess and made a clear chart
jepidoptera Jun 13, 2023
d34116a
added a disclaimer
jepidoptera Jun 13, 2023
dc80555
Implemented LRNA mint for asset fee - WIP
poliwop Jun 15, 2023
b80c3e0
Simpler version of the test, which works
poliwop Jun 15, 2023
a6a651e
Extend to fuzz Omnipool state, fee
poliwop Jun 16, 2023
f69a342
Added spec change for LRNA specified LRNA trade
poliwop Jun 16, 2023
fdbd814
Implemented for LRNA sales, added test
poliwop Jun 16, 2023
80d255b
Fixed SwapLRNA.ipynb spec omission
poliwop Jun 16, 2023
a64a1b9
Implemented LRNA mint for swaps between assets
poliwop Jun 16, 2023
7259585
Code cleanup
poliwop Jun 16, 2023
f51e468
Relaxed test_swap_lrna to allow LRNA minting during swap
poliwop Jun 16, 2023
b4df0bf
Extended to allow a custom percentage of LRNA mint to be enabled
poliwop Jun 19, 2023
c195af2
Added test to check lrna_mint_pct
poliwop Jun 19, 2023
8ccb9d2
Moved the mint coefficient to Omnipool configuration
poliwop Jun 19, 2023
4b4051f
PR cleanup
poliwop Jun 19, 2023
19d73d1
edited description and moved it to the top
jepidoptera Jun 19, 2023
0f8af9a
added fee analysis notebook
jepidoptera Jun 20, 2023
545981d
Failing test does not reproduce locally, even using reproduce_failure…
poliwop Jun 21, 2023
06462a2
new version of notebook
poliwop Jun 22, 2023
91052f4
re-ran notebook, finalized result
jepidoptera Jun 26, 2023
f33dc79
looked at fees again with the new mechanism, confirmed that revenue f…
jepidoptera Jun 27, 2023
cc5b0cc
Merge branch 'main' into model-LP-fees
jepidoptera Jun 27, 2023
890f330
curve style fees in stableswap (#137)
jepidoptera Jun 21, 2023
4b8c28b
Merge branch 'main' into adjust-LRNA-for-fees
poliwop Jun 27, 2023
272711c
allow more control over which assets are traded in back_and_forth
jepidoptera Jul 12, 2023
68c6262
increased max trade volume to 5%, changed trade strategy, and added a…
jepidoptera Jul 12, 2023
2d70410
Merge branch 'main' into model-LP-fees
jepidoptera Jul 12, 2023
0db222f
corrected back_and_forth trade strategy
jepidoptera Jul 12, 2023
4d4ac6a
some minor corrections
jepidoptera Jul 12, 2023
476e72b
got rid of simulation and graph line for 0-trade scenario
jepidoptera Jul 13, 2023
8f8b7c7
deleted some useless lines
jepidoptera Jul 13, 2023
d5cf604
clarified a few things
jepidoptera Jul 13, 2023
16c0f14
Merge branch 'adjust-LRNA-for-fees' into model-LP-fees
jepidoptera Jul 13, 2023
51a6fba
Reverting changes to specification
poliwop Jul 18, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.

25 changes: 18 additions & 7 deletions hydradx/spec/Swap.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,10 @@
"$$\n",
"\\begin{align}\n",
"\\Delta Q_i &= Q_i\\frac{- \\Delta R_i}{R_i + \\Delta R_i}\\\\\n",
"\\Delta Q_j' &= -\\Delta Q_i (1 - f_P)\\\\\n",
"\\Delta R_j' &= R_j\\frac{- \\Delta Q_j'}{Q_j + \\Delta Q_j'}\\\\\n",
"\\Delta Q_j^t' &= -\\Delta Q_i (1 - f_P)\\\\\n",
jepidoptera marked this conversation as resolved.
Show resolved Hide resolved
"\\Delta Q_j^m &= \\frac{(Q + \\Delta Q_j^t') \\Delta Q_j^t' f_A}{Q_j}\\\\\n",
"\\Delta Q_j &= \\Delta Q_j^t' + \\Delta Q_j^m\\\\\n",
"\\Delta R_j' &= R_j\\frac{- \\Delta Q_j^t'}{Q_j + \\Delta Q_j^t'}\\\\\n",
"\\Delta R_j &= \\Delta R_j'(1 - f_A)\n",
"\\end{align}\n",
"$$"
Expand Down Expand Up @@ -132,8 +134,10 @@
"$$\n",
"\\begin{align}\n",
"\\Delta Q_i &= Q_i \\frac{-\\Delta R_i}{R_i + \\Delta R_i}\\\\\n",
"\\Delta Q_j &= -\\Delta Q_i(1 - f_P)\\\\\n",
"\\Delta R_j &= R_j \\frac{-\\Delta Q_j}{Q_j + \\Delta Q_j}(1 - f_A)\\\\\n",
"\\Delta Q_j^t &= -\\Delta Q_i(1 - f_P)\\\\\n",
"\\Delta Q_j^m &= \\frac{(Q_j + \\Delta Q_j^t)\\Delta Q_j^t f_A}{Q_j}\\\\\n",
"\\Delta Q_j &= \\Delta Q_j^t + \\Delta Q_j^m\\\\\n",
"\\Delta R_j &= R_j \\frac{-\\Delta Q_j^t}{Q_j^t + \\Delta Q_j^t}(1 - f_A)\\\\\n",
"\\Delta L &= min(-\\Delta Q_i f_P, -L)\\\\\n",
"\\Delta Q_H &= -\\Delta Q_i f_P - \\Delta L\n",
"\\end{align}\n",
Expand All @@ -148,8 +152,10 @@
"### $\\Delta R_j < 0$ provided\n",
"$$\n",
"\\begin{align}\n",
"\\Delta Q_j &= Q_j\\frac{-\\Delta R_j}{R_j(1 - f_A) + \\Delta R_j}\\\\\n",
"\\Delta Q_i &= -\\frac{\\Delta Q_j}{1 - f_P}\\\\\n",
"\\Delta Q_j^t &= Q_j\\frac{-\\Delta R_j}{R_j(1 - f_A) + \\Delta R_j}\\\\\n",
"\\Delta Q_j^m &= \\frac{f_A(1 - f_A) R_j}{R_j(1 - f_A) + \\Delta R_j}\\Delta Q_j^t\\\\\n",
"\\Delta Q_j &= \\Delta Q_j^t + \\Delta Q_j^m\\\\\n",
"\\Delta Q_i &= -\\frac{\\Delta Q_j^t}{1 - f_P}\\\\\n",
"\\Delta R_i &= R_i\\frac{-\\Delta Q_i}{Q_i + \\Delta Q_i}\\\\\n",
"\\Delta L &= min(-\\Delta Q_i f_P, -L)\\\\\n",
"\\Delta Q_H &= -\\Delta Q_i f_P - \\Delta L\n",
Expand Down Expand Up @@ -181,7 +187,12 @@
"cell_type": "code",
"execution_count": null,
"id": "b2e739d5-22a0-4a72-a479-1337339b5d04",
"metadata": {},
"metadata": {
"ExecuteTime": {
"end_time": "2023-06-16T17:39:54.078367641Z",
"start_time": "2023-06-16T17:39:54.067954002Z"
}
},
"outputs": [],
"source": []
}
Expand Down
70 changes: 44 additions & 26 deletions hydradx/spec/SwapLRNA.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@
"cell_type": "code",
"execution_count": 5,
"id": "74c2097f-82ff-45a3-90d5-37dcea976d40",
"metadata": {},
"metadata": {
"ExecuteTime": {
"end_time": "2023-06-16T17:38:58.073637337Z",
"start_time": "2023-06-16T17:38:58.044598411Z"
}
},
"outputs": [],
"source": [
"import os\n",
Expand Down Expand Up @@ -88,8 +93,10 @@
"source": [
"$$\n",
"\\begin{align}\n",
"\\Delta Q_i &= -\\Delta q^\\alpha\\\\\n",
"\\Delta R_i &= R_i\\frac{- \\Delta Q_i}{Q_i + \\Delta Q_i}(1 - f_A)\\\\\n",
"\\Delta Q_i^t &= -\\Delta q^\\alpha\\\\\n",
"\\Delta Q_i^m &= f_A \\left(Q + \\Delta Q_i^t\\right)\\frac{\\Delta Q_i^t}{Q}\\\\\n",
"\\Delta Q_i &= \\Delta Q_i^t + \\Delta Q_i^m\\\\\n",
"\\Delta R_i &= R_i\\frac{- \\Delta Q_i^t}{Q_i + \\Delta Q_i^t}(1 - f_A)\\\\\n",
"\\Delta L &= -\\frac{\\Delta Q_i (Q + L)}{Q + \\Delta Q_i} - \\Delta Q_i\\\\\n",
"\\Delta r_i^\\alpha &= - \\Delta R_i\\\\\n",
"\\end{align}\n",
Expand All @@ -100,14 +107,19 @@
"cell_type": "code",
"execution_count": 6,
"id": "f33e16b1-0277-4288-be82-6c289631c224",
"metadata": {},
"metadata": {
"ExecuteTime": {
"end_time": "2023-06-16T17:38:58.096588049Z",
"start_time": "2023-06-16T17:38:58.068489841Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"def swap_lrna_delta_Ri(state: OmnipoolState, delta_qi: float, i: str) -> float:\n",
" return state.liquidity[i] * (- delta_qi / (state.lrna[i] + delta_qi))\n",
"def swap_lrna_delta_Qi(state: OmnipoolState, delta_ri: float, i: str) -> float:\n",
" return state.lrna[i] * (- delta_ri / (state.liquidity[i] + delta_ri))\n",
"\n"
]
}
Expand All @@ -132,9 +144,11 @@
"$$\n",
"\\begin{align}\n",
"\\Delta R_i &= -\\Delta r_i^\\alpha\\\\\n",
"\\Delta Q_i &= Q_i\\frac{-\\Delta R_i}{R_i(1 - f_A) + \\Delta R_i}\\\\\n",
"\\Delta Q_i^t &= Q_i\\frac{-\\Delta R_i}{R_i(1 - f_A) + \\Delta R_i}\\\\\n",
"\\Delta Q_i^m &= \\frac{f_A (1 - f_A) R_i}{R_i(1 - f_A) + \\Delta R_i} \\Delta Q_i^t\\\\\n",
"\\Delta Q_i &= \\Delta Q_i^t + \\Delta Q_i^m\\\\\n",
"\\Delta L &= -\\frac{\\Delta Q_i (Q + L)}{Q + \\Delta Q_i} - \\Delta Q_i\\\\\n",
"\\Delta q^\\alpha &= - \\Delta Q_i\\\\\n",
"\\Delta q^\\alpha &= - \\Delta Q_i^t\\\\\n",
"\\end{align}\n",
"$$\n",
"\n",
Expand All @@ -145,14 +159,20 @@
"cell_type": "code",
"execution_count": 7,
"id": "6f056d9c-4982-4d82-9748-8d2e6cb5b2a2",
"metadata": {},
"metadata": {
"ExecuteTime": {
"end_time": "2023-06-16T17:38:58.143398075Z",
"start_time": "2023-06-16T17:38:58.074524296Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"def swap_lrna_delta_Qi(state: OmnipoolState, delta_ri: float, i: str) -> float:\n",
" return state.lrna[i] * (- delta_ri / (state.liquidity[i] + delta_ri))\n",
"def asset_invariant(state: OmnipoolState, i: str) -> float:\n",
" \"\"\"Invariant for specific asset\"\"\"\n",
" return state.liquidity[i] * state.lrna[i]\n",
"\n"
]
}
Expand All @@ -165,25 +185,19 @@
"cell_type": "code",
"execution_count": 8,
"id": "bd16beca-63b8-4864-bc1d-3decce681cb8",
"metadata": {},
"metadata": {
"ExecuteTime": {
"end_time": "2023-06-16T17:38:58.144059900Z",
"start_time": "2023-06-16T17:38:58.116900980Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"def swap_lrna(\n",
" old_state: OmnipoolState,\n",
" old_agent: Agent,\n",
" delta_ra: float = 0,\n",
" delta_qa: float = 0,\n",
" tkn: str = ''\n",
") -> tuple[OmnipoolState, Agent]:\n",
" \"\"\"Compute new state after LRNA swap\"\"\"\n",
"\n",
" new_state = old_state.copy()\n",
" new_agent = old_agent.copy()\n",
"\n",
" return new_state.execute_lrna_swap(new_agent, delta_ra, delta_qa, tkn)\n",
"def weight_i(state: OmnipoolState, i: str) -> float:\n",
" return state.lrna[i] / state.lrna_total\n",
"\n"
]
}
Expand All @@ -198,7 +212,11 @@
"outputs": [],
"source": [],
"metadata": {
"collapsed": false
"collapsed": false,
"ExecuteTime": {
"end_time": "2023-06-16T17:38:58.144273343Z",
"start_time": "2023-06-16T17:38:58.117260530Z"
}
}
}
],
Expand Down
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